modifyselection.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* bender-tags: model, composer */
  6. 'use strict';
  7. import Document from '/ckeditor5/engine/model/document.js';
  8. import modifySelection from '/ckeditor5/engine/model/composer/modifyselection.js';
  9. import { setData, getData } from '/tests/engine/_utils/model.js';
  10. describe( 'Delete utils', () => {
  11. let document;
  12. beforeEach( () => {
  13. document = new Document();
  14. document.createRoot();
  15. } );
  16. describe( 'modifySelection', () => {
  17. describe( 'unit=character', () => {
  18. describe( 'within element', () => {
  19. test(
  20. 'does nothing on empty content',
  21. '<selection />',
  22. '<selection />'
  23. );
  24. test(
  25. 'does nothing on empty content (with empty element)',
  26. '<p><selection /></p>',
  27. '<p><selection /></p>'
  28. );
  29. test(
  30. 'does nothing on empty content (backward)',
  31. '<selection />',
  32. '<selection />',
  33. { direction: 'backward' }
  34. );
  35. test(
  36. 'does nothing on root boundary',
  37. '<p>foo<selection /></p>',
  38. '<p>foo<selection /></p>'
  39. );
  40. test(
  41. 'does nothing on root boundary (backward)',
  42. '<p><selection />foo</p>',
  43. '<p><selection />foo</p>',
  44. { direction: 'backward' }
  45. );
  46. test(
  47. 'extends one character forward',
  48. '<p>f<selection />oo</p>',
  49. '<p>f<selection>o</selection>o</p>'
  50. );
  51. test(
  52. 'extends one character backward',
  53. '<p>fo<selection />o</p>',
  54. '<p>f<selection backward>o</selection>o</p>',
  55. { direction: 'backward' }
  56. );
  57. test(
  58. 'extends one character forward (non-collapsed)',
  59. '<p>f<selection>o</selection>obar</p>',
  60. '<p>f<selection>oo</selection>bar</p>'
  61. );
  62. test(
  63. 'extends one character backward (non-collapsed)',
  64. '<p>foob<selection backward>a</selection>r</p>',
  65. '<p>foo<selection backward>ba</selection>r</p>',
  66. { direction: 'backward' }
  67. );
  68. test(
  69. 'extends to element boundary',
  70. '<p>fo<selection />o</p>',
  71. '<p>fo<selection>o</selection></p>'
  72. );
  73. test(
  74. 'extends to element boundary (backward)',
  75. '<p>f<selection />oo</p>',
  76. '<p><selection backward>f</selection>oo</p>',
  77. { direction: 'backward' }
  78. );
  79. test(
  80. 'shrinks forward selection (to collapsed)',
  81. '<p>foo<selection>b</selection>ar</p>',
  82. '<p>foo<selection />bar</p>',
  83. { direction: 'backward' }
  84. );
  85. test(
  86. 'shrinks backward selection (to collapsed)',
  87. '<p>foo<selection backward>b</selection>ar</p>',
  88. '<p>foob<selection />ar</p>'
  89. );
  90. test(
  91. 'extends one element forward',
  92. '<p>f<selection /><img></img>oo</p>',
  93. '<p>f<selection><img></img></selection>oo</p>'
  94. );
  95. test(
  96. 'extends one non-empty element forward',
  97. '<p>f<selection /><img>x</img>oo</p>',
  98. '<p>f<selection><img>x</img></selection>oo</p>'
  99. );
  100. test(
  101. 'extends one element backward',
  102. '<p>fo<img></img><selection />o</p>',
  103. '<p>fo<selection backward><img></img></selection>o</p>',
  104. { direction: 'backward' }
  105. );
  106. } );
  107. describe( 'beyond element', () => {
  108. test(
  109. 'extends over boundary of empty elements',
  110. '<p><selection /></p><p></p><p></p>',
  111. '<p><selection></p><p></selection></p><p></p>'
  112. );
  113. test(
  114. 'extends over boundary of empty elements (backward)',
  115. '<p></p><p></p><p><selection /></p>',
  116. '<p></p><p><selection backward></p><p></selection></p>',
  117. { direction: 'backward' }
  118. );
  119. test(
  120. 'extends over boundary of non-empty elements',
  121. '<p>a<selection /></p><p>bcd</p>',
  122. '<p>a<selection></p><p></selection>bcd</p>'
  123. );
  124. test(
  125. 'extends over boundary of non-empty elements (backward)',
  126. '<p>a</p><p><selection />bcd</p>',
  127. '<p>a<selection backward></p><p></selection>bcd</p>',
  128. { direction: 'backward' }
  129. );
  130. test(
  131. 'extends over character after boundary',
  132. '<p>a<selection></p><p></selection>bcd</p>',
  133. '<p>a<selection></p><p>b</selection>cd</p>'
  134. );
  135. test(
  136. 'extends over character after boundary (backward)',
  137. '<p>abc<selection backward></p><p></selection>d</p>',
  138. '<p>ab<selection backward>c</p><p></selection>d</p>',
  139. { direction: 'backward' }
  140. );
  141. test(
  142. 'extends over boundary when next element has nested elements',
  143. '<p>a<selection /></p><p><x>bcd</x></p>',
  144. '<p>a<selection></p><p></selection><x>bcd</x></p>'
  145. );
  146. test(
  147. 'extends over element when next element has nested elements',
  148. '<p>a<selection></p><p></selection><x>bcd</x>ef</p>',
  149. '<p>a<selection></p><p><x>bcd</x></selection>ef</p>'
  150. );
  151. test(
  152. 'extends over element when next node is a text',
  153. '<p>a<selection /></p>bc',
  154. '<p>a<selection></p></selection>bc'
  155. );
  156. test(
  157. 'extends over element when next node is a text (backward)',
  158. 'ab<p><selection />c</p>',
  159. 'ab<selection backward><p></selection>c</p>',
  160. { direction: 'backward' }
  161. );
  162. test(
  163. 'shrinks over boundary of empty elements',
  164. '<p><selection backward></p><p></selection></p>',
  165. '<p></p><p><selection /></p>'
  166. );
  167. test(
  168. 'shrinks over boundary of empty elements (backward)',
  169. '<p><selection></p><p></selection></p>',
  170. '<p><selection /></p><p></p>',
  171. { direction: 'backward' }
  172. );
  173. test(
  174. 'shrinks over boundary of non-empty elements',
  175. '<p>a<selection backward></p><p></selection>b</p>',
  176. '<p>a</p><p><selection />b</p>'
  177. );
  178. test(
  179. 'shrinks over boundary of non-empty elements (backward)',
  180. '<p>a<selection></p><p></selection>b</p>',
  181. '<p>a<selection /></p><p>b</p>',
  182. { direction: 'backward' }
  183. );
  184. } );
  185. } );
  186. test(
  187. 'updates selection attributes',
  188. '<p><$text bold=true>foo</$text><selection>b</selection></p>',
  189. '<p><$text bold=true>foo</$text><selection bold=true />b</p>',
  190. { direction: 'backward' }
  191. );
  192. } );
  193. function test( title, input, output, options ) {
  194. it( title, () => {
  195. setData( document, input );
  196. modifySelection( document.selection, options );
  197. expect( getData( document ) ).to.equal( output );
  198. } );
  199. }
  200. } );