|
|
@@ -1,25 +1,28 @@
|
|
|
/**
|
|
|
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
|
|
|
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
|
|
|
* For licensing, see LICENSE.md.
|
|
|
*/
|
|
|
|
|
|
-/* globals document */
|
|
|
+/* globals document, Event */
|
|
|
|
|
|
import BalloonEditorUI from '../src/ballooneditorui';
|
|
|
import BalloonEditorUIView from '../src/ballooneditoruiview';
|
|
|
|
|
|
import HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';
|
|
|
-import buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';
|
|
|
-import buildModelConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter';
|
|
|
+
|
|
|
+import { downcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversion/downcast-converters';
|
|
|
+import { upcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
|
|
|
|
|
|
import BalloonEditor from '../src/ballooneditor';
|
|
|
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
|
|
|
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
|
|
|
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
|
|
|
-import ContextualToolbar from '@ckeditor/ckeditor5-ui/src/toolbar/contextual/contextualtoolbar';
|
|
|
+import BalloonToolbar from '@ckeditor/ckeditor5-ui/src/toolbar/balloon/balloontoolbar';
|
|
|
+import DataApiMixin from '@ckeditor/ckeditor5-core/src/editor/utils/dataapimixin';
|
|
|
+import ElementApiMixin from '@ckeditor/ckeditor5-core/src/editor/utils/elementapimixin';
|
|
|
+import RootElement from '@ckeditor/ckeditor5-engine/src/model/rootelement';
|
|
|
|
|
|
import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
|
|
|
-import count from '@ckeditor/ckeditor5-utils/src/count';
|
|
|
|
|
|
testUtils.createSinonSandbox();
|
|
|
|
|
|
@@ -40,27 +43,65 @@ describe( 'BalloonEditor', () => {
|
|
|
describe( 'constructor()', () => {
|
|
|
beforeEach( () => {
|
|
|
editor = new BalloonEditor( editorElement, {
|
|
|
- plugins: [ ContextualToolbar, Bold ],
|
|
|
+ plugins: [ BalloonToolbar, Bold ],
|
|
|
toolbar: [ 'Bold' ]
|
|
|
} );
|
|
|
} );
|
|
|
|
|
|
- it( 'pushes ContextualToolbar to the list of plugins', () => {
|
|
|
- expect( editor.config.get( 'plugins' ) ).to.include( ContextualToolbar );
|
|
|
- } );
|
|
|
-
|
|
|
- it( 'pipes config#toolbar to config#contextualToolbar', () => {
|
|
|
- expect( editor.config.get( 'contextualToolbar' ) ).to.have.members( [ 'Bold' ] );
|
|
|
+ it( 'pushes BalloonToolbar to the list of plugins', () => {
|
|
|
+ expect( editor.config.get( 'plugins' ) ).to.include( BalloonToolbar );
|
|
|
} );
|
|
|
|
|
|
- it( 'creates a single document root', () => {
|
|
|
- expect( count( editor.document.getRootNames() ) ).to.equal( 1 );
|
|
|
- expect( editor.document.getRoot() ).to.have.property( 'name', '$root' );
|
|
|
+ it( 'pipes config#toolbar to config#balloonToolbar', () => {
|
|
|
+ expect( editor.config.get( 'balloonToolbar' ) ).to.have.members( [ 'Bold' ] );
|
|
|
} );
|
|
|
|
|
|
it( 'uses HTMLDataProcessor', () => {
|
|
|
expect( editor.data.processor ).to.be.instanceof( HtmlDataProcessor );
|
|
|
} );
|
|
|
+
|
|
|
+ it( 'has a Data Interface', () => {
|
|
|
+ testUtils.isMixed( BalloonEditor, DataApiMixin );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'has a Element Interface', () => {
|
|
|
+ testUtils.isMixed( BalloonEditor, ElementApiMixin );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'creates main root element', () => {
|
|
|
+ expect( editor.model.document.getRoot( 'main' ) ).to.instanceof( RootElement );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'handles form element', () => {
|
|
|
+ const form = document.createElement( 'form' );
|
|
|
+ const textarea = document.createElement( 'textarea' );
|
|
|
+ form.appendChild( textarea );
|
|
|
+ document.body.appendChild( form );
|
|
|
+
|
|
|
+ // Prevents page realods in Firefox ;|
|
|
|
+ form.addEventListener( 'submit', evt => {
|
|
|
+ evt.preventDefault();
|
|
|
+ } );
|
|
|
+
|
|
|
+ return BalloonEditor.create( textarea, {
|
|
|
+ plugins: [ Paragraph ]
|
|
|
+ } ).then( editor => {
|
|
|
+ expect( textarea.value ).to.equal( '' );
|
|
|
+
|
|
|
+ editor.setData( '<p>Foo</p>' );
|
|
|
+
|
|
|
+ form.dispatchEvent( new Event( 'submit', {
|
|
|
+ // We need to be able to do preventDefault() to prevent page reloads in Firefox.
|
|
|
+ cancelable: true
|
|
|
+ } ) );
|
|
|
+
|
|
|
+ expect( textarea.value ).to.equal( '<p>Foo</p>' );
|
|
|
+
|
|
|
+ return editor.destroy().then( () => {
|
|
|
+ form.remove();
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+ } );
|
|
|
} );
|
|
|
|
|
|
describe( 'create()', () => {
|
|
|
@@ -90,10 +131,6 @@ describe( 'BalloonEditor', () => {
|
|
|
expect( editor.editing.view.getDomRoot() ).to.equal( editor.ui.view.editable.element );
|
|
|
} );
|
|
|
|
|
|
- it( 'creates a single div editable root in the view', () => {
|
|
|
- expect( editor.editing.view.getRoot() ).to.have.property( 'name', 'div' );
|
|
|
- } );
|
|
|
-
|
|
|
it( 'creates the UI using BalloonEditorUI classes', () => {
|
|
|
expect( editor.ui ).to.be.instanceof( BalloonEditorUI );
|
|
|
expect( editor.ui.view ).to.be.instanceof( BalloonEditorUIView );
|
|
|
@@ -215,23 +252,18 @@ describe( 'BalloonEditor', () => {
|
|
|
.then( newEditor => {
|
|
|
editor = newEditor;
|
|
|
|
|
|
- const schema = editor.document.schema;
|
|
|
-
|
|
|
- schema.registerItem( 'heading' );
|
|
|
- schema.allow( { name: 'heading', inside: '$root' } );
|
|
|
- schema.allow( { name: '$text', inside: 'heading' } );
|
|
|
-
|
|
|
- buildModelConverter().for( editor.data.modelToView )
|
|
|
- .fromElement( 'heading' )
|
|
|
- .toElement( 'heading' );
|
|
|
+ const schema = editor.model.schema;
|
|
|
|
|
|
- buildViewConverter().for( editor.data.viewToModel )
|
|
|
- .fromElement( 'heading' )
|
|
|
- .toElement( 'heading' );
|
|
|
+ schema.register( 'heading' );
|
|
|
+ schema.extend( 'heading', { allowIn: '$root' } );
|
|
|
+ schema.extend( '$text', { allowIn: 'heading' } );
|
|
|
|
|
|
- buildModelConverter().for( editor.editing.modelToView )
|
|
|
- .fromElement( 'heading' )
|
|
|
- .toElement( 'heading-editing-representation' );
|
|
|
+ editor.conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'heading', view: 'heading' } ) );
|
|
|
+ editor.conversion.for( 'dataDowncast' ).add( downcastElementToElement( { model: 'heading', view: 'heading' } ) );
|
|
|
+ editor.conversion.for( 'editingDowncast' ).add( downcastElementToElement( {
|
|
|
+ model: 'heading',
|
|
|
+ view: 'heading-editing-representation'
|
|
|
+ } ) );
|
|
|
} );
|
|
|
} );
|
|
|
|