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

Commit

Permalink
Merge c1baebc into 5fef9a1
Browse files Browse the repository at this point in the history
  • Loading branch information
oleq committed Jan 28, 2019
2 parents 5fef9a1 + c1baebc commit 585f9ab
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 25 deletions.
2 changes: 1 addition & 1 deletion src/classiceditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default class ClassicEditor extends Editor {

this.model.document.createRoot();

this.ui = new ClassicEditorUI( this, new ClassicEditorUIView( this.locale ) );
this.ui = new ClassicEditorUI( this, new ClassicEditorUIView( this.locale, this.editing.view ) );

attachToForm( this );
}
Expand Down
102 changes: 80 additions & 22 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 { addPlaceholder, getRootPlaceholderElement } from '@ckeditor/ckeditor5-engine/src/view/placeholder';
import ElementReplacer from '@ckeditor/ckeditor5-utils/src/elementreplacer';

/**
Expand Down Expand Up @@ -67,9 +68,74 @@ export default class ClassicEditorUI extends EditorUI {
init( replacementElement ) {
const editor = this.editor;
const view = this.view;
const editingView = editor.editing.view;
const editable = view.editable;
const editingRoot = editingView.document.getRoot();

// The editable UI and editing root should share the same name. Then name is used
// to recognize the particular editable, for instance in ARIA attributes.
editable.name = editingRoot.rootName;

view.render();

// The editable UI element in DOM is available for sure only after the editor UI view has been rendered.
// But it can be available earlier if a DOM element has been passed to BalloonEditor.create().
const editableElement = editable.element;

// Register the editable UI view in the editor. A single editor instance can aggregate multiple
// editable areas (roots) but the classic editor has only one.
this._editableElements.set( editable.name, editableElement );

// Let the global focus tracker know that the editable UI element is focusable and
// belongs to the editor. From now on, the focus tracker will sustain the editor focus
// as long as the editable is focused (e.g. the user is typing).
this.focusTracker.add( editableElement );

// Let the editable UI element respond to the changes in the global editor focus
// tracker. It has been added to the same tracker a few lines above but, in reality, there are
// many focusable areas in the editor, like balloons, toolbars or dropdowns and as long
// as they have focus, the editable should act like it is focused too (although technically
// it isn't), e.g. by setting the proper CSS class, visually announcing focus to the user.
// Doing otherwise will result in editable focus styles disappearing, once e.g. the
// toolbar gets focused.
view.editable.bind( 'isFocused' ).to( this.focusTracker );

// If an element containing the initial data of the editor was provided, replace it with
// an editor instance's UI in DOM until the editor is destroyed. For instance, a <textarea>
// can be such element.
if ( replacementElement ) {
this._elementReplacer.replace( replacementElement, this.element );
}

this._initPlaceholder();
this._initToolbar();
this.fire( 'ready' );
}

/**
* @inheritDoc
*/
destroy() {
const view = this.view;
const editingView = this.editor.editing.view;

this._elementReplacer.restore();
editingView.detachDomRoot( view.editable.name );
view.destroy();

super.destroy();
}

/**
* Initializes the editor toolbar.
*
* @private
*/
_initToolbar() {
const editor = this.editor;
const view = this.view;
const editingView = editor.editing.view;

// Set–up the sticky panel with toolbar.
view.stickyPanel.bind( 'isActive' ).to( this.focusTracker, 'isFocused' );
view.stickyPanel.limiterElement = view.element;
Expand All @@ -78,40 +144,32 @@ export default class ClassicEditorUI extends EditorUI {
view.stickyPanel.viewportTopOffset = this._toolbarConfig.viewportTopOffset;
}

// Setup the editable.
const editingRoot = editor.editing.view.document.getRoot();
view.editable.bind( 'isReadOnly' ).to( editingRoot );
view.editable.bind( 'isFocused' ).to( editor.editing.view.document );
view.editable.name = editingRoot.rootName;

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

this.focusTracker.add( view.editable.element );

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

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

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

this.fire( 'ready' );
}

/**
* @inheritDoc
* Enable the placeholder text on the editing root, if any was configured.
*
* @private
*/
destroy() {
this._elementReplacer.restore();
_initPlaceholder() {
const editor = this.editor;
const editingView = editor.editing.view;
const editingRoot = editingView.document.getRoot();

this.view.destroy();
const placeholderText = editor.config.get( 'placeholder' ) || editor.sourceElement.getAttribute( 'placeholder' );

super.destroy();
if ( placeholderText ) {
const placeholderElement = getRootPlaceholderElement( editingRoot );

addPlaceholder( editingView, placeholderElement, placeholderText );
}
}
}
4 changes: 2 additions & 2 deletions src/classiceditoruiview.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default class ClassicEditorUIView extends BoxedEditorUIView {
*
* @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.
*/
constructor( locale ) {
constructor( locale, editingView ) {
super( locale );

/**
Expand All @@ -52,7 +52,7 @@ export default class ClassicEditorUIView extends BoxedEditorUIView {
* @readonly
* @member {module:ui/editableui/inline/inlineeditableuiview~InlineEditableUIView}
*/
this.editable = new InlineEditableUIView( locale );
this.editable = new InlineEditableUIView( locale, editingView );
}

/**
Expand Down
5 changes: 5 additions & 0 deletions tests/manual/placeholder.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div id="editor-1" placeholder="Placeholder from the attribute">
<p>Remove this text to see the placeholder.</p>
</div>
<br />
<div id="editor-2" placeholder="Placeholder from the attribute"></div>
37 changes: 37 additions & 0 deletions tests/manual/placeholder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/

/* globals console:false, document, window */

import ClassicEditor from '../../src/classiceditor';
import Enter from '@ckeditor/ckeditor5-enter/src/enter';
import Typing from '@ckeditor/ckeditor5-typing/src/typing';
import Heading from '@ckeditor/ckeditor5-heading/src/heading';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
import Undo from '@ckeditor/ckeditor5-undo/src/undo';
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';

window.editors = {};

function initEditor( element, placeholder ) {
ClassicEditor
.create( element, {
plugins: [ Enter, Typing, Paragraph, Undo, Heading, Bold, Italic ],
toolbar: [ 'heading', '|', 'bold', 'italic', 'undo', 'redo' ],
placeholder
} )
.then( newEditor => {
console.log( 'Editor was initialized', newEditor );

window.editors[ element.id ] = newEditor;
} )
.catch( err => {
console.error( err.stack );
} );
}

initEditor( document.querySelector( '#editor-1' ) );
initEditor( document.querySelector( '#editor-2' ), 'The placeholder from editor.config.placeholder' );
1 change: 1 addition & 0 deletions tests/manual/placeholder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TODO

0 comments on commit 585f9ab

Please sign in to comment.