upcast-selection-converters.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /**
  2. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. import View from '../../src/view/view';
  6. import ViewSelection from '../../src/view/selection';
  7. import ViewRange from '../../src/view/range';
  8. import createViewRoot from '../view/_utils/createroot';
  9. import Model from '../../src/model/model';
  10. import Mapper from '../../src/conversion/mapper';
  11. import { convertSelectionChange } from '../../src/conversion/upcast-selection-converters';
  12. import { setData as modelSetData, getData as modelGetData } from '../../src/dev-utils/model';
  13. import { setData as viewSetData } from '../../src/dev-utils/view';
  14. describe( 'convertSelectionChange', () => {
  15. let model, view, viewDocument, mapper, convertSelection, modelRoot, viewRoot;
  16. beforeEach( () => {
  17. model = new Model();
  18. modelRoot = model.document.createRoot();
  19. model.schema.register( 'paragraph', { inheritAllFrom: '$block' } );
  20. modelSetData( model, '<paragraph>foo</paragraph><paragraph>bar</paragraph>' );
  21. view = new View();
  22. viewDocument = view.document;
  23. viewRoot = createViewRoot( viewDocument, 'div', 'main' );
  24. viewSetData( view, '<p>foo</p><p>bar</p>' );
  25. mapper = new Mapper();
  26. mapper.bindElements( modelRoot, viewRoot );
  27. mapper.bindElements( modelRoot.getChild( 0 ), viewRoot.getChild( 0 ) );
  28. mapper.bindElements( modelRoot.getChild( 1 ), viewRoot.getChild( 1 ) );
  29. convertSelection = convertSelectionChange( model, mapper );
  30. } );
  31. afterEach( () => {
  32. view.destroy();
  33. } );
  34. it( 'should convert collapsed selection', () => {
  35. const viewSelection = new ViewSelection();
  36. viewSelection._setTo( ViewRange.createFromParentsAndOffsets(
  37. viewRoot.getChild( 0 ).getChild( 0 ), 1, viewRoot.getChild( 0 ).getChild( 0 ), 1 ) );
  38. convertSelection( null, { newSelection: viewSelection } );
  39. expect( modelGetData( model ) ).to.equals( '<paragraph>f[]oo</paragraph><paragraph>bar</paragraph>' );
  40. expect( modelGetData( model ) ).to.equal( '<paragraph>f[]oo</paragraph><paragraph>bar</paragraph>' );
  41. } );
  42. it( 'should support unicode', () => {
  43. modelSetData( model, '<paragraph>நிலைக்கு</paragraph>' );
  44. viewSetData( view, '<p>நிலைக்கு</p>' );
  45. // Re-bind elements that were just re-set.
  46. mapper.bindElements( modelRoot.getChild( 0 ), viewRoot.getChild( 0 ) );
  47. const viewSelection = new ViewSelection( [
  48. ViewRange.createFromParentsAndOffsets( viewRoot.getChild( 0 ).getChild( 0 ), 2, viewRoot.getChild( 0 ).getChild( 0 ), 6 )
  49. ] );
  50. convertSelection( null, { newSelection: viewSelection } );
  51. expect( modelGetData( model ) ).to.equal( '<paragraph>நி[லைக்]கு</paragraph>' );
  52. } );
  53. it( 'should convert multi ranges selection', () => {
  54. const viewSelection = new ViewSelection( [
  55. ViewRange.createFromParentsAndOffsets(
  56. viewRoot.getChild( 0 ).getChild( 0 ), 1, viewRoot.getChild( 0 ).getChild( 0 ), 2 ),
  57. ViewRange.createFromParentsAndOffsets(
  58. viewRoot.getChild( 1 ).getChild( 0 ), 1, viewRoot.getChild( 1 ).getChild( 0 ), 2 )
  59. ] );
  60. convertSelection( null, { newSelection: viewSelection } );
  61. expect( modelGetData( model ) ).to.equal(
  62. '<paragraph>f[o]o</paragraph><paragraph>b[a]r</paragraph>' );
  63. const ranges = Array.from( model.document.selection.getRanges() );
  64. expect( ranges.length ).to.equal( 2 );
  65. expect( ranges[ 0 ].start.parent ).to.equal( modelRoot.getChild( 0 ) );
  66. expect( ranges[ 0 ].start.offset ).to.equal( 1 );
  67. expect( ranges[ 0 ].end.parent ).to.equal( modelRoot.getChild( 0 ) );
  68. expect( ranges[ 0 ].end.offset ).to.equal( 2 );
  69. expect( ranges[ 1 ].start.parent ).to.equal( modelRoot.getChild( 1 ) );
  70. expect( ranges[ 1 ].start.offset ).to.equal( 1 );
  71. expect( ranges[ 1 ].end.parent ).to.equal( modelRoot.getChild( 1 ) );
  72. expect( ranges[ 1 ].end.offset ).to.equal( 2 );
  73. } );
  74. it( 'should convert reverse selection', () => {
  75. const viewSelection = new ViewSelection( [
  76. ViewRange.createFromParentsAndOffsets(
  77. viewRoot.getChild( 0 ).getChild( 0 ), 1, viewRoot.getChild( 0 ).getChild( 0 ), 2 ),
  78. ViewRange.createFromParentsAndOffsets(
  79. viewRoot.getChild( 1 ).getChild( 0 ), 1, viewRoot.getChild( 1 ).getChild( 0 ), 2 )
  80. ], { backward: true } );
  81. convertSelection( null, { newSelection: viewSelection } );
  82. expect( modelGetData( model ) ).to.equal( '<paragraph>f[o]o</paragraph><paragraph>b[a]r</paragraph>' );
  83. expect( model.document.selection.isBackward ).to.true;
  84. } );
  85. it( 'should not enqueue changes if selection has not changed', () => {
  86. const viewSelection = new ViewSelection( [
  87. ViewRange.createFromParentsAndOffsets(
  88. viewRoot.getChild( 0 ).getChild( 0 ), 1, viewRoot.getChild( 0 ).getChild( 0 ), 1 )
  89. ] );
  90. convertSelection( null, { newSelection: viewSelection } );
  91. const spy = sinon.spy();
  92. model.on( 'change', spy );
  93. convertSelection( null, { newSelection: viewSelection } );
  94. expect( spy.called ).to.be.false;
  95. } );
  96. } );