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

Commit

Permalink
Merge ef2978c into 18bab70
Browse files Browse the repository at this point in the history
  • Loading branch information
f1ames committed Nov 7, 2018
2 parents 18bab70 + ef2978c commit a20ecc4
Show file tree
Hide file tree
Showing 14 changed files with 203 additions and 42 deletions.
7 changes: 5 additions & 2 deletions src/view/attributeelement.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@ const DEFAULT_PRIORITY = 10;
* be defined by the feature developer. Creating an element you should use {@link module:engine/view/containerelement~ContainerElement}
* class or `AttributeElement`.
*
* The constructor of this class shouldn't be used directly. To create new `AttributeElement` use the
* {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement `downcastWriter#createAttributeElement()`} method.
*
* @extends module:engine/view/element~Element
*/
export default class AttributeElement extends Element {
/**
* Creates a attribute element.
* Creates an attribute element.
*
* @see module:engine/view/downcastwriter~DowncastWriter#createAttributeElement
* @protected
* @see module:engine/view/element~Element
* @protected
*/
constructor( name, attrs, children ) {
super( name, attrs, children );
Expand Down
6 changes: 5 additions & 1 deletion src/view/containerelement.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import Element from './element';
* Editing engine does not define fixed HTML DTD. This is why the type of the {@link module:engine/view/element~Element} need to
* be defined by the feature developer.
*
* To create new `ContainerElement`
* {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement `DowncastWriter#createContainerElement()`}
* method should be used.
*
* Creating an element you should use `ContainerElement` class or {@link module:engine/view/attributeelement~AttributeElement}. This is
* important to define the type of the element because of two reasons:
*
Expand Down Expand Up @@ -47,8 +51,8 @@ export default class ContainerElement extends Element {
/**
* Creates a container element.
*
* @see module:engine/view/element~Element
* @see module:engine/view/downcastwriter~DowncastWriter#createContainerElement
* @see module:engine/view/element~Element
* @protected
*/
constructor( name, attrs, children ) {
Expand Down
8 changes: 6 additions & 2 deletions src/view/documentfragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@ import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';

/**
* DocumentFragment class.
*
* The constructor of this class shouldn't be used directly. To create new DocumentFragment instance use the
* {@link module:engine/view/upcastwriter~UpcastWriter#createDocumentFragment `UpcastWriter#createDocumentFragment()`}
* method instead.
*/
export default class DocumentFragment {
/**
* Creates new DocumentFragment instance.
*
* @protected
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children] List of nodes to be inserted into
* created document fragment.
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
* A list of nodes to be inserted into the created document fragment.
*/
constructor( children ) {
/**
Expand Down
4 changes: 2 additions & 2 deletions src/view/downcastwriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ export default class DowncastWriter {
*
* writer.createText( 'foo' );
*
* @param {String} data Text data.
* @returns {module:engine/view/text~Text} Created text node.
* @param {String} data The text's data.
* @returns {module:engine/view/text~Text} The created text node.
*/
createText( data ) {
return new Text( data );
Expand Down
3 changes: 3 additions & 0 deletions src/view/editableelement.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const documentSymbol = Symbol( 'document' );
*
* Editable is automatically read-only when its {@link module:engine/view/document~Document Document} is read-only.
*
* The constructor of this class shouldn't be used directly. To create new `EditableElement` use the
* {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement `downcastWriter#createEditableElement()`} method.
*
* @extends module:engine/view/containerelement~ContainerElement
* @mixes module:utils/observablemixin~ObservableMixin
*/
Expand Down
36 changes: 15 additions & 21 deletions src/view/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,21 @@ import { isPlainObject } from 'lodash-es';
* This is why the type of the {@link module:engine/view/element~Element} need to
* be defined by the feature developer. When creating an element you should use one of the following methods:
*
* * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement `writer.createContainerElement()`} in order to create
* a {@link module:engine/view/containerelement~ContainerElement},
* * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement `writer.createAttributeElement()`} in order to create
* a {@link module:engine/view/attributeelement~AttributeElement},
* * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement `writer.createEmptyElement()`} in order to create
* a {@link module:engine/view/emptyelement~EmptyElement}.
* * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `writer.createUIElement()`} in order to create
* a {@link module:engine/view/uielement~UIElement}.
* * {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement `writer.createEditableElement()`} in order to create
* a {@link module:engine/view/editableelement~EditableElement}.
* * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement `downcastWriter#createContainerElement()`}
* in order to create a {@link module:engine/view/containerelement~ContainerElement},
* * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement `downcastWriter#createAttributeElement()`}
* in order to create a {@link module:engine/view/attributeelement~AttributeElement},
* * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement `downcastWriter#createEmptyElement()`}
* in order to create a {@link module:engine/view/emptyelement~EmptyElement}.
* * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`}
* in order to create a {@link module:engine/view/uielement~UIElement}.
* * {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement `downcastWriter#createEditableElement()`}
* in order to create a {@link module:engine/view/editableelement~EditableElement}.
*
* Note that for view elements which are not created from the model, like elements from mutations, paste or
* {@link module:engine/controller/datacontroller~DataController#set data.set} it is not possible to define the type of the element, so
* these will be instances of the {@link module:engine/view/element~Element}.
* {@link module:engine/controller/datacontroller~DataController#set data.set} it is not possible to define the type of the element.
* In such cases the {@link module:engine/view/upcastwriter~UpcastWriter#createElement `UpcastWriter#createElement()`} method
* should be used to create generic view elements.
*
* @extends module:engine/view/node~Node
*/
Expand All @@ -45,22 +46,15 @@ export default class Element extends Node {
*
* Attributes can be passed in various formats:
*
* new Element( 'div', { 'class': 'editor', 'contentEditable': 'true' } ); // object
* new Element( 'div', { class: 'editor', contentEditable: 'true' } ); // object
* new Element( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator
* new Element( 'div', mapOfAttributes ); // map
*
* **Note:** Constructor of this class shouldn't be used directly in the code. Use the
* {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement} for inline element,
* {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement} for block element,
* {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement} for editable element,
* {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement} for empty element or
* {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement} for UI element instead.
*
* @protected
* @param {String} name Node name.
* @param {Object|Iterable} [attrs] Collection of attributes.
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
* List of nodes to be inserted into created element.
* A list of nodes to be inserted into created element.
*/
constructor( name, attrs, children ) {
super();
Expand Down
5 changes: 4 additions & 1 deletion src/view/emptyelement.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
import Node from './node';

/**
* EmptyElement class. It is used to represent elements that cannot contain any child nodes.
* EmptyElement class. It is used to represent elements that cannot contain any child nodes (for example `<img>` elements).
*
* The constructor of this class shouldn't be used directly. To create new `EmptyElement` use the
* {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement `downcastWriter#createEmptyElement()`} method.
*/
export default class EmptyElement extends Element {
/**
Expand Down
6 changes: 4 additions & 2 deletions src/view/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ import { clone } from 'lodash-es';
/**
* Abstract tree view node class.
*
* This is an abstract class. Its constructor should not be used directly.
* Use the {@link module:engine/view/element~Element} class to create view elements
* or {@link module:engine/view/text~Text} class to create view text nodes.
*
* @abstract
*/
export default class Node {
/**
* Creates a tree view node.
*
* This is an abstract class, so this constructor should not be used directly.
*/
constructor() {
/**
Expand Down
11 changes: 7 additions & 4 deletions src/view/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@ import Node from './node';
/**
* Tree view text node.
*
* The constructor of this class shouldn't be used directly. To create new Text instances
* use the {@link module:engine/view/downcastwriter~DowncastWriter#createText `DowncastWriter#createText()`}
* method when working on data downcasted from the model or the
* {@link module:engine/view/upcastwriter~UpcastWriter#createText `UpcastWriter#createText()`}
* method when working on non-semantic views.
*
* @extends module:engine/view/node~Node
*/
export default class Text extends Node {
/**
* Creates a tree view text node.
*
* **Note:** Constructor of this class shouldn't be used directly in the code.
* Use the {@link module:engine/view/downcastwriter~DowncastWriter#createText} method instead.
*
* @protected
* @param {String} data Text.
* @param {String} data The text's data.
*/
constructor( data ) {
super();
Expand Down
3 changes: 3 additions & 0 deletions src/view/uielement.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
/**
* UIElement class. It is used to represent UI not a content of the document.
* This element can't be split and selection can't be placed inside this element.
*
* The constructor of this class shouldn't be used directly. To create new `UIElement` use the
* {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`} method.
*/
export default class UIElement extends Element {
/**
Expand Down
42 changes: 42 additions & 0 deletions src/view/upcastwriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* @module module:engine/view/upcastwriter
*/

import DocumentFragment from './documentfragment';
import Element from './element';
import Text from './text';
import { isPlainObject } from 'lodash-es';
import Position from './position';
import Range from './range';
Expand All @@ -23,6 +25,46 @@ import Selection from './selection';
* {@link module:engine/view/downcastwriter~DowncastWriter downcast writer}.
*/
export default class UpcastWriter {
/**
* Creates a new {@link module:engine/view/documentfragment~DocumentFragment} instance.
*
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
* A list of nodes to be inserted into the created document fragment.
* @returns {module:engine/view/documentfragment~DocumentFragment} The created document fragment.
*/
createDocumentFragment( children ) {
return new DocumentFragment( children );
}

/**
* Creates a new {@link module:engine/view/element~Element} instance.
*
* Attributes can be passed in various formats:
*
* upcastWriter.createElement( 'div', { class: 'editor', contentEditable: 'true' } ); // object
* upcastWriter.createElement( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator
* upcastWriter.createElement( 'div', mapOfAttributes ); // map
*
* @param {String} name Node name.
* @param {Object|Iterable} [attrs] Collection of attributes.
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
* A list of nodes to be inserted into created element.
* @returns {module:engine/view/element~Element} Created element.
*/
createElement( name, attrs, children ) {
return new Element( name, attrs, children );
}

/**
* Creates a new {@link module:engine/view/text~Text} instance.
*
* @param {String} data The text's data.
* @returns {module:engine/view/text~Text} The created text node.
*/
createText( data ) {
return new Text( data );
}

/**
* Clones the provided element.
*
Expand Down
19 changes: 12 additions & 7 deletions src/view/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,16 +311,20 @@ export default class View {
* Change method is the primary way of changing the view. You should use it to modify any node in the view tree.
* It makes sure that after all changes are made view is rendered to DOM. It prevents situations when DOM is updated
* when view state is not yet correct. It allows to nest calls one inside another and still perform single rendering
* after all changes are applied.
* after all changes are applied. It also returns the return value of its callback.
*
* view.change( writer => {
* writer.insert( position1, writer.createText( 'foo' ) );
* const text = view.change( writer => {
*
* const newText = writer.createText( 'foo' );
* writer.insert( position1, newText );
*
* view.change( writer => {
* writer.insert( position2, writer.createText( 'bar' ) );
* } );
*
* writer.remove( range );
*
* return newText;
* } );
*
* Change block is executed immediately.
Expand All @@ -332,6 +336,7 @@ export default class View {
* change block is used after rendering to DOM has started.
*
* @param {Function} callback Callback function which may modify the view.
* @returns {*} Value returned by the callback.
*/
change( callback ) {
if ( this._renderingInProgress || this._postFixersInProgress ) {
Expand All @@ -353,15 +358,13 @@ export default class View {

// Recursive call to view.change() method - execute listener immediately.
if ( this._ongoingChange ) {
callback( this._writer );

return;
return callback( this._writer );
}

// This lock will assure that all recursive calls to view.change() will end up in same block - one "render"
// event for all nested calls.
this._ongoingChange = true;
callback( this._writer );
const callbackResult = callback( this._writer );
this._ongoingChange = false;

// This lock is used by editing controller to render changes from outer most model.change() once. As plugins might call
Expand All @@ -373,6 +376,8 @@ export default class View {

this.fire( 'render' );
}

return callbackResult;
}

/**
Expand Down
Loading

0 comments on commit a20ecc4

Please sign in to comment.