8
0

getselectedcontent.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. import Document from 'ckeditor5/engine/model/document.js';
  6. import DocumentFragment from 'ckeditor5/engine/model/documentfragment.js';
  7. import getSelectedContent from 'ckeditor5/engine/controller/getselectedcontent.js';
  8. import { setData, stringify } from 'ckeditor5/engine/dev-utils/model.js';
  9. describe( 'Delete utils', () => {
  10. let doc;
  11. describe( 'getSelectedContent', () => {
  12. describe( 'in simple scenarios', () => {
  13. beforeEach( () => {
  14. doc = new Document();
  15. doc.createRoot();
  16. const schema = doc.schema;
  17. schema.registerItem( 'image', '$inline' );
  18. schema.allow( { name: '$text', inside: '$root' } );
  19. schema.allow( { name: 'image', inside: '$root' } );
  20. schema.allow( { name: '$inline', attributes: [ 'bold' ] } );
  21. schema.allow( { name: '$inline', attributes: [ 'italic' ] } );
  22. } );
  23. it( 'returns empty fragment for no selection', () => {
  24. setData( doc, 'abc' );
  25. const frag = getSelectedContent( doc.selection );
  26. expect( frag ).instanceOf( DocumentFragment );
  27. expect( frag.isEmpty ).to.be.true;
  28. } );
  29. it( 'returns empty fragment for empty selection', () => {
  30. setData( doc, 'a[]bc' );
  31. const frag = getSelectedContent( doc.selection );
  32. expect( frag ).instanceOf( DocumentFragment );
  33. expect( frag.isEmpty ).to.be.true;
  34. } );
  35. it( 'gets one character', () => {
  36. setData( doc, 'a[b]c' );
  37. const frag = getSelectedContent( doc.selection );
  38. const content = stringify( frag );
  39. expect( frag ).instanceOf( DocumentFragment );
  40. expect( content ).to.equal( 'b' );
  41. } );
  42. it( 'gets full text', () => {
  43. setData( doc, '[abc]' );
  44. const content = stringify( getSelectedContent( doc.selection ) );
  45. expect( content ).to.equal( 'abc' );
  46. } );
  47. it( 'gets text with an attribute', () => {
  48. setData( doc, 'xxx<$text bold="true">a[b]c</$text>' );
  49. const content = stringify( getSelectedContent( doc.selection ) );
  50. expect( content ).to.equal( '<$text bold="true">b</$text>' );
  51. } );
  52. it( 'gets text with attributes', () => {
  53. setData( doc, 'x<$text bold="true">a[b</$text><$text italic="true">c]d</$text>x' );
  54. const content = stringify( getSelectedContent( doc.selection ) );
  55. expect( content ).to.equal( '<$text bold="true">b</$text><$text italic="true">c</$text>' );
  56. } );
  57. it( 'gets text with and without attribute', () => {
  58. setData( doc, '<$text bold="true">a[b</$text>c]d' );
  59. const content = stringify( getSelectedContent( doc.selection ) );
  60. expect( content ).to.equal( '<$text bold="true">b</$text>c' );
  61. } );
  62. it( 'gets text and element', () => {
  63. setData( doc, '[ab<image></image>c]' );
  64. const content = stringify( getSelectedContent( doc.selection ) );
  65. expect( content ).to.equal( 'ab<image></image>c' );
  66. } );
  67. it( 'gets one element', () => {
  68. setData( doc, 'a[<image></image>]b' );
  69. const content = stringify( getSelectedContent( doc.selection ) );
  70. expect( content ).to.equal( '<image></image>' );
  71. } );
  72. it( 'gets multiple elements', () => {
  73. setData( doc, '[<image></image><image></image>]' );
  74. const content = stringify( getSelectedContent( doc.selection ) );
  75. expect( content ).to.equal( '<image></image><image></image>' );
  76. } );
  77. } );
  78. describe( 'in blocks', () => {
  79. beforeEach( () => {
  80. doc = new Document();
  81. doc.createRoot();
  82. const schema = doc.schema;
  83. schema.registerItem( 'paragraph', '$block' );
  84. schema.registerItem( 'heading1', '$block' );
  85. schema.registerItem( 'blockImage' );
  86. schema.registerItem( 'caption' );
  87. schema.registerItem( 'image', '$inline' );
  88. schema.allow( { name: 'blockImage', inside: '$root' } );
  89. schema.allow( { name: 'caption', inside: 'blockImage' } );
  90. schema.allow( { name: '$inline', inside: 'caption' } );
  91. } );
  92. it( 'gets one character', () => {
  93. setData( doc, '<paragraph>a[b]c</paragraph>' );
  94. const content = stringify( getSelectedContent( doc.selection ) );
  95. expect( content ).to.equal( 'b' );
  96. } );
  97. it( 'gets entire paragraph content', () => {
  98. setData( doc, '<paragraph>[a<image></image>b]</paragraph>' );
  99. const content = stringify( getSelectedContent( doc.selection ) );
  100. expect( content ).to.equal( 'a<image></image>b' );
  101. } );
  102. it( 'gets two blocks - partial, partial', () => {
  103. setData( doc, '<heading1>a[bc</heading1><paragraph>de]f</paragraph>' );
  104. const content = stringify( getSelectedContent( doc.selection ) );
  105. expect( content ).to.equal( '<heading1>bc</heading1><paragraph>de</paragraph>' );
  106. } );
  107. it( 'gets two blocks - full, partial', () => {
  108. setData( doc, '<heading1>[abc</heading1><paragraph>de]f</paragraph>' );
  109. const content = stringify( getSelectedContent( doc.selection ) );
  110. expect( content ).to.equal( '<heading1>abc</heading1><paragraph>de</paragraph>' );
  111. } );
  112. it( 'gets two blocks - full, partial 2', () => {
  113. setData( doc, '<heading1>[abc</heading1><paragraph>de<image></image>]f</paragraph>' );
  114. const content = stringify( getSelectedContent( doc.selection ) );
  115. expect( content ).to.equal( '<heading1>abc</heading1><paragraph>de<image></image></paragraph>' );
  116. } );
  117. it( 'gets two blocks - full, partial 3', () => {
  118. setData( doc, '<heading1>x</heading1><heading1>[abc</heading1><paragraph><image></image>de]f</paragraph>' );
  119. const content = stringify( getSelectedContent( doc.selection ) );
  120. expect( content ).to.equal( '<heading1>abc</heading1><paragraph><image></image>de</paragraph>' );
  121. } );
  122. it( 'gets two blocks - full, partial 4', () => {
  123. setData( doc, '<heading1>[abc</heading1><paragraph>de]f<image></image></paragraph>' );
  124. const content = stringify( getSelectedContent( doc.selection ) );
  125. expect( content ).to.equal( '<heading1>abc</heading1><paragraph>de</paragraph>' );
  126. } );
  127. it( 'gets two blocks - partial, full', () => {
  128. setData( doc, '<heading1>a[bc</heading1><paragraph>def]</paragraph>' );
  129. const content = stringify( getSelectedContent( doc.selection ) );
  130. expect( content ).to.equal( '<heading1>bc</heading1><paragraph>def</paragraph>' );
  131. } );
  132. it( 'gets two blocks - partial, full 2', () => {
  133. setData( doc, '<heading1>a[<image></image>bc</heading1><paragraph>def]</paragraph>' );
  134. const content = stringify( getSelectedContent( doc.selection ) );
  135. expect( content ).to.equal( '<heading1><image></image>bc</heading1><paragraph>def</paragraph>' );
  136. } );
  137. // See https://github.com/ckeditor/ckeditor5-engine/issues/652#issuecomment-261358484
  138. it( 'gets two blocks - empty, full', () => {
  139. setData( doc, '<heading1>abc[</heading1><paragraph>def]</paragraph>' );
  140. const content = stringify( getSelectedContent( doc.selection ) );
  141. expect( content ).to.equal( '<paragraph>def</paragraph>' );
  142. } );
  143. // See https://github.com/ckeditor/ckeditor5-engine/issues/652#issuecomment-261358484
  144. it( 'gets two blocks - partial, empty', () => {
  145. setData( doc, '<heading1>a[bc</heading1><paragraph>]def</paragraph>' );
  146. const content = stringify( getSelectedContent( doc.selection ) );
  147. expect( content ).to.equal( '<heading1>bc</heading1>' );
  148. } );
  149. it( 'gets three blocks', () => {
  150. setData( doc, '<heading1>a[bc</heading1><paragraph>x</paragraph><paragraph>de]f</paragraph>' );
  151. const content = stringify( getSelectedContent( doc.selection ) );
  152. expect( content ).to.equal( '<heading1>bc</heading1><paragraph>x</paragraph><paragraph>de</paragraph>' );
  153. } );
  154. it( 'gets block image', () => {
  155. setData( doc, '<paragraph>a</paragraph>[<blockImage><caption>Foo</caption></blockImage>]<paragraph>b</paragraph>' );
  156. const content = stringify( getSelectedContent( doc.selection ) );
  157. expect( content ).to.equal( '<blockImage><caption>Foo</caption></blockImage>' );
  158. } );
  159. it( 'gets two blocks', () => {
  160. setData( doc, '<paragraph>a</paragraph>[<blockImage></blockImage><blockImage></blockImage>]<paragraph>b</paragraph>' );
  161. const content = stringify( getSelectedContent( doc.selection ) );
  162. expect( content ).to.equal( '<blockImage></blockImage><blockImage></blockImage>' );
  163. } );
  164. } );
  165. describe( 'in blocks (deeply nested)', () => {
  166. beforeEach( () => {
  167. doc = new Document();
  168. doc.createRoot();
  169. const schema = doc.schema;
  170. schema.registerItem( 'paragraph', '$block' );
  171. schema.registerItem( 'heading1', '$block' );
  172. schema.registerItem( 'quote' );
  173. schema.allow( { name: '$block', inside: 'quote' } );
  174. schema.allow( { name: 'quote', inside: '$root' } );
  175. } );
  176. it( 'gets content when ends are equally deeply nested', () => {
  177. setData( doc, '<heading1>x</heading1><quote><paragraph>a[bc</paragraph><paragraph>de]f</paragraph></quote>' );
  178. const content = stringify( getSelectedContent( doc.selection ) );
  179. expect( content ).to.equal( '<paragraph>bc</paragraph><paragraph>de</paragraph>' );
  180. } );
  181. it( 'gets content when left end nested deeper', () => {
  182. setData( doc, '<quote><paragraph>a[bc</paragraph></quote><paragraph>de]f</paragraph>' );
  183. const content = stringify( getSelectedContent( doc.selection ) );
  184. expect( content ).to.equal( '<quote><paragraph>bc</paragraph></quote><paragraph>de</paragraph>' );
  185. } );
  186. it( 'gets content when left end nested deeper 2', () => {
  187. setData( doc, '<quote><paragraph>a[bc</paragraph><heading1>x</heading1></quote><paragraph>de]f</paragraph>' );
  188. const content = stringify( getSelectedContent( doc.selection ) );
  189. expect( content ).to.equal( '<quote><paragraph>bc</paragraph><heading1>x</heading1></quote><paragraph>de</paragraph>' );
  190. } );
  191. it( 'gets content when left end nested deeper 3', () => {
  192. setData( doc, '<quote><heading1>x</heading1><paragraph>a[bc</paragraph></quote><paragraph>de]f</paragraph>' );
  193. const content = stringify( getSelectedContent( doc.selection ) );
  194. expect( content ).to.equal( '<quote><paragraph>bc</paragraph></quote><paragraph>de</paragraph>' );
  195. } );
  196. // See https://github.com/ckeditor/ckeditor5-engine/issues/652#issuecomment-261358484
  197. it( 'gets content when left end nested deeper 4', () => {
  198. setData( doc, '<quote><heading1>x[</heading1><paragraph>abc</paragraph></quote><paragraph>de]f</paragraph>' );
  199. const content = stringify( getSelectedContent( doc.selection ) );
  200. expect( content ).to.equal( '<quote><paragraph>abc</paragraph></quote><paragraph>de</paragraph>' );
  201. } );
  202. it( 'gets content when right end nested deeper', () => {
  203. setData( doc, '<paragraph>a[bc</paragraph><quote><paragraph>de]f</paragraph></quote>' );
  204. const content = stringify( getSelectedContent( doc.selection ) );
  205. expect( content ).to.equal( '<paragraph>bc</paragraph><quote><paragraph>de</paragraph></quote>' );
  206. } );
  207. it( 'gets content when both ends nested deeper than the middle element', () => {
  208. setData( doc, '<quote><heading1>a[bc</heading1></quote><heading1>x</heading1><quote><heading1>de]f</heading1></quote>' );
  209. const content = stringify( getSelectedContent( doc.selection ) );
  210. expect( content )
  211. .to.equal( '<quote><heading1>bc</heading1></quote><heading1>x</heading1><quote><heading1>de</heading1></quote>' );
  212. } );
  213. } );
  214. } );
  215. } );