Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge e898463 into a3c5c82
Browse files Browse the repository at this point in the history
  • Loading branch information
f1ames committed Jan 22, 2019
2 parents a3c5c82 + e898463 commit b70590e
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 78 deletions.
34 changes: 5 additions & 29 deletions src/classiceditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import attachToForm from '@ckeditor/ckeditor5-core/src/editor/utils/attachtoform
import HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';
import ClassicEditorUI from './classiceditorui';
import ClassicEditorUIView from './classiceditoruiview';
import ElementReplacer from '@ckeditor/ckeditor5-utils/src/elementreplacer';
import getDataFromElement from '@ckeditor/ckeditor5-utils/src/dom/getdatafromelement';
import mix from '@ckeditor/ckeditor5-utils/src/mix';
import { isElement } from 'lodash-es';
Expand Down Expand Up @@ -66,14 +65,6 @@ export default class ClassicEditor extends Editor {
this.sourceElement = sourceElementOrData;
}

/**
* The element replacer instance used to hide the editor's source element.
*
* @protected
* @member {module:utils/elementreplacer~ElementReplacer}
*/
this._elementReplacer = new ElementReplacer();

this.data.processor = new HtmlDataProcessor();

this.model.document.createRoot();
Expand All @@ -83,13 +74,6 @@ export default class ClassicEditor extends Editor {
attachToForm( this );
}

/**
* @inheritDoc
*/
get element() {
return this.ui.view.element;
}

/**
* Destroys the editor instance, releasing all resources used by it.
*
Expand All @@ -102,7 +86,6 @@ export default class ClassicEditor extends Editor {
this.updateSourceElement();
}

this._elementReplacer.restore();
this.ui.destroy();

return super.destroy();
Expand Down Expand Up @@ -167,15 +150,15 @@ export default class ClassicEditor extends Editor {
*
* If a source element is passed, then its contents will be automatically
* {@link module:editor-classic/classiceditor~ClassicEditor#setData loaded} to the editor on startup
* and the {@link module:core/editor/editorwithui~EditorWithUI#element editor element} will replace the passed element in the DOM
* and the {@link module:core/editor/editorui~EditorUI#getEditableElement editor element} will replace the passed element in the DOM
* (the original one will be hidden and the editor will be injected next to it).
*
* Moreover, the data will be set back to the source element once the editor is destroyed and
* (if the element is a `<textarea>`) when a form in which this element is contained is submitted (which ensures
* automatic integration with native web forms).
*
* If the data is passed, a detached editor will be created. It means that you need to insert it into the DOM manually
* (by accessing the {@link module:editor-classic/classiceditor~ClassicEditor#element `editor.element`} property).
* If the data is passed, a detached editor will be created. It means that you need to insert it into the DOM manually (by accessing
* it via the {@link module:editor-classic/classiceditorui~ClassicEditorUI#getEditableElement `editor.ui.getEditableElement()`} method).
*
* See the examples above to learn more.
*
Expand All @@ -189,15 +172,8 @@ export default class ClassicEditor extends Editor {

resolve(
editor.initPlugins()
.then( () => editor.ui.init() )
.then( () => {
if ( isElement( sourceElementOrData ) ) {
editor._elementReplacer.replace( sourceElementOrData, editor.element );
}

editor.fire( 'uiReady' );
} )
.then( () => editor.editing.view.attachDomRoot( editor.ui.view.editableElement ) )
.then( () => editor.ui.init( isElement( sourceElementOrData ) ? sourceElementOrData : null ) )
.then( () => editor.editing.view.attachDomRoot( editor.ui.getEditableElement() ) )
.then( () => {
const initialData = isElement( sourceElementOrData ) ?
getDataFromElement( sourceElementOrData ) :
Expand Down
72 changes: 65 additions & 7 deletions src/classiceditorui.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import EditorUI from '@ckeditor/ckeditor5-core/src/editor/editorui';
import enableToolbarKeyboardFocus from '@ckeditor/ckeditor5-ui/src/toolbar/enabletoolbarkeyboardfocus';
import normalizeToolbarConfig from '@ckeditor/ckeditor5-ui/src/toolbar/normalizetoolbarconfig';
import ElementReplacer from '@ckeditor/ckeditor5-utils/src/elementreplacer';

/**
* The classic editor UI class.
Expand All @@ -18,24 +19,62 @@ import normalizeToolbarConfig from '@ckeditor/ckeditor5-ui/src/toolbar/normalize
*/
export default class ClassicEditorUI extends EditorUI {
/**
* @inheritDoc
* Creates an instance of the classic editor UI class.
*
* @param {module:core/editor/editor~Editor} editor The editor instance.
* @param {module:ui/editorui/editoruiview~EditorUIView} view The view of the UI.
*/
constructor( editor, view ) {
super( editor, view );
super( editor );

/**
* The main (top–most) view of the editor UI.
*
* @private
* @member {module:ui/editorui/editoruiview~EditorUIView} #_view
*/
this._view = view;

/**
* A normalized `config.toolbar` object.
*
* @type {Object}
* @private
* @member {Object}
*/
this._toolbarConfig = normalizeToolbarConfig( editor.config.get( 'toolbar' ) );

/**
* The element replacer instance used to hide the editor's source element.
*
* @protected
* @member {module:utils/elementreplacer~ElementReplacer}
*/
this._elementReplacer = new ElementReplacer();
}

/**
* The main (top–most) view of the editor UI.
*
* @readonly
* @member {module:ui/editorui/editoruiview~EditorUIView} #view
*/
get view() {
return this._view;
}

/**
* @inheritDoc
*/
get element() {
return this.view.element;
}

/**
* Initializes the UI.
*
* @param {HTMLElement|null} replacementElement The DOM element that will be the source for the created editor.
*/
init() {
init( replacementElement ) {
const editor = this.editor;
const view = this.view;

Expand All @@ -55,15 +94,34 @@ export default class ClassicEditorUI extends EditorUI {
view.editable.bind( 'isFocused' ).to( editor.editing.view.document );
view.editable.name = editingRoot.rootName;

this.focusTracker.add( this.view.editableElement );
this._editableElements.set( view.editable.name, view.editable.element );

this.view.toolbar.fillFromConfig( this._toolbarConfig.items, this.componentFactory );
this.focusTracker.add( view.editable.element );

view.toolbar.fillFromConfig( this._toolbarConfig.items, this.componentFactory );

enableToolbarKeyboardFocus( {
origin: editor.editing.view,
originFocusTracker: this.focusTracker,
originKeystrokeHandler: editor.keystrokes,
toolbar: this.view.toolbar
toolbar: view.toolbar
} );

if ( replacementElement ) {
this._elementReplacer.replace( replacementElement, this.element );
}

this.fire( 'ready' );
}

/**
* @inheritDoc
*/
destroy() {
this._elementReplacer.restore();

this._view.destroy();

super.destroy();
}
}
7 changes: 0 additions & 7 deletions src/classiceditoruiview.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,4 @@ export default class ClassicEditorUIView extends BoxedEditorUIView {
this.top.add( this.stickyPanel );
this.main.add( this.editable );
}

/**
* @inheritDoc
*/
get editableElement() {
return this.editable.element;
}
}
26 changes: 8 additions & 18 deletions tests/classiceditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import ElementApiMixin from '@ckeditor/ckeditor5-core/src/editor/utils/elementap
import RootElement from '@ckeditor/ckeditor5-engine/src/model/rootelement';

import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
import log from '@ckeditor/ckeditor5-utils/src/log';

import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
import { describeMemoryUsage, testMemoryUsage } from '@ckeditor/ckeditor5-core/tests/_utils/memory';

Expand All @@ -32,6 +34,8 @@ describe( 'ClassicEditor', () => {
editorElement.innerHTML = '<p><strong>foo</strong> bar</p>';

document.body.appendChild( editorElement );

testUtils.sinon.stub( log, 'warn' ).callsFake( () => {} );
} );

afterEach( () => {
Expand Down Expand Up @@ -171,20 +175,6 @@ describe( 'ClassicEditor', () => {
it( 'attaches editable UI as view\'s DOM root', () => {
expect( editor.editing.view.getDomRoot() ).to.equal( editor.ui.view.editable.element );
} );

it( 'editor.element points to the editor\'s UI when editor was initialized on the DOM element', () => {
expect( editor.element ).to.equal( editor.ui.view.element );
} );

it( 'editor.element points to the editor\'s UI when editor was initialized with data', () => {
return ClassicEditor.create( '<p>Hello world!</p>', {
plugins: [ Paragraph ]
} ).then( editor => {
expect( editor.element ).to.equal( editor.ui.view.element );

return editor.destroy();
} );
} );
} );
} );

Expand All @@ -203,7 +193,7 @@ describe( 'ClassicEditor', () => {
class EventWatcher extends Plugin {
init() {
this.editor.on( 'pluginsReady', spy );
this.editor.on( 'uiReady', spy );
this.editor.ui.on( 'ready', spy );
this.editor.on( 'dataReady', spy );
this.editor.on( 'ready', spy );
}
Expand All @@ -214,7 +204,7 @@ describe( 'ClassicEditor', () => {
plugins: [ EventWatcher ]
} )
.then( newEditor => {
expect( fired ).to.deep.equal( [ 'pluginsReady', 'uiReady', 'dataReady', 'ready' ] );
expect( fired ).to.deep.equal( [ 'pluginsReady', 'ready', 'dataReady', 'ready' ] );

editor = newEditor;
} );
Expand Down Expand Up @@ -242,12 +232,12 @@ describe( 'ClassicEditor', () => {
} );
} );

it( 'fires uiReady once UI is rendered', () => {
it( 'fires ready once UI is rendered', () => {
let isReady;

class EventWatcher extends Plugin {
init() {
this.editor.on( 'uiReady', () => {
this.editor.ui.on( 'ready', () => {
isReady = this.editor.ui.view.isRendered;
} );
}
Expand Down
30 changes: 28 additions & 2 deletions tests/classiceditorui.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
import utils from '@ckeditor/ckeditor5-utils/tests/_utils/utils';

describe( 'ClassicEditorUI', () => {
let editor, view, ui;
let editor, view, ui, viewElement;

testUtils.createSinonSandbox();

Expand All @@ -31,6 +31,7 @@ describe( 'ClassicEditorUI', () => {

ui = editor.ui;
view = ui.view;
viewElement = view.element;
} );
} );

Expand Down Expand Up @@ -178,6 +179,32 @@ describe( 'ClassicEditorUI', () => {
} );
} );
} );

describe( 'view()', () => {
it( 'returns view instance', () => {
expect( ui.view ).to.equal( view );
} );
} );

describe( 'element()', () => {
it( 'returns correct element instance', () => {
expect( ui.element ).to.equal( viewElement );
} );
} );

describe( 'getEditableElement()', () => {
it( 'returns editable element (default)', () => {
expect( ui.getEditableElement() ).to.equal( view.editable.element );
} );

it( 'returns editable element (root name passed)', () => {
expect( ui.getEditableElement( 'main' ) ).to.equal( view.editable.element );
} );

it( 'returns null if editable with the given name is absent', () => {
expect( ui.getEditableElement( 'absent' ) ).to.null;
} );
} );
} );

function viewCreator( name ) {
Expand Down Expand Up @@ -216,7 +243,6 @@ class VirtualClassicTestEditor extends VirtualTestEditor {
editor.initPlugins()
.then( () => {
editor.ui.init();
editor.fire( 'uiReady' );
editor.fire( 'dataReady' );
editor.fire( 'ready' );
} )
Expand Down
19 changes: 4 additions & 15 deletions tests/classiceditoruiview.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@
* For licensing, see LICENSE.md.
*/

/* globals document */

import ClassicEditorUIView from '../src/classiceditoruiview';
import StickyPanelView from '@ckeditor/ckeditor5-ui/src/panel/sticky/stickypanelview';
import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
import InlineEditableUIView from '@ckeditor/ckeditor5-ui/src/editableui/inline/inlineeditableuiview';
import Locale from '@ckeditor/ckeditor5-utils/src/locale';

import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';

describe( 'ClassicEditorUIView', () => {
let locale, view;

testUtils.createSinonSandbox();

beforeEach( () => {
locale = new Locale( 'en' );
view = new ClassicEditorUIView( locale );
Expand Down Expand Up @@ -67,17 +69,4 @@ describe( 'ClassicEditorUIView', () => {
} );
} );
} );

describe( 'editableElement', () => {
it( 'returns editable\'s view element', () => {
document.body.appendChild( view.element );

view.stickyPanel.limiterElement = view.element;

expect( view.editableElement.getAttribute( 'contentEditable' ) ).to.equal( 'true' );

view.element.remove();
view.destroy();
} );
} );
} );

0 comments on commit b70590e

Please sign in to comment.