unlinkcommand.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
  6. import UnlinkCommand from '../src/unlinkcommand';
  7. import LinkEditing from '../src/linkediting';
  8. import { setData, getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
  9. import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
  10. describe( 'UnlinkCommand', () => {
  11. let editor, model, document, command;
  12. testUtils.createSinonSandbox();
  13. beforeEach( () => {
  14. return ModelTestEditor.create()
  15. .then( newEditor => {
  16. editor = newEditor;
  17. model = editor.model;
  18. document = model.document;
  19. command = new UnlinkCommand( editor );
  20. model.schema.extend( '$text', {
  21. allowIn: '$root',
  22. allowAttributes: 'linkHref'
  23. } );
  24. model.schema.register( 'p', { inheritAllFrom: '$block' } );
  25. } );
  26. } );
  27. afterEach( () => {
  28. return editor.destroy();
  29. } );
  30. describe( 'isEnabled', () => {
  31. it( 'should be true when selection has `linkHref` attribute', () => {
  32. model.change( writer => {
  33. writer.setSelectionAttribute( 'linkHref', 'value' );
  34. } );
  35. expect( command.isEnabled ).to.true;
  36. } );
  37. it( 'should be false when selection doesn\'t have `linkHref` attribute', () => {
  38. model.change( writer => {
  39. writer.removeSelectionAttribute( 'linkHref' );
  40. } );
  41. expect( command.isEnabled ).to.false;
  42. } );
  43. } );
  44. describe( 'execute()', () => {
  45. describe( 'non-collapsed selection', () => {
  46. it( 'should remove `linkHref` attribute from selected text', () => {
  47. setData( model, '<$text linkHref="url">f[ooba]r</$text>' );
  48. command.execute();
  49. expect( getData( model ) ).to.equal( '<$text linkHref="url">f</$text>[ooba]<$text linkHref="url">r</$text>' );
  50. } );
  51. it( 'should remove `linkHref` attribute from selected text and do not modified other attributes', () => {
  52. setData( model, '<$text bold="true" linkHref="url">f[ooba]r</$text>' );
  53. command.execute();
  54. const assertAll = () => {
  55. expect( getData( model ) ).to.equal(
  56. '<$text bold="true" linkHref="url">f</$text>' +
  57. '[<$text bold="true">ooba</$text>]' +
  58. '<$text bold="true" linkHref="url">r</$text>'
  59. );
  60. };
  61. const assertEdge = () => {
  62. expect( getData( model ) ).to.equal(
  63. '<$text bold="true" linkHref="url">f</$text>' +
  64. '[<$text bold="true">ooba]<$text linkHref="url">r</$text></$text>'
  65. );
  66. };
  67. testUtils.checkAssertions( assertAll, assertEdge );
  68. } );
  69. it( 'should remove `linkHref` attribute from selected text when attributes have different value', () => {
  70. setData( model, '[<$text linkHref="url">foo</$text><$text linkHref="other url">bar</$text>]' );
  71. command.execute();
  72. expect( getData( model ) ).to.equal( '[foobar]' );
  73. } );
  74. it( 'should remove `linkHref` attribute from selection', () => {
  75. setData( model, '<$text linkHref="url">f[ooba]r</$text>' );
  76. command.execute();
  77. expect( document.selection.hasAttribute( 'linkHref' ) ).to.false;
  78. } );
  79. } );
  80. describe( 'collapsed selection', () => {
  81. it( 'should remove `linkHref` attribute from selection siblings with the same attribute value', () => {
  82. setData( model, '<$text linkHref="url">foo[]bar</$text>' );
  83. command.execute();
  84. expect( getData( model ) ).to.equal( 'foo[]bar' );
  85. } );
  86. it( 'should remove `linkHref` attribute from selection siblings with the same attribute value and do not modify ' +
  87. 'other attributes', () => {
  88. setData(
  89. model,
  90. '<$text linkHref="other url">fo</$text>' +
  91. '<$text linkHref="url">o[]b</$text>' +
  92. '<$text linkHref="other url">ar</$text>'
  93. );
  94. command.execute();
  95. expect( getData( model ) ).to.equal(
  96. '<$text linkHref="other url">fo</$text>' +
  97. 'o[]b' +
  98. '<$text linkHref="other url">ar</$text>'
  99. );
  100. } );
  101. it( 'should do nothing with nodes with the same `linkHref` value when there is a node with different value `linkHref` ' +
  102. 'attribute between', () => {
  103. setData(
  104. model,
  105. '<$text linkHref="same url">f</$text>' +
  106. '<$text linkHref="other url">o</$text>' +
  107. '<$text linkHref="same url">o[]b</$text>' +
  108. '<$text linkHref="other url">a</$text>' +
  109. '<$text linkHref="same url">r</$text>'
  110. );
  111. command.execute();
  112. expect( getData( model ) )
  113. .to.equal(
  114. '<$text linkHref="same url">f</$text>' +
  115. '<$text linkHref="other url">o</$text>' +
  116. 'o[]b' +
  117. '<$text linkHref="other url">a</$text>' +
  118. '<$text linkHref="same url">r</$text>'
  119. );
  120. } );
  121. it( 'should remove `linkHref` attribute from selection siblings with the same attribute value ' +
  122. 'and do nothing with other attributes',
  123. () => {
  124. setData(
  125. model,
  126. '<$text linkHref="url">f</$text>' +
  127. '<$text bold="true" linkHref="url">o</$text>' +
  128. '<$text linkHref="url">o[]b</$text>' +
  129. '<$text bold="true" linkHref="url">a</$text>' +
  130. '<$text linkHref="url">r</$text>'
  131. );
  132. command.execute();
  133. expect( getData( model ) ).to.equal(
  134. 'f' +
  135. '<$text bold="true">o</$text>' +
  136. 'o[]b' +
  137. '<$text bold="true">a</$text>' +
  138. 'r'
  139. );
  140. } );
  141. it( 'should remove `linkHref` attribute from selection siblings only in the same parent as selection parent', () => {
  142. setData(
  143. model,
  144. '<p><$text linkHref="url">bar</$text></p>' +
  145. '<p><$text linkHref="url">fo[]o</$text></p>' +
  146. '<p><$text linkHref="url">bar</$text></p>'
  147. );
  148. command.execute();
  149. expect( getData( model ) ).to.equal(
  150. '<p><$text linkHref="url">bar</$text></p>' +
  151. '<p>fo[]o</p>' +
  152. '<p><$text linkHref="url">bar</$text></p>'
  153. );
  154. } );
  155. it( 'should remove `linkHref` attribute from selection siblings when selection is at the end of link', () => {
  156. setData( model, '<$text linkHref="url">foobar</$text>[]' );
  157. command.execute();
  158. expect( getData( model ) ).to.equal( 'foobar[]' );
  159. } );
  160. it( 'should remove `linkHref` attribute from selection siblings when selection is at the beginning of link', () => {
  161. setData( model, '[]<$text linkHref="url">foobar</$text>' );
  162. command.execute();
  163. expect( getData( model ) ).to.equal( '[]foobar' );
  164. } );
  165. it( 'should remove `linkHref` attribute from selection siblings on the left side when selection is between two elements with ' +
  166. 'different `linkHref` attributes',
  167. () => {
  168. setData( model, '<$text linkHref="url">foo</$text>[]<$text linkHref="other url">bar</$text>' );
  169. command.execute();
  170. expect( getData( model ) ).to.equal( 'foo[]<$text linkHref="other url">bar</$text>' );
  171. } );
  172. it( 'should remove `linkHref` attribute from selection', () => {
  173. setData( model, '<$text linkHref="url">foo[]bar</$text>' );
  174. command.execute();
  175. expect( document.selection.hasAttribute( 'linkHref' ) ).to.false;
  176. } );
  177. } );
  178. } );
  179. describe( 'manual decorators', () => {
  180. beforeEach( () => {
  181. editor.destroy();
  182. return ModelTestEditor.create( {
  183. extraPlugins: [ LinkEditing ],
  184. link: {
  185. decorators: {
  186. isFoo: {
  187. mode: 'manual',
  188. label: 'Foo',
  189. attributes: {
  190. class: 'foo'
  191. }
  192. },
  193. isBar: {
  194. mode: 'manual',
  195. label: 'Bar',
  196. attributes: {
  197. target: '_blank'
  198. }
  199. }
  200. }
  201. }
  202. } )
  203. .then( newEditor => {
  204. editor = newEditor;
  205. model = editor.model;
  206. document = model.document;
  207. command = new UnlinkCommand( editor );
  208. model.schema.extend( '$text', {
  209. allowIn: '$root',
  210. allowAttributes: [ 'linkHref', 'linkIsFoo', 'linkIsBar' ]
  211. } );
  212. model.schema.register( 'p', { inheritAllFrom: '$block' } );
  213. } );
  214. } );
  215. afterEach( () => {
  216. return editor.destroy();
  217. } );
  218. it( 'should remove manual decorators from links together with linkHref', () => {
  219. setData( model, '<$text linkIsFoo="true" linkIsBar="true" linkHref="url">f[]oobar</$text>' );
  220. command.execute();
  221. expect( getData( model ) ).to.equal( 'f[]oobar' );
  222. } );
  223. } );
  224. } );