move.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. import { Client, syncClients, expectClients } from './utils.js';
  2. describe( 'transform', () => {
  3. let john, kate;
  4. beforeEach( () => {
  5. return Promise.all( [
  6. Client.get( 'john' ).then( client => ( john = client ) ),
  7. Client.get( 'kate' ).then( client => ( kate = client ) )
  8. ] );
  9. } );
  10. afterEach( () => {
  11. return Promise.all( [ john.destroy(), kate.destroy() ] );
  12. } );
  13. describe( 'move', () => {
  14. describe( 'by move', () => {
  15. it( 'elements in different paths', () => {
  16. john.setData( '[<paragraph>Foo</paragraph>]<paragraph>Bar</paragraph>' );
  17. kate.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  18. john.move( [ 2 ] );
  19. kate.move( [ 0 ] );
  20. syncClients();
  21. expectClients(
  22. '<paragraph>Bar</paragraph>' +
  23. '<paragraph>Foo</paragraph>'
  24. );
  25. } );
  26. it( 'text in same path #1', () => {
  27. john.setData( '<paragraph>[Foo] Bar</paragraph>' );
  28. kate.setData( '<paragraph>Foo [Bar]</paragraph>' );
  29. john.move( [ 0, 4 ] );
  30. kate.move( [ 0, 0 ] );
  31. syncClients();
  32. expectClients( '<paragraph>Bar Foo</paragraph>' );
  33. } );
  34. it( 'text in same path #2', () => {
  35. john.setData( '<paragraph>F[oo] Bar</paragraph>' );
  36. kate.setData( '<paragraph>Foo B[ar]</paragraph>' );
  37. john.move( [ 0, 0 ] );
  38. kate.move( [ 0, 4 ] );
  39. syncClients();
  40. expectClients( '<paragraph>ooF arB</paragraph>' );
  41. } );
  42. it( 'text in same path #3', () => {
  43. john.setData( '<paragraph>Foo [Bar]</paragraph>' );
  44. kate.setData( '<paragraph>Foo [Bar]</paragraph>' );
  45. john.move( [ 0, 0 ] );
  46. kate.move( [ 0, 0 ] );
  47. syncClients();
  48. expectClients( '<paragraph>BarFoo </paragraph>' );
  49. } );
  50. it( 'text in same path #4', () => {
  51. john.setData( '<paragraph>F[oo] Bar</paragraph>' );
  52. kate.setData( '<paragraph>Foo B[ar]</paragraph>' );
  53. john.move( [ 0, 6 ] );
  54. kate.move( [ 0, 2 ] );
  55. syncClients();
  56. expectClients( '<paragraph>Foo Bar</paragraph>' );
  57. } );
  58. it( 'text at different paths #1', () => {
  59. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  60. kate.setData( '<paragraph>Foo</paragraph><paragraph>B[ar]</paragraph>' );
  61. john.move( [ 0, 0 ] );
  62. kate.move( [ 1, 0 ] );
  63. syncClients();
  64. expectClients( '<paragraph>ooF</paragraph><paragraph>arB</paragraph>' );
  65. } );
  66. it( 'text in different paths #2', () => {
  67. john.setData( '<paragraph>[Foo]</paragraph><paragraph>Bar</paragraph>' );
  68. kate.setData( '<paragraph>Foo</paragraph><paragraph>[Bar]</paragraph>' );
  69. john.move( [ 1, 0 ] );
  70. kate.move( [ 0, 0 ] );
  71. syncClients();
  72. expectClients( '<paragraph>Bar</paragraph><paragraph>Foo</paragraph>' );
  73. } );
  74. it( 'text in different paths #3', () => {
  75. john.setData( '<paragraph>F[oo]</paragraph><blockQuote><paragraph>Bar</paragraph></blockQuote>' );
  76. kate.setData( '<paragraph>Foo</paragraph><blockQuote><paragraph>B[ar]</paragraph></blockQuote>' );
  77. john.move( [ 1, 0, 0 ] );
  78. kate.move( [ 0, 0 ] );
  79. syncClients();
  80. expectClients(
  81. '<paragraph>arF</paragraph>' +
  82. '<blockQuote>' +
  83. '<paragraph>ooB</paragraph>' +
  84. '</blockQuote>'
  85. );
  86. } );
  87. it( 'text inside other client\'s range #1', () => {
  88. john.setData( '<paragraph>F[oo Ba]r</paragraph>' );
  89. kate.setData( '<paragraph>Fo[o B]ar</paragraph>' );
  90. john.move( [ 0, 0 ] );
  91. kate.move( [ 0, 7 ] );
  92. syncClients();
  93. expectClients( '<paragraph>oo BaFr</paragraph>' );
  94. } );
  95. it( 'text inside other client\'s range #2', () => {
  96. john.setData( '<paragraph>F[oo Ba]r</paragraph>' );
  97. kate.setData( '<paragraph>Fo[o B]ar</paragraph>' );
  98. john.move( [ 0, 0 ] );
  99. kate.move( [ 0, 2 ] );
  100. syncClients();
  101. expectClients( '<paragraph>oo BaFr</paragraph>' );
  102. } );
  103. it( 'text inside other client\'s range #3', () => {
  104. john.setData( '<paragraph>F[oo Ba]r</paragraph>' );
  105. kate.setData( '<paragraph>[Foo B]ar</paragraph>' );
  106. john.move( [ 0, 0 ] );
  107. kate.move( [ 0, 7 ] );
  108. syncClients();
  109. expectClients( '<paragraph>oo BarF</paragraph>' );
  110. } );
  111. } );
  112. describe( 'by wrap', () => {
  113. it( 'element in different path', () => {
  114. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  115. kate.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  116. john.move( [ 0, 0 ] );
  117. kate.wrap( 'blockQuote' );
  118. syncClients();
  119. expectClients(
  120. '<paragraph>ooF</paragraph>' +
  121. '<blockQuote>' +
  122. '<paragraph>Bar</paragraph>' +
  123. '</blockQuote>'
  124. );
  125. } );
  126. it( 'element in different path #2', () => {
  127. john.setData( '<paragraph>[Foo]</paragraph><paragraph>Bar</paragraph>' );
  128. kate.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  129. john.move( [ 1, 0 ] );
  130. kate.wrap( 'blockQuote' );
  131. syncClients();
  132. expectClients(
  133. '<paragraph></paragraph>' +
  134. '<blockQuote>' +
  135. '<paragraph>FooBar</paragraph>' +
  136. '</blockQuote>'
  137. );
  138. } );
  139. it( 'element in same path', () => {
  140. john.setData( '<paragraph>F[oo]</paragraph>' );
  141. kate.setData( '[<paragraph>Foo</paragraph>]' );
  142. john.move( [ 0, 0 ] );
  143. kate.wrap( 'blockQuote' );
  144. syncClients();
  145. expectClients(
  146. '<blockQuote>' +
  147. '<paragraph>ooF</paragraph>' +
  148. '</blockQuote>'
  149. );
  150. } );
  151. it( 'element while moving', () => {
  152. john.setData( '[<paragraph>Foo</paragraph>]<paragraph>Bar</paragraph>' );
  153. kate.setData( '[<paragraph>Foo</paragraph>]<paragraph>Bar</paragraph>' );
  154. john.move( [ 2 ] );
  155. kate.wrap( 'blockQuote' );
  156. syncClients();
  157. expectClients(
  158. '<paragraph>Bar</paragraph>' +
  159. '<blockQuote>' +
  160. '<paragraph>Foo</paragraph>' +
  161. '</blockQuote>'
  162. );
  163. } );
  164. it( 'intersecting wrap', () => {
  165. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  166. kate.setData( '<paragraph>[Foo]</paragraph><paragraph>Bar</paragraph>' );
  167. john.move( [ 1, 0 ] );
  168. kate.wrap( 'div' );
  169. syncClients();
  170. expectClients(
  171. '<paragraph><div>F</div></paragraph>' +
  172. '<paragraph>ooBar</paragraph>'
  173. );
  174. } );
  175. } );
  176. describe( 'by unwrap', () => {
  177. it( 'element in different path #1', () => {
  178. john.setData( '<paragraph>F[oo]</paragraph><blockQuote><paragraph>Bar</paragraph></blockQuote>' );
  179. kate.setData( '<paragraph>Foo</paragraph><blockQuote>[<paragraph>Bar</paragraph>]</blockQuote>' );
  180. john.move( [ 0, 0 ] );
  181. kate.unwrap();
  182. syncClients();
  183. expectClients(
  184. '<paragraph>ooF</paragraph>' +
  185. '<paragraph>Bar</paragraph>'
  186. );
  187. } );
  188. it( 'element in different path #2', () => {
  189. john.setData( '<paragraph>[Foo]</paragraph><blockQuote><paragraph>Bar</paragraph></blockQuote>' );
  190. kate.setData( '<paragraph>Foo</paragraph><blockQuote>[<paragraph>Bar</paragraph>]</blockQuote>' );
  191. john.move( [ 1, 0, 0 ] );
  192. kate.unwrap();
  193. syncClients();
  194. expectClients(
  195. '<paragraph></paragraph>' +
  196. '<paragraph>FooBar</paragraph>'
  197. );
  198. } );
  199. it( 'element in same path', () => {
  200. john.setData( '<blockQuote><paragraph>F[oo]</paragraph></blockQuote>' );
  201. kate.setData( '<blockQuote>[<paragraph>Foo</paragraph>]</blockQuote>' );
  202. john.move( [ 0, 0, 0 ] );
  203. kate.unwrap();
  204. syncClients();
  205. expectClients(
  206. '<paragraph>ooF</paragraph>'
  207. );
  208. } );
  209. } );
  210. describe( 'by split', () => {
  211. it( 'text in different path #1', () => {
  212. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  213. kate.setData( '<paragraph>Foo</paragraph><paragraph>B[]ar</paragraph>' );
  214. john.move( [ 0, 0 ] );
  215. kate.split();
  216. syncClients();
  217. expectClients(
  218. '<paragraph>ooF</paragraph>' +
  219. '<paragraph>B</paragraph>' +
  220. '<paragraph>ar</paragraph>'
  221. );
  222. } );
  223. it( 'text in different path #2', () => {
  224. john.setData( '<paragraph>[Foo]</paragraph><paragraph>Bar</paragraph>' );
  225. kate.setData( '<paragraph>Foo</paragraph><paragraph>B[]ar</paragraph>' );
  226. john.move( [ 1, 1 ] );
  227. kate.split();
  228. syncClients();
  229. expectClients(
  230. '<paragraph></paragraph>' +
  231. '<paragraph>BFoo</paragraph>' +
  232. '<paragraph>ar</paragraph>'
  233. );
  234. } );
  235. it( 'text in same path', () => {
  236. john.setData( '<paragraph>F[oo] Bar</paragraph>' );
  237. kate.setData( '<paragraph>Foo B[]ar</paragraph>' );
  238. john.move( [ 0, 0 ] );
  239. kate.split();
  240. syncClients();
  241. expectClients(
  242. '<paragraph>ooF B</paragraph>' +
  243. '<paragraph>ar</paragraph>'
  244. );
  245. } );
  246. it.skip( 'text in other user\'s selection', () => {
  247. john.setData( '<paragraph>[Foo] Bar</paragraph>' );
  248. kate.setData( '<paragraph>F[]oo Bar</paragraph>' );
  249. john.move( [ 0, 4 ] );
  250. kate.split();
  251. syncClients();
  252. expectClients(
  253. '<paragraph></paragraph>' +
  254. '<paragraph> FooBar</paragraph>'
  255. );
  256. } );
  257. it( 'moved element', () => {
  258. john.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  259. kate.setData( '<paragraph>Foo</paragraph><paragraph>Ba[]r</paragraph>' );
  260. john.move( [ 0 ] );
  261. kate.split();
  262. syncClients();
  263. expectClients(
  264. '<paragraph>Ba</paragraph>' +
  265. '<paragraph>r</paragraph>' +
  266. '<paragraph>Foo</paragraph>'
  267. );
  268. } );
  269. it.skip( 'inside moved text', () => {
  270. john.setData( '<paragraph>F[oo Ba]r</paragraph><paragraph>Abc</paragraph>' );
  271. kate.setData( '<paragraph>Foo[] Bar</paragraph><paragraph>Abc</paragraph>' );
  272. john.move( [ 1, 0 ] );
  273. kate.split();
  274. syncClients();
  275. // Actual result for Kate:
  276. // <paragraph>F</paragraph><paragraph>r</paragraph><paragraph> BaooAbc</paragraph>
  277. // Move operations have wrong targets when they target at same place.
  278. expectClients(
  279. '<paragraph>F</paragraph>' +
  280. '<paragraph>r</paragraph>' +
  281. '<paragraph>oo BaAbc</paragraph>'
  282. );
  283. } );
  284. } );
  285. describe( 'by remove', () => {
  286. it( 'text in same path #1', () => {
  287. john.setData( '<paragraph>[Foo] Bar</paragraph>' );
  288. kate.setData( '<paragraph>Foo [Bar]</paragraph>' );
  289. john.move( [ 0, 4 ] );
  290. kate.remove();
  291. syncClients();
  292. expectClients( '<paragraph> Foo</paragraph>' );
  293. } );
  294. it( 'text in same path #2', () => {
  295. john.setData( '<paragraph>F[oo] Bar</paragraph>' );
  296. kate.setData( '<paragraph>Foo B[ar]</paragraph>' );
  297. john.move( [ 0, 0 ] );
  298. kate.remove();
  299. syncClients();
  300. expectClients( '<paragraph>ooF B</paragraph>' );
  301. } );
  302. it( 'text in same path #3', () => {
  303. john.setData( '<paragraph>Foo [Bar]</paragraph>' );
  304. kate.setData( '<paragraph>Foo [Bar]</paragraph>' );
  305. john.move( [ 0, 0 ] );
  306. kate.remove();
  307. syncClients();
  308. expectClients( '<paragraph>Foo </paragraph>' );
  309. } );
  310. it( 'text at different paths #1', () => {
  311. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  312. kate.setData( '<paragraph>Foo</paragraph><paragraph>B[ar]</paragraph>' );
  313. john.move( [ 0, 0 ] );
  314. kate.remove();
  315. syncClients();
  316. expectClients( '<paragraph>ooF</paragraph><paragraph>B</paragraph>' );
  317. } );
  318. it( 'text in different paths #2', () => {
  319. john.setData( '<paragraph>[Foo]</paragraph><paragraph>Bar</paragraph>' );
  320. kate.setData( '<paragraph>Foo</paragraph><paragraph>[Bar]</paragraph>' );
  321. john.move( [ 1, 0 ] );
  322. kate.remove();
  323. syncClients();
  324. expectClients( '<paragraph></paragraph><paragraph>Foo</paragraph>' );
  325. } );
  326. it( 'text in different paths #3', () => {
  327. john.setData( '<paragraph>F[oo]</paragraph><blockQuote><paragraph>Bar</paragraph></blockQuote>' );
  328. kate.setData( '<paragraph>Foo</paragraph><blockQuote><paragraph>B[ar]</paragraph></blockQuote>' );
  329. john.move( [ 1, 0, 0 ] );
  330. kate.remove();
  331. syncClients();
  332. expectClients(
  333. '<paragraph>F</paragraph>' +
  334. '<blockQuote>' +
  335. '<paragraph>ooB</paragraph>' +
  336. '</blockQuote>'
  337. );
  338. } );
  339. it( 'text in other user\'s selection, then undo', () => {
  340. john.setData( '<paragraph>Fo[o B]ar</paragraph>' );
  341. kate.setData( '<paragraph>[Foo B]ar</paragraph>' );
  342. john.move( [ 0, 0 ] );
  343. kate.remove();
  344. syncClients();
  345. john.undo();
  346. kate.undo();
  347. syncClients();
  348. expectClients(
  349. '<paragraph>Foo Bar</paragraph>'
  350. );
  351. } );
  352. } );
  353. describe( 'by merge', () => {
  354. it( 'element into paragraph #1', () => {
  355. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  356. kate.setData( '<paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph>' );
  357. john.move( [ 0, 0 ] );
  358. kate.merge();
  359. syncClients();
  360. expectClients(
  361. '<paragraph>ooFBar</paragraph>'
  362. );
  363. } );
  364. it( 'element into paragraph #2', () => {
  365. john.setData( '<paragraph>Foo</paragraph><paragraph>B[ar]</paragraph>' );
  366. kate.setData( '<paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph>' );
  367. john.move( [ 0, 0 ] );
  368. kate.merge();
  369. syncClients();
  370. expectClients(
  371. '<paragraph>arFooB</paragraph>'
  372. );
  373. } );
  374. it( 'element into paragraph #3', () => {
  375. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  376. kate.setData( '<paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph>' );
  377. john.move( [ 1, 0 ] );
  378. kate.merge();
  379. syncClients();
  380. expectClients(
  381. '<paragraph>FooBar</paragraph>'
  382. );
  383. } );
  384. it( 'wrapped element into wrapped paragraph #1', () => {
  385. john.setData( '<blockQuote><paragraph>F[oo]</paragraph><paragraph>Bar</paragraph></blockQuote>' );
  386. kate.setData( '<blockQuote><paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph></blockQuote>' );
  387. john.move( [ 0, 0, 0 ] );
  388. kate.merge();
  389. syncClients();
  390. expectClients(
  391. '<blockQuote><paragraph>ooFBar</paragraph></blockQuote>'
  392. );
  393. } );
  394. it( 'wrapped element into wrapped paragraph #2', () => {
  395. john.setData( '<blockQuote><paragraph>Foo</paragraph><paragraph>B[ar]</paragraph></blockQuote>' );
  396. kate.setData( '<blockQuote><paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph></blockQuote>' );
  397. john.move( [ 0, 0, 0 ] );
  398. kate.merge();
  399. syncClients();
  400. expectClients(
  401. '<blockQuote><paragraph>arFooB</paragraph></blockQuote>'
  402. );
  403. } );
  404. it( 'wrapped element into wrapped paragraph #3', () => {
  405. john.setData( '<blockQuote><paragraph>F[oo]</paragraph><paragraph>Bar</paragraph></blockQuote>' );
  406. kate.setData( '<blockQuote><paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph></blockQuote>' );
  407. john.move( [ 0, 1, 0 ] );
  408. kate.merge();
  409. syncClients();
  410. expectClients(
  411. '<blockQuote><paragraph>FooBar</paragraph></blockQuote>'
  412. );
  413. } );
  414. it( 'moved element', () => {
  415. john.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  416. kate.setData( '<paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph>' );
  417. john.move( [ 0 ] );
  418. kate.merge();
  419. syncClients();
  420. expectClients( '<paragraph>FooBar</paragraph>' );
  421. } );
  422. it( 'moved element, then undo', () => {
  423. john.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  424. kate.setData( '<paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph>' );
  425. john.move( [ 0 ] );
  426. kate.merge();
  427. syncClients();
  428. expectClients( '<paragraph>FooBar</paragraph>' );
  429. john.undo();
  430. syncClients();
  431. expectClients( '<paragraph>FooBar</paragraph>' );
  432. } );
  433. } );
  434. describe( 'by remove attribute', () => {
  435. it( 'from element in different path', () => {
  436. john.setData( '<paragraph>F[oo]</paragraph><paragraph bold="true">Bar</paragraph>' );
  437. kate.setData( '<paragraph>Foo</paragraph>[<paragraph bold="true">Bar</paragraph>]' );
  438. john.move( [ 1, 0 ] );
  439. kate.removeAttribute( 'bold' );
  440. syncClients();
  441. expectClients(
  442. '<paragraph>F</paragraph>' +
  443. '<paragraph>ooBar</paragraph>'
  444. );
  445. } );
  446. it( 'from text in different path', () => {
  447. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  448. kate.setData( '<paragraph>Foo</paragraph><paragraph>[Bar]</paragraph>' );
  449. john.move( [ 1, 0 ] );
  450. kate.removeAttribute( 'bold' );
  451. syncClients();
  452. expectClients(
  453. '<paragraph>F</paragraph>' +
  454. '<paragraph>ooBar</paragraph>'
  455. );
  456. } );
  457. it( 'from text in same path', () => {
  458. john.setData( '<paragraph>[Fo]<$text bold="true">o</$text></paragraph>' );
  459. kate.setData( '<paragraph>Fo<$text bold="true">[o]</$text></paragraph>' );
  460. john.move( [ 0, 3 ] );
  461. kate.removeAttribute( 'bold' );
  462. syncClients();
  463. expectClients(
  464. '<paragraph>oFo</paragraph>'
  465. );
  466. } );
  467. it( 'from element in same path', () => {
  468. john.setData( '<paragraph bold="true">[Fo]o</paragraph>' );
  469. kate.setData( '[<paragraph bold="true">Foo</paragraph>]' );
  470. john.move( [ 0, 3 ] );
  471. kate.removeAttribute( 'bold' );
  472. syncClients();
  473. expectClients(
  474. '<paragraph>oFo</paragraph>'
  475. );
  476. } );
  477. it( 'from text with 2 attributes in same path', () => {
  478. john.setData( '<paragraph>[Fo]<$text bold="true" italic="true">o</$text></paragraph>' );
  479. kate.setData( '<paragraph>Fo<$text bold="true" italic="true">[o]</$text></paragraph>' );
  480. john.move( [ 0, 3 ] );
  481. kate.removeAttribute( 'bold' );
  482. syncClients();
  483. expectClients(
  484. '<paragraph><$text italic="true">o</$text>Fo</paragraph>'
  485. );
  486. } );
  487. it( 'from text in other user\'s selection', () => {
  488. john.setData( '<paragraph><$text bold="true">[Foo]</$text></paragraph><paragraph></paragraph>' );
  489. kate.setData( '<paragraph><$text bold="true">[Foo]</$text></paragraph><paragraph></paragraph>' );
  490. john.move( [ 1, 0 ] );
  491. kate.removeAttribute( 'bold' );
  492. syncClients();
  493. expectClients(
  494. '<paragraph></paragraph>' +
  495. '<paragraph>Foo</paragraph>'
  496. );
  497. } );
  498. } );
  499. describe( 'by rename', () => {
  500. it( 'element in different path #1', () => {
  501. john.setData( '<paragraph>Foo</paragraph><paragraph>B[ar]</paragraph>' );
  502. kate.setData( '<paragraph>[]Foo</paragraph><paragraph>Bar</paragraph>' );
  503. john.move( [ 1, 0 ] );
  504. kate.rename( 'heading1' );
  505. syncClients();
  506. expectClients( '<heading1>Foo</heading1><paragraph>arB</paragraph>' );
  507. } );
  508. it( 'element in different path #2', () => {
  509. john.setData( '<blockQuote><paragraph>Foo</paragraph><paragraph>[Bar]</paragraph></blockQuote>' );
  510. kate.setData( '<blockQuote>[]<paragraph>Foo</paragraph><paragraph>Bar</paragraph></blockQuote>' );
  511. john.move( [ 0, 0, 0 ] );
  512. kate.rename( 'blockQuote2' );
  513. syncClients();
  514. expectClients(
  515. '<blockQuote2>' +
  516. '<paragraph>BarFoo</paragraph>' +
  517. '<paragraph></paragraph>' +
  518. '</blockQuote2>'
  519. );
  520. } );
  521. it( 'element in different path #3', () => {
  522. john.setData( '<blockQuote><paragraph>[Foo]</paragraph><paragraph>Bar</paragraph></blockQuote>' );
  523. kate.setData( '<blockQuote><paragraph>[]Foo</paragraph><paragraph>Bar</paragraph></blockQuote>' );
  524. john.move( [ 0, 1, 0 ] );
  525. kate.rename( 'heading1' );
  526. syncClients();
  527. expectClients(
  528. '<blockQuote>' +
  529. '<heading1></heading1>' +
  530. '<paragraph>FooBar</paragraph>' +
  531. '</blockQuote>'
  532. );
  533. } );
  534. it( 'element in same path', () => {
  535. john.setData( '<paragraph>Foo [Bar]</paragraph>' );
  536. kate.setData( '<paragraph>[]Foo Bar</paragraph>' );
  537. john.move( [ 0, 0 ] );
  538. kate.rename( 'heading1' );
  539. syncClients();
  540. expectClients( '<heading1>BarFoo </heading1>' );
  541. } );
  542. } );
  543. } );
  544. } );