insert.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  1. /**
  2. * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. import { Client, syncClients, expectClients, clearBuffer } from './utils.js';
  6. describe( 'transform', () => {
  7. let john, kate;
  8. beforeEach( () => {
  9. return Promise.all( [
  10. Client.get( 'john' ).then( client => ( john = client ) ),
  11. Client.get( 'kate' ).then( client => ( kate = client ) )
  12. ] );
  13. } );
  14. afterEach( () => {
  15. clearBuffer();
  16. return Promise.all( [ john.destroy(), kate.destroy() ] );
  17. } );
  18. describe( 'insert', () => {
  19. describe( 'by insert', () => {
  20. it( 'elements at same position #1', () => {
  21. john.setData( '[]<paragraph>Foo</paragraph>' );
  22. kate.setData( '[]<paragraph>Foo</paragraph>' );
  23. john.insert( '<paragraph>Abc</paragraph>' );
  24. kate.insert( '<paragraph>Xyz</paragraph>' );
  25. syncClients();
  26. expectClients(
  27. '<paragraph>Abc</paragraph>' +
  28. '<paragraph>Xyz</paragraph>' +
  29. '<paragraph>Foo</paragraph>'
  30. );
  31. } );
  32. it( 'elements at same position #2', () => {
  33. john.setData( '[]<paragraph>Foo</paragraph>' );
  34. kate.setData( '[]<paragraph>Foo</paragraph>' );
  35. kate.insert( '<paragraph>Xyz</paragraph>' );
  36. john.insert( '<paragraph>Abc</paragraph>' );
  37. syncClients();
  38. expectClients(
  39. '<paragraph>Abc</paragraph>' +
  40. '<paragraph>Xyz</paragraph>' +
  41. '<paragraph>Foo</paragraph>'
  42. );
  43. } );
  44. it( 'elements in same parent', () => {
  45. john.setData( '[]<paragraph>Foo</paragraph>' );
  46. kate.setData( '<paragraph>Foo</paragraph>[]' );
  47. john.insert( '<paragraph>Abc</paragraph>' );
  48. kate.insert( '<paragraph>Xyz</paragraph>' );
  49. syncClients();
  50. expectClients(
  51. '<paragraph>Abc</paragraph>' +
  52. '<paragraph>Foo</paragraph>' +
  53. '<paragraph>Xyz</paragraph>'
  54. );
  55. } );
  56. it( 'elements in same path', () => {
  57. john.setData( '[]<blockQuote><paragraph>Foo</paragraph></blockQuote>' );
  58. kate.setData( '<blockQuote>[]<paragraph>Foo</paragraph></blockQuote>' );
  59. john.insert( '<paragraph>Abc</paragraph>' );
  60. kate.insert( '<paragraph>Xyz</paragraph>' );
  61. syncClients();
  62. expectClients(
  63. '<paragraph>Abc</paragraph>' +
  64. '<blockQuote>' +
  65. '<paragraph>Xyz</paragraph>' +
  66. '<paragraph>Foo</paragraph>' +
  67. '</blockQuote>'
  68. );
  69. } );
  70. it( 'text at different paths', () => {
  71. john.setData( '<paragraph>Abc[]</paragraph><paragraph>Xyz</paragraph>' );
  72. kate.setData( '<paragraph>Abc</paragraph><paragraph>[]Xyz</paragraph>' );
  73. john.type( 'Foo' );
  74. kate.type( 'Bar' );
  75. syncClients();
  76. expectClients(
  77. '<paragraph>AbcFoo</paragraph>' +
  78. '<paragraph>BarXyz</paragraph>'
  79. );
  80. } );
  81. it( 'text, then wrap and undo', () => {
  82. john.setData( '<paragraph>Foo[]</paragraph>' );
  83. kate.setData( '<paragraph>Foo[]</paragraph>' );
  84. john.type( 'Bar' );
  85. kate.type( 'Abc' );
  86. syncClients();
  87. john.setSelection( [ 0 ], [ 1 ] );
  88. john.wrap( 'blockQuote' );
  89. kate.undo();
  90. syncClients();
  91. expectClients(
  92. '<blockQuote>' +
  93. '<paragraph>FooBar</paragraph>' +
  94. '</blockQuote>'
  95. );
  96. } );
  97. it( 'text, then insert element and merge', () => {
  98. john.setData( '<paragraph>[]</paragraph><paragraph>Abc</paragraph>' );
  99. kate.setData( '<paragraph>[]</paragraph><paragraph>Abc</paragraph>' );
  100. john.type( 'Foo' );
  101. kate.type( ' Bar' );
  102. syncClients();
  103. expectClients(
  104. '<paragraph>Foo Bar</paragraph>' +
  105. '<paragraph>Abc</paragraph>'
  106. );
  107. john.setSelection( [ 1 ] );
  108. kate.setSelection( [ 1 ] );
  109. john.insert( '<paragraph>Xyz</paragraph>' );
  110. kate.merge();
  111. syncClients();
  112. expectClients(
  113. '<paragraph>Foo BarAbc</paragraph>' +
  114. '<paragraph>Xyz</paragraph>'
  115. );
  116. } );
  117. it( 'text, then split and undo', () => {
  118. john.setData( '<paragraph>[]</paragraph>' );
  119. kate.setData( '<paragraph>[]</paragraph>' );
  120. john.type( 'Foo' );
  121. kate.type( ' Bar' );
  122. syncClients();
  123. john.setSelection( [ 0, 1 ] );
  124. kate.setSelection( [ 0, 4 ] );
  125. john.split();
  126. kate.split();
  127. syncClients();
  128. john.undo();
  129. kate.undo();
  130. syncClients();
  131. john.undo();
  132. kate.undo();
  133. syncClients();
  134. expectClients( '<paragraph></paragraph>' );
  135. } );
  136. } );
  137. describe( 'by move', () => {
  138. it( 'element at different paths #1', () => {
  139. john.setData( '[]<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );
  140. kate.setData( '<paragraph>Foo</paragraph><paragraph>B[ar]</paragraph>' );
  141. john.insert( '<paragraph>Abc</paragraph>' );
  142. kate.move( [ 1, 0 ] );
  143. syncClients();
  144. expectClients(
  145. '<paragraph>Abc</paragraph>' +
  146. '<paragraph>Foo</paragraph>' +
  147. '<paragraph>arB</paragraph>'
  148. );
  149. } );
  150. it( 'element at different paths #2', () => {
  151. john.setData( '<blockQuote><paragraph>Foo</paragraph>[]</blockQuote><paragraph>Bar</paragraph>' );
  152. kate.setData( '<blockQuote><paragraph>Foo</paragraph></blockQuote><paragraph>B[ar]</paragraph>' );
  153. john.insert( '<paragraph>Abc</paragraph>' );
  154. kate.move( [ 0, 0, 0 ] );
  155. syncClients();
  156. expectClients(
  157. '<blockQuote>' +
  158. '<paragraph>arFoo</paragraph>' +
  159. '<paragraph>Abc</paragraph>' +
  160. '</blockQuote>' +
  161. '<paragraph>B</paragraph>'
  162. );
  163. } );
  164. it( 'text at different paths', () => {
  165. john.setData( '<paragraph>[]Foo</paragraph><paragraph>Bar</paragraph>' );
  166. kate.setData( '<paragraph>Foo</paragraph><paragraph>B[ar]</paragraph>' );
  167. john.type( 'Abc' );
  168. kate.move( [ 1, 0 ] );
  169. syncClients();
  170. expectClients(
  171. '<paragraph>AbcFoo</paragraph>' +
  172. '<paragraph>arB</paragraph>'
  173. );
  174. } );
  175. it( 'text at same path', () => {
  176. john.setData( '<paragraph>F[]oo Bar</paragraph>' );
  177. kate.setData( '<paragraph>Foo B[ar]</paragraph>' );
  178. john.type( 'Abc' );
  179. kate.move( [ 0, 0 ] );
  180. syncClients();
  181. expectClients( '<paragraph>arFAbcoo B</paragraph>' );
  182. } );
  183. it( 'text at same position #1', () => {
  184. john.setData( '<paragraph>Foo[] Bar</paragraph>' );
  185. kate.setData( '<paragraph>Foo [Bar]</paragraph>' );
  186. john.type( 'Abc' );
  187. kate.move( [ 0, 3 ] );
  188. syncClients();
  189. expectClients( '<paragraph>FooBarAbc </paragraph>' );
  190. } );
  191. it( 'text at same position #2', () => {
  192. john.setData( '<paragraph>Foo []Bar</paragraph>' );
  193. kate.setData( '<paragraph>Foo [Bar]</paragraph>' );
  194. john.type( 'Abc' );
  195. kate.move( [ 0, 0 ] );
  196. syncClients();
  197. expectClients( '<paragraph>BarFoo Abc</paragraph>' );
  198. } );
  199. } );
  200. describe( 'by wrap', () => {
  201. it( 'element in same path #1', () => {
  202. john.setData( '<paragraph>Foo Bar</paragraph>[]' );
  203. kate.setData( '[<paragraph>Foo Bar</paragraph>]' );
  204. john.insert( '<paragraph>Abc</paragraph>' );
  205. kate.wrap( 'blockQuote' );
  206. syncClients();
  207. expectClients(
  208. '<blockQuote>' +
  209. '<paragraph>Foo Bar</paragraph>' +
  210. '</blockQuote>' +
  211. '<paragraph>Abc</paragraph>'
  212. );
  213. } );
  214. // Incorrect result due to wrap/unwrap being represented by inserts and moves.
  215. it.skip( 'element in same path #2', () => {
  216. john.setData( '<paragraph>Foo[]</paragraph>' );
  217. kate.setData( '[<paragraph>Foo</paragraph>]' );
  218. john.type( ' Bar' );
  219. kate.wrap( 'blockQuote' );
  220. syncClients();
  221. expectClients(
  222. '<blockQuote>' +
  223. '<paragraph>Foo Bar</paragraph>' +
  224. '</blockQuote>'
  225. );
  226. } );
  227. it( 'element in different paths #1', () => {
  228. john.setData( '<paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph>' );
  229. kate.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  230. john.insert( '<paragraph>Abc</paragraph>' );
  231. kate.wrap( 'blockQuote' );
  232. syncClients();
  233. expectClients(
  234. '<paragraph>Foo</paragraph>' +
  235. '<paragraph>Abc</paragraph>' +
  236. '<blockQuote>' +
  237. '<paragraph>Bar</paragraph>' +
  238. '</blockQuote>'
  239. );
  240. } );
  241. it( 'element in different paths #2', () => {
  242. john.setData( '<paragraph>Foo</paragraph><paragraph>Bar[]</paragraph>' );
  243. kate.setData( '[<paragraph>Foo</paragraph>]<paragraph>Bar</paragraph>' );
  244. john.type( 'Abc' );
  245. kate.wrap( 'blockQuote' );
  246. syncClients();
  247. expectClients(
  248. '<blockQuote>' +
  249. '<paragraph>Foo</paragraph>' +
  250. '</blockQuote>' +
  251. '<paragraph>BarAbc</paragraph>'
  252. );
  253. } );
  254. it( 'element, then unwrap and split', () => {
  255. john.setData( '<paragraph>Foo[]</paragraph>' );
  256. kate.setData( '[<paragraph>Foo</paragraph>]' );
  257. john.type( ' Bar' );
  258. kate.wrap( 'blockQuote' );
  259. syncClients();
  260. expectClients( '<blockQuote><paragraph>Foo Bar</paragraph></blockQuote>' );
  261. john.setSelection( [ 0, 0 ] );
  262. kate.setSelection( [ 0, 0, 2 ] );
  263. john.unwrap();
  264. kate.split();
  265. syncClients();
  266. expectClients(
  267. '<paragraph>Fo</paragraph>' +
  268. '<paragraph>o Bar</paragraph>'
  269. );
  270. } );
  271. it( 'element, then add marker and split', () => {
  272. john.setData( '<paragraph>Foo[]</paragraph>' );
  273. kate.setData( '[<paragraph>Foo</paragraph>]' );
  274. john.type( ' Bar' );
  275. kate.wrap( 'blockQuote' );
  276. syncClients();
  277. john.setSelection( [ 0, 0, 0 ], [ 0, 0, 3 ] );
  278. kate.setSelection( [ 0, 0, 2 ] );
  279. john.setMarker( 'm1' );
  280. kate.split();
  281. syncClients();
  282. expectClients(
  283. '<blockQuote>' +
  284. '<paragraph><m1:start></m1:start>Fo</paragraph>' +
  285. '<paragraph>o<m1:end></m1:end> Bar</paragraph>' +
  286. '</blockQuote>'
  287. );
  288. } );
  289. it( 'element, then split at the same position and undo', () => {
  290. john.setData( '<paragraph>Foo[]</paragraph>' );
  291. kate.setData( '[<paragraph>Foo</paragraph>]' );
  292. john.type( ' Bar' );
  293. kate.wrap( 'blockQuote' );
  294. syncClients();
  295. expectClients( '<blockQuote><paragraph>Foo Bar</paragraph></blockQuote>' );
  296. john.setSelection( [ 0, 0, 3 ] );
  297. kate.setSelection( [ 0, 0, 3 ] );
  298. john.split();
  299. kate.split();
  300. syncClients();
  301. expectClients(
  302. '<blockQuote>' +
  303. '<paragraph>Foo</paragraph>' +
  304. '<paragraph> Bar</paragraph>' +
  305. '</blockQuote>'
  306. );
  307. kate.undo();
  308. syncClients();
  309. // Below is not the best result ever but it is acceptable.
  310. expectClients(
  311. '<blockQuote>' +
  312. '<paragraph>Foo Bar</paragraph>' +
  313. '</blockQuote>'
  314. );
  315. } );
  316. } );
  317. describe( 'by unwrap', () => {
  318. it( 'element in different path', () => {
  319. john.setData( '<paragraph>Foo[]</paragraph><blockQuote><paragraph>Bar</paragraph></blockQuote>' );
  320. kate.setData( '<paragraph>Foo</paragraph><blockQuote>[<paragraph>Bar</paragraph>]</blockQuote>' );
  321. john.type( 'Abc' );
  322. kate.unwrap();
  323. syncClients();
  324. expectClients( '<paragraph>FooAbc</paragraph><paragraph>Bar</paragraph>' );
  325. } );
  326. it( 'text in different path', () => {
  327. john.setData( '<paragraph>Foo[]</paragraph><blockQuote><paragraph>Bar</paragraph></blockQuote>' );
  328. kate.setData( '<paragraph>Foo</paragraph><blockQuote><paragraph>[]Bar</paragraph></blockQuote>' );
  329. john.type( 'Abc' );
  330. kate.unwrap();
  331. syncClients();
  332. expectClients( '<paragraph>FooAbc</paragraph><blockQuote>Bar</blockQuote>' );
  333. } );
  334. it( 'element in same path #1', () => {
  335. john.setData( '<blockQuote><paragraph>Foo[]</paragraph></blockQuote>' );
  336. kate.setData( '<blockQuote>[<paragraph>Foo</paragraph>]</blockQuote>' );
  337. john.type( ' Bar' );
  338. kate.unwrap();
  339. syncClients();
  340. expectClients( '<paragraph>Foo Bar</paragraph>' );
  341. } );
  342. it( 'element in same path #2', () => {
  343. john.setData( '<blockQuote><paragraph>Foo</paragraph>[]</blockQuote>' );
  344. kate.setData( '<blockQuote>[<paragraph>Foo</paragraph>]</blockQuote>' );
  345. john.insert( '<paragraph>Bar</paragraph>' );
  346. kate.unwrap();
  347. syncClients();
  348. // Below would be the expected effect with correct wrap transformation.
  349. // expectClients(
  350. // '<paragraph>Foo</paragraph>' +
  351. // '<paragraph>Bar</paragraph>'
  352. // );
  353. expectClients(
  354. '<paragraph>Foo</paragraph>'
  355. );
  356. } );
  357. it( 'element, then wrap and undo on both clients', () => {
  358. john.setData( '<blockQuote><paragraph>Foo</paragraph>[]</blockQuote>' );
  359. kate.setData( '<blockQuote>[<paragraph>Foo</paragraph>]</blockQuote>' );
  360. john.insert( '<paragraph>Bar</paragraph>' );
  361. kate.unwrap();
  362. syncClients();
  363. kate.setSelection( [ 0 ], [ 1 ] );
  364. kate.wrap( 'blockQuote' );
  365. john.undo();
  366. syncClients();
  367. expectClients(
  368. '<blockQuote>' +
  369. '<paragraph>Foo</paragraph>' +
  370. '</blockQuote>'
  371. );
  372. } );
  373. it( 'element, then wrap, unwrap and undo', () => {
  374. john.setData( '<blockQuote><paragraph>Foo[]</paragraph></blockQuote>' );
  375. kate.setData( '<blockQuote>[]<paragraph>Foo</paragraph></blockQuote>' );
  376. john.type( ' Bar' );
  377. kate.unwrap();
  378. syncClients();
  379. expectClients( '<paragraph>Foo Bar</paragraph>' );
  380. john.setSelection( [ 0 ], [ 1 ] );
  381. john.wrap( 'blockQuote' );
  382. syncClients();
  383. expectClients( '<blockQuote><paragraph>Foo Bar</paragraph></blockQuote>' );
  384. john.undo();
  385. kate.setSelection( [ 0, 0 ], [ 0, 1 ] );
  386. kate.unwrap();
  387. syncClients();
  388. expectClients( '<paragraph>Foo Bar</paragraph>' );
  389. } );
  390. } );
  391. describe( 'by split', () => {
  392. it( 'text in same path #1', () => {
  393. john.setData( '<paragraph>Foo</paragraph>[]' );
  394. kate.setData( '<paragraph>F[]oo</paragraph>' );
  395. john.insert( '<paragraph>Bar</paragraph>' );
  396. kate.split();
  397. syncClients();
  398. expectClients(
  399. '<paragraph>F</paragraph>' +
  400. '<paragraph>oo</paragraph>' +
  401. '<paragraph>Bar</paragraph>'
  402. );
  403. } );
  404. it( 'text in same path #2', () => {
  405. john.setData( '<paragraph>Fo[]o</paragraph>' );
  406. kate.setData( '<paragraph>F[]oo</paragraph>' );
  407. john.type( 'Bar' );
  408. kate.split();
  409. syncClients();
  410. expectClients( '<paragraph>F</paragraph><paragraph>oBaro</paragraph>' );
  411. } );
  412. it( 'text in different paths #1', () => {
  413. john.setData( '[]<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );
  414. kate.setData( '<paragraph>Foo</paragraph><paragraph>B[]ar</paragraph>' );
  415. john.insert( '<paragraph>Abc</paragraph>' );
  416. kate.split();
  417. syncClients();
  418. expectClients(
  419. '<paragraph>Abc</paragraph>' +
  420. '<paragraph>Foo</paragraph>' +
  421. '<paragraph>B</paragraph>' +
  422. '<paragraph>ar</paragraph>'
  423. );
  424. } );
  425. it( 'text in different paths #2', () => {
  426. john.setData( '<paragraph>Foo[]</paragraph><paragraph>Bar</paragraph>' );
  427. kate.setData( '<paragraph>Foo</paragraph><paragraph>B[]ar</paragraph>' );
  428. john.type( 'Abc' );
  429. kate.split();
  430. syncClients();
  431. expectClients(
  432. '<paragraph>FooAbc</paragraph>' +
  433. '<paragraph>B</paragraph>' +
  434. '<paragraph>ar</paragraph>'
  435. );
  436. } );
  437. it( 'text at same position', () => {
  438. john.setData( '<paragraph>F[]oo</paragraph>' );
  439. kate.setData( '<paragraph>F[]oo</paragraph>' );
  440. john.type( 'Bar' );
  441. kate.split();
  442. syncClients();
  443. expectClients( '<paragraph>FBar</paragraph><paragraph>oo</paragraph>' );
  444. } );
  445. it( 'text at same position #2', () => {
  446. john.setData( '<paragraph>Foo[]</paragraph>' );
  447. kate.setData( '<paragraph>Foo[]</paragraph>' );
  448. john.type( 'Bar' );
  449. kate.split();
  450. syncClients();
  451. expectClients( '<paragraph>FooBar</paragraph><paragraph></paragraph>' );
  452. } );
  453. it( 'text, then insert element and split', () => {
  454. john.setData( '<paragraph>[]Foo</paragraph>' );
  455. kate.setData( '<paragraph>F[]oo</paragraph>' );
  456. john.type( 'Bar' );
  457. kate.split();
  458. syncClients();
  459. john.setSelection( [ 1 ] );
  460. kate.setSelection( [ 1, 1 ] );
  461. john.insert( '<paragraph>Abc</paragraph>' );
  462. kate.split();
  463. syncClients();
  464. expectClients(
  465. '<paragraph>BarF</paragraph>' +
  466. '<paragraph>Abc</paragraph>' +
  467. '<paragraph>o</paragraph>' +
  468. '<paragraph>o</paragraph>'
  469. );
  470. } );
  471. } );
  472. describe( 'by remove', () => {
  473. it( 'text in different path', () => {
  474. john.setData( '<paragraph>Foo[]</paragraph><paragraph>Bar</paragraph>' );
  475. kate.setData( '<paragraph>Foo</paragraph><paragraph>[Bar]</paragraph>' );
  476. john.type( 'Abc' );
  477. kate.remove();
  478. syncClients();
  479. expectClients( '<paragraph>FooAbc</paragraph><paragraph></paragraph>' );
  480. } );
  481. it( 'text in same path', () => {
  482. john.setData( '<paragraph>Foo[]</paragraph>' );
  483. kate.setData( '<paragraph>[Foo]</paragraph>' );
  484. john.type( 'Bar' );
  485. kate.remove();
  486. syncClients();
  487. expectClients( '<paragraph>Bar</paragraph>' );
  488. } );
  489. it( 'element in different path', () => {
  490. john.setData( '<paragraph>Foo[]</paragraph><paragraph>Bar</paragraph>' );
  491. kate.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  492. john.type( 'Abc' );
  493. kate.remove();
  494. syncClients();
  495. expectClients( '<paragraph>FooAbc</paragraph>' );
  496. } );
  497. it( 'element in same path', () => {
  498. john.setData( '<paragraph>Foo[]</paragraph><paragraph>Bar</paragraph>' );
  499. kate.setData( '[<paragraph>Foo</paragraph>]<paragraph>Bar</paragraph>' );
  500. john.type( 'Abc' );
  501. kate.remove();
  502. syncClients();
  503. expectClients( '<paragraph>Bar</paragraph>' );
  504. } );
  505. it( 'text, then rename, split and undo', () => {
  506. john.setData( '<paragraph>Foo Bar[]</paragraph>' );
  507. kate.setData( '<paragraph>Foo [Bar]</paragraph>' );
  508. john.type( 'Bar' );
  509. kate.remove();
  510. syncClients();
  511. expectClients( '<paragraph>Foo Bar</paragraph>' );
  512. john.setSelection( [ 0, 0 ] );
  513. kate.setSelection( [ 0, 4 ] );
  514. john.rename( 'heading1' );
  515. kate.split();
  516. syncClients();
  517. expectClients( '<heading1>Foo </heading1><heading1>Bar</heading1>' );
  518. kate.undo();
  519. syncClients();
  520. expectClients( '<heading1>Foo Bar</heading1>' );
  521. } );
  522. it( 'element, then add marker, split and undo with type #1', () => {
  523. john.setData( '<paragraph>Foo</paragraph>[]' );
  524. kate.setData( '[<paragraph>Foo</paragraph>]' );
  525. john.insert( '<paragraph>Bar</paragraph>' );
  526. kate.remove();
  527. syncClients();
  528. expectClients( '<paragraph>Bar</paragraph><paragraph></paragraph>' ); // Autoparagraphing.
  529. john.setSelection( [ 0, 0 ], [ 0, 3 ] );
  530. kate.setSelection( [ 0, 2 ] );
  531. john.setMarker( 'm1' );
  532. kate.split();
  533. syncClients();
  534. expectClients(
  535. '<paragraph><m1:start></m1:start>Ba</paragraph>' +
  536. '<paragraph>r<m1:end></m1:end></paragraph>' +
  537. '<paragraph></paragraph>'
  538. );
  539. john.undo();
  540. john.setSelection( [ 1, 1 ] );
  541. john.type( 'Abc' );
  542. kate.undo();
  543. syncClients();
  544. expectClients( '<paragraph>BarAbc</paragraph><paragraph></paragraph>' );
  545. kate.undo();
  546. syncClients();
  547. expectClients( '<paragraph>Foo</paragraph><paragraph>BarAbc</paragraph>' );
  548. } );
  549. it( 'element, then add marker, split and undo with type #2', () => {
  550. john.setData( '<paragraph>Foo</paragraph>[]' );
  551. kate.setData( '[<paragraph>Foo</paragraph>]' );
  552. john.insert( '<paragraph>Bar</paragraph>' );
  553. kate.remove();
  554. syncClients();
  555. expectClients( '<paragraph>Bar</paragraph><paragraph></paragraph>' ); // Autoparagraphing.
  556. john.setSelection( [ 0, 0 ], [ 0, 3 ] );
  557. kate.setSelection( [ 0, 2 ] );
  558. john.setMarker( 'm1' );
  559. kate.split();
  560. syncClients();
  561. expectClients(
  562. '<paragraph><m1:start></m1:start>Ba</paragraph>' +
  563. '<paragraph>r<m1:end></m1:end></paragraph>' +
  564. '<paragraph></paragraph>'
  565. );
  566. john.undo();
  567. john.setSelection( [ 1, 1 ] );
  568. john.type( 'Abc' );
  569. kate.undo();
  570. kate.undo();
  571. syncClients();
  572. expectClients( '<paragraph>Foo</paragraph><paragraph>BarAbc</paragraph>' );
  573. } );
  574. } );
  575. describe( 'by merge', () => {
  576. it( 'element into paragraph', () => {
  577. john.setData( '<paragraph>Foo</paragraph><paragraph>[]</paragraph>' );
  578. kate.setData( '<paragraph>Foo</paragraph>[]<paragraph></paragraph>' );
  579. john.type( ' Bar' );
  580. kate.merge();
  581. syncClients();
  582. expectClients( '<paragraph>Foo Bar</paragraph>' );
  583. } );
  584. } );
  585. describe( 'by marker', () => {
  586. it( 'in different path #1', () => {
  587. john.setData( '[]<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );
  588. kate.setData( '<paragraph>Foo</paragraph><paragraph>[Bar]</paragraph>' );
  589. john.insert( '<paragraph>Abc</paragraph>' );
  590. kate.setMarker( 'm1' );
  591. syncClients();
  592. expectClients(
  593. '<paragraph>Abc</paragraph>' +
  594. '<paragraph>Foo</paragraph>' +
  595. '<paragraph><m1:start></m1:start>Bar<m1:end></m1:end></paragraph>'
  596. );
  597. } );
  598. it( 'in different path #2', () => {
  599. john.setData( '<paragraph>Foo[]</paragraph><paragraph>Bar</paragraph>' );
  600. kate.setData( '<paragraph>Foo</paragraph><paragraph>[Bar]</paragraph>' );
  601. john.type( 'Abc' );
  602. kate.setMarker( 'm1' );
  603. syncClients();
  604. expectClients(
  605. '<paragraph>FooAbc</paragraph>' +
  606. '<paragraph><m1:start></m1:start>Bar<m1:end></m1:end></paragraph>'
  607. );
  608. } );
  609. it( 'in same path', () => {
  610. john.setData( '<paragraph>[]Foo</paragraph>' );
  611. kate.setData( '<paragraph>Fo[o]</paragraph>' );
  612. john.type( 'Bar' );
  613. kate.setMarker( 'm1' );
  614. syncClients();
  615. expectClients( '<paragraph>BarFo<m1:start></m1:start>o<m1:end></m1:end></paragraph>' );
  616. } );
  617. } );
  618. describe( 'by rename', () => {
  619. it( 'element in different path', () => {
  620. john.setData( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>[]' );
  621. kate.setData( '<paragraph>F[]oo</paragraph><paragraph>Bar</paragraph>' );
  622. john.insert( '<paragraph>Abc</paragraph>' );
  623. kate.rename( 'heading1' );
  624. syncClients();
  625. expectClients(
  626. '<heading1>Foo</heading1>' +
  627. '<paragraph>Bar</paragraph>' +
  628. '<paragraph>Abc</paragraph>'
  629. );
  630. } );
  631. it( 'element in same path', () => {
  632. john.setData( '<paragraph>Foo</paragraph>[]' );
  633. kate.setData( '<paragraph>F[]oo</paragraph>' );
  634. john.insert( '<paragraph>Bar</paragraph>' );
  635. kate.rename( 'heading1' );
  636. syncClients();
  637. expectClients(
  638. '<heading1>Foo</heading1>' +
  639. '<paragraph>Bar</paragraph>'
  640. );
  641. } );
  642. it( 'text in same path', () => {
  643. john.setData( '<paragraph>Foo[] Bar</paragraph>' );
  644. kate.setData( '<paragraph>F[]oo Bar</paragraph>' );
  645. john.type( 'Abc' );
  646. kate.rename( 'heading1' );
  647. syncClients();
  648. expectClients( '<heading1>FooAbc Bar</heading1>' );
  649. } );
  650. it( 'text in different paths', () => {
  651. john.setData( '<blockQuote><paragraph>Foo</paragraph></blockQuote><paragraph>B[]ar</paragraph>' );
  652. kate.setData( '<blockQuote><paragraph>F[]oo</paragraph></blockQuote><paragraph>Bar</paragraph>' );
  653. john.type( 'Abc' );
  654. kate.rename( 'heading1' );
  655. syncClients();
  656. expectClients(
  657. '<blockQuote>' +
  658. '<heading1>Foo</heading1>' +
  659. '</blockQuote>' +
  660. '<paragraph>BAbcar</paragraph>'
  661. );
  662. } );
  663. } );
  664. } );
  665. } );