8
0

selection-post-fixer.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /**
  2. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. import Model from '../../../src/model/model';
  6. import ModelPosition from '../../../src/model/position';
  7. import ModelRange from '../../../src/model/range';
  8. import { injectSelectionPostFixer } from '../../../src/model/utils/selection-post-fixer';
  9. import { getData as getModelData, setData as setModelData } from '../../../src/dev-utils/model';
  10. describe( 'Selection post-fixer', () => {
  11. describe( 'injectSelectionPostFixer()', () => {
  12. it( 'is a function', () => {
  13. expect( injectSelectionPostFixer ).to.be.a( 'function' );
  14. } );
  15. } );
  16. describe( 'injected behavior', () => {
  17. let model, modelRoot;
  18. beforeEach( () => {
  19. model = new Model();
  20. modelRoot = model.document.createRoot();
  21. model.schema.register( 'paragraph', { inheritAllFrom: '$block' } );
  22. model.schema.register( 'table', {
  23. allowWhere: '$block',
  24. isObject: true,
  25. isLimit: true
  26. } );
  27. model.schema.register( 'tableRow', {
  28. allowIn: 'table',
  29. isLimit: true
  30. } );
  31. model.schema.register( 'tableCell', {
  32. allowIn: 'tableRow',
  33. allowContentOf: '$block',
  34. isLimit: true
  35. } );
  36. setModelData( model,
  37. '<paragraph>[]foo</paragraph>' +
  38. '<table>' +
  39. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  40. '</table>' +
  41. '<paragraph>bar</paragraph>'
  42. );
  43. } );
  44. it( 'should not crash if there is no correct position for model selection', () => {
  45. setModelData( model, '' );
  46. expect( getModelData( model ) ).to.equal( '[]' );
  47. } );
  48. it( 'should react to structure changes', () => {
  49. model.change( writer => {
  50. writer.remove( modelRoot.getChild( 0 ) );
  51. } );
  52. expect( getModelData( model ) ).to.equal(
  53. '[<table>' +
  54. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  55. '</table>]' +
  56. '<paragraph>bar</paragraph>'
  57. );
  58. } );
  59. it( 'should react to selection changes', () => {
  60. // <paragraph>foo</paragraph>[]<table>...
  61. model.change( writer => {
  62. writer.setSelection(
  63. ModelRange.createFromParentsAndOffsets( modelRoot, 1, modelRoot, 1 )
  64. );
  65. } );
  66. expect( getModelData( model ) ).to.equal(
  67. '<paragraph>foo[]</paragraph>' +
  68. '<table>' +
  69. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  70. '</table>' +
  71. '<paragraph>bar</paragraph>'
  72. );
  73. } );
  74. describe( 'not collapsed selection', () => {
  75. it( 'should fix #1', () => {
  76. model.change( writer => {
  77. writer.setSelection( ModelRange.createFromParentsAndOffsets(
  78. modelRoot.getChild( 0 ), 1,
  79. modelRoot.getChild( 1 ).getChild( 0 ), 1
  80. ) );
  81. } );
  82. expect( getModelData( model ) ).to.equal(
  83. '<paragraph>f[oo</paragraph>' +
  84. '<table>' +
  85. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  86. '</table>]' +
  87. '<paragraph>bar</paragraph>'
  88. );
  89. } );
  90. it( 'should fix #2', () => {
  91. model.change( writer => {
  92. writer.setSelection( ModelRange.createFromParentsAndOffsets(
  93. modelRoot.getChild( 1 ).getChild( 0 ), 1,
  94. modelRoot.getChild( 2 ), 1
  95. ) );
  96. } );
  97. expect( getModelData( model ) ).to.equal(
  98. '<paragraph>foo</paragraph>' +
  99. '[<table>' +
  100. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  101. '</table>' +
  102. '<paragraph>b]ar</paragraph>'
  103. );
  104. } );
  105. it( 'should fix #3', () => {
  106. model.change( writer => {
  107. writer.setSelection( ModelRange.createFromParentsAndOffsets(
  108. modelRoot.getChild( 0 ), 1,
  109. modelRoot.getChild( 1 ), 0
  110. ) );
  111. } );
  112. expect( getModelData( model ) ).to.equal(
  113. '<paragraph>f[oo</paragraph>' +
  114. '<table>' +
  115. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  116. '</table>]' +
  117. '<paragraph>bar</paragraph>'
  118. );
  119. } );
  120. it( 'should fix #4', () => {
  121. model.change( writer => {
  122. writer.setSelection( ModelRange.createFromParentsAndOffsets(
  123. modelRoot.getChild( 1 ).getChild( 0 ).getChild( 0 ), 1,
  124. modelRoot.getChild( 1 ).getChild( 0 ).getChild( 1 ), 2
  125. ) );
  126. } );
  127. expect( getModelData( model ) ).to.equal(
  128. '<paragraph>foo</paragraph>' +
  129. '[<table>' +
  130. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  131. '</table>]' +
  132. '<paragraph>bar</paragraph>'
  133. );
  134. } );
  135. it( 'should fix #5', () => {
  136. setModelData( model,
  137. '<paragraph>foo</paragraph>' +
  138. '<table>' +
  139. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  140. '</table>' +
  141. '[]<table>' +
  142. '<tableRow><tableCell>xxx</tableCell><tableCell>yyy</tableCell></tableRow>' +
  143. '</table>' +
  144. '<paragraph>baz</paragraph>'
  145. );
  146. expect( getModelData( model ) ).to.equal(
  147. '<paragraph>foo</paragraph>' +
  148. '[<table>' +
  149. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  150. '</table>]' +
  151. '<table>' +
  152. '<tableRow><tableCell>xxx</tableCell><tableCell>yyy</tableCell></tableRow>' +
  153. '</table>' +
  154. '<paragraph>baz</paragraph>'
  155. );
  156. } );
  157. it( 'should not fix #1', () => {
  158. setModelData( model,
  159. '<paragraph>foo</paragraph>' +
  160. '<table>' +
  161. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  162. '</table>' +
  163. '<paragraph>b[ar</paragraph>' +
  164. '<paragraph>ba]z</paragraph>'
  165. );
  166. expect( getModelData( model ) ).to.equal(
  167. '<paragraph>foo</paragraph>' +
  168. '<table>' +
  169. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  170. '</table>' +
  171. '<paragraph>b[ar</paragraph>' +
  172. '<paragraph>ba]z</paragraph>'
  173. );
  174. } );
  175. it( 'should fix multiple ranges #1', () => {
  176. model.change( writer => {
  177. const ranges = [
  178. new ModelRange( new ModelPosition( modelRoot, [ 0, 1 ] ), new ModelPosition( modelRoot, [ 1, 0 ] ) ),
  179. new ModelRange( new ModelPosition( modelRoot, [ 1, 0, 0, 0 ] ), new ModelPosition( modelRoot, [ 1, 1 ] ) )
  180. ];
  181. writer.setSelection( ranges );
  182. } );
  183. expect( getModelData( model ) ).to.equal(
  184. '<paragraph>f[oo</paragraph>' +
  185. '<table>' +
  186. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  187. '</table>]' +
  188. '<paragraph>bar</paragraph>'
  189. );
  190. } );
  191. it( 'should fix multiple ranges #2', () => {
  192. model.change( writer => {
  193. const ranges = [
  194. new ModelRange( new ModelPosition( modelRoot, [ 0, 1 ] ), new ModelPosition( modelRoot, [ 1, 0 ] ) ),
  195. new ModelRange( new ModelPosition( modelRoot, [ 1, 0, 0, 0 ] ), new ModelPosition( modelRoot, [ 2, 2 ] ) )
  196. ];
  197. writer.setSelection( ranges );
  198. } );
  199. expect( getModelData( model ) ).to.equal(
  200. '<paragraph>f[oo</paragraph>' +
  201. '<table>' +
  202. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  203. '</table>' +
  204. '<paragraph>ba]r</paragraph>'
  205. );
  206. } );
  207. it( 'should fix multiple ranges #3', () => {
  208. setModelData( model,
  209. '<paragraph>foo</paragraph>' +
  210. '<table>' +
  211. '<tableRow><tableCell>[aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  212. '<tableRow>]<tableCell>[aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  213. '<tableRow>]<tableCell>[aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  214. '<tableRow>]<tableCell>[aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  215. '</table>' +
  216. '<paragraph>b]az</paragraph>'
  217. );
  218. expect( getModelData( model ) ).to.equal(
  219. '<paragraph>foo</paragraph>' +
  220. '[<table>' +
  221. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  222. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  223. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  224. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  225. '</table>' +
  226. '<paragraph>b]az</paragraph>'
  227. );
  228. } );
  229. it( 'should fix multiple ranges #4', () => {
  230. model.change( writer => {
  231. const ranges = [
  232. new ModelRange( new ModelPosition( modelRoot, [ 0, 1 ] ), new ModelPosition( modelRoot, [ 1, 0 ] ) ),
  233. new ModelRange( new ModelPosition( modelRoot, [ 1, 0, 0, 0 ] ), new ModelPosition( modelRoot, [ 2, 1 ] ) ),
  234. new ModelRange( new ModelPosition( modelRoot, [ 2, 2 ] ), new ModelPosition( modelRoot, [ 2, 3 ] ) )
  235. ];
  236. writer.setSelection( ranges );
  237. } );
  238. expect( getModelData( model ) ).to.equal(
  239. '<paragraph>f[oo</paragraph>' +
  240. '<table>' +
  241. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  242. '</table>' +
  243. '<paragraph>b]a[r]</paragraph>'
  244. );
  245. } );
  246. } );
  247. describe( 'collapsed selection', () => {
  248. it( 'should fix #1', () => {
  249. // <table>[]<tableRow>...
  250. model.change( writer => {
  251. writer.setSelection(
  252. ModelRange.createFromParentsAndOffsets( modelRoot.getChild( 1 ), 0, modelRoot.getChild( 1 ), 0 )
  253. );
  254. } );
  255. expect( getModelData( model ) ).to.equal(
  256. '<paragraph>foo[]</paragraph>' +
  257. '<table>' +
  258. '<tableRow><tableCell>aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  259. '</table>' +
  260. '<paragraph>bar</paragraph>'
  261. );
  262. } );
  263. it( 'should fix #2', () => {
  264. // <table><tableRow>[]<tableCell>...
  265. model.change( writer => {
  266. const row = modelRoot.getChild( 1 ).getChild( 0 );
  267. writer.setSelection(
  268. ModelRange.createFromParentsAndOffsets( row, 0, row, 0 )
  269. );
  270. } );
  271. expect( getModelData( model ) ).to.equal(
  272. '<paragraph>foo</paragraph>' +
  273. '<table>' +
  274. '<tableRow><tableCell>[]aaa</tableCell><tableCell>bbb</tableCell></tableRow>' +
  275. '</table>' +
  276. '<paragraph>bar</paragraph>'
  277. );
  278. } );
  279. } );
  280. } );
  281. } );