@@ -40,6 +40,16 @@ describe('StructuredContentSelectPlugin', () => {
4040 ) ;
4141 }
4242
43+ function pressArrow ( key ) {
44+ const event = new KeyboardEvent ( 'keydown' , { key, bubbles : true } ) ;
45+ let handled = false ;
46+ editor . view . someProp ( 'handleKeyDown' , ( handler ) => {
47+ handled = handler ( editor . view , event ) ;
48+ return handled ;
49+ } ) ;
50+ return handled ;
51+ }
52+
4353 it ( 'selects inline SDT content on first click in editing mode' , ( ) => {
4454 const inlineSdt = schema . nodes . structuredContent . create ( { id : 'inline-1' } , schema . text ( 'Field' ) ) ;
4555 const paragraph = schema . nodes . paragraph . create ( null , [ schema . text ( 'A ' ) , inlineSdt , schema . text ( ' Z' ) ] ) ;
@@ -161,6 +171,63 @@ describe('StructuredContentSelectPlugin', () => {
161171 expect ( ( text . match ( / \u200B / g) ?? [ ] ) . length ) . toBe ( 1 ) ;
162172 } ) ;
163173
174+ it ( 'exits inline SDT with one ArrowRight when only trailing ZWSP slots remain' , ( ) => {
175+ const inlineSdt = schema . nodes . structuredContent . create ( { id : 'inline-1' } , schema . text ( 'Field\u200B\u200B' ) ) ;
176+ const paragraph = schema . nodes . paragraph . create ( null , [ schema . text ( 'A ' ) , inlineSdt , schema . text ( ' Z' ) ] ) ;
177+ applyDoc ( schema . nodes . doc . create ( null , [ paragraph ] ) ) ;
178+
179+ const sdt = findNode ( editor . state . doc , 'structuredContent' ) ;
180+ expect ( sdt ) . not . toBeNull ( ) ;
181+
182+ const contentFrom = sdt . pos + 1 ;
183+ const afterVisibleText = contentFrom + 'Field' . length ;
184+ const afterSdt = sdt . pos + sdt . node . nodeSize ;
185+ editor . view . dispatch ( editor . state . tr . setSelection ( TextSelection . create ( editor . state . doc , afterVisibleText ) ) ) ;
186+
187+ const event = new KeyboardEvent ( 'keydown' , { key : 'ArrowRight' , bubbles : true } ) ;
188+ editor . view . someProp ( 'handleKeyDown' , ( handler ) => handler ( editor . view , event ) ) ;
189+
190+ expect ( editor . state . selection . empty ) . toBe ( true ) ;
191+ expect ( editor . state . selection . from ) . toBe ( afterSdt ) ;
192+ expect ( editor . state . selection . to ) . toBe ( afterSdt ) ;
193+ } ) ;
194+
195+ it ( 'does not exit inline SDT with ArrowRight when a trailing inline leaf remains before ZWSP slots' , ( ) => {
196+ const image = schema . nodes . image . create ( { src : 'image.png' } ) ;
197+ const inlineSdt = schema . nodes . structuredContent . create ( { id : 'inline-1' } , [ image , schema . text ( '\u200B' ) ] ) ;
198+ const paragraph = schema . nodes . paragraph . create ( null , [ schema . text ( 'A ' ) , inlineSdt , schema . text ( ' Z' ) ] ) ;
199+ applyDoc ( schema . nodes . doc . create ( null , [ paragraph ] ) ) ;
200+
201+ const sdt = findNode ( editor . state . doc , 'structuredContent' ) ;
202+ expect ( sdt ) . not . toBeNull ( ) ;
203+
204+ const contentFrom = sdt . pos + 1 ;
205+ editor . view . dispatch ( editor . state . tr . setSelection ( TextSelection . create ( editor . state . doc , contentFrom ) ) ) ;
206+ const beforePos = editor . state . selection . from ;
207+
208+ expect ( pressArrow ( 'ArrowRight' ) ) . toBe ( false ) ;
209+ expect ( editor . state . selection . empty ) . toBe ( true ) ;
210+ expect ( editor . state . selection . from ) . toBe ( beforePos ) ;
211+ } ) ;
212+
213+ it ( 'does not exit inline SDT with ArrowLeft when a leading inline leaf remains after ZWSP slots' , ( ) => {
214+ const image = schema . nodes . image . create ( { src : 'image.png' } ) ;
215+ const inlineSdt = schema . nodes . structuredContent . create ( { id : 'inline-1' } , [ schema . text ( '\u200B' ) , image ] ) ;
216+ const paragraph = schema . nodes . paragraph . create ( null , [ schema . text ( 'A ' ) , inlineSdt , schema . text ( ' Z' ) ] ) ;
217+ applyDoc ( schema . nodes . doc . create ( null , [ paragraph ] ) ) ;
218+
219+ const sdt = findNode ( editor . state . doc , 'structuredContent' ) ;
220+ expect ( sdt ) . not . toBeNull ( ) ;
221+
222+ const contentTo = sdt . pos + sdt . node . nodeSize - 1 ;
223+ editor . view . dispatch ( editor . state . tr . setSelection ( TextSelection . create ( editor . state . doc , contentTo ) ) ) ;
224+ const beforePos = editor . state . selection . from ;
225+
226+ expect ( pressArrow ( 'ArrowLeft' ) ) . toBe ( false ) ;
227+ expect ( editor . state . selection . empty ) . toBe ( true ) ;
228+ expect ( editor . state . selection . from ) . toBe ( beforePos ) ;
229+ } ) ;
230+
164231 it ( 'ArrowLeft exit does not insert zero-width text before inline SDT' , ( ) => {
165232 const inlineSdt = schema . nodes . structuredContent . create ( { id : 'inline-1' } , schema . text ( 'Field' ) ) ;
166233 const paragraph = schema . nodes . paragraph . create ( null , [ schema . text ( 'A ' ) , inlineSdt , schema . text ( ' Z' ) ] ) ;
0 commit comments