Skip to content

Commit 1f75d51

Browse files
committed
feat: Expose appendTextAtCursor bridge method
1 parent 5ef6543 commit 1f75d51

File tree

1 file changed

+80
-1
lines changed

1 file changed

+80
-1
lines changed

src/components/editor/use-host-bridge.js

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@ import { useEffect, useCallback, useRef } from '@wordpress/element';
55
import { useDispatch, useSelect } from '@wordpress/data';
66
import { store as coreStore } from '@wordpress/core-data';
77
import { store as editorStore } from '@wordpress/editor';
8-
import { parse, serialize } from '@wordpress/blocks';
8+
import { parse, serialize, getBlockType } from '@wordpress/blocks';
9+
import { store as blockEditorStore } from '@wordpress/block-editor';
10+
import { insert, create, toHTMLString } from '@wordpress/rich-text';
11+
12+
/**
13+
* Internal dependencies
14+
*/
15+
import { warn } from '../../utils/logger';
916

1017
window.editor = window.editor || {};
1118

@@ -14,6 +21,13 @@ export function useHostBridge( post, editorRef ) {
1421
const { undo, redo, switchEditorMode } = useDispatch( editorStore );
1522
const { getEditedPostAttribute, getEditedPostContent } =
1623
useSelect( editorStore );
24+
const { updateBlock, selectionChange } = useDispatch( blockEditorStore );
25+
const {
26+
getSelectedBlockClientId,
27+
getBlock,
28+
getSelectionStart,
29+
getSelectionEnd,
30+
} = useSelect( blockEditorStore );
1731

1832
const editContent = useCallback(
1933
( edits ) => {
@@ -79,6 +93,64 @@ export function useHostBridge( post, editorRef ) {
7993
switchEditorMode( mode );
8094
};
8195

96+
window.editor.appendTextAtCursor = ( text ) => {
97+
const selectedBlockClientId = getSelectedBlockClientId();
98+
99+
if ( ! selectedBlockClientId ) {
100+
warn( 'Unable to append text: no block selected' );
101+
return false;
102+
}
103+
104+
const block = getBlock( selectedBlockClientId );
105+
106+
if ( ! block ) {
107+
warn(
108+
'Unable to append text: could not retrieve selected block'
109+
);
110+
return false;
111+
}
112+
113+
const blockType = getBlockType( block.name );
114+
const hasContentAttribute = blockType?.attributes?.content;
115+
116+
if ( ! hasContentAttribute ) {
117+
warn(
118+
`Unable to append text: block type ${ block.name } does not support text content`
119+
);
120+
return false;
121+
}
122+
123+
const blockContent = block.attributes?.content || '';
124+
const currentValue = create( { html: blockContent } );
125+
const selectionStart = getSelectionStart();
126+
const selectionEnd = getSelectionEnd();
127+
const newValue = insert(
128+
currentValue,
129+
text,
130+
selectionStart?.offset,
131+
selectionEnd?.offset
132+
);
133+
134+
updateBlock( selectedBlockClientId, {
135+
attributes: {
136+
...block.attributes,
137+
content: toHTMLString( { value: newValue } ),
138+
},
139+
} );
140+
141+
const newCursorPosition =
142+
selectionStart?.offset + text.length || newValue.text.length;
143+
144+
selectionChange( {
145+
clientId: selectionStart?.clientId || selectedBlockClientId,
146+
attributeKey: selectionStart?.attributeKey || 'content',
147+
startOffset: newCursorPosition,
148+
endOffset: newCursorPosition,
149+
} );
150+
151+
return true;
152+
};
153+
82154
return () => {
83155
delete window.editor.setContent;
84156
delete window.editor.setTitle;
@@ -87,6 +159,7 @@ export function useHostBridge( post, editorRef ) {
87159
delete window.editor.undo;
88160
delete window.editor.redo;
89161
delete window.editor.switchEditorMode;
162+
delete window.editor.appendTextAtCursor;
90163
};
91164
}, [
92165
editorRef,
@@ -96,6 +169,12 @@ export function useHostBridge( post, editorRef ) {
96169
redo,
97170
switchEditorMode,
98171
undo,
172+
getSelectedBlockClientId,
173+
getBlock,
174+
getSelectionStart,
175+
getSelectionEnd,
176+
updateBlock,
177+
selectionChange,
99178
] );
100179
}
101180

0 commit comments

Comments
 (0)