11import { type Kit , runAlphabetKitTestSuite } from '../../__tests__/setup' ;
2+ import { Anchor } from '../../rga/constants' ;
23import { CommonSliceType } from '../../slice' ;
4+ import { SliceBehavior , SliceHeaderShift } from '../../slice/constants' ;
35
46const testSuite = ( setup : ( ) => Kit ) => {
57 describe ( '.export()' , ( ) => {
@@ -10,6 +12,13 @@ const testSuite = (setup: () => Kit) => {
1012 expect ( json ) . toEqual ( [ 'abcdefghijklmnopqrstuvwxyz' , 0 , [ ] ] ) ;
1113 } ) ;
1214
15+ test ( 'can export part of un-annotated document' , ( ) => {
16+ const { editor} = setup ( ) ;
17+ editor . cursor . setAt ( 5 , 5 ) ;
18+ const json = editor . export ( editor . cursor ) ;
19+ expect ( json ) . toEqual ( [ 'fghij' , 5 , [ ] ] ) ;
20+ } ) ;
21+
1322 test ( 'range which contains bold text' , ( ) => {
1423 const { editor, peritext} = setup ( ) ;
1524 editor . cursor . setAt ( 3 , 3 ) ;
@@ -20,6 +29,18 @@ const testSuite = (setup: () => Kit) => {
2029 expect ( json ) . toEqual ( [ 'cdefg' , 2 , [ [ expect . any ( Number ) , 3 , 6 , 'bold' ] ] ] ) ;
2130 } ) ;
2231
32+ test ( 'exports only "saved" slices' , ( ) => {
33+ const { editor, peritext} = setup ( ) ;
34+ editor . cursor . setAt ( 3 , 3 ) ;
35+ editor . local . insOverwrite ( 'italic' ) ;
36+ editor . saved . insOverwrite ( 'bold' ) ;
37+ editor . extra . insOverwrite ( 'underline' ) ;
38+ const range = peritext . rangeAt ( 2 , 5 ) ;
39+ peritext . refresh ( ) ;
40+ const json = editor . export ( range ) ;
41+ expect ( json ) . toEqual ( [ 'cdefg' , 2 , [ [ expect . any ( Number ) , 3 , 6 , 'bold' ] ] ] ) ;
42+ } ) ;
43+
2344 test ( 'range which start in bold text' , ( ) => {
2445 const { editor, peritext} = setup ( ) ;
2546 editor . cursor . setAt ( 3 , 10 ) ;
@@ -39,6 +60,54 @@ const testSuite = (setup: () => Kit) => {
3960 const json = editor . export ( range ) ;
4061 expect ( json ) . toEqual ( [ 'abcde' , 0 , [ [ expect . any ( Number ) , 3 , 13 , CommonSliceType . b ] ] ] ) ;
4162 } ) ;
63+
64+ test ( 'can export <p> marker' , ( ) => {
65+ const { editor, peritext} = setup ( ) ;
66+ editor . cursor . setAt ( 10 ) ;
67+ editor . saved . insMarker ( CommonSliceType . p ) ;
68+ const range = peritext . rangeAt ( 8 , 5 ) ;
69+ peritext . refresh ( ) ;
70+ const json = editor . export ( range ) ;
71+ const header =
72+ ( SliceBehavior . Marker << SliceHeaderShift . Behavior ) +
73+ ( Anchor . Before << SliceHeaderShift . X1Anchor ) +
74+ ( Anchor . Before << SliceHeaderShift . X2Anchor ) ;
75+ expect ( json ) . toEqual ( [ 'ij\nkl' , 8 , [ [ header , 10 , 10 , CommonSliceType . p ] ] ] ) ;
76+ } ) ;
77+
78+ test ( 'can export <p> marker, <blockquote> marker, and italic text' , ( ) => {
79+ const { editor, peritext} = setup ( ) ;
80+ editor . cursor . setAt ( 15 ) ;
81+ editor . saved . insMarker ( CommonSliceType . blockquote ) ;
82+ editor . cursor . setAt ( 10 ) ;
83+ editor . saved . insMarker ( CommonSliceType . p ) ;
84+ editor . cursor . setAt ( 12 , 2 ) ;
85+ editor . saved . insOverwrite ( CommonSliceType . i ) ;
86+ const range = peritext . rangeAt ( 8 , 12 ) ;
87+ peritext . refresh ( ) ;
88+ const json = editor . export ( range ) ;
89+ const pHeader =
90+ ( SliceBehavior . Marker << SliceHeaderShift . Behavior ) +
91+ ( Anchor . Before << SliceHeaderShift . X1Anchor ) +
92+ ( Anchor . Before << SliceHeaderShift . X2Anchor ) ;
93+ const iHeader =
94+ ( SliceBehavior . One << SliceHeaderShift . Behavior ) +
95+ ( Anchor . Before << SliceHeaderShift . X1Anchor ) +
96+ ( Anchor . After << SliceHeaderShift . X2Anchor ) ;
97+ const blockquoteHeader =
98+ ( SliceBehavior . Marker << SliceHeaderShift . Behavior ) +
99+ ( Anchor . Before << SliceHeaderShift . X1Anchor ) +
100+ ( Anchor . Before << SliceHeaderShift . X2Anchor ) ;
101+ expect ( json ) . toEqual ( [
102+ 'ij\nklmno\npqr' ,
103+ 8 ,
104+ [
105+ [ pHeader , 10 , 10 , CommonSliceType . p ] ,
106+ [ iHeader , 12 , 14 , CommonSliceType . i ] ,
107+ [ blockquoteHeader , 16 , 16 , CommonSliceType . blockquote ] ,
108+ ] ,
109+ ] ) ;
110+ } ) ;
42111 } ) ;
43112
44113 describe ( '.import()' , ( ) => {
@@ -66,6 +135,159 @@ const testSuite = (setup: () => Kit) => {
66135 expect ( i2 . text ( ) ) . toBe ( 'fghij' ) ;
67136 expect ( ! ! i2 . attr ( ) . bold ) . toBe ( true ) ;
68137 } ) ;
138+
139+ test ( 'can import a contained <b> annotation' , ( ) => {
140+ const kit1 = setup ( ) ;
141+ kit1 . editor . cursor . setAt ( 0 , 3 ) ;
142+ kit1 . editor . saved . insOverwrite ( CommonSliceType . b ) ;
143+ kit1 . peritext . refresh ( ) ;
144+ const range = kit1 . peritext . rangeAt ( 1 , 1 ) ;
145+ const view = kit1 . editor . export ( range ) ;
146+ kit1 . editor . import ( 5 , view ) ;
147+ kit1 . peritext . refresh ( ) ;
148+ const jsonml = kit1 . peritext . blocks . toJson ( ) ;
149+ expect ( jsonml ) . toEqual ( [
150+ '' ,
151+ null ,
152+ [
153+ CommonSliceType . p ,
154+ expect . any ( Object ) ,
155+ [ CommonSliceType . b , expect . any ( Object ) , 'abc' ] ,
156+ 'de' ,
157+ [ CommonSliceType . b , expect . any ( Object ) , 'b' ] ,
158+ 'fghijklmnopqrstuvwxyz' ,
159+ ] ,
160+ ] ) ;
161+ const block = kit1 . peritext . blocks . root . children [ 0 ] ;
162+ const inlines = [ ...block . texts ( ) ] ;
163+ const inline = inlines . find ( ( i ) => i . text ( ) === 'b' ) ! ;
164+ expect ( inline . start . anchor ) . toBe ( Anchor . Before ) ;
165+ expect ( inline . end . anchor ) . toBe ( Anchor . After ) ;
166+ } ) ;
167+
168+ test ( 'can import a contained <b> annotation (with end edge anchored to neighbor chars)' , ( ) => {
169+ const kit1 = setup ( ) ;
170+ kit1 . editor . cursor . setAt ( 0 , 3 ) ;
171+ const start = kit1 . editor . cursor . start . clone ( ) ;
172+ const end = kit1 . editor . cursor . end . clone ( ) ;
173+ start . refAfter ( ) ;
174+ end . refBefore ( ) ;
175+ kit1 . editor . cursor . set ( start , end ) ;
176+ kit1 . editor . saved . insOverwrite ( CommonSliceType . b ) ;
177+ kit1 . peritext . refresh ( ) ;
178+ const range = kit1 . peritext . rangeAt ( 1 , 1 ) ;
179+ const view = kit1 . editor . export ( range ) ;
180+ kit1 . editor . import ( 5 , view ) ;
181+ kit1 . peritext . refresh ( ) ;
182+ const jsonml = kit1 . peritext . blocks . toJson ( ) ;
183+ expect ( jsonml ) . toEqual ( [
184+ '' ,
185+ null ,
186+ [
187+ CommonSliceType . p ,
188+ expect . any ( Object ) ,
189+ [ CommonSliceType . b , expect . any ( Object ) , 'abc' ] ,
190+ 'de' ,
191+ [ CommonSliceType . b , expect . any ( Object ) , 'b' ] ,
192+ 'fghijklmnopqrstuvwxyz' ,
193+ ] ,
194+ ] ) ;
195+ const block = kit1 . peritext . blocks . root . children [ 0 ] ;
196+ const inlines = [ ...block . texts ( ) ] ;
197+ const inline = inlines . find ( ( i ) => i . text ( ) === 'b' ) ! ;
198+ expect ( inline . start . anchor ) . toBe ( Anchor . After ) ;
199+ expect ( inline . end . anchor ) . toBe ( Anchor . Before ) ;
200+ } ) ;
201+
202+ test ( 'annotation start edge cannot point to ABS start' , ( ) => {
203+ const kit1 = setup ( ) ;
204+ kit1 . editor . cursor . setAt ( 1 , 2 ) ;
205+ const start = kit1 . editor . cursor . start . clone ( ) ;
206+ const end = kit1 . editor . cursor . end . clone ( ) ;
207+ start . refAfter ( ) ;
208+ end . refBefore ( ) ;
209+ kit1 . editor . cursor . set ( start , end ) ;
210+ kit1 . editor . saved . insOverwrite ( CommonSliceType . b ) ;
211+ kit1 . editor . delCursors ( ) ;
212+ kit1 . peritext . refresh ( ) ;
213+ const range = kit1 . peritext . rangeAt ( 1 , 1 ) ;
214+ const view = kit1 . editor . export ( range ) ;
215+ kit1 . editor . import ( 0 , view ) ;
216+ kit1 . peritext . refresh ( ) ;
217+ const jsonml = kit1 . peritext . blocks . toJson ( ) ;
218+ expect ( jsonml ) . toEqual ( [
219+ '' ,
220+ null ,
221+ [
222+ CommonSliceType . p ,
223+ expect . any ( Object ) ,
224+ [ CommonSliceType . b , expect . any ( Object ) , 'b' ] ,
225+ 'a' ,
226+ [ CommonSliceType . b , expect . any ( Object ) , 'bc' ] ,
227+ 'defghijklmnopqrstuvwxyz' ,
228+ ] ,
229+ ] ) ;
230+ const block = kit1 . peritext . blocks . root . children [ 0 ] ;
231+ const inlines = [ ...block . texts ( ) ] ;
232+ const inline = inlines . find ( ( i ) => i . text ( ) === 'b' ) ! ;
233+ expect ( inline . start . anchor ) . toBe ( Anchor . Before ) ;
234+ expect ( inline . end . anchor ) . toBe ( Anchor . Before ) ;
235+ } ) ;
236+
237+ test ( 'annotation end edge cannot point to ABS end' , ( ) => {
238+ const kit1 = setup ( ) ;
239+ kit1 . editor . cursor . setAt ( 1 , 2 ) ;
240+ const start = kit1 . editor . cursor . start . clone ( ) ;
241+ const end = kit1 . editor . cursor . end . clone ( ) ;
242+ start . refAfter ( ) ;
243+ end . refBefore ( ) ;
244+ kit1 . editor . cursor . set ( start , end ) ;
245+ kit1 . editor . saved . insOverwrite ( CommonSliceType . b ) ;
246+ kit1 . editor . delCursors ( ) ;
247+ kit1 . peritext . refresh ( ) ;
248+ const range = kit1 . peritext . rangeAt ( 1 , 1 ) ;
249+ const view = kit1 . editor . export ( range ) ;
250+ const length = kit1 . peritext . strApi ( ) . length ( ) ;
251+ kit1 . editor . import ( length , view ) ;
252+ kit1 . peritext . refresh ( ) ;
253+ const jsonml = kit1 . peritext . blocks . toJson ( ) ;
254+ expect ( jsonml ) . toEqual ( [
255+ '' ,
256+ null ,
257+ [
258+ CommonSliceType . p ,
259+ expect . any ( Object ) ,
260+ 'a' ,
261+ [ CommonSliceType . b , expect . any ( Object ) , 'bc' ] ,
262+ 'defghijklmnopqrstuvwxyz' ,
263+ [ CommonSliceType . b , expect . any ( Object ) , 'b' ] ,
264+ ] ,
265+ ] ) ;
266+ const block = kit1 . peritext . blocks . root . children [ 0 ] ;
267+ const inlines = [ ...block . texts ( ) ] ;
268+ const inline = inlines . find ( ( i ) => i . text ( ) === 'b' ) ! ;
269+ expect ( inline . start . anchor ) . toBe ( Anchor . After ) ;
270+ expect ( inline . end . anchor ) . toBe ( Anchor . After ) ;
271+ } ) ;
272+
273+ test ( 'can copy a paragraph split' , ( ) => {
274+ const kit1 = setup ( ) ;
275+ const kit2 = setup ( ) ;
276+ kit1 . editor . cursor . setAt ( 5 ) ;
277+ kit1 . editor . saved . insMarker ( CommonSliceType . p ) ;
278+ kit1 . editor . cursor . setAt ( 3 , 5 ) ;
279+ kit1 . peritext . refresh ( ) ;
280+ const json = kit1 . editor . export ( kit1 . editor . cursor ) ;
281+ kit2 . editor . import ( 0 , json ) ;
282+ kit2 . peritext . refresh ( ) ;
283+ const json2 = kit2 . peritext . blocks . toJson ( ) ;
284+ expect ( json2 ) . toEqual ( [
285+ '' ,
286+ null ,
287+ [ CommonSliceType . p , null , 'de' ] ,
288+ [ CommonSliceType . p , null , 'fgabcdefghijklmnopqrstuvwxyz' ] ,
289+ ] ) ;
290+ } ) ;
69291 } ) ;
70292} ;
71293
0 commit comments