8
0

tablenavigation.js 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203
  1. import { getCode } from '@ckeditor/ckeditor5-utils/src/keyboard';
  2. import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
  3. import { modelTable } from './_utils/utils';
  4. import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
  5. import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
  6. import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
  7. import ImageEditing from '@ckeditor/ckeditor5-image/src/image/imageediting';
  8. import MediaEmbedEditing from '@ckeditor/ckeditor5-media-embed/src/mediaembedediting';
  9. import TableNavigation from '../src/tablenavigation';
  10. import Table from '../src/table';
  11. import TableEditing from '../src/tableediting';
  12. import TableSelection from '../src/tableselection';
  13. import ImageCaptionEditing from '@ckeditor/ckeditor5-image/src/imagecaption/imagecaptionediting';
  14. import HorizontalLineEditing from '@ckeditor/ckeditor5-horizontal-line/src/horizontallineediting';
  15. import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
  16. import Image from '@ckeditor/ckeditor5-image/src/image';
  17. import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
  18. import HorizontalLine from '@ckeditor/ckeditor5-horizontal-line/src/horizontalline';
  19. import global from '@ckeditor/ckeditor5-utils/src/dom/global';
  20. describe( 'TableNavigation', () => {
  21. let editor, model, modelRoot, tableSelection;
  22. const imageUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAUCAQAAADRyVAeAAAAKklEQVR42u3PAQ0AAAwCI' +
  23. 'O0f+u/hoAHNZUJFRERERERERERERERERLYiD9N4FAFj2iK6AAAAAElFTkSuQmCC';
  24. beforeEach( () => {
  25. return VirtualTestEditor
  26. .create( {
  27. plugins: [ TableEditing, TableNavigation, TableSelection, Paragraph, ImageEditing, ImageCaptionEditing, MediaEmbedEditing,
  28. HorizontalLineEditing ]
  29. } )
  30. .then( newEditor => {
  31. editor = newEditor;
  32. model = editor.model;
  33. modelRoot = model.document.getRoot();
  34. tableSelection = editor.plugins.get( TableSelection );
  35. } );
  36. } );
  37. afterEach( () => {
  38. editor.destroy();
  39. } );
  40. it( 'should have pluginName', () => {
  41. expect( TableNavigation.pluginName ).to.equal( 'TableNavigation' );
  42. } );
  43. describe( 'Tab key handling', () => {
  44. let domEvtDataStub;
  45. beforeEach( () => {
  46. domEvtDataStub = {
  47. keyCode: getCode( 'Tab' ),
  48. preventDefault: sinon.spy(),
  49. stopPropagation: sinon.spy()
  50. };
  51. } );
  52. it( 'should do nothing if not tab pressed', () => {
  53. setModelData( model, modelTable( [
  54. [ '11', '12[]' ]
  55. ] ) );
  56. domEvtDataStub.keyCode = getCode( 'a' );
  57. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  58. sinon.assert.notCalled( domEvtDataStub.preventDefault );
  59. sinon.assert.notCalled( domEvtDataStub.stopPropagation );
  60. assertEqualMarkup( getModelData( model ), modelTable( [
  61. [ '11', '12[]' ]
  62. ] ) );
  63. } );
  64. it( 'should do nothing if Ctrl+Tab is pressed', () => {
  65. setModelData( model, modelTable( [
  66. [ '11', '12[]' ]
  67. ] ) );
  68. domEvtDataStub.ctrlKey = true;
  69. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  70. sinon.assert.notCalled( domEvtDataStub.preventDefault );
  71. sinon.assert.notCalled( domEvtDataStub.stopPropagation );
  72. assertEqualMarkup( getModelData( model ), modelTable( [
  73. [ '11', '12[]' ]
  74. ] ) );
  75. } );
  76. describe( 'on TAB', () => {
  77. it( 'should do nothing if selection is not in a table', () => {
  78. setModelData( model, '<paragraph>[]</paragraph>' + modelTable( [ [ '11', '12' ] ] ) );
  79. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  80. sinon.assert.notCalled( domEvtDataStub.preventDefault );
  81. sinon.assert.notCalled( domEvtDataStub.stopPropagation );
  82. assertEqualMarkup( getModelData( model ), '<paragraph>[]</paragraph>' + modelTable( [
  83. [ '11', '12' ]
  84. ] ) );
  85. } );
  86. it( 'should move to next cell', () => {
  87. setModelData( model, modelTable( [
  88. [ '11[]', '12' ]
  89. ] ) );
  90. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  91. sinon.assert.calledOnce( domEvtDataStub.preventDefault );
  92. sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
  93. assertEqualMarkup( getModelData( model ), modelTable( [
  94. [ '11', '[12]' ]
  95. ] ) );
  96. } );
  97. it( 'should create another row and move to first cell in new row', () => {
  98. setModelData( model, modelTable( [
  99. [ '11', '[12]' ]
  100. ] ) );
  101. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  102. assertEqualMarkup( getModelData( model ), modelTable( [
  103. [ '11', '12' ],
  104. [ '[]', '' ]
  105. ] ) );
  106. } );
  107. it( 'should not create another row and not move the caret if insertTableRowBelow command is disabled', () => {
  108. setModelData( model, modelTable( [
  109. [ '11', '12[]' ]
  110. ] ) );
  111. const insertTableRowBelowCommand = editor.commands.get( 'insertTableRowBelow' );
  112. insertTableRowBelowCommand.forceDisabled( 'test' );
  113. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  114. assertEqualMarkup( getModelData( model ), modelTable( [
  115. [ '11', '12[]' ]
  116. ] ) );
  117. } );
  118. it( 'should move to the first cell of next row if on end of a row', () => {
  119. setModelData( model, modelTable( [
  120. [ '11', '12[]' ],
  121. [ '21', '22' ]
  122. ] ) );
  123. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  124. assertEqualMarkup( getModelData( model ), modelTable( [
  125. [ '11', '12' ],
  126. [ '[21]', '22' ]
  127. ] ) );
  128. } );
  129. it( 'should move to the next table cell if part of block content is selected', () => {
  130. setModelData( model, modelTable( [
  131. [ '11', '<paragraph>12</paragraph><paragraph>[foo]</paragraph><paragraph>bar</paragraph>', '13' ]
  132. ] ) );
  133. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  134. assertEqualMarkup( getModelData( model ), modelTable( [
  135. [
  136. '11',
  137. '<paragraph>12</paragraph><paragraph>foo</paragraph><paragraph>bar</paragraph>',
  138. '[13]'
  139. ]
  140. ] ) );
  141. } );
  142. it( 'should move to next cell with an image', () => {
  143. setModelData( model, modelTable( [
  144. [ '11[]', '<paragraph>foo</paragraph><image><caption></caption></image>' ]
  145. ] ) );
  146. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  147. sinon.assert.calledOnce( domEvtDataStub.preventDefault );
  148. sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
  149. assertEqualMarkup( getModelData( model ), modelTable( [
  150. [ '11', '<paragraph>[foo</paragraph><image><caption></caption></image>]' ]
  151. ] ) );
  152. } );
  153. it( 'should move to next cell with an blockQuote', () => {
  154. model.schema.register( 'blockQuote', {
  155. allowWhere: '$block',
  156. allowContentOf: '$root'
  157. } );
  158. editor.conversion.elementToElement( { model: 'blockQuote', view: 'blockquote' } );
  159. setModelData( model, modelTable( [
  160. [ '11[]', '<blockQuote><paragraph>foo</paragraph></blockQuote>' ]
  161. ] ) );
  162. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  163. sinon.assert.calledOnce( domEvtDataStub.preventDefault );
  164. sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
  165. assertEqualMarkup( getModelData( model ), modelTable( [
  166. [ '11', '<blockQuote><paragraph>[foo]</paragraph></blockQuote>' ]
  167. ] ) );
  168. } );
  169. it( 'should listen with lower priority then its children', () => {
  170. // Cancel TAB event.
  171. editor.keystrokes.set( 'Tab', ( data, cancel ) => cancel() );
  172. setModelData( model, modelTable( [
  173. [ '11[]', '12' ]
  174. ] ) );
  175. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  176. sinon.assert.calledOnce( domEvtDataStub.preventDefault );
  177. sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
  178. assertEqualMarkup( getModelData( model ), modelTable( [
  179. [ '11[]', '12' ]
  180. ] ) );
  181. } );
  182. describe( 'on table widget selected', () => {
  183. beforeEach( () => {
  184. editor.model.schema.register( 'block', {
  185. allowWhere: '$block',
  186. allowContentOf: '$block',
  187. isObject: true
  188. } );
  189. editor.conversion.elementToElement( { model: 'block', view: 'block' } );
  190. } );
  191. it( 'should move caret to the first table cell on TAB', () => {
  192. const spy = sinon.spy();
  193. editor.keystrokes.set( 'Tab', spy, { priority: 'lowest' } );
  194. setModelData( model, '[' + modelTable( [
  195. [ '11', '12' ]
  196. ] ) + ']' );
  197. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  198. sinon.assert.calledOnce( domEvtDataStub.preventDefault );
  199. sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
  200. assertEqualMarkup( getModelData( model ), modelTable( [
  201. [ '[11]', '12' ]
  202. ] ) );
  203. // Should cancel event - so no other tab handler is called.
  204. sinon.assert.notCalled( spy );
  205. } );
  206. it( 'shouldn\'t do anything on other blocks', () => {
  207. const spy = sinon.spy();
  208. editor.editing.view.document.on( 'keydown', spy );
  209. setModelData( model, '[<block>foo</block>]' );
  210. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  211. sinon.assert.notCalled( domEvtDataStub.preventDefault );
  212. sinon.assert.notCalled( domEvtDataStub.stopPropagation );
  213. assertEqualMarkup( getModelData( model ), '[<block>foo</block>]' );
  214. // Should not cancel event.
  215. sinon.assert.calledOnce( spy );
  216. } );
  217. } );
  218. } );
  219. describe( 'on SHIFT+TAB', () => {
  220. beforeEach( () => {
  221. domEvtDataStub.shiftKey = true;
  222. } );
  223. it( 'should do nothing if selection is not in a table', () => {
  224. setModelData( model, '<paragraph>[]</paragraph>' + modelTable( [
  225. [ '11', '12' ]
  226. ] ) );
  227. domEvtDataStub.keyCode = getCode( 'Tab' );
  228. domEvtDataStub.shiftKey = true;
  229. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  230. sinon.assert.notCalled( domEvtDataStub.preventDefault );
  231. sinon.assert.notCalled( domEvtDataStub.stopPropagation );
  232. assertEqualMarkup( getModelData( model ), '<paragraph>[]</paragraph>' + modelTable( [
  233. [ '11', '12' ]
  234. ] ) );
  235. } );
  236. it( 'should move to previous cell', () => {
  237. setModelData( model, modelTable( [
  238. [ '11', '12[]' ]
  239. ] ) );
  240. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  241. sinon.assert.calledOnce( domEvtDataStub.preventDefault );
  242. sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
  243. assertEqualMarkup( getModelData( model ), modelTable( [
  244. [ '[11]', '12' ]
  245. ] ) );
  246. } );
  247. it( 'should not move if caret is in first table cell', () => {
  248. setModelData( model, '<paragraph>foo</paragraph>' + modelTable( [
  249. [ '[]11', '12' ]
  250. ] ) );
  251. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  252. assertEqualMarkup( getModelData( model ),
  253. '<paragraph>foo</paragraph>' + modelTable( [ [ '[]11', '12' ] ] )
  254. );
  255. } );
  256. it( 'should move to the last cell of previous row if on beginning of a row', () => {
  257. setModelData( model, modelTable( [
  258. [ '11', '12' ],
  259. [ '[]21', '22' ]
  260. ] ) );
  261. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  262. assertEqualMarkup( getModelData( model ), modelTable( [
  263. [ '11', '[12]' ],
  264. [ '21', '22' ]
  265. ] ) );
  266. } );
  267. it( 'should move to the previous table cell if part of block content is selected', () => {
  268. setModelData( model, modelTable( [
  269. [ '11', '<paragraph>12</paragraph><paragraph>[foo]</paragraph><paragraph>bar</paragraph>', '13' ]
  270. ] ) );
  271. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  272. assertEqualMarkup( getModelData( model ), modelTable( [
  273. [
  274. '[11]',
  275. '<paragraph>12</paragraph><paragraph>foo</paragraph><paragraph>bar</paragraph>',
  276. '13'
  277. ]
  278. ] ) );
  279. } );
  280. it( 'should move to previous cell with an image', () => {
  281. setModelData( model, modelTable( [
  282. [ '<paragraph>foo</paragraph><image><caption></caption></image>', 'bar[]' ]
  283. ] ) );
  284. editor.editing.view.document.fire( 'keydown', domEvtDataStub );
  285. sinon.assert.calledOnce( domEvtDataStub.preventDefault );
  286. sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
  287. assertEqualMarkup( getModelData( model ), modelTable( [
  288. [ '<paragraph>[foo</paragraph><image><caption></caption></image>]', 'bar' ]
  289. ] ) );
  290. } );
  291. } );
  292. } );
  293. describe( 'Arrow keys handling', () => {
  294. let leftArrowDomEvtDataStub, rightArrowDomEvtDataStub, upArrowDomEvtDataStub, downArrowDomEvtDataStub;
  295. beforeEach( () => {
  296. leftArrowDomEvtDataStub = {
  297. keyCode: getCode( 'ArrowLeft' ),
  298. preventDefault: sinon.spy(),
  299. stopPropagation: sinon.spy(),
  300. domTarget: global.document.body
  301. };
  302. rightArrowDomEvtDataStub = {
  303. keyCode: getCode( 'ArrowRight' ),
  304. preventDefault: sinon.spy(),
  305. stopPropagation: sinon.spy(),
  306. domTarget: global.document.body
  307. };
  308. upArrowDomEvtDataStub = {
  309. keyCode: getCode( 'ArrowUp' ),
  310. preventDefault: sinon.spy(),
  311. stopPropagation: sinon.spy(),
  312. domTarget: global.document.body
  313. };
  314. downArrowDomEvtDataStub = {
  315. keyCode: getCode( 'ArrowDown' ),
  316. preventDefault: sinon.spy(),
  317. stopPropagation: sinon.spy(),
  318. domTarget: global.document.body
  319. };
  320. } );
  321. it( 'should do nothing if not arrow key pressed', () => {
  322. setModelData( model, modelTable( [
  323. [ '00', '01[]' ]
  324. ] ) );
  325. leftArrowDomEvtDataStub.keyCode = getCode( 'a' );
  326. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  327. sinon.assert.notCalled( leftArrowDomEvtDataStub.preventDefault );
  328. sinon.assert.notCalled( leftArrowDomEvtDataStub.stopPropagation );
  329. assertEqualMarkup( getModelData( model ), modelTable( [
  330. [ '00', '01[]' ]
  331. ] ) );
  332. } );
  333. it( 'should do nothing if selection is not in a table', () => {
  334. const modelData = '<paragraph>[]foobar</paragraph>' + modelTable( [ [ '00', '01' ] ] );
  335. setModelData( model, modelData );
  336. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  337. sinon.assert.notCalled( upArrowDomEvtDataStub.preventDefault );
  338. sinon.assert.notCalled( upArrowDomEvtDataStub.stopPropagation );
  339. assertEqualMarkup( getModelData( model ), modelData );
  340. } );
  341. describe( '#_navigateFromCellInDirection (finding proper cell to move selection to)', () => {
  342. let tableNavigation;
  343. beforeEach( () => {
  344. tableNavigation = editor.plugins.get( TableNavigation );
  345. } );
  346. describe( 'with no col/row-spanned cells', () => {
  347. beforeEach( () => {
  348. setModelData( model, '<paragraph>foo</paragraph>' + modelTable( [
  349. [ '00', '01', '02' ],
  350. [ '10', '11', '12' ],
  351. [ '20', '21', '22' ]
  352. ] ) + '<paragraph>bar</paragraph>' );
  353. } );
  354. describe( 'from the first table cell', () => {
  355. let tableCell;
  356. beforeEach( () => {
  357. tableCell = modelRoot.getNodeByPath( [ 1, 0, 0 ] );
  358. } );
  359. it( 'should navigate to the start position of the cell on the right when direction is "right"', () => {
  360. tableNavigation._navigateFromCellInDirection( tableCell, 'right' );
  361. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  362. [ '00', '[]01', '02' ],
  363. [ '10', '11', '12' ],
  364. [ '20', '21', '22' ]
  365. ] ) + '<paragraph>bar</paragraph>' );
  366. } );
  367. it( 'should navigate to the start position the cell below when direction is "down"', () => {
  368. tableNavigation._navigateFromCellInDirection( tableCell, 'down' );
  369. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  370. [ '00', '01', '02' ],
  371. [ '[]10', '11', '12' ],
  372. [ '20', '21', '22' ]
  373. ] ) + '<paragraph>bar</paragraph>' );
  374. } );
  375. it( 'should select a whole table when direction is "up"', () => {
  376. tableNavigation._navigateFromCellInDirection( tableCell, 'up' );
  377. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>[' + modelTable( [
  378. [ '00', '01', '02' ],
  379. [ '10', '11', '12' ],
  380. [ '20', '21', '22' ]
  381. ] ) + ']<paragraph>bar</paragraph>' );
  382. } );
  383. it( 'should select a whole table when direction is "left"', () => {
  384. tableNavigation._navigateFromCellInDirection( tableCell, 'left' );
  385. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>[' + modelTable( [
  386. [ '00', '01', '02' ],
  387. [ '10', '11', '12' ],
  388. [ '20', '21', '22' ]
  389. ] ) + ']<paragraph>bar</paragraph>' );
  390. } );
  391. } );
  392. describe( 'from the last table cell', () => {
  393. let tableCell;
  394. beforeEach( () => {
  395. tableCell = modelRoot.getNodeByPath( [ 1, 2, 2 ] );
  396. } );
  397. it( 'should navigate to the end position of the cell on the left when direction is "left"', () => {
  398. tableNavigation._navigateFromCellInDirection( tableCell, 'left' );
  399. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  400. [ '00', '01', '02' ],
  401. [ '10', '11', '12' ],
  402. [ '20', '21[]', '22' ]
  403. ] ) + '<paragraph>bar</paragraph>' );
  404. } );
  405. it( 'should navigate to the end position of the cell above when direction is "up"', () => {
  406. tableNavigation._navigateFromCellInDirection( tableCell, 'up' );
  407. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  408. [ '00', '01', '02' ],
  409. [ '10', '11', '12[]' ],
  410. [ '20', '21', '22' ]
  411. ] ) + '<paragraph>bar</paragraph>' );
  412. } );
  413. it( 'should select a whole table when direction is "down"', () => {
  414. tableNavigation._navigateFromCellInDirection( tableCell, 'down' );
  415. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>[' + modelTable( [
  416. [ '00', '01', '02' ],
  417. [ '10', '11', '12' ],
  418. [ '20', '21', '22' ]
  419. ] ) + ']<paragraph>bar</paragraph>' );
  420. } );
  421. it( 'should select a whole table when direction is "right"', () => {
  422. tableNavigation._navigateFromCellInDirection( tableCell, 'right' );
  423. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>[' + modelTable( [
  424. [ '00', '01', '02' ],
  425. [ '10', '11', '12' ],
  426. [ '20', '21', '22' ]
  427. ] ) + ']<paragraph>bar</paragraph>' );
  428. } );
  429. } );
  430. describe( 'from a cell in the first column (but not first row)', () => {
  431. let tableCell;
  432. beforeEach( () => {
  433. tableCell = modelRoot.getNodeByPath( [ 1, 1, 0 ] );
  434. } );
  435. it( 'should navigate to start position of the cell on the right when direction is "right"', () => {
  436. tableNavigation._navigateFromCellInDirection( tableCell, 'right' );
  437. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  438. [ '00', '01', '02' ],
  439. [ '10', '[]11', '12' ],
  440. [ '20', '21', '22' ]
  441. ] ) + '<paragraph>bar</paragraph>' );
  442. } );
  443. it( 'should navigate to the end position of the cell above when direction is "up"', () => {
  444. tableNavigation._navigateFromCellInDirection( tableCell, 'up' );
  445. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  446. [ '00[]', '01', '02' ],
  447. [ '10', '11', '12' ],
  448. [ '20', '21', '22' ]
  449. ] ) + '<paragraph>bar</paragraph>' );
  450. } );
  451. it( 'should navigate to the start position of the cell below when direction is "down"', () => {
  452. tableNavigation._navigateFromCellInDirection( tableCell, 'down' );
  453. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  454. [ '00', '01', '02' ],
  455. [ '10', '11', '12' ],
  456. [ '[]20', '21', '22' ]
  457. ] ) + '<paragraph>bar</paragraph>' );
  458. } );
  459. it( 'should navigate to the end position of the last cell in the previous row when direction is "left"', () => {
  460. tableNavigation._navigateFromCellInDirection( tableCell, 'left' );
  461. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  462. [ '00', '01', '02[]' ],
  463. [ '10', '11', '12' ],
  464. [ '20', '21', '22' ]
  465. ] ) + '<paragraph>bar</paragraph>' );
  466. } );
  467. } );
  468. describe( 'from a cell in the last column (but not last row)', () => {
  469. let tableCell;
  470. beforeEach( () => {
  471. tableCell = modelRoot.getNodeByPath( [ 1, 1, 2 ] );
  472. } );
  473. it( 'should navigate to the end position of the cell on the left when direction is "left"', () => {
  474. tableNavigation._navigateFromCellInDirection( tableCell, 'left' );
  475. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  476. [ '00', '01', '02' ],
  477. [ '10', '11[]', '12' ],
  478. [ '20', '21', '22' ]
  479. ] ) + '<paragraph>bar</paragraph>' );
  480. } );
  481. it( 'should navigate to the end position the cell above when direction is "up"', () => {
  482. tableNavigation._navigateFromCellInDirection( tableCell, 'up' );
  483. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  484. [ '00', '01', '02[]' ],
  485. [ '10', '11', '12' ],
  486. [ '20', '21', '22' ]
  487. ] ) + '<paragraph>bar</paragraph>' );
  488. } );
  489. it( 'should navigate to the start position of the cell below when direction is "down"', () => {
  490. tableNavigation._navigateFromCellInDirection( tableCell, 'down' );
  491. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  492. [ '00', '01', '02' ],
  493. [ '10', '11', '12' ],
  494. [ '20', '21', '[]22' ]
  495. ] ) + '<paragraph>bar</paragraph>' );
  496. } );
  497. it( 'should navigate to the start position of the first cell in the next row when direction is "right"', () => {
  498. tableNavigation._navigateFromCellInDirection( tableCell, 'right' );
  499. assertEqualMarkup( getModelData( model ), '<paragraph>foo</paragraph>' + modelTable( [
  500. [ '00', '01', '02' ],
  501. [ '10', '11', '12' ],
  502. [ '[]20', '21', '22' ]
  503. ] ) + '<paragraph>bar</paragraph>' );
  504. } );
  505. } );
  506. } );
  507. describe( 'with col/row-spanned cells', () => {
  508. beforeEach( () => {
  509. // +----+----+----+----+----+
  510. // | 00 | 01 | 02 | 03 | 04 |
  511. // +----+----+----+----+----+
  512. // | 10 | 11 | 13 | 14 |
  513. // +----+ + +----+
  514. // | 20 | | | 24 |
  515. // +----+----+----+----+----+
  516. // | 30 | 31 | 33 | 34 |
  517. // +----+----+----+----+----+
  518. // | 40 | 41 | 42 | 43 | 44 |
  519. // +----+----+----+----+----+
  520. setModelData( model, modelTable( [
  521. [ '00', '01', '02', '03', '04' ],
  522. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  523. [ '20', '24' ],
  524. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  525. [ '40', '41', '42', '43', '44' ]
  526. ] ) );
  527. } );
  528. describe( 'when navigating to the right', () => {
  529. it( 'should navigate to the row-col-spanned cell when approaching from the upper spanned row', () => {
  530. const tableCell = modelRoot.getNodeByPath( [ 0, 1, 0 ] );
  531. tableNavigation._navigateFromCellInDirection( tableCell, 'right' );
  532. assertEqualMarkup( getModelData( model ), modelTable( [
  533. [ '00', '01', '02', '03', '04' ],
  534. [ '10', { contents: '[]11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  535. [ '20', '24' ],
  536. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  537. [ '40', '41', '42', '43', '44' ]
  538. ] ) );
  539. } );
  540. it( 'should navigate to the row-col-spanned cell when approaching from the lower spanned row', () => {
  541. const tableCell = modelRoot.getNodeByPath( [ 0, 2, 0 ] );
  542. tableNavigation._navigateFromCellInDirection( tableCell, 'right' );
  543. assertEqualMarkup( getModelData( model ), modelTable( [
  544. [ '00', '01', '02', '03', '04' ],
  545. [ '10', { contents: '[]11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  546. [ '20', '24' ],
  547. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  548. [ '40', '41', '42', '43', '44' ]
  549. ] ) );
  550. } );
  551. it( 'should navigate to the row-spanned cell when approaching from the other row-spanned cell', () => {
  552. const tableCell = modelRoot.getNodeByPath( [ 0, 1, 1 ] );
  553. tableNavigation._navigateFromCellInDirection( tableCell, 'right' );
  554. assertEqualMarkup( getModelData( model ), modelTable( [
  555. [ '00', '01', '02', '03', '04' ],
  556. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '[]13', rowspan: 2 }, '14' ],
  557. [ '20', '24' ],
  558. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  559. [ '40', '41', '42', '43', '44' ]
  560. ] ) );
  561. } );
  562. it( 'should navigate to the cell in the upper spanned row when approaching from the row-spanned cell', () => {
  563. const tableCell = modelRoot.getNodeByPath( [ 0, 1, 2 ] ); // Cell 13.
  564. tableNavigation._navigateFromCellInDirection( tableCell, 'right' );
  565. assertEqualMarkup( getModelData( model ), modelTable( [
  566. [ '00', '01', '02', '03', '04' ],
  567. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '[]14' ],
  568. [ '20', '24' ],
  569. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  570. [ '40', '41', '42', '43', '44' ]
  571. ] ) );
  572. } );
  573. it( 'should navigate to the col-spanned cell', () => {
  574. const tableCell = modelRoot.getNodeByPath( [ 0, 3, 0 ] );
  575. tableNavigation._navigateFromCellInDirection( tableCell, 'right' );
  576. assertEqualMarkup( getModelData( model ), modelTable( [
  577. [ '00', '01', '02', '03', '04' ],
  578. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  579. [ '20', '24' ],
  580. [ '30', { contents: '[]31', colspan: 2 }, '33', '34' ],
  581. [ '40', '41', '42', '43', '44' ]
  582. ] ) );
  583. } );
  584. it( 'should navigate from the col-spanned cell', () => {
  585. const tableCell = modelRoot.getNodeByPath( [ 0, 3, 1 ] );
  586. tableNavigation._navigateFromCellInDirection( tableCell, 'right' );
  587. assertEqualMarkup( getModelData( model ), modelTable( [
  588. [ '00', '01', '02', '03', '04' ],
  589. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  590. [ '20', '24' ],
  591. [ '30', { contents: '31', colspan: 2 }, '[]33', '34' ],
  592. [ '40', '41', '42', '43', '44' ]
  593. ] ) );
  594. } );
  595. } );
  596. describe( 'when navigating to the left', () => {
  597. it( 'should navigate to the row-spanned cell when approaching from the upper spanned row', () => {
  598. const tableCell = modelRoot.getNodeByPath( [ 0, 1, 3 ] ); // Cell 14.
  599. tableNavigation._navigateFromCellInDirection( tableCell, 'left' );
  600. assertEqualMarkup( getModelData( model ), modelTable( [
  601. [ '00', '01', '02', '03', '04' ],
  602. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13[]', rowspan: 2 }, '14' ],
  603. [ '20', '24' ],
  604. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  605. [ '40', '41', '42', '43', '44' ]
  606. ] ) );
  607. } );
  608. it( 'should navigate to the row-spanned cell when approaching from the lower spanned row', () => {
  609. const tableCell = modelRoot.getNodeByPath( [ 0, 2, 1 ] ); // Cell 24.
  610. tableNavigation._navigateFromCellInDirection( tableCell, 'left' );
  611. assertEqualMarkup( getModelData( model ), modelTable( [
  612. [ '00', '01', '02', '03', '04' ],
  613. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13[]', rowspan: 2 }, '14' ],
  614. [ '20', '24' ],
  615. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  616. [ '40', '41', '42', '43', '44' ]
  617. ] ) );
  618. } );
  619. it( 'should navigate to the row-spanned cell when approaching from the other row-spanned cell', () => {
  620. const tableCell = modelRoot.getNodeByPath( [ 0, 1, 2 ] ); // Cell 13.
  621. tableNavigation._navigateFromCellInDirection( tableCell, 'left' );
  622. assertEqualMarkup( getModelData( model ), modelTable( [
  623. [ '00', '01', '02', '03', '04' ],
  624. [ '10', { contents: '11[]', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  625. [ '20', '24' ],
  626. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  627. [ '40', '41', '42', '43', '44' ]
  628. ] ) );
  629. } );
  630. it( 'should navigate to the cell in the upper spanned row when approaching from the row-spanned cell', () => {
  631. const tableCell = modelRoot.getNodeByPath( [ 0, 1, 1 ] ); // Cell 11.
  632. tableNavigation._navigateFromCellInDirection( tableCell, 'left' );
  633. assertEqualMarkup( getModelData( model ), modelTable( [
  634. [ '00', '01', '02', '03', '04' ],
  635. [ '10[]', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  636. [ '20', '24' ],
  637. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  638. [ '40', '41', '42', '43', '44' ]
  639. ] ) );
  640. } );
  641. it( 'should navigate to the col-spanned cell', () => {
  642. const tableCell = modelRoot.getNodeByPath( [ 0, 3, 2 ] ); // Cell 33.
  643. tableNavigation._navigateFromCellInDirection( tableCell, 'left' );
  644. assertEqualMarkup( getModelData( model ), modelTable( [
  645. [ '00', '01', '02', '03', '04' ],
  646. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  647. [ '20', '24' ],
  648. [ '30', { contents: '31[]', colspan: 2 }, '33', '34' ],
  649. [ '40', '41', '42', '43', '44' ]
  650. ] ) );
  651. } );
  652. it( 'should navigate from the col-spanned cell', () => {
  653. const tableCell = modelRoot.getNodeByPath( [ 0, 3, 1 ] );
  654. tableNavigation._navigateFromCellInDirection( tableCell, 'left' );
  655. assertEqualMarkup( getModelData( model ), modelTable( [
  656. [ '00', '01', '02', '03', '04' ],
  657. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  658. [ '20', '24' ],
  659. [ '30[]', { contents: '31', colspan: 2 }, '33', '34' ],
  660. [ '40', '41', '42', '43', '44' ]
  661. ] ) );
  662. } );
  663. } );
  664. describe( 'when navigating down', () => {
  665. it( 'should navigate to the row-col-spanned cell when approaching from the first spanned column', () => {
  666. const tableCell = modelRoot.getNodeByPath( [ 0, 0, 1 ] );
  667. tableNavigation._navigateFromCellInDirection( tableCell, 'down' );
  668. assertEqualMarkup( getModelData( model ), modelTable( [
  669. [ '00', '01', '02', '03', '04' ],
  670. [ '10', { contents: '[]11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  671. [ '20', '24' ],
  672. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  673. [ '40', '41', '42', '43', '44' ]
  674. ] ) );
  675. } );
  676. it( 'should navigate to the row-col-spanned cell when approaching from the last spanned column', () => {
  677. const tableCell = modelRoot.getNodeByPath( [ 0, 0, 2 ] );
  678. tableNavigation._navigateFromCellInDirection( tableCell, 'down' );
  679. assertEqualMarkup( getModelData( model ), modelTable( [
  680. [ '00', '01', '02', '03', '04' ],
  681. [ '10', { contents: '[]11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  682. [ '20', '24' ],
  683. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  684. [ '40', '41', '42', '43', '44' ]
  685. ] ) );
  686. } );
  687. it( 'should navigate to the row-spanned cell when approaching from the other col-spanned cell', () => {
  688. const tableCell = modelRoot.getNodeByPath( [ 0, 1, 1 ] );
  689. tableNavigation._navigateFromCellInDirection( tableCell, 'down' );
  690. assertEqualMarkup( getModelData( model ), modelTable( [
  691. [ '00', '01', '02', '03', '04' ],
  692. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  693. [ '20', '24' ],
  694. [ '30', { contents: '[]31', colspan: 2 }, '33', '34' ],
  695. [ '40', '41', '42', '43', '44' ]
  696. ] ) );
  697. } );
  698. it( 'should navigate to the cell in the first spanned column when approaching from the col-spanned cell', () => {
  699. const tableCell = modelRoot.getNodeByPath( [ 0, 1, 1 ] ); // Cell 11.
  700. tableNavigation._navigateFromCellInDirection( tableCell, 'down' );
  701. assertEqualMarkup( getModelData( model ), modelTable( [
  702. [ '00', '01', '02', '03', '04' ],
  703. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  704. [ '20', '24' ],
  705. [ '30', { contents: '[]31', colspan: 2 }, '33', '34' ],
  706. [ '40', '41', '42', '43', '44' ]
  707. ] ) );
  708. } );
  709. it( 'should navigate to the row-spanned cell', () => {
  710. const tableCell = modelRoot.getNodeByPath( [ 0, 0, 3 ] );
  711. tableNavigation._navigateFromCellInDirection( tableCell, 'down' );
  712. assertEqualMarkup( getModelData( model ), modelTable( [
  713. [ '00', '01', '02', '03', '04' ],
  714. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '[]13', rowspan: 2 }, '14' ],
  715. [ '20', '24' ],
  716. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  717. [ '40', '41', '42', '43', '44' ]
  718. ] ) );
  719. } );
  720. it( 'should navigate from the row-spanned cell', () => {
  721. const tableCell = modelRoot.getNodeByPath( [ 0, 1, 2 ] ); // Cell 13.
  722. tableNavigation._navigateFromCellInDirection( tableCell, 'down' );
  723. assertEqualMarkup( getModelData( model ), modelTable( [
  724. [ '00', '01', '02', '03', '04' ],
  725. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  726. [ '20', '24' ],
  727. [ '30', { contents: '31', colspan: 2 }, '[]33', '34' ],
  728. [ '40', '41', '42', '43', '44' ]
  729. ] ) );
  730. } );
  731. } );
  732. describe( 'when navigating up', () => {
  733. it( 'should navigate to the col-spanned cell when approaching from the first spanned column', () => {
  734. const tableCell = modelRoot.getNodeByPath( [ 0, 4, 1 ] );
  735. tableNavigation._navigateFromCellInDirection( tableCell, 'up' );
  736. assertEqualMarkup( getModelData( model ), modelTable( [
  737. [ '00', '01', '02', '03', '04' ],
  738. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  739. [ '20', '24' ],
  740. [ '30', { contents: '31[]', colspan: 2 }, '33', '34' ],
  741. [ '40', '41', '42', '43', '44' ]
  742. ] ) );
  743. } );
  744. it( 'should navigate to the col-spanned cell when approaching from the last spanned column', () => {
  745. const tableCell = modelRoot.getNodeByPath( [ 0, 4, 2 ] );
  746. tableNavigation._navigateFromCellInDirection( tableCell, 'up' );
  747. assertEqualMarkup( getModelData( model ), modelTable( [
  748. [ '00', '01', '02', '03', '04' ],
  749. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  750. [ '20', '24' ],
  751. [ '30', { contents: '31[]', colspan: 2 }, '33', '34' ],
  752. [ '40', '41', '42', '43', '44' ]
  753. ] ) );
  754. } );
  755. it( 'should navigate to the row-col-spanned cell when approaching from the other col-spanned cell', () => {
  756. const tableCell = modelRoot.getNodeByPath( [ 0, 3, 1 ] );
  757. tableNavigation._navigateFromCellInDirection( tableCell, 'up' );
  758. assertEqualMarkup( getModelData( model ), modelTable( [
  759. [ '00', '01', '02', '03', '04' ],
  760. [ '10', { contents: '11[]', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  761. [ '20', '24' ],
  762. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  763. [ '40', '41', '42', '43', '44' ]
  764. ] ) );
  765. } );
  766. it( 'should navigate to the cell in the first spanned column when approaching from the col-spanned cell', () => {
  767. const tableCell = modelRoot.getNodeByPath( [ 0, 1, 1 ] );
  768. tableNavigation._navigateFromCellInDirection( tableCell, 'up' );
  769. assertEqualMarkup( getModelData( model ), modelTable( [
  770. [ '00', '01[]', '02', '03', '04' ],
  771. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  772. [ '20', '24' ],
  773. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  774. [ '40', '41', '42', '43', '44' ]
  775. ] ) );
  776. } );
  777. it( 'should navigate to the row-spanned cell', () => {
  778. const tableCell = modelRoot.getNodeByPath( [ 0, 3, 2 ] ); // Cell 33.
  779. tableNavigation._navigateFromCellInDirection( tableCell, 'up' );
  780. assertEqualMarkup( getModelData( model ), modelTable( [
  781. [ '00', '01', '02', '03', '04' ],
  782. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13[]', rowspan: 2 }, '14' ],
  783. [ '20', '24' ],
  784. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  785. [ '40', '41', '42', '43', '44' ]
  786. ] ) );
  787. } );
  788. it( 'should navigate from the row-spanned cell', () => {
  789. const tableCell = modelRoot.getNodeByPath( [ 0, 1, 2 ] ); // Cell 13.
  790. tableNavigation._navigateFromCellInDirection( tableCell, 'up' );
  791. assertEqualMarkup( getModelData( model ), modelTable( [
  792. [ '00', '01', '02', '03[]', '04' ],
  793. [ '10', { contents: '11', colspan: 2, rowspan: 2 }, { contents: '13', rowspan: 2 }, '14' ],
  794. [ '20', '24' ],
  795. [ '30', { contents: '31', colspan: 2 }, '33', '34' ],
  796. [ '40', '41', '42', '43', '44' ]
  797. ] ) );
  798. } );
  799. } );
  800. } );
  801. } );
  802. describe( 'with the table cells selected from outside', () => {
  803. describe( 'on single table cell selected', () => {
  804. beforeEach( () => {
  805. setModelData( model, modelTable( [
  806. [ '00', '01', '02' ],
  807. [ '10', '11', '12' ],
  808. [ '20', '21', '22' ]
  809. ] ) );
  810. tableSelection._setCellSelection(
  811. modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
  812. modelRoot.getNodeByPath( [ 0, 1, 1 ] )
  813. );
  814. } );
  815. it( 'should move to the cell on the left', () => {
  816. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  817. sinon.assert.calledOnce( leftArrowDomEvtDataStub.preventDefault );
  818. sinon.assert.calledOnce( leftArrowDomEvtDataStub.stopPropagation );
  819. assertEqualMarkup( getModelData( model ), modelTable( [
  820. [ '00', '01', '02' ],
  821. [ '10[]', '11', '12' ],
  822. [ '20', '21', '22' ]
  823. ] ) );
  824. } );
  825. it( 'should move to the cell on the right', () => {
  826. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  827. sinon.assert.calledOnce( rightArrowDomEvtDataStub.preventDefault );
  828. sinon.assert.calledOnce( rightArrowDomEvtDataStub.stopPropagation );
  829. assertEqualMarkup( getModelData( model ), modelTable( [
  830. [ '00', '01', '02' ],
  831. [ '10', '11', '[]12' ],
  832. [ '20', '21', '22' ]
  833. ] ) );
  834. } );
  835. it( 'should move to the cell above selection', () => {
  836. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  837. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  838. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  839. assertEqualMarkup( getModelData( model ), modelTable( [
  840. [ '00', '01[]', '02' ],
  841. [ '10', '11', '12' ],
  842. [ '20', '21', '22' ]
  843. ] ) );
  844. } );
  845. it( 'should move to the cell below selection', () => {
  846. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  847. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  848. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  849. assertEqualMarkup( getModelData( model ), modelTable( [
  850. [ '00', '01', '02' ],
  851. [ '10', '11', '12' ],
  852. [ '20', '[]21', '22' ]
  853. ] ) );
  854. } );
  855. } );
  856. describe( 'on multiple table cell selected vertically', () => {
  857. beforeEach( () => {
  858. setModelData( model, modelTable( [
  859. [ '00', '01', '02', '03' ],
  860. [ '10', '11', '12', '13' ],
  861. [ '20', '21', '22', '23' ],
  862. [ '30', '31', '32', '33' ]
  863. ] ) );
  864. tableSelection._setCellSelection(
  865. modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
  866. modelRoot.getNodeByPath( [ 0, 2, 1 ] )
  867. );
  868. } );
  869. it( 'should move to the cell on the left top of selection', () => {
  870. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  871. sinon.assert.calledOnce( leftArrowDomEvtDataStub.preventDefault );
  872. sinon.assert.calledOnce( leftArrowDomEvtDataStub.stopPropagation );
  873. assertEqualMarkup( getModelData( model ), modelTable( [
  874. [ '00', '01', '02', '03' ],
  875. [ '10[]', '11', '12', '13' ],
  876. [ '20', '21', '22', '23' ],
  877. [ '30', '31', '32', '33' ]
  878. ] ) );
  879. } );
  880. it( 'should move to the cell on the right bottom of selection', () => {
  881. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  882. sinon.assert.calledOnce( rightArrowDomEvtDataStub.preventDefault );
  883. sinon.assert.calledOnce( rightArrowDomEvtDataStub.stopPropagation );
  884. assertEqualMarkup( getModelData( model ), modelTable( [
  885. [ '00', '01', '02', '03' ],
  886. [ '10', '11', '12', '13' ],
  887. [ '20', '21', '[]22', '23' ],
  888. [ '30', '31', '32', '33' ]
  889. ] ) );
  890. } );
  891. it( 'should move to the cell above selection', () => {
  892. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  893. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  894. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  895. assertEqualMarkup( getModelData( model ), modelTable( [
  896. [ '00', '01[]', '02', '03' ],
  897. [ '10', '11', '12', '13' ],
  898. [ '20', '21', '22', '23' ],
  899. [ '30', '31', '32', '33' ]
  900. ] ) );
  901. } );
  902. it( 'should move to the cell below selection', () => {
  903. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  904. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  905. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  906. assertEqualMarkup( getModelData( model ), modelTable( [
  907. [ '00', '01', '02', '03' ],
  908. [ '10', '11', '12', '13' ],
  909. [ '20', '21', '22', '23' ],
  910. [ '30', '[]31', '32', '33' ]
  911. ] ) );
  912. } );
  913. } );
  914. describe( 'on multiple table cell selected horizontally', () => {
  915. beforeEach( () => {
  916. setModelData( model, modelTable( [
  917. [ '00', '01', '02', '03' ],
  918. [ '10', '11', '12', '13' ],
  919. [ '20', '21', '22', '23' ],
  920. [ '30', '31', '32', '33' ]
  921. ] ) );
  922. // Note that this also tests that selection direction doesn't matter.
  923. tableSelection._setCellSelection(
  924. modelRoot.getNodeByPath( [ 0, 1, 2 ] ),
  925. modelRoot.getNodeByPath( [ 0, 1, 1 ] )
  926. );
  927. } );
  928. it( 'should move to the cell on the left top of selection', () => {
  929. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  930. sinon.assert.calledOnce( leftArrowDomEvtDataStub.preventDefault );
  931. sinon.assert.calledOnce( leftArrowDomEvtDataStub.stopPropagation );
  932. assertEqualMarkup( getModelData( model ), modelTable( [
  933. [ '00', '01', '02', '03' ],
  934. [ '10[]', '11', '12', '13' ],
  935. [ '20', '21', '22', '23' ],
  936. [ '30', '31', '32', '33' ]
  937. ] ) );
  938. } );
  939. it( 'should move to the cell on the right bottom of selection', () => {
  940. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  941. sinon.assert.calledOnce( rightArrowDomEvtDataStub.preventDefault );
  942. sinon.assert.calledOnce( rightArrowDomEvtDataStub.stopPropagation );
  943. assertEqualMarkup( getModelData( model ), modelTable( [
  944. [ '00', '01', '02', '03' ],
  945. [ '10', '11', '12', '[]13' ],
  946. [ '20', '21', '22', '23' ],
  947. [ '30', '31', '32', '33' ]
  948. ] ) );
  949. } );
  950. it( 'should move to the cell above selection', () => {
  951. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  952. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  953. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  954. assertEqualMarkup( getModelData( model ), modelTable( [
  955. [ '00', '01[]', '02', '03' ],
  956. [ '10', '11', '12', '13' ],
  957. [ '20', '21', '22', '23' ],
  958. [ '30', '31', '32', '33' ]
  959. ] ) );
  960. } );
  961. it( 'should move to the cell below selection', () => {
  962. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  963. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  964. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  965. assertEqualMarkup( getModelData( model ), modelTable( [
  966. [ '00', '01', '02', '03' ],
  967. [ '10', '11', '12', '13' ],
  968. [ '20', '21', '[]22', '23' ],
  969. [ '30', '31', '32', '33' ]
  970. ] ) );
  971. } );
  972. } );
  973. describe( 'on multiple table cell selected diagonally', () => {
  974. beforeEach( () => {
  975. setModelData( model, modelTable( [
  976. [ '00', '01', '02', '03' ],
  977. [ '10', '11', '12', '13' ],
  978. [ '20', '21', '22', '23' ],
  979. [ '30', '31', '32', '33' ]
  980. ] ) );
  981. tableSelection._setCellSelection(
  982. modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
  983. modelRoot.getNodeByPath( [ 0, 2, 2 ] )
  984. );
  985. } );
  986. it( 'should move to the cell on the left top of selection', () => {
  987. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  988. sinon.assert.calledOnce( leftArrowDomEvtDataStub.preventDefault );
  989. sinon.assert.calledOnce( leftArrowDomEvtDataStub.stopPropagation );
  990. assertEqualMarkup( getModelData( model ), modelTable( [
  991. [ '00', '01', '02', '03' ],
  992. [ '10[]', '11', '12', '13' ],
  993. [ '20', '21', '22', '23' ],
  994. [ '30', '31', '32', '33' ]
  995. ] ) );
  996. } );
  997. it( 'should move to the cell on the right bottom of selection', () => {
  998. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  999. sinon.assert.calledOnce( rightArrowDomEvtDataStub.preventDefault );
  1000. sinon.assert.calledOnce( rightArrowDomEvtDataStub.stopPropagation );
  1001. assertEqualMarkup( getModelData( model ), modelTable( [
  1002. [ '00', '01', '02', '03' ],
  1003. [ '10', '11', '12', '13' ],
  1004. [ '20', '21', '22', '[]23' ],
  1005. [ '30', '31', '32', '33' ]
  1006. ] ) );
  1007. } );
  1008. it( 'should move to the cell above selection', () => {
  1009. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1010. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1011. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1012. assertEqualMarkup( getModelData( model ), modelTable( [
  1013. [ '00', '01[]', '02', '03' ],
  1014. [ '10', '11', '12', '13' ],
  1015. [ '20', '21', '22', '23' ],
  1016. [ '30', '31', '32', '33' ]
  1017. ] ) );
  1018. } );
  1019. it( 'should move to the cell below selection', () => {
  1020. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1021. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1022. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1023. assertEqualMarkup( getModelData( model ), modelTable( [
  1024. [ '00', '01', '02', '03' ],
  1025. [ '10', '11', '12', '13' ],
  1026. [ '20', '21', '22', '23' ],
  1027. [ '30', '31', '[]32', '33' ]
  1028. ] ) );
  1029. } );
  1030. } );
  1031. } );
  1032. describe( 'with selection inside a table cell', () => {
  1033. describe( 'with selection at the edge of a cell', () => {
  1034. describe( 'simple cell text content', () => {
  1035. it( 'should navigate to the cell on the left', () => {
  1036. setModelData( model, modelTable( [
  1037. [ '00', '01', '02' ],
  1038. [ '10', '[]11', '12' ],
  1039. [ '20', '21', '22' ]
  1040. ] ) );
  1041. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  1042. sinon.assert.calledOnce( leftArrowDomEvtDataStub.preventDefault );
  1043. sinon.assert.calledOnce( leftArrowDomEvtDataStub.stopPropagation );
  1044. assertEqualMarkup( getModelData( model ), modelTable( [
  1045. [ '00', '01', '02' ],
  1046. [ '10[]', '11', '12' ],
  1047. [ '20', '21', '22' ]
  1048. ] ) );
  1049. } );
  1050. it( 'should navigate to the cell on the right', () => {
  1051. setModelData( model, modelTable( [
  1052. [ '00', '01', '02' ],
  1053. [ '10', '11[]', '12' ],
  1054. [ '20', '21', '22' ]
  1055. ] ) );
  1056. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  1057. sinon.assert.calledOnce( rightArrowDomEvtDataStub.preventDefault );
  1058. sinon.assert.calledOnce( rightArrowDomEvtDataStub.stopPropagation );
  1059. assertEqualMarkup( getModelData( model ), modelTable( [
  1060. [ '00', '01', '02' ],
  1061. [ '10', '11', '[]12' ],
  1062. [ '20', '21', '22' ]
  1063. ] ) );
  1064. } );
  1065. it( 'should navigate to the cell above', () => {
  1066. setModelData( model, modelTable( [
  1067. [ '00', '01', '02' ],
  1068. [ '10', '[]11', '12' ],
  1069. [ '20', '21', '22' ]
  1070. ] ) );
  1071. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1072. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1073. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1074. assertEqualMarkup( getModelData( model ), modelTable( [
  1075. [ '00', '01[]', '02' ],
  1076. [ '10', '11', '12' ],
  1077. [ '20', '21', '22' ]
  1078. ] ) );
  1079. } );
  1080. it( 'should navigate to the cell below', () => {
  1081. setModelData( model, modelTable( [
  1082. [ '00', '01', '02' ],
  1083. [ '10', '11[]', '12' ],
  1084. [ '20', '21', '22' ]
  1085. ] ) );
  1086. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1087. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1088. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1089. assertEqualMarkup( getModelData( model ), modelTable( [
  1090. [ '00', '01', '02' ],
  1091. [ '10', '11', '12' ],
  1092. [ '20', '[]21', '22' ]
  1093. ] ) );
  1094. } );
  1095. } );
  1096. describe( 'multiple paragraphs in the cell content', () => {
  1097. it( 'should navigate to the cell on the left', () => {
  1098. setModelData( model, modelTable( [
  1099. [ '00', '01', '02' ],
  1100. [ '10', '<paragraph>[]11</paragraph><paragraph>x</paragraph>', '12' ],
  1101. [ '20', '21', '22' ]
  1102. ] ) );
  1103. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  1104. sinon.assert.calledOnce( leftArrowDomEvtDataStub.preventDefault );
  1105. sinon.assert.calledOnce( leftArrowDomEvtDataStub.stopPropagation );
  1106. assertEqualMarkup( getModelData( model ), modelTable( [
  1107. [ '00', '01', '02' ],
  1108. [ '10[]', '<paragraph>11</paragraph><paragraph>x</paragraph>', '12' ],
  1109. [ '20', '21', '22' ]
  1110. ] ) );
  1111. } );
  1112. it( 'should navigate to the cell on the right', () => {
  1113. setModelData( model, modelTable( [
  1114. [ '00', '01', '02' ],
  1115. [ '10', '<paragraph>11</paragraph><paragraph>x[]</paragraph>', '12' ],
  1116. [ '20', '21', '22' ]
  1117. ] ) );
  1118. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  1119. sinon.assert.calledOnce( rightArrowDomEvtDataStub.preventDefault );
  1120. sinon.assert.calledOnce( rightArrowDomEvtDataStub.stopPropagation );
  1121. assertEqualMarkup( getModelData( model ), modelTable( [
  1122. [ '00', '01', '02' ],
  1123. [ '10', '<paragraph>11</paragraph><paragraph>x</paragraph>', '[]12' ],
  1124. [ '20', '21', '22' ]
  1125. ] ) );
  1126. } );
  1127. it( 'should navigate to the cell above', () => {
  1128. setModelData( model, modelTable( [
  1129. [ '00', '01', '02' ],
  1130. [ '10', '<paragraph>[]11</paragraph><paragraph>x</paragraph>', '12' ],
  1131. [ '20', '21', '22' ]
  1132. ] ) );
  1133. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1134. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1135. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1136. assertEqualMarkup( getModelData( model ), modelTable( [
  1137. [ '00', '01[]', '02' ],
  1138. [ '10', '<paragraph>11</paragraph><paragraph>x</paragraph>', '12' ],
  1139. [ '20', '21', '22' ]
  1140. ] ) );
  1141. } );
  1142. it( 'should navigate to the cell below', () => {
  1143. setModelData( model, modelTable( [
  1144. [ '00', '01', '02' ],
  1145. [ '10', '<paragraph>11</paragraph><paragraph>x[]</paragraph>', '12' ],
  1146. [ '20', '21', '22' ]
  1147. ] ) );
  1148. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1149. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1150. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1151. assertEqualMarkup( getModelData( model ), modelTable( [
  1152. [ '00', '01', '02' ],
  1153. [ '10', '<paragraph>11</paragraph><paragraph>x</paragraph>', '12' ],
  1154. [ '20', '[]21', '22' ]
  1155. ] ) );
  1156. } );
  1157. } );
  1158. describe( 'image widget with caption as only cell content', () => {
  1159. it( 'should navigate to the cell on the left', () => {
  1160. setModelData( model, modelTable( [
  1161. [ '00', '01', '02' ],
  1162. [ '10', `<image src="${ imageUrl }"><caption>[]11</caption></image>`, '12' ],
  1163. [ '20', '21', '22' ]
  1164. ] ) );
  1165. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  1166. sinon.assert.calledOnce( leftArrowDomEvtDataStub.preventDefault );
  1167. sinon.assert.calledOnce( leftArrowDomEvtDataStub.stopPropagation );
  1168. assertEqualMarkup( getModelData( model ), modelTable( [
  1169. [ '00', '01', '02' ],
  1170. [ '10[]', `<image src="${ imageUrl }"><caption>11</caption></image>`, '12' ],
  1171. [ '20', '21', '22' ]
  1172. ] ) );
  1173. } );
  1174. it( 'should navigate to the cell on the right', () => {
  1175. setModelData( model, modelTable( [
  1176. [ '00', '01', '02' ],
  1177. [ '10', `<image src="${ imageUrl }"><caption>11[]</caption></image>`, '12' ],
  1178. [ '20', '21', '22' ]
  1179. ] ) );
  1180. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  1181. sinon.assert.calledOnce( rightArrowDomEvtDataStub.preventDefault );
  1182. sinon.assert.calledOnce( rightArrowDomEvtDataStub.stopPropagation );
  1183. assertEqualMarkup( getModelData( model ), modelTable( [
  1184. [ '00', '01', '02' ],
  1185. [ '10', `<image src="${ imageUrl }"><caption>11</caption></image>`, '[]12' ],
  1186. [ '20', '21', '22' ]
  1187. ] ) );
  1188. } );
  1189. it( 'should navigate to the cell above', () => {
  1190. setModelData( model, modelTable( [
  1191. [ '00', '01', '02' ],
  1192. [ '10', `<image src="${ imageUrl }"><caption>[]11</caption></image>`, '12' ],
  1193. [ '20', '21', '22' ]
  1194. ] ) );
  1195. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1196. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1197. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1198. assertEqualMarkup( getModelData( model ), modelTable( [
  1199. [ '00', '01[]', '02' ],
  1200. [ '10', `<image src="${ imageUrl }"><caption>11</caption></image>`, '12' ],
  1201. [ '20', '21', '22' ]
  1202. ] ) );
  1203. } );
  1204. it( 'should navigate to the cell below', () => {
  1205. setModelData( model, modelTable( [
  1206. [ '00', '01', '02' ],
  1207. [ '10', `<image src="${ imageUrl }"><caption>11[]</caption></image>`, '12' ],
  1208. [ '20', '21', '22' ]
  1209. ] ) );
  1210. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1211. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1212. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1213. assertEqualMarkup( getModelData( model ), modelTable( [
  1214. [ '00', '01', '02' ],
  1215. [ '10', `<image src="${ imageUrl }"><caption>11</caption></image>`, '12' ],
  1216. [ '20', '[]21', '22' ]
  1217. ] ) );
  1218. } );
  1219. } );
  1220. describe( 'horizontal line as only cell content (widget without $text positions)', () => {
  1221. beforeEach( () => {
  1222. setModelData( model, modelTable( [
  1223. [ '00', '01', '02' ],
  1224. [ '10', '[<horizontalLine></horizontalLine>]', '12' ],
  1225. [ '20', '21', '22' ]
  1226. ] ) );
  1227. } );
  1228. it( 'should navigate to the cell on the left', () => {
  1229. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  1230. sinon.assert.calledOnce( leftArrowDomEvtDataStub.preventDefault );
  1231. sinon.assert.calledOnce( leftArrowDomEvtDataStub.stopPropagation );
  1232. assertEqualMarkup( getModelData( model ), modelTable( [
  1233. [ '00', '01', '02' ],
  1234. [ '10[]', '<horizontalLine></horizontalLine>', '12' ],
  1235. [ '20', '21', '22' ]
  1236. ] ) );
  1237. } );
  1238. it( 'should navigate to the cell on the right', () => {
  1239. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  1240. sinon.assert.calledOnce( rightArrowDomEvtDataStub.preventDefault );
  1241. sinon.assert.calledOnce( rightArrowDomEvtDataStub.stopPropagation );
  1242. assertEqualMarkup( getModelData( model ), modelTable( [
  1243. [ '00', '01', '02' ],
  1244. [ '10', '<horizontalLine></horizontalLine>', '[]12' ],
  1245. [ '20', '21', '22' ]
  1246. ] ) );
  1247. } );
  1248. it( 'should navigate to the cell above', () => {
  1249. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1250. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1251. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1252. assertEqualMarkup( getModelData( model ), modelTable( [
  1253. [ '00', '01[]', '02' ],
  1254. [ '10', '<horizontalLine></horizontalLine>', '12' ],
  1255. [ '20', '21', '22' ]
  1256. ] ) );
  1257. } );
  1258. it( 'should navigate to the cell below', () => {
  1259. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1260. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1261. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1262. assertEqualMarkup( getModelData( model ), modelTable( [
  1263. [ '00', '01', '02' ],
  1264. [ '10', '<horizontalLine></horizontalLine>', '12' ],
  1265. [ '20', '[]21', '22' ]
  1266. ] ) );
  1267. } );
  1268. } );
  1269. describe( 'two horizontal lines as only cell content (widget without $text positions)', () => {
  1270. it( 'should navigate to the cell on the left', () => {
  1271. setModelData( model, modelTable( [
  1272. [ '00', '01', '02' ],
  1273. [ '10', '[<horizontalLine></horizontalLine>]<horizontalLine></horizontalLine>', '12' ],
  1274. [ '20', '21', '22' ]
  1275. ] ) );
  1276. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  1277. sinon.assert.calledOnce( leftArrowDomEvtDataStub.preventDefault );
  1278. sinon.assert.calledOnce( leftArrowDomEvtDataStub.stopPropagation );
  1279. assertEqualMarkup( getModelData( model ), modelTable( [
  1280. [ '00', '01', '02' ],
  1281. [ '10[]', '<horizontalLine></horizontalLine><horizontalLine></horizontalLine>', '12' ],
  1282. [ '20', '21', '22' ]
  1283. ] ) );
  1284. } );
  1285. it( 'should navigate to the cell on the right', () => {
  1286. setModelData( model, modelTable( [
  1287. [ '00', '01', '02' ],
  1288. [ '10', '<horizontalLine></horizontalLine>[<horizontalLine></horizontalLine>]', '12' ],
  1289. [ '20', '21', '22' ]
  1290. ] ) );
  1291. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  1292. sinon.assert.calledOnce( rightArrowDomEvtDataStub.preventDefault );
  1293. sinon.assert.calledOnce( rightArrowDomEvtDataStub.stopPropagation );
  1294. assertEqualMarkup( getModelData( model ), modelTable( [
  1295. [ '00', '01', '02' ],
  1296. [ '10', '<horizontalLine></horizontalLine><horizontalLine></horizontalLine>', '[]12' ],
  1297. [ '20', '21', '22' ]
  1298. ] ) );
  1299. } );
  1300. it( 'should navigate to the cell above', () => {
  1301. setModelData( model, modelTable( [
  1302. [ '00', '01', '02' ],
  1303. [ '10', '[<horizontalLine></horizontalLine>]<horizontalLine></horizontalLine>', '12' ],
  1304. [ '20', '21', '22' ]
  1305. ] ) );
  1306. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1307. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1308. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1309. assertEqualMarkup( getModelData( model ), modelTable( [
  1310. [ '00', '01[]', '02' ],
  1311. [ '10', '<horizontalLine></horizontalLine><horizontalLine></horizontalLine>', '12' ],
  1312. [ '20', '21', '22' ]
  1313. ] ) );
  1314. } );
  1315. it( 'should navigate to the cell below', () => {
  1316. setModelData( model, modelTable( [
  1317. [ '00', '01', '02' ],
  1318. [ '10', '<horizontalLine></horizontalLine>[<horizontalLine></horizontalLine>]', '12' ],
  1319. [ '20', '21', '22' ]
  1320. ] ) );
  1321. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1322. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1323. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1324. assertEqualMarkup( getModelData( model ), modelTable( [
  1325. [ '00', '01', '02' ],
  1326. [ '10', '<horizontalLine></horizontalLine><horizontalLine></horizontalLine>', '12' ],
  1327. [ '20', '[]21', '22' ]
  1328. ] ) );
  1329. } );
  1330. } );
  1331. } );
  1332. describe( 'with selection not at the edge of a cell', () => {
  1333. let editorElement, editor, model, styleElement;
  1334. beforeEach( async () => {
  1335. editorElement = global.document.createElement( 'div' );
  1336. global.document.body.appendChild( editorElement );
  1337. editor = await ClassicTestEditor.create( editorElement, {
  1338. plugins: [ Table, Paragraph, Image, ImageCaption, HorizontalLine ]
  1339. } );
  1340. model = editor.model;
  1341. styleElement = global.document.createElement( 'style' );
  1342. styleElement.type = 'text/css';
  1343. styleElement.appendChild( global.document.createTextNode( '.ck-editor { width: 500px !important; }' ) );
  1344. global.document.querySelector( 'head' ).appendChild( styleElement );
  1345. } );
  1346. afterEach( async () => {
  1347. editorElement.remove();
  1348. styleElement.remove();
  1349. await editor.destroy();
  1350. } );
  1351. describe( 'simple cell text content', () => {
  1352. it( 'should not navigate to the cell on the left', () => {
  1353. setModelData( model, modelTable( [
  1354. [ '00', '01', '02' ],
  1355. [ '10', '1[]1', '12' ],
  1356. [ '20', '21', '22' ]
  1357. ] ) );
  1358. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  1359. sinon.assert.notCalled( leftArrowDomEvtDataStub.preventDefault );
  1360. sinon.assert.notCalled( leftArrowDomEvtDataStub.stopPropagation );
  1361. } );
  1362. it( 'should not navigate to the cell on the right', () => {
  1363. setModelData( model, modelTable( [
  1364. [ '00', '01', '02' ],
  1365. [ '10', '1[]1', '12' ],
  1366. [ '20', '21', '22' ]
  1367. ] ) );
  1368. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  1369. sinon.assert.notCalled( rightArrowDomEvtDataStub.preventDefault );
  1370. sinon.assert.notCalled( rightArrowDomEvtDataStub.stopPropagation );
  1371. } );
  1372. it( 'should not navigate to the cell above', () => {
  1373. setModelData( model, modelTable( [
  1374. [ '00', '01', '02' ],
  1375. [ '10', '1[]1', '12' ],
  1376. [ '20', '21', '22' ]
  1377. ] ) );
  1378. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1379. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1380. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1381. assertEqualMarkup( getModelData( model ), modelTable( [
  1382. [ '00', '01', '02' ],
  1383. [ '10', '[]11', '12' ],
  1384. [ '20', '21', '22' ]
  1385. ] ) );
  1386. } );
  1387. it( 'should not navigate to the cell below', () => {
  1388. setModelData( model, modelTable( [
  1389. [ '00', '01', '02' ],
  1390. [ '10', '1[]1', '12' ],
  1391. [ '20', '21', '22' ]
  1392. ] ) );
  1393. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1394. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1395. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1396. assertEqualMarkup( getModelData( model ), modelTable( [
  1397. [ '00', '01', '02' ],
  1398. [ '10', '11[]', '12' ],
  1399. [ '20', '21', '22' ]
  1400. ] ) );
  1401. } );
  1402. } );
  1403. describe( 'selection inside paragraph', () => {
  1404. const text = new Array( 100 ).fill( 0 ).map( () => 'word' ).join( ' ' );
  1405. it( 'should not navigate if caret is in the middle line of a text', () => {
  1406. setModelData( model, modelTable( [
  1407. [ '00', '01', '02' ],
  1408. [ '10', text + '[] ' + text, '12' ],
  1409. [ '20', '21', '22' ]
  1410. ] ) );
  1411. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1412. sinon.assert.notCalled( upArrowDomEvtDataStub.preventDefault );
  1413. sinon.assert.notCalled( upArrowDomEvtDataStub.stopPropagation );
  1414. } );
  1415. it( 'should move caret to beginning of cell content if caret is in the first line of a text', () => {
  1416. setModelData( model, modelTable( [
  1417. [ '00', '01', '02' ],
  1418. [ '10', 'word[] word' + text, '12' ],
  1419. [ '20', '21', '22' ]
  1420. ] ) );
  1421. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1422. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1423. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1424. assertEqualMarkup( getModelData( model ), modelTable( [
  1425. [ '00', '01', '02' ],
  1426. [ '10', '[]word word' + text, '12' ],
  1427. [ '20', '21', '22' ]
  1428. ] ) );
  1429. } );
  1430. it( 'should move caret to end of cell content if caret is in the last line of a text', () => {
  1431. setModelData( model, modelTable( [
  1432. [ '00', '01', '02' ],
  1433. [ '10', text + 'word[] word', '12' ],
  1434. [ '20', '21', '22' ]
  1435. ] ) );
  1436. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1437. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1438. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1439. assertEqualMarkup( getModelData( model ), modelTable( [
  1440. [ '00', '01', '02' ],
  1441. [ '10', text + 'word word[]', '12' ],
  1442. [ '20', '21', '22' ]
  1443. ] ) );
  1444. } );
  1445. } );
  1446. describe( 'with multiple paragraphs of text', () => {
  1447. const text = new Array( 100 ).fill( 0 ).map( () => 'word' ).join( ' ' );
  1448. it( 'should not navigate if caret is in the middle line of a text', () => {
  1449. setModelData( model, modelTable( [
  1450. [ '00', '01', '02' ],
  1451. [ '10', `<paragraph>${ text }[]${ text }</paragraph><paragraph>foobar</paragraph>`, '12' ],
  1452. [ '20', '21', '22' ]
  1453. ] ) );
  1454. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1455. sinon.assert.notCalled( upArrowDomEvtDataStub.preventDefault );
  1456. sinon.assert.notCalled( upArrowDomEvtDataStub.stopPropagation );
  1457. } );
  1458. it( 'should move caret to beginning of cell content if caret is in the first line of a text', () => {
  1459. setModelData( model, modelTable( [
  1460. [ '00', '01', '02' ],
  1461. [ '10', `<paragraph>word[]${ text }</paragraph><paragraph>foobar</paragraph>`, '12' ],
  1462. [ '20', '21', '22' ]
  1463. ] ) );
  1464. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1465. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1466. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1467. assertEqualMarkup( getModelData( model ), modelTable( [
  1468. [ '00', '01', '02' ],
  1469. [ '10', `<paragraph>[]word${ text }</paragraph><paragraph>foobar</paragraph>`, '12' ],
  1470. [ '20', '21', '22' ]
  1471. ] ) );
  1472. } );
  1473. it( 'should not move caret to end of cell content if caret is not last line of text', () => {
  1474. setModelData( model, modelTable( [
  1475. [ '00', '01', '02' ],
  1476. [ '10', `<paragraph>${ text }word []word</paragraph><paragraph>foobar</paragraph>`, '12' ],
  1477. [ '20', '21', '22' ]
  1478. ] ) );
  1479. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1480. sinon.assert.notCalled( downArrowDomEvtDataStub.preventDefault );
  1481. sinon.assert.notCalled( downArrowDomEvtDataStub.stopPropagation );
  1482. } );
  1483. it( 'should move caret to end of cell content if caret is in the last line of a text', () => {
  1484. setModelData( model, modelTable( [
  1485. [ '00', '01', '02' ],
  1486. [ '10', `<paragraph>foobar</paragraph><paragraph>${ text }word []word</paragraph>`, '12' ],
  1487. [ '20', '21', '22' ]
  1488. ] ) );
  1489. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1490. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1491. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1492. assertEqualMarkup( getModelData( model ), modelTable( [
  1493. [ '00', '01', '02' ],
  1494. [ '10', `<paragraph>foobar</paragraph><paragraph>${ text }word word[]</paragraph>`, '12' ],
  1495. [ '20', '21', '22' ]
  1496. ] ) );
  1497. } );
  1498. } );
  1499. describe( 'with horizontal line widget', () => {
  1500. const text = new Array( 100 ).fill( 0 ).map( () => 'word' ).join( ' ' );
  1501. it( 'should not navigate if caret is in the middle line of a text', () => {
  1502. setModelData( model, modelTable( [
  1503. [ '00', '01', '02' ],
  1504. [ '10', `<horizontalLine></horizontalLine><paragraph>${ text }[]${ text }</paragraph>`, '12' ],
  1505. [ '20', '21', '22' ]
  1506. ] ) );
  1507. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1508. sinon.assert.notCalled( upArrowDomEvtDataStub.preventDefault );
  1509. sinon.assert.notCalled( upArrowDomEvtDataStub.stopPropagation );
  1510. } );
  1511. it( 'should move caret to beginning of cell content if caret is in the first line of a text', () => {
  1512. setModelData( model, modelTable( [
  1513. [ '00', '01', '02' ],
  1514. [ '10', `<horizontalLine></horizontalLine><paragraph>word[] ${ text }</paragraph>`, '12' ],
  1515. [ '20', '21', '22' ]
  1516. ] ) );
  1517. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1518. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1519. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1520. assertEqualMarkup( getModelData( model ), modelTable( [
  1521. [ '00', '01', '02' ],
  1522. [ '10', `[<horizontalLine></horizontalLine>]<paragraph>word ${ text }</paragraph>`, '12' ],
  1523. [ '20', '21', '22' ]
  1524. ] ) );
  1525. } );
  1526. it( 'should move caret to end of cell content if caret is in the last line of a text', () => {
  1527. setModelData( model, modelTable( [
  1528. [ '00', '01', '02' ],
  1529. [ '10', `<paragraph>${ text } word []word</paragraph><horizontalLine></horizontalLine>`, '12' ],
  1530. [ '20', '21', '22' ]
  1531. ] ) );
  1532. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1533. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1534. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1535. assertEqualMarkup( getModelData( model ), modelTable( [
  1536. [ '00', '01', '02' ],
  1537. [ '10', `<paragraph>${ text } word word</paragraph>[<horizontalLine></horizontalLine>]`, '12' ],
  1538. [ '20', '21', '22' ]
  1539. ] ) );
  1540. } );
  1541. it( 'should not move caret to end of cell content if widget is selected in middle of cell content', () => {
  1542. const paragraph = `<paragraph>${ text }</paragraph>`;
  1543. const hr = '<horizontalLine></horizontalLine>';
  1544. setModelData( model, modelTable( [
  1545. [ '00', '01', '02' ],
  1546. [ '10', `${ paragraph }[${ hr }]${ paragraph }${ hr }`, '12' ],
  1547. [ '20', '21', '22' ]
  1548. ] ) );
  1549. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1550. assertEqualMarkup( getModelData( model ), modelTable( [
  1551. [ '00', '01', '02' ],
  1552. [ '10', `${ paragraph }${ hr }<paragraph>[]${ text }</paragraph>${ hr }`, '12' ],
  1553. [ '20', '21', '22' ]
  1554. ] ) );
  1555. } );
  1556. it( 'should not move caret to end of cell content if widget is next to selection', () => {
  1557. const paragraph = `<paragraph>${ text }</paragraph>`;
  1558. const hr = '<horizontalLine></horizontalLine>';
  1559. setModelData( model, modelTable( [
  1560. [ '00', '01', '02' ],
  1561. [ '10', `${ paragraph }[]${ hr }`, '12' ],
  1562. [ '20', '21', '22' ]
  1563. ] ) );
  1564. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1565. assertEqualMarkup( getModelData( model ), modelTable( [
  1566. [ '00', '01', '02' ],
  1567. [ '10', `${ paragraph }[${ hr }]`, '12' ],
  1568. [ '20', '21', '22' ]
  1569. ] ) );
  1570. } );
  1571. } );
  1572. describe( 'contains image widget with caption and selection inside the caption', () => {
  1573. it( 'should not navigate to the cell on the left', () => {
  1574. setModelData( model, modelTable( [
  1575. [ '00', '01', '02' ],
  1576. [ '10', `<paragraph>foo</paragraph><image src="${ imageUrl }"><caption>[]11</caption></image>`, '12' ],
  1577. [ '20', '21', '22' ]
  1578. ] ) );
  1579. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  1580. sinon.assert.notCalled( leftArrowDomEvtDataStub.preventDefault );
  1581. sinon.assert.notCalled( leftArrowDomEvtDataStub.stopPropagation );
  1582. } );
  1583. it( 'should not navigate to the cell on the right', () => {
  1584. setModelData( model, modelTable( [
  1585. [ '00', '01', '02' ],
  1586. [ '10', `<image src="${ imageUrl }"><caption>11[]</caption></image><paragraph>foo</paragraph>`, '12' ],
  1587. [ '20', '21', '22' ]
  1588. ] ) );
  1589. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  1590. sinon.assert.notCalled( rightArrowDomEvtDataStub.preventDefault );
  1591. sinon.assert.notCalled( rightArrowDomEvtDataStub.stopPropagation );
  1592. } );
  1593. it( 'should not navigate to the cell above', () => {
  1594. setModelData( model, modelTable( [
  1595. [ '00', '01', '02' ],
  1596. [ '10', `<paragraph>foo</paragraph><image src="${ imageUrl }"><caption>1[]1</caption></image>`, '12' ],
  1597. [ '20', '21', '22' ]
  1598. ] ) );
  1599. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1600. sinon.assert.notCalled( upArrowDomEvtDataStub.preventDefault );
  1601. sinon.assert.notCalled( upArrowDomEvtDataStub.stopPropagation );
  1602. } );
  1603. it( 'should not navigate to the cell above but should select image widget', () => {
  1604. setModelData( model, modelTable( [
  1605. [ '00', '01', '02' ],
  1606. [ '10', `<image src="${ imageUrl }"><caption>1[]1</caption></image><paragraph>foo</paragraph>`, '12' ],
  1607. [ '20', '21', '22' ]
  1608. ] ) );
  1609. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1610. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1611. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1612. assertEqualMarkup( getModelData( model ), modelTable( [
  1613. [ '00', '01', '02' ],
  1614. [ '10', `[<image src="${ imageUrl }"><caption>11</caption></image>]<paragraph>foo</paragraph>`, '12' ],
  1615. [ '20', '21', '22' ]
  1616. ] ) );
  1617. } );
  1618. it( 'should not navigate to the cell below when followed by paragraph', () => {
  1619. setModelData( model, modelTable( [
  1620. [ '00', '01', '02' ],
  1621. [ '10', `<image src="${ imageUrl }"><caption>1[]1</caption></image><paragraph>foo</paragraph>`, '12' ],
  1622. [ '20', '21', '22' ]
  1623. ] ) );
  1624. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1625. sinon.assert.notCalled( downArrowDomEvtDataStub.preventDefault );
  1626. sinon.assert.notCalled( downArrowDomEvtDataStub.stopPropagation );
  1627. } );
  1628. it( 'should not navigate to the cell below but should select image widget', () => {
  1629. setModelData( model, modelTable( [
  1630. [ '00', '01', '02' ],
  1631. [ '10', `<paragraph>foo</paragraph><image src="${ imageUrl }"><caption>1[]1</caption></image>`, '12' ],
  1632. [ '20', '21', '22' ]
  1633. ] ) );
  1634. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1635. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1636. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1637. assertEqualMarkup( getModelData( model ), modelTable( [
  1638. [ '00', '01', '02' ],
  1639. [ '10', `<paragraph>foo</paragraph>[<image src="${ imageUrl }"><caption>11</caption></image>]`, '12' ],
  1640. [ '20', '21', '22' ]
  1641. ] ) );
  1642. } );
  1643. it( 'should not navigate to the cell above but should select image widget without caption', () => {
  1644. setModelData( model, modelTable( [
  1645. [ '00', '01', '02' ],
  1646. [ '10', `<image src="${ imageUrl }"><caption></caption></image><paragraph>f[]oo</paragraph>`, '12' ],
  1647. [ '20', '21', '22' ]
  1648. ] ) );
  1649. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1650. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1651. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1652. assertEqualMarkup( getModelData( model ), modelTable( [
  1653. [ '00', '01', '02' ],
  1654. [ '10', `[<image src="${ imageUrl }"><caption></caption></image>]<paragraph>foo</paragraph>`, '12' ],
  1655. [ '20', '21', '22' ]
  1656. ] ) );
  1657. } );
  1658. it( 'should not navigate to the cell below but should select image widget without caption', () => {
  1659. setModelData( model, modelTable( [
  1660. [ '00', '01', '02' ],
  1661. [ '10', `<paragraph>f[]oo</paragraph><image src="${ imageUrl }"><caption></caption></image>`, '12' ],
  1662. [ '20', '21', '22' ]
  1663. ] ) );
  1664. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1665. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1666. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1667. assertEqualMarkup( getModelData( model ), modelTable( [
  1668. [ '00', '01', '02' ],
  1669. [ '10', `<paragraph>foo</paragraph>[<image src="${ imageUrl }"><caption></caption></image>]`, '12' ],
  1670. [ '20', '21', '22' ]
  1671. ] ) );
  1672. } );
  1673. } );
  1674. } );
  1675. } );
  1676. describe( 'for right-to-left content language', () => {
  1677. beforeEach( () => {
  1678. return VirtualTestEditor
  1679. .create( {
  1680. plugins: [ TableEditing, TableNavigation, TableSelection, Paragraph, ImageEditing, MediaEmbedEditing ],
  1681. language: 'ar'
  1682. } )
  1683. .then( newEditor => {
  1684. editor = newEditor;
  1685. model = editor.model;
  1686. modelRoot = model.document.getRoot();
  1687. tableSelection = editor.plugins.get( TableSelection );
  1688. } );
  1689. } );
  1690. describe( 'with the table cell selected from outside', () => {
  1691. beforeEach( () => {
  1692. setModelData( model, modelTable( [
  1693. [ '00', '01', '02' ],
  1694. [ '10', '11', '12' ],
  1695. [ '20', '21', '22' ]
  1696. ] ) );
  1697. tableSelection._setCellSelection(
  1698. modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
  1699. modelRoot.getNodeByPath( [ 0, 1, 1 ] )
  1700. );
  1701. } );
  1702. it( 'should move to the cell on the right (it\'s visually flipped by browser)', () => {
  1703. editor.editing.view.document.fire( 'keydown', leftArrowDomEvtDataStub );
  1704. sinon.assert.calledOnce( leftArrowDomEvtDataStub.preventDefault );
  1705. sinon.assert.calledOnce( leftArrowDomEvtDataStub.stopPropagation );
  1706. assertEqualMarkup( getModelData( model ), modelTable( [
  1707. [ '00', '01', '02' ],
  1708. [ '10', '11', '[]12' ],
  1709. [ '20', '21', '22' ]
  1710. ] ) );
  1711. } );
  1712. it( 'should move to the cell on the left (it\'s visually flipped by browser)', () => {
  1713. editor.editing.view.document.fire( 'keydown', rightArrowDomEvtDataStub );
  1714. sinon.assert.calledOnce( rightArrowDomEvtDataStub.preventDefault );
  1715. sinon.assert.calledOnce( rightArrowDomEvtDataStub.stopPropagation );
  1716. assertEqualMarkup( getModelData( model ), modelTable( [
  1717. [ '00', '01', '02' ],
  1718. [ '10[]', '11', '12' ],
  1719. [ '20', '21', '22' ]
  1720. ] ) );
  1721. } );
  1722. it( 'should move to the cell above selection', () => {
  1723. editor.editing.view.document.fire( 'keydown', upArrowDomEvtDataStub );
  1724. sinon.assert.calledOnce( upArrowDomEvtDataStub.preventDefault );
  1725. sinon.assert.calledOnce( upArrowDomEvtDataStub.stopPropagation );
  1726. assertEqualMarkup( getModelData( model ), modelTable( [
  1727. [ '00', '01[]', '02' ],
  1728. [ '10', '11', '12' ],
  1729. [ '20', '21', '22' ]
  1730. ] ) );
  1731. } );
  1732. it( 'should move to the cell below selection', () => {
  1733. editor.editing.view.document.fire( 'keydown', downArrowDomEvtDataStub );
  1734. sinon.assert.calledOnce( downArrowDomEvtDataStub.preventDefault );
  1735. sinon.assert.calledOnce( downArrowDomEvtDataStub.stopPropagation );
  1736. assertEqualMarkup( getModelData( model ), modelTable( [
  1737. [ '00', '01', '02' ],
  1738. [ '10', '11', '12' ],
  1739. [ '20', '[]21', '22' ]
  1740. ] ) );
  1741. } );
  1742. } );
  1743. } );
  1744. } );
  1745. } );