mergeattributes.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /**
  2. * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. import Writer from '../../../src/view/writer';
  6. import ContainerElement from '../../../src/view/containerelement';
  7. import Text from '../../../src/view/text';
  8. import Position from '../../../src/view/position';
  9. import { stringify, parse } from '../../../src/dev-utils/view';
  10. describe( 'Writer', () => {
  11. describe( 'mergeAttributes', () => {
  12. let writer;
  13. // Executes test using `parse` and `stringify` utils functions. Uses range delimiters `[]{}` to create and
  14. // test merge position.
  15. //
  16. // @param {String} input
  17. // @param {String} expected
  18. function test( input, expected ) {
  19. const { view, selection } = parse( input );
  20. const newPosition = writer.mergeAttributes( selection.getFirstPosition() );
  21. expect( stringify( view, newPosition, { showType: true, showPriority: true } ) ).to.equal( expected );
  22. }
  23. before( () => {
  24. writer = new Writer();
  25. } );
  26. it( 'should not merge if inside text node', () => {
  27. test( '<container:p>fo{}bar</container:p>', '<container:p>fo{}bar</container:p>' );
  28. } );
  29. it( 'should not merge if between containers', () => {
  30. test(
  31. '<container:div><container:p>foo</container:p>[]<container:p>bar</container:p></container:div>',
  32. '<container:div><container:p>foo</container:p>[]<container:p>bar</container:p></container:div>'
  33. );
  34. } );
  35. it( 'should return same position when inside empty container', () => {
  36. test(
  37. '<container:p>[]</container:p>',
  38. '<container:p>[]</container:p>'
  39. );
  40. } );
  41. it( 'should not merge when position is placed at the beginning of the container', () => {
  42. test(
  43. '<container:p>[]<attribute:b view-priority="1"></attribute:b></container:p>',
  44. '<container:p>[]<attribute:b view-priority="1"></attribute:b></container:p>'
  45. );
  46. } );
  47. it( 'should not merge when position is placed at the end of the container', () => {
  48. test(
  49. '<container:p><attribute:b view-priority="1"></attribute:b>[]</container:p>',
  50. '<container:p><attribute:b view-priority="1"></attribute:b>[]</container:p>'
  51. );
  52. } );
  53. it( 'should merge when placed between two text nodes', () => {
  54. // <p>foobar</p> -> <p>foo|bar</p>
  55. const t1 = new Text( 'foo' );
  56. const t2 = new Text( 'bar' );
  57. const p = new ContainerElement( 'p', null, [ t1, t2 ] );
  58. const position = new Position( p, 1 );
  59. const newPosition = writer.mergeAttributes( position );
  60. expect( stringify( p, newPosition ) ).to.equal( '<p>foo{}bar</p>' );
  61. } );
  62. it( 'should merge when placed between similar attribute nodes', () => {
  63. test(
  64. '<container:p>' +
  65. '<attribute:b view-priority="1" foo="bar">baz</attribute:b>[]' +
  66. '<attribute:b view-priority="1" foo="bar">qux</attribute:b>' +
  67. '</container:p>',
  68. '<container:p><attribute:b view-priority="1" foo="bar">baz{}qux</attribute:b></container:p>'
  69. );
  70. } );
  71. it( 'should not merge when placed between non-similar attribute nodes', () => {
  72. test(
  73. '<container:p>' +
  74. '<attribute:b view-priority="1" foo="bar"></attribute:b>[]<attribute:b view-priority="1" foo="baz"></attribute:b>' +
  75. '</container:p>',
  76. '<container:p>' +
  77. '<attribute:b view-priority="1" foo="bar"></attribute:b>[]<attribute:b view-priority="1" foo="baz"></attribute:b>' +
  78. '</container:p>'
  79. );
  80. } );
  81. it( 'should not merge when placed between similar attribute nodes with different priority', () => {
  82. test(
  83. '<container:p>' +
  84. '<attribute:b view-priority="1" foo="bar"></attribute:b>[]<attribute:b view-priority="2" foo="bar"></attribute:b>' +
  85. '</container:p>',
  86. '<container:p>' +
  87. '<attribute:b view-priority="1" foo="bar"></attribute:b>[]<attribute:b view-priority="2" foo="bar"></attribute:b>' +
  88. '</container:p>'
  89. );
  90. } );
  91. it( 'should merge attribute nodes and their contents if possible', () => {
  92. test(
  93. '<container:p>' +
  94. '<attribute:b view-priority="1" foo="bar">foo</attribute:b>[]' +
  95. '<attribute:b view-priority="1" foo="bar">bar</attribute:b>' +
  96. '</container:p>',
  97. '<container:p><attribute:b view-priority="1" foo="bar">foo{}bar</attribute:b></container:p>'
  98. );
  99. } );
  100. it( 'should remove empty attributes after merge #1', () => {
  101. test(
  102. '<container:p><attribute:b>[]</attribute:b></container:p>',
  103. '<container:p>[]</container:p>'
  104. );
  105. } );
  106. it( 'should remove empty attributes after merge #2', () => {
  107. test(
  108. '<container:p><attribute:b>foo</attribute:b><attribute:i>[]</attribute:i><attribute:b>bar</attribute:b></container:p>',
  109. '<container:p><attribute:b view-priority="10">foo{}bar</attribute:b></container:p>'
  110. );
  111. } );
  112. it( 'should remove empty attributes after merge #3', () => {
  113. test(
  114. '<container:p><attribute:b></attribute:b><attribute:i>[]</attribute:i><attribute:b></attribute:b></container:p>',
  115. '<container:p>[]</container:p>'
  116. );
  117. } );
  118. it( 'should not merge when placed between EmptyElements', () => {
  119. test(
  120. '<container:p><empty:img></empty:img>[]<empty:img></empty:img></container:p>',
  121. '<container:p><empty:img></empty:img>[]<empty:img></empty:img></container:p>'
  122. );
  123. } );
  124. it( 'should not merge when placed between UIElements', () => {
  125. test(
  126. '<container:p><ui:span></ui:span>[]<ui:span></ui:span></container:p>',
  127. '<container:p><ui:span></ui:span>[]<ui:span></ui:span></container:p>'
  128. );
  129. } );
  130. } );
  131. } );