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

Commit ec13c85

Browse files
authoredNov 8, 2018
Merge pull request #1579 from ckeditor/t/1549
Feature: Introduced `createDocumentFragment()`, `createElement()` and `createText()` methods in `UpcastWriter`. Additionally, the `View.change()` method now returns the return value of its callback. Closes #1549.
2 parents 18bab70 + f0d6d5d commit ec13c85

18 files changed

+335
-156
lines changed
 

‎src/dev-utils/model.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import { isPlainObject } from 'lodash-es';
3838
import toMap from '@ckeditor/ckeditor5-utils/src/tomap';
3939

4040
/**
41-
* Writes the content of the {@link module:engine/model/document~Document document} to an HTML-like string.
41+
* Writes the content of a model {@link module:engine/model/document~Document document} to an HTML-like string.
4242
*
4343
* **Note:** A {@link module:engine/model/text~Text text} node that contains attributes will be represented as:
4444
*
@@ -72,9 +72,10 @@ export function getData( model, options = {} ) {
7272
getData._stringify = stringify;
7373

7474
/**
75-
* Sets the content of the {@link module:engine/model/document~Document document} provided as an HTML-like string.
75+
* Sets the content of a model {@link module:engine/model/document~Document document} provided as an HTML-like string.
7676
*
77-
* **Note:** Remember to register elements in the {@link module:engine/model/model~Model#schema model's schema} before inserting them.
77+
* **Note:** Remember to register elements in the {@link module:engine/model/model~Model#schema model's schema} before
78+
* trying to use them.
7879
*
7980
* **Note:** To create a {@link module:engine/model/text~Text text} node that contains attributes use:
8081
*

‎src/dev-utils/view.js

+34-31
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export function getData( view, options = {} ) {
8080
getData._stringify = stringify;
8181

8282
/**
83-
* Sets the content of the {@link module:engine/view/document~Document document} provided as an HTML-like string.
83+
* Sets the content of a view {@link module:engine/view/document~Document document} provided as an HTML-like string.
8484
*
8585
* @param {module:engine/view/view~View} view
8686
* @param {String} data An HTML-like string to write into the document.
@@ -111,44 +111,47 @@ setData._parse = parse;
111111

112112
/**
113113
* Converts view elements to HTML-like string representation.
114+
*
114115
* A root element can be provided as {@link module:engine/view/text~Text text}:
115116
*
116-
* const text = new Text( 'foobar' );
117+
* const text = downcastWriter.createText( 'foobar' );
117118
* stringify( text ); // 'foobar'
118119
*
119120
* or as an {@link module:engine/view/element~Element element}:
120121
*
121-
* const element = new Element( 'p', null, new Text( 'foobar' ) );
122+
* const element = downcastWriter.createElement( 'p', null, downcastWriter.createText( 'foobar' ) );
122123
* stringify( element ); // '<p>foobar</p>'
123124
*
124125
* or as a {@link module:engine/view/documentfragment~DocumentFragment document fragment}:
125126
*
126-
* const text = new Text( 'foobar' );
127-
* const b = new Element( 'b', { name: 'test' }, text );
128-
* const p = new Element( 'p', { style: 'color:red;' } );
129-
* const fragment = new DocumentFragment( [ p, b ] );
127+
* const text = downcastWriter.createText( 'foobar' );
128+
* const b = downcastWriter.createElement( 'b', { name: 'test' }, text );
129+
* const p = downcastWriter.createElement( 'p', { style: 'color:red;' } );
130+
* const fragment = downcastWriter.createDocumentFragment( [ p, b ] );
130131
*
131132
* stringify( fragment ); // '<p style="color:red;"></p><b name="test">foobar</b>'
132133
*
133134
* Additionally, a {@link module:engine/view/documentselection~DocumentSelection selection} instance can be provided.
134-
* Ranges from the selection will then be included in output data.
135+
* Ranges from the selection will then be included in the output data.
135136
* If a range position is placed inside the element node, it will be represented with `[` and `]`:
136137
*
137-
* const text = new Text( 'foobar' );
138-
* const b = new Element( 'b', null, text );
139-
* const p = new Element( 'p', null, b );
140-
* const selection = new Selection(
141-
* Range._createFromParentsAndOffsets( p, 0, p, 1 )
138+
* const text = downcastWriter.createText( 'foobar' );
139+
* const b = downcastWriter.createElement( 'b', null, text );
140+
* const p = downcastWriter.createElement( 'p', null, b );
141+
* const selection = downcastWriter.createSelection(
142+
* downcastWriter.createRangeIn( p )
142143
* );
143144
*
144145
* stringify( p, selection ); // '<p>[<b>foobar</b>]</p>'
145146
*
146147
* If a range is placed inside the text node, it will be represented with `{` and `}`:
147148
*
148-
* const text = new Text( 'foobar' );
149-
* const b = new Element( 'b', null, text );
150-
* const p = new Element( 'p', null, b );
151-
* const selection = new Selection( Range._createFromParentsAndOffsets( text, 1, text, 5 ) );
149+
* const text = downcastWriter.createText( 'foobar' );
150+
* const b = downcastWriter.createElement( 'b', null, text );
151+
* const p = downcastWriter.createElement( 'p', null, b );
152+
* const selection = downcastWriter.createSelection(
153+
* downcastWriter.createRange( downcastWriter.createPositionAt( text, 1 ), downcastWriter.createPositionAt( text, 5 ) )
154+
* );
152155
*
153156
* stringify( p, selection ); // '<p><b>f{ooba}r</b></p>'
154157
*
@@ -159,10 +162,10 @@ setData._parse = parse;
159162
*
160163
* Multiple ranges are supported:
161164
*
162-
* const text = new Text( 'foobar' );
163-
* const selection = new Selection( [
164-
* Range._createFromParentsAndOffsets( text, 0, text, 1 ) ),
165-
* Range._createFromParentsAndOffsets( text, 3, text, 5 ) )
165+
* const text = downcastWriter.createText( 'foobar' );
166+
* const selection = downcastWriter.createSelection( [
167+
* downcastWriter.createRange( downcastWriter.createPositionAt( text, 0 ), downcastWriter.createPositionAt( text, 1 ) ),
168+
* downcastWriter.createRange( downcastWriter.createPositionAt( text, 3 ), downcastWriter.createPositionAt( text, 5 ) )
166169
* ] );
167170
*
168171
* stringify( text, selection ); // '{f}oo{ba}r'
@@ -172,9 +175,9 @@ setData._parse = parse;
172175
* is provided, it will be converted to a selection containing this range. If a position instance is provided, it will
173176
* be converted to a selection containing one range collapsed at this position.
174177
*
175-
* const text = new Text( 'foobar' );
176-
* const range = Range._createFromParentsAndOffsets( text, 0, text, 1 );
177-
* const position = new Position( text, 3 );
178+
* const text = downcastWriter.createText( 'foobar' );
179+
* const range = downcastWriter.createRange( downcastWriter.createPositionAt( text, 0 ), downcastWriter.createPositionAt( text, 1 ) );
180+
* const position = downcastWriter.createPositionAt( text, 3 );
178181
*
179182
* stringify( text, range ); // '{f}oobar'
180183
* stringify( text, position ); // 'foo{}bar'
@@ -186,10 +189,10 @@ setData._parse = parse;
186189
* {@link module:engine/view/emptyelement~EmptyElement empty elements}
187190
* and {@link module:engine/view/uielement~UIElement UI elements}:
188191
*
189-
* const attribute = new AttributeElement( 'b' );
190-
* const container = new ContainerElement( 'p' );
191-
* const empty = new EmptyElement( 'img' );
192-
* const ui = new UIElement( 'span' );
192+
* const attribute = downcastWriter.createAttributeElement( 'b' );
193+
* const container = downcastWriter.createContainerElement( 'p' );
194+
* const empty = downcastWriter.createEmptyElement( 'img' );
195+
* const ui = downcastWriter.createUIElement( 'span' );
193196
* getData( attribute, null, { showType: true } ); // '<attribute:b></attribute:b>'
194197
* getData( container, null, { showType: true } ); // '<container:p></container:p>'
195198
* getData( empty, null, { showType: true } ); // '<empty:img></empty:img>'
@@ -198,14 +201,14 @@ setData._parse = parse;
198201
* If `options.showPriority` is set to `true`, a priority will be displayed for all
199202
* {@link module:engine/view/attributeelement~AttributeElement attribute elements}.
200203
*
201-
* const attribute = new AttributeElement( 'b' );
204+
* const attribute = downcastWriter.createAttributeElement( 'b' );
202205
* attribute._priority = 20;
203206
* getData( attribute, null, { showPriority: true } ); // <b view-priority="20"></b>
204207
*
205208
* If `options.showAttributeElementId` is set to `true`, the attribute element's id will be displayed for all
206209
* {@link module:engine/view/attributeelement~AttributeElement attribute elements} that have it set.
207210
*
208-
* const attribute = new AttributeElement( 'span' );
211+
* const attribute = downcastWriter.createAttributeElement( 'span' );
209212
* attribute._id = 'marker:foo';
210213
* getData( attribute, null, { showAttributeElementId: true } ); // <span view-id="marker:foo"></span>
211214
*
@@ -249,7 +252,7 @@ export function stringify( node, selectionOrPositionOrRange = null, options = {}
249252
}
250253

251254
/**
252-
* Parses an HTML-like string and returns view tree nodes.
255+
* Parses an HTML-like string and returns a view tree.
253256
* A simple string will be converted to a {@link module:engine/view/text~Text text} node:
254257
*
255258
* parse( 'foobar' ); // Returns an instance of text.

‎src/view/attributeelement.js

+10-7
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,25 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
1414
const DEFAULT_PRIORITY = 10;
1515

1616
/**
17-
* Attributes are elements which define document presentation. They are mostly elements like `<b>` or `<span>`.
18-
* Attributes can be broken and merged by the {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer}.
17+
* Attribute elements are used to represent formatting elements in the view (think – `<b>`, `<span style="font-size: 2em">`, etc.).
18+
* Most often they are created when downcasting model text attributes.
1919
*
20-
* Editing engine does not define fixed HTML DTD. This is why the type of the {@link module:engine/view/element~Element} need to
21-
* be defined by the feature developer. Creating an element you should use {@link module:engine/view/containerelement~ContainerElement}
22-
* class or `AttributeElement`.
20+
* Editing engine does not define a fixed HTML DTD. This is why a feature developer needs to choose between various
21+
* types (container element, {@link module:engine/view/attributeelement~AttributeElement attribute element},
22+
* {@link module:engine/view/emptyelement~EmptyElement empty element}, etc) when developing a feature.
23+
*
24+
* To create a new attribute element instance use the
25+
* {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement `DowncastWriter#createAttributeElement()`} method.
2326
*
2427
* @extends module:engine/view/element~Element
2528
*/
2629
export default class AttributeElement extends Element {
2730
/**
28-
* Creates a attribute element.
31+
* Creates an attribute element.
2932
*
3033
* @see module:engine/view/downcastwriter~DowncastWriter#createAttributeElement
31-
* @protected
3234
* @see module:engine/view/element~Element
35+
* @protected
3336
*/
3437
constructor( name, attrs, children ) {
3538
super( name, attrs, children );

‎src/view/containerelement.js

+13-26
Original file line numberDiff line numberDiff line change
@@ -11,44 +11,31 @@ import Element from './element';
1111

1212
/**
1313
* Containers are elements which define document structure. They define boundaries for
14-
* {@link module:engine/view/attributeelement~AttributeElement attributes}. They are mostly use for block elements like `<p>` or `<div>`.
14+
* {@link module:engine/view/attributeelement~AttributeElement attributes}. They are mostly used for block elements like `<p>` or `<div>`.
1515
*
16-
* Editing engine does not define fixed HTML DTD. This is why the type of the {@link module:engine/view/element~Element} need to
17-
* be defined by the feature developer.
16+
* Editing engine does not define a fixed HTML DTD. This is why a feature developer needs to choose between various
17+
* types (container element, {@link module:engine/view/attributeelement~AttributeElement attribute element},
18+
* {@link module:engine/view/emptyelement~EmptyElement empty element}, etc) when developing a feature.
1819
*
19-
* Creating an element you should use `ContainerElement` class or {@link module:engine/view/attributeelement~AttributeElement}. This is
20-
* important to define the type of the element because of two reasons:
20+
* The container element should be your default choice when writing a converter, unless:
2121
*
22-
* Firstly, {@link module:engine/view/domconverter~DomConverter} needs the information what is an editable block to convert elements to
23-
* DOM properly. {@link module:engine/view/domconverter~DomConverter} will ensure that `ContainerElement` is editable and it is possible
24-
* to put caret inside it, even if the container is empty.
22+
* * this element represents a model text attribute (then use {@link module:engine/view/attributeelement~AttributeElement}),
23+
* * this is an empty element like `<img>` (then use {@link module:engine/view/emptyelement~EmptyElement}),
24+
* * this is a root element,
25+
* * this is a nested editable element (then use {@link module:engine/view/editableelement~EditableElement}).
2526
*
26-
* Secondly, {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer} uses this information.
27-
* Nodes {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breaking} and
28-
* {@link module:engine/view/downcastwriter~DowncastWriter#mergeAttributes merging} is performed only in a bounds of a container nodes.
29-
*
30-
* For instance if `<p>` is an container and `<b>` is attribute:
31-
*
32-
* <p><b>fo^o</b></p>
33-
*
34-
* {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breakAttributes} will create:
35-
*
36-
* <p><b>fo</b><b>o</b></p>
37-
*
38-
* There might be a need to mark `<span>` element as a container node, for example in situation when it will be a
39-
* container of an inline widget:
40-
*
41-
* <span color="red">foobar</span> // attribute
42-
* <span data-widget>foobar</span> // container
27+
* To create a new container element instance use the
28+
* {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement `DowncastWriter#createContainerElement()`}
29+
* method.
4330
*
4431
* @extends module:engine/view/element~Element
4532
*/
4633
export default class ContainerElement extends Element {
4734
/**
4835
* Creates a container element.
4936
*
50-
* @see module:engine/view/element~Element
5137
* @see module:engine/view/downcastwriter~DowncastWriter#createContainerElement
38+
* @see module:engine/view/element~Element
5239
* @protected
5340
*/
5441
constructor( name, attrs, children ) {

‎src/view/documentfragment.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,19 @@ import isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';
1414
import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
1515

1616
/**
17-
* DocumentFragment class.
17+
* Document fragment.
18+
*
19+
* To create a new document fragment instance use the
20+
* {@link module:engine/view/upcastwriter~UpcastWriter#createDocumentFragment `UpcastWriter#createDocumentFragment()`}
21+
* method.
1822
*/
1923
export default class DocumentFragment {
2024
/**
2125
* Creates new DocumentFragment instance.
2226
*
2327
* @protected
24-
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children] List of nodes to be inserted into
25-
* created document fragment.
28+
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
29+
* A list of nodes to be inserted into the created document fragment.
2630
*/
2731
constructor( children ) {
2832
/**

‎src/view/downcastwriter.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ import { isPlainObject } from 'lodash-es';
2727
* It provides a set of methods used to manipulate view nodes.
2828
*
2929
* The `DowncastWriter` is designed to work with semantic views which are the views that were/are being downcasted from the model.
30-
* To work with ordinary views (e.g. parsed from a string) use the {@link module:engine/view/upcastwriter~UpcastWriter upcast writer}.
30+
* To work with ordinary views (e.g. parsed from a pasted content) use the
31+
* {@link module:engine/view/upcastwriter~UpcastWriter upcast writer}.
3132
*
3233
* Do not create an instance of this writer manually. To modify a view structure, use
33-
* the {@link module:engine/view/view~View#change View#change()) block.
34+
* the {@link module:engine/view/view~View#change `View#change()`) block.
3435
*/
3536
export default class DowncastWriter {
3637
constructor( document ) {
@@ -141,8 +142,8 @@ export default class DowncastWriter {
141142
*
142143
* writer.createText( 'foo' );
143144
*
144-
* @param {String} data Text data.
145-
* @returns {module:engine/view/text~Text} Created text node.
145+
* @param {String} data The text's data.
146+
* @returns {module:engine/view/text~Text} The created text node.
146147
*/
147148
createText( data ) {
148149
return new Text( data );

‎src/view/editableelement.js

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ const documentSymbol = Symbol( 'document' );
2020
*
2121
* Editable is automatically read-only when its {@link module:engine/view/document~Document Document} is read-only.
2222
*
23+
* The constructor of this class shouldn't be used directly. To create new `EditableElement` use the
24+
* {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement `downcastWriter#createEditableElement()`} method.
25+
*
2326
* @extends module:engine/view/containerelement~ContainerElement
2427
* @mixes module:utils/observablemixin~ObservableMixin
2528
*/

0 commit comments

Comments
 (0)
This repository has been archived.