ckeditor.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* bender-tags: browser-only */
  6. 'use strict';
  7. import testUtils from '/tests/ckeditor5/_utils/utils.js';
  8. import CKEDITOR from '/ckeditor.js';
  9. import Editor from '/ckeditor5/editor.js';
  10. import Config from '/ckeditor5/utils/config.js';
  11. import CKEditorError from '/ckeditor5/utils/ckeditorerror.js';
  12. const content = document.getElementById( 'content' );
  13. const editorConfig = { creator: 'creator-test' };
  14. testUtils.createSinonSandbox();
  15. testUtils.defineEditorCreatorMock( 'test' );
  16. beforeEach( () => {
  17. // Destroy all editor instances.
  18. while ( CKEDITOR.instances.length ) {
  19. CKEDITOR.instances.get( 0 ).destroy();
  20. }
  21. } );
  22. describe( 'create', () => {
  23. it( 'should return a promise', () => {
  24. expect( CKEDITOR.create( content, editorConfig ) ).to.be.instanceof( Promise );
  25. } );
  26. it( 'should create a new editor instance', () => {
  27. return CKEDITOR.create( content, editorConfig ).then( ( editor ) => {
  28. expect( editor ).to.be.instanceof( Editor );
  29. } );
  30. } );
  31. it( 'should set configurations on the new editor', () => {
  32. return CKEDITOR.create( content, { test: 1, creator: 'creator-test' } ).then( ( editor ) => {
  33. expect( editor.config.test ).to.equal( 1 );
  34. } );
  35. } );
  36. it( 'should add the editor to the `instances` collection', () => {
  37. return CKEDITOR.create( content, editorConfig ).then( ( editor ) => {
  38. expect( CKEDITOR.instances ).to.have.length( 1 );
  39. expect( CKEDITOR.instances.get( 0 ) ).to.equal( editor );
  40. } );
  41. } );
  42. it( 'should remove the editor from the `instances` collection on `destroy` event', () => {
  43. let editor1, editor2;
  44. // Create the first editor.
  45. return CKEDITOR.create( content, editorConfig ).then( ( editor ) => {
  46. editor1 = editor;
  47. // Create the second editor.
  48. return CKEDITOR.create( '.editor', editorConfig ).then( ( editor ) => {
  49. editor2 = editor;
  50. // It should have 2 editors.
  51. expect( CKEDITOR.instances ).to.have.length( 2 );
  52. // Destroy one of them.
  53. editor1.destroy();
  54. // It should have 1 editor now.
  55. expect( CKEDITOR.instances ).to.have.length( 1 );
  56. // Ensure that the remaining is the right one.
  57. expect( CKEDITOR.instances.get( 0 ) ).to.equal( editor2 );
  58. } );
  59. } );
  60. } );
  61. describe( 'elements param', () => {
  62. const container = document.createElement( 'div' );
  63. let el1, el2;
  64. document.body.appendChild( container );
  65. beforeEach( () => {
  66. container.innerHTML = '';
  67. el1 = document.createElement( 'div' );
  68. el2 = document.createElement( 'div' );
  69. container.appendChild( el1 );
  70. container.appendChild( el2 );
  71. } );
  72. it( 'should work with a string', () => {
  73. return CKEDITOR.create( 'div', editorConfig ).then( ( editor ) => {
  74. assertElements( editor, document.querySelectorAll( 'div' ).length );
  75. } );
  76. } );
  77. it( 'should work with an HTMLElement', () => {
  78. return CKEDITOR.create( el1, editorConfig ).then( ( editor ) => {
  79. assertElements( editor, 1 );
  80. } );
  81. } );
  82. it( 'should work with a NodeList', () => {
  83. const elements = container.querySelectorAll( 'div' );
  84. return CKEDITOR.create( elements, editorConfig ).then( ( editor ) => {
  85. assertElements( editor, 2 );
  86. } );
  87. } );
  88. it( 'should work with an HTMLCollection', () => {
  89. const elements = container.getElementsByTagName( 'div' );
  90. return CKEDITOR.create( elements, editorConfig ).then( ( editor ) => {
  91. assertElements( editor, 2 );
  92. } );
  93. } );
  94. it( 'should work with an array', () => {
  95. const elements = Array.from( container.getElementsByTagName( 'div' ) );
  96. return CKEDITOR.create( elements, editorConfig ).then( ( editor ) => {
  97. assertElements( editor, 2 );
  98. } );
  99. } );
  100. it( 'should work with an object', () => {
  101. const elements = {
  102. editableA: el1,
  103. editableB: el2
  104. };
  105. return CKEDITOR.create( elements, editorConfig ).then( ( editor ) => {
  106. assertElements( editor, 2 );
  107. } );
  108. } );
  109. it( 'should be rejected on element not found (when string passed)', () => {
  110. let addSpy = testUtils.sinon.spy( CKEDITOR.instances, 'add' );
  111. return CKEDITOR.create( '.undefined' )
  112. .then( () => {
  113. throw new Error( 'It should not enter this function.' );
  114. } )
  115. .catch( ( error ) => {
  116. expect( error ).to.be.instanceof( CKEditorError );
  117. expect( error.message ).to.match( /^ckeditor5-create-no-elements:/ );
  118. // We need to make sure that create()'s execution is stopped.
  119. // Assertion based on a real mistake we made that reject() wasn't followed by a return.
  120. sinon.assert.notCalled( addSpy );
  121. } );
  122. } );
  123. it( 'should be rejected on an empty elements array-like obj', () => {
  124. return CKEDITOR.create( [] )
  125. .then( () => {
  126. throw new Error( 'It should not enter this function.' );
  127. } )
  128. .catch( ( error ) => {
  129. expect( error ).to.be.instanceof( CKEditorError );
  130. expect( error.message ).to.match( /^ckeditor5-create-no-elements:/ );
  131. } );
  132. } );
  133. it( 'should be rejected on an empty object', () => {
  134. return CKEDITOR.create( {} )
  135. .then( () => {
  136. throw new Error( 'It should not enter this function.' );
  137. } )
  138. .catch( ( error ) => {
  139. expect( error ).to.be.instanceof( CKEditorError );
  140. expect( error.message ).to.match( /^ckeditor5-create-no-elements:/ );
  141. } );
  142. } );
  143. it( 'should take names from the ids or data-editable attributes', () => {
  144. el1.id = 'foo';
  145. el2.dataset.editable = 'bar';
  146. return CKEDITOR.create( [ el1, el2 ], editorConfig )
  147. .then( ( editor ) => {
  148. expect( editor.elements.get( 'foo' ) ).to.equal( el1 );
  149. expect( editor.elements.get( 'bar' ) ).to.equal( el2 );
  150. } );
  151. } );
  152. it( 'should take names from the object keys', () => {
  153. el1.id = 'foo';
  154. el2.dataset.editable = 'bar';
  155. return CKEDITOR.create( { a: el1, b: el2 }, editorConfig )
  156. .then( ( editor ) => {
  157. expect( editor.elements.get( 'a' ) ).to.equal( el1 );
  158. expect( editor.elements.get( 'b' ) ).to.equal( el2 );
  159. } );
  160. } );
  161. it( 'should generate editableN names', () => {
  162. return CKEDITOR.create( [ el1, el2 ], editorConfig )
  163. .then( ( editor ) => {
  164. expect( Array.from( editor.elements.keys() ).join( ',' ) ).to.match( /^editable\d+,editable\d+$/ );
  165. } );
  166. } );
  167. function assertElements( editor, expectedSize ) {
  168. expect( editor.elements ).to.be.instanceof( Map );
  169. expect( editor.elements ).to.have.property( 'size', expectedSize );
  170. }
  171. } );
  172. } );
  173. describe( 'config', () => {
  174. it( 'should be an instance of Config', () => {
  175. expect( CKEDITOR.config ).to.be.an.instanceof( Config );
  176. } );
  177. } );