8
0

removecolumncommand.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
  6. import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
  7. import RemoveColumnCommand from '../../src/commands/removecolumncommand';
  8. import TableSelection from '../../src/tableselection';
  9. import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
  10. import TableUtils from '../../src/tableutils';
  11. import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
  12. describe( 'RemoveColumnCommand', () => {
  13. let editor, model, command;
  14. beforeEach( () => {
  15. return ModelTestEditor
  16. .create( {
  17. plugins: [ TableUtils, TableSelection ]
  18. } )
  19. .then( newEditor => {
  20. editor = newEditor;
  21. model = editor.model;
  22. command = new RemoveColumnCommand( editor );
  23. defaultSchema( model.schema );
  24. defaultConversion( editor.conversion );
  25. } );
  26. } );
  27. afterEach( () => {
  28. return editor.destroy();
  29. } );
  30. describe( 'isEnabled', () => {
  31. it( 'should be true if selection is inside table cell', () => {
  32. setData( model, modelTable( [
  33. [ '00[]', '01' ],
  34. [ '10', '11' ]
  35. ] ) );
  36. expect( command.isEnabled ).to.be.true;
  37. } );
  38. it( 'should be true if selection contains multiple cells', () => {
  39. setData( model, modelTable( [
  40. [ '00', '01', '02' ],
  41. [ '10', '11', '12' ]
  42. ] ) );
  43. const tableSelection = editor.plugins.get( TableSelection );
  44. const modelRoot = model.document.getRoot();
  45. tableSelection._setCellSelection(
  46. modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
  47. modelRoot.getNodeByPath( [ 0, 0, 1 ] )
  48. );
  49. expect( command.isEnabled ).to.be.true;
  50. } );
  51. it( 'should be false if selection is inside table with one column only', () => {
  52. setData( model, modelTable( [
  53. [ '00' ],
  54. [ '10[]' ],
  55. [ '20[]' ]
  56. ] ) );
  57. expect( command.isEnabled ).to.be.false;
  58. } );
  59. it( 'should be false if all columns are selected', () => {
  60. setData( model, modelTable( [
  61. [ '00', '01', '02' ],
  62. [ '10', '11', '12' ]
  63. ] ) );
  64. const tableSelection = editor.plugins.get( TableSelection );
  65. const modelRoot = model.document.getRoot();
  66. tableSelection._setCellSelection(
  67. modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
  68. modelRoot.getNodeByPath( [ 0, 0, 2 ] )
  69. );
  70. expect( command.isEnabled ).to.be.false;
  71. } );
  72. it( 'should be false if all columns are selected - table with more than 10 columns (array sort bug)', () => {
  73. setData( model, modelTable( [
  74. [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12' ]
  75. ] ) );
  76. const tableSelection = editor.plugins.get( TableSelection );
  77. const modelRoot = model.document.getRoot();
  78. tableSelection._setCellSelection(
  79. modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
  80. modelRoot.getNodeByPath( [ 0, 0, 12 ] )
  81. );
  82. expect( command.isEnabled ).to.be.false;
  83. } );
  84. it( 'should be false if selection is outside a table', () => {
  85. setData( model, '<paragraph>11[]</paragraph>' );
  86. expect( command.isEnabled ).to.be.false;
  87. } );
  88. } );
  89. describe( 'execute()', () => {
  90. it( 'should remove a given column', () => {
  91. setData( model, modelTable( [
  92. [ '00', '01', '02' ],
  93. [ '10', '[]11', '12' ],
  94. [ '20', '21', '22' ]
  95. ] ) );
  96. command.execute();
  97. assertEqualMarkup( getData( model ), modelTable( [
  98. [ '00', '02' ],
  99. [ '10', '[]12' ],
  100. [ '20', '22' ]
  101. ] ) );
  102. } );
  103. it( 'should remove a given column from a table start', () => {
  104. setData( model, modelTable( [
  105. [ '[]00', '01' ],
  106. [ '10', '11' ],
  107. [ '20', '21' ]
  108. ] ) );
  109. command.execute();
  110. assertEqualMarkup( getData( model ), modelTable( [
  111. [ '[]01' ],
  112. [ '11' ],
  113. [ '21' ]
  114. ] ) );
  115. } );
  116. describe( 'with multiple cells selected', () => {
  117. it( 'should properly remove the first column', () => {
  118. setData( model, modelTable( [
  119. [ '00', '01' ],
  120. [ '10', '11' ],
  121. [ '20', '21' ],
  122. [ '30', '31' ]
  123. ] ) );
  124. const tableSelection = editor.plugins.get( TableSelection );
  125. const modelRoot = model.document.getRoot();
  126. tableSelection._setCellSelection(
  127. modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
  128. modelRoot.getNodeByPath( [ 0, 2, 0 ] )
  129. );
  130. command.execute();
  131. assertEqualMarkup( getData( model ), modelTable( [
  132. [ '01' ],
  133. [ '11' ],
  134. [ '[]21' ],
  135. [ '31' ]
  136. ] ) );
  137. } );
  138. it( 'should properly remove a middle column', () => {
  139. setData( model, modelTable( [
  140. [ '00', '01', '02' ],
  141. [ '10', '11', '12' ],
  142. [ '20', '21', '22' ],
  143. [ '30', '31', '32' ]
  144. ] ) );
  145. const tableSelection = editor.plugins.get( TableSelection );
  146. const modelRoot = model.document.getRoot();
  147. tableSelection._setCellSelection(
  148. modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
  149. modelRoot.getNodeByPath( [ 0, 2, 1 ] )
  150. );
  151. command.execute();
  152. assertEqualMarkup( getData( model ), modelTable( [
  153. [ '00', '02' ],
  154. [ '10', '12' ],
  155. [ '20', '[]22' ],
  156. [ '30', '32' ]
  157. ] ) );
  158. } );
  159. it( 'should properly remove the last column', () => {
  160. setData( model, modelTable( [
  161. [ '00', '01' ],
  162. [ '10', '11' ],
  163. [ '20', '21' ],
  164. [ '30', '31' ]
  165. ] ) );
  166. const tableSelection = editor.plugins.get( TableSelection );
  167. const modelRoot = model.document.getRoot();
  168. tableSelection._setCellSelection(
  169. modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
  170. modelRoot.getNodeByPath( [ 0, 2, 1 ] )
  171. );
  172. command.execute();
  173. assertEqualMarkup( getData( model ), modelTable( [
  174. [ '00' ],
  175. [ '[]10' ],
  176. [ '20' ],
  177. [ '30' ]
  178. ] ) );
  179. } );
  180. it( 'should properly remove two first columns', () => {
  181. setData( model, modelTable( [
  182. [ '00', '01', '02' ],
  183. [ '10', '11', '12' ],
  184. [ '20', '21', '22' ],
  185. [ '30', '31', '32' ]
  186. ] ) );
  187. const tableSelection = editor.plugins.get( TableSelection );
  188. const modelRoot = model.document.getRoot();
  189. tableSelection._setCellSelection(
  190. modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
  191. modelRoot.getNodeByPath( [ 0, 1, 1 ] )
  192. );
  193. command.execute();
  194. assertEqualMarkup( getData( model ), modelTable( [
  195. [ '02' ],
  196. [ '[]12' ],
  197. [ '22' ],
  198. [ '32' ]
  199. ] ) );
  200. } );
  201. it( 'should properly remove two middle columns', () => {
  202. setData( model, modelTable( [
  203. [ '00', '01', '02', '03' ],
  204. [ '10', '11', '12', '13' ],
  205. [ '20', '21', '22', '23' ],
  206. [ '30', '31', '32', '33' ]
  207. ] ) );
  208. const tableSelection = editor.plugins.get( TableSelection );
  209. const modelRoot = model.document.getRoot();
  210. tableSelection._setCellSelection(
  211. modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
  212. modelRoot.getNodeByPath( [ 0, 2, 2 ] )
  213. );
  214. command.execute();
  215. assertEqualMarkup( getData( model ), modelTable( [
  216. [ '00', '03' ],
  217. [ '10', '13' ],
  218. [ '20', '[]23' ],
  219. [ '30', '33' ]
  220. ] ) );
  221. } );
  222. it( 'should properly remove two middle columns with reversed selection', () => {
  223. setData( model, modelTable( [
  224. [ '00', '01', '02', '03' ],
  225. [ '10', '11', '12', '13' ],
  226. [ '20', '21', '22', '23' ],
  227. [ '30', '31', '32', '33' ]
  228. ] ) );
  229. const tableSelection = editor.plugins.get( TableSelection );
  230. const modelRoot = model.document.getRoot();
  231. tableSelection._setCellSelection(
  232. modelRoot.getNodeByPath( [ 0, 2, 2 ] ),
  233. modelRoot.getNodeByPath( [ 0, 1, 1 ] )
  234. );
  235. command.execute();
  236. assertEqualMarkup( getData( model ), modelTable( [
  237. [ '00', '03' ],
  238. [ '10', '13' ],
  239. [ '20', '[]23' ],
  240. [ '30', '33' ]
  241. ] ) );
  242. } );
  243. it( 'should properly remove two last columns', () => {
  244. // There's no handling for selection in case like that.
  245. setData( model, modelTable( [
  246. [ '00', '01', '02' ],
  247. [ '10', '11', '12' ],
  248. [ '20', '21', '22' ],
  249. [ '30', '31', '32' ]
  250. ] ) );
  251. const tableSelection = editor.plugins.get( TableSelection );
  252. const modelRoot = model.document.getRoot();
  253. tableSelection._setCellSelection(
  254. modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
  255. modelRoot.getNodeByPath( [ 0, 2, 2 ] )
  256. );
  257. command.execute();
  258. assertEqualMarkup( getData( model ), modelTable( [
  259. [ '00' ],
  260. [ '[]10' ],
  261. [ '20' ],
  262. [ '30' ]
  263. ] ) );
  264. } );
  265. it( 'should properly remove multiple heading columns', () => {
  266. // There's no handling for selection in case like that.
  267. setData( model, modelTable( [
  268. [ '00', '01', '02', '03', '04' ],
  269. [ '10', '11', '12', '13', '14' ]
  270. ], { headingColumns: 3 } ) );
  271. const tableSelection = editor.plugins.get( TableSelection );
  272. const modelRoot = model.document.getRoot();
  273. tableSelection._setCellSelection(
  274. modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
  275. modelRoot.getNodeByPath( [ 0, 1, 3 ] )
  276. );
  277. command.execute();
  278. assertEqualMarkup( getData( model ), modelTable( [
  279. [ '00', '04' ],
  280. [ '10', '[]14' ]
  281. ], { headingColumns: 1 } ) );
  282. } );
  283. it( 'should properly calculate truncated colspans', () => {
  284. setData( model, modelTable( [
  285. [ { contents: '00', colspan: 3 } ],
  286. [ '10', '11', '12' ],
  287. [ '20', '21', '22' ]
  288. ] ) );
  289. const tableSelection = editor.plugins.get( TableSelection );
  290. const modelRoot = model.document.getRoot();
  291. tableSelection._setCellSelection(
  292. modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
  293. modelRoot.getNodeByPath( [ 0, 1, 1 ] )
  294. );
  295. command.execute();
  296. assertEqualMarkup( getData( model ), modelTable( [
  297. [ '00' ],
  298. [ '[]12' ],
  299. [ '22' ]
  300. ] ) );
  301. } );
  302. } );
  303. it( 'should change heading columns if removing a heading column', () => {
  304. setData( model, modelTable( [
  305. [ '00', '01' ],
  306. [ '[]10', '11' ],
  307. [ '20', '21' ]
  308. ], { headingColumns: 2 } ) );
  309. command.execute();
  310. assertEqualMarkup( getData( model ), modelTable( [
  311. [ '01' ],
  312. [ '[]11' ],
  313. [ '21' ]
  314. ], { headingColumns: 1 } ) );
  315. } );
  316. it( 'should decrease colspan of table cells from previous column', () => {
  317. setData( model, modelTable( [
  318. [ { colspan: 4, contents: '00' }, '04' ],
  319. [ { colspan: 3, contents: '10' }, '13', '14' ],
  320. [ { colspan: 2, contents: '20' }, '22[]', '23', '24' ],
  321. [ '30', { colspan: 2, contents: '31' }, '33', '34' ],
  322. [ '40', '41', '42', '43', '44' ]
  323. ] ) );
  324. command.execute();
  325. assertEqualMarkup( getData( model ), modelTable( [
  326. [ { colspan: 3, contents: '00' }, '04' ],
  327. [ { colspan: 2, contents: '10' }, '13', '14' ],
  328. [ { colspan: 2, contents: '20' }, '[]23', '24' ],
  329. [ '30', '31', '33', '34' ],
  330. [ '40', '41', '43', '44' ]
  331. ] ) );
  332. } );
  333. it( 'should decrease colspan of cells that are on removed column', () => {
  334. setData( model, modelTable( [
  335. [ { colspan: 3, contents: '[]00' }, '03' ],
  336. [ { colspan: 2, contents: '10' }, '12', '13' ],
  337. [ '20', '21', '22', '23' ]
  338. ] ) );
  339. command.execute();
  340. assertEqualMarkup( getData( model ), modelTable( [
  341. [ { colspan: 2, contents: '[]00' }, '03' ],
  342. [ '10', '12', '13' ],
  343. [ '21', '22', '23' ]
  344. ] ) );
  345. } );
  346. it( 'should move focus to previous column of removed cell if in last column', () => {
  347. setData( model, modelTable( [
  348. [ '00', '01', '02' ],
  349. [ '10', '11', '12[]' ],
  350. [ '20', '21', '22' ]
  351. ] ) );
  352. command.execute();
  353. assertEqualMarkup( getData( model ), modelTable( [
  354. [ '00', '01' ],
  355. [ '10', '[]11' ],
  356. [ '20', '21' ]
  357. ] ) );
  358. } );
  359. it( 'should work property if the rowspan is in the first column (the other cell in row is selected)', () => {
  360. setData( model, modelTable( [
  361. [ { rowspan: 2, contents: '00' }, '[]01' ],
  362. [ '11' ]
  363. ] ) );
  364. command.execute();
  365. assertEqualMarkup( getData( model ), modelTable( [
  366. [ '[]00' ]
  367. ] ) );
  368. } );
  369. it( 'should work property if the rowspan is in the first column (the cell in row below is selected)', () => {
  370. setData( model, modelTable( [
  371. [ { rowspan: 2, contents: '00' }, '01' ],
  372. [ '[]11' ]
  373. ] ) );
  374. command.execute();
  375. assertEqualMarkup( getData( model ), modelTable( [
  376. [ '[]00' ]
  377. ] ) );
  378. } );
  379. it( 'should work property if the rowspan is in the first column (the cell with rowspan is selected)', () => {
  380. setData( model, modelTable( [
  381. [ { rowspan: 2, contents: '00[]' }, '01' ],
  382. [ '11' ]
  383. ] ) );
  384. command.execute();
  385. assertEqualMarkup( getData( model ), modelTable( [
  386. [ '[]01' ],
  387. [ '11' ]
  388. ] ) );
  389. } );
  390. it( 'should work property if the rowspan is in the last column (the other cell in row is selected)', () => {
  391. setData( model, modelTable( [
  392. [ '[]00', { rowspan: 2, contents: '01' } ],
  393. [ '10' ]
  394. ] ) );
  395. command.execute();
  396. assertEqualMarkup( getData( model ), modelTable( [
  397. [ '[]01' ]
  398. ] ) );
  399. } );
  400. it( 'should work property if the rowspan is in the last column (the cell in row below is selected)', () => {
  401. setData( model, modelTable( [
  402. [ '00', { rowspan: 2, contents: '01' } ],
  403. [ '[]10' ]
  404. ] ) );
  405. command.execute();
  406. assertEqualMarkup( getData( model ), modelTable( [
  407. [ '[]01' ]
  408. ] ) );
  409. } );
  410. it( 'should work property if the rowspan is in the last column (the cell with rowspan is selected)', () => {
  411. setData( model, modelTable( [
  412. [ '00', { rowspan: 2, contents: '[]01' } ],
  413. [ '10' ]
  414. ] ) );
  415. command.execute();
  416. assertEqualMarkup( getData( model ), modelTable( [
  417. [ '[]00' ],
  418. [ '10' ]
  419. ] ) );
  420. } );
  421. it( 'should remove column if removing row with one column - other columns are spanned', () => {
  422. setData( model, modelTable( [
  423. [ '[]00', { rowspan: 2, contents: '01' }, { rowspan: 2, contents: '02' } ],
  424. [ '10' ],
  425. [ '20', '21', '22' ]
  426. ] ) );
  427. command.execute();
  428. assertEqualMarkup( getData( model ), modelTable( [
  429. [ '[]01', '02' ],
  430. [ '21', '22' ]
  431. ] ) );
  432. } );
  433. } );
  434. } );