@@ -5,7 +5,14 @@ import { useEffect, useCallback, useRef } from '@wordpress/element';
5
5
import { useDispatch , useSelect } from '@wordpress/data' ;
6
6
import { store as coreStore } from '@wordpress/core-data' ;
7
7
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' ;
9
16
10
17
window . editor = window . editor || { } ;
11
18
@@ -14,6 +21,13 @@ export function useHostBridge( post, editorRef ) {
14
21
const { undo, redo, switchEditorMode } = useDispatch ( editorStore ) ;
15
22
const { getEditedPostAttribute, getEditedPostContent } =
16
23
useSelect ( editorStore ) ;
24
+ const { updateBlock, selectionChange } = useDispatch ( blockEditorStore ) ;
25
+ const {
26
+ getSelectedBlockClientId,
27
+ getBlock,
28
+ getSelectionStart,
29
+ getSelectionEnd,
30
+ } = useSelect ( blockEditorStore ) ;
17
31
18
32
const editContent = useCallback (
19
33
( edits ) => {
@@ -79,6 +93,64 @@ export function useHostBridge( post, editorRef ) {
79
93
switchEditorMode ( mode ) ;
80
94
} ;
81
95
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
+
82
154
return ( ) => {
83
155
delete window . editor . setContent ;
84
156
delete window . editor . setTitle ;
@@ -87,6 +159,7 @@ export function useHostBridge( post, editorRef ) {
87
159
delete window . editor . undo ;
88
160
delete window . editor . redo ;
89
161
delete window . editor . switchEditorMode ;
162
+ delete window . editor . appendTextAtCursor ;
90
163
} ;
91
164
} , [
92
165
editorRef ,
@@ -96,6 +169,12 @@ export function useHostBridge( post, editorRef ) {
96
169
redo ,
97
170
switchEditorMode ,
98
171
undo ,
172
+ getSelectedBlockClientId ,
173
+ getBlock ,
174
+ getSelectionStart ,
175
+ getSelectionEnd ,
176
+ updateBlock ,
177
+ selectionChange ,
99
178
] ) ;
100
179
}
101
180
0 commit comments