Piotrek Koszuliński 5 年之前
父节点
当前提交
4347f7d136

+ 40 - 15
packages/ckeditor5-engine/docs/framework/guides/deep-dive/schema.md

@@ -44,48 +44,73 @@ While this would be incorrect:
 </$root>
 </$root>
 ```
 ```
 
 
-## Declaring as a limit element
+## Defining additional semantics
 
 
-Consider a feature like an image caption. The caption text area should construct a boundary to some internal actions.
+In addition to setting allowed structures, the schema can also define additional traits of model elements. By using the `is*` properties a feature author may declare how a certain element should be treated by other features and the engine.
 
 
- - A selection that starts inside should not end outside.
- - Pressing <kbd>Backspace</kbd> or <kbd>Delete</kbd> should not delete the area. Pressing <kbd>Enter</kbd> should not split the area.
+### Limit elements
 
 
- It should also act as a boundary for external actions:
+Consider a feature like an image caption. The caption text area should construct a boundary to some internal actions:
 
 
- - A selection that starts outside, should not end inside.
+* A selection that starts inside should not end outside.
+* Pressing <kbd>Backspace</kbd> or <kbd>Delete</kbd> should not delete the area. Pressing <kbd>Enter</kbd> should not split the area.
+
+It should also act as a boundary for external actions. This is mostly enforced by a selection post-fixer that ensures that a selection that starts outside, should not end inside. That means that most actions will either apply to the "outside" of such an element or to a content inside it.
+
+Taken these characteristics, the image caption should be defined as limit element by using the {@link module:engine/model/schema~SchemaItemDefinition#isLimit `isLimit`} property.
 
 
 ```js
 ```js
 schema.register( 'myCaption', {
 schema.register( 'myCaption', {
-    isLimit: true
+	isLimit: true
 } );
 } );
 ```
 ```
 
 
-{@link module:engine/model/schema~SchemaItemDefinition#isLimit `isLimit`} makes the engine construct such boundaries, and let {@link module:engine/model/utils/selection-post-fixer `selection-post-fixer`} update the user's selection if needed.
+The engine and various features then check it via {@link module:engine/model/schema~Schema#isLimit `Schema#isLimit()`} and can act accordingly.
 
 
 <info-box>
 <info-box>
-    "Limit element" does not mean "editable element". The concept of "editability" is reserved for the view and expressed by {@link module:engine/view/editableelement~EditableElement `EditableElement` class}.
+	"Limit element" does not mean "editable element". The concept of "editability" is reserved for the view and expressed by the {@link module:engine/view/editableelement~EditableElement `EditableElement` class}.
 </info-box>
 </info-box>
 
 
-## Declaring as a self-sufficient object
+### Object elements
 
 
 For the image caption as in the example above it does not make much sense to select the caption box, then copy or drag it somewhere else.
 For the image caption as in the example above it does not make much sense to select the caption box, then copy or drag it somewhere else.
-A caption without the image it describes does not make much sense. However, the image is more self-sufficient. Most likely users should be able to select the entire image (with all its internals), then copy or move it around. {@link module:engine/model/schema~SchemaItemDefinition#isObject `isObject`} should be used to mark such behavior.
+
+A caption without the image that it describes does not make much sense. However, the image is more self-sufficient. Most likely users should be able to select the entire image (with all its internals), then copy or move it around. {@link module:engine/model/schema~SchemaItemDefinition#isObject `isObject`} should be used to mark such behavior.
 
 
 ```js
 ```js
 schema.register( 'myImage', {
 schema.register( 'myImage', {
-    isObject: true
+	isObject: true
 } );
 } );
 ```
 ```
 
 
-Every "object" is also a "limit" element. 
+The {@link module:engine/model/schema~Schema#isObject `Schema#isObject()`} can later be used to check this property.
 
 
 <info-box>
 <info-box>
-    It means for every element with `isObject` set to `true`, {@link module:engine/model/schema~Schema#isLimit `schema.isLimit( element )`} will always return `true`. 
+	Every "object" is also a "limit" element.
 
 
-    However, {@link module:engine/model/schema~Schema#getDefinition `schema.getDefinition( 'element' )`} may return `false` in a case when `{ isLimit: true, isObject: true}` was registered.
+	It means that for every element with `isObject` set to `true`, {@link module:engine/model/schema~Schema#isLimit `Schema#isLimit( element )`} will always return `true`.
+
+	However, {@link module:engine/model/schema~Schema#getDefinition `Schema#getDefinition( 'element' )`} may return `false` in a case when `{ isLimit: true, isObject: true}` was registered.
 </info-box>
 </info-box>
 
 
+### Block elements
+
+Generally speaking, content is usually made out of blocks like paragraphs, list items, images, headings, etc. All these elements should be marked as blocks by using {@link module:engine/model/schema~SchemaItemDefinition#isBlock `isBlock`}.
+
+It is important to remember that a block should not allow another block inside. Container elements like `<blockQuote>` which can contain other block elements should not be marked as blocks.
+
+<info-box>
+	There is also the `$block` generic item which has `isBlock` set to `true`. Most block type items will inherit from `$block` (through `inheritAllFrom`).
+</info-box>
+
+### Inline elements
+
+In the editor, all HTML formatting elements such as `<strong>` or `<code>` are represented by text attributes. Therefore, inline model elements are not to be used for this scenarios.
+
+Currently, the {@link module:engine/model/schema~SchemaItemDefinition#isInline `isInline`} property is used for the `$text` token (so, text nodes) and elements such as `<softBreak>` or placeholder elements such as in the {@link framework/guides/tutorials/implementing-an-inline-widget Implementing an inline widget} tutorial.
+
+The support for inline elements in CKEditor 5 is so far limited to self-contained elements. This is &mdash; all elements marked with `isInline` should also be marked with `isObject`.
+
 ## Generic items
 ## Generic items
 
 
 There are three basic generic items: `$root`, `$block` and `$text`. They are defined as follows:
 There are three basic generic items: `$root`, `$block` and `$text`. They are defined as follows:

+ 49 - 38
packages/ckeditor5-engine/src/model/schema.js

@@ -210,6 +210,9 @@ export default class Schema {
 	 *		const paragraphElement = writer.createElement( 'paragraph' );
 	 *		const paragraphElement = writer.createElement( 'paragraph' );
 	 *		schema.isBlock( paragraphElement ); // -> true
 	 *		schema.isBlock( paragraphElement ); // -> true
 	 *
 	 *
+	 * See the {@glink framework/guides/deep-dive/schema#block-elements Block elements} section of the "Schema" deep dive}
+	 * guide for more details.
+	 *
 	 * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item
 	 * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item
 	 */
 	 */
 	isBlock( item ) {
 	isBlock( item ) {
@@ -219,8 +222,8 @@ export default class Schema {
 	}
 	}
 
 
 	/**
 	/**
-	 * Returns `true` if the given item is should be treated as a limit element.
-	 * If it should act as a boundary between actions inside and outside.
+	 * Returns `true` if the given item should be treated as a limit element.
+	 *
 	 * It considers the item to be a limit element if its
 	 * It considers the item to be a limit element if its
 	 * {@link module:engine/model/schema~SchemaItemDefinition}'s
 	 * {@link module:engine/model/schema~SchemaItemDefinition}'s
 	 * {@link module:engine/model/schema~SchemaItemDefinition#isLimit `isLimit`} or
 	 * {@link module:engine/model/schema~SchemaItemDefinition#isLimit `isLimit`} or
@@ -232,14 +235,8 @@ export default class Schema {
 	 *		schema.isLimit( editor.model.document.getRoot() ); // -> true
 	 *		schema.isLimit( editor.model.document.getRoot() ); // -> true
 	 *		schema.isLimit( 'image' ); // -> true
 	 *		schema.isLimit( 'image' ); // -> true
 	 *
 	 *
-	 * See the {@glink framework/guides/deep-dive/schema "Schema" deep dive} guide.
-	 *
-	 * It considers `isObject` with higher priority than `isLimit`. Meaning, even if
-	 * `isLimit` was explicitly  set to `false` in `SchemaItemDefinition`, but `isObject` was set to `true`,
-	 * `isLimit()` will return `true`.
-	 *
-	 * **Note**: In the above scenario {@link module:engine/model/schema~Schema#getDefinition `schema.getDefinition( item ).isLimit`}
-	 * will be `false`, to match the exact definition given.
+	 * See the {@glink framework/guides/deep-dive/schema#limit-elements Limit elements} section of the "Schema" deep dive}
+	 * guide for more details.
 	 *
 	 *
 	 * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item
 	 * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item
 	 */
 	 */
@@ -255,7 +252,7 @@ export default class Schema {
 
 
 	/**
 	/**
 	 * Returns `true` if the given item is should be treated as an object element.
 	 * Returns `true` if the given item is should be treated as an object element.
-	 * If it should act as a self-sufficient element.
+	 *
 	 * It considers the item to be an object element if its
 	 * It considers the item to be an object element if its
 	 * {@link module:engine/model/schema~SchemaItemDefinition}'s
 	 * {@link module:engine/model/schema~SchemaItemDefinition}'s
 	 * {@link module:engine/model/schema~SchemaItemDefinition#isObject `isObject`} property
 	 * {@link module:engine/model/schema~SchemaItemDefinition#isObject `isObject`} property
@@ -267,7 +264,8 @@ export default class Schema {
 	 *		const imageElement = writer.createElement( 'image' );
 	 *		const imageElement = writer.createElement( 'image' );
 	 *		schema.isObject( imageElement ); // -> true
 	 *		schema.isObject( imageElement ); // -> true
 	 *
 	 *
-	 * See the {@glink framework/guides/deep-dive/schema "Schema" deep dive} guide.
+	 * See the {@glink framework/guides/deep-dive/schema#object-elements Object elements} section of the "Schema" deep dive}
+	 * guide for more details.
 	 *
 	 *
 	 * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item
 	 * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item
 	 */
 	 */
@@ -287,6 +285,9 @@ export default class Schema {
 	 *		const text = writer.createText('foo' );
 	 *		const text = writer.createText('foo' );
 	 *		schema.isInline( text ); // -> true
 	 *		schema.isInline( text ); // -> true
 	 *
 	 *
+	 * See the {@glink framework/guides/deep-dive/schema#inline-elements Inline elements} section of the "Schema" deep dive}
+	 * guide for more details.
+	 *
 	 * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item
 	 * @param {module:engine/model/item~Item|module:engine/model/schema~SchemaContextItem|String} item
 	 */
 	 */
 	isInline( item ) {
 	isInline( item ) {
@@ -1018,34 +1019,35 @@ mix( Schema, ObservableMixin );
  *
  *
  * You can define the following rules:
  * You can define the following rules:
  *
  *
- * * {@link #allowIn `allowIn`} &ndash; Defines in which other items this item will be allowed.
- * * {@link #allowAttributes `allowAttributes`} &ndash; Defines allowed attributes of the given item.
- * * {@link #allowContentOf `allowContentOf`} &ndash; Inherits "allowed children" from other items.
- * * {@link #allowWhere `allowWhere`} &ndash; Inherits "allowed in" from other items.
- * * {@link #allowAttributesOf `allowAttributesOf`} &ndash; Inherits attributes from other items.
- * * {@link #inheritTypesFrom `inheritTypesFrom`} &ndash; Inherits `is*` properties of other items.
- * * {@link #inheritAllFrom `inheritAllFrom`} &ndash; A shorthand for `allowContentOf`, `allowWhere`,
- * `allowAttributesOf`, `inheritTypesFrom`.
- * * Additionally, you can define the following `is*` properties: `isBlock`, `isLimit`, `isObject`, `isInline`. Read about them below.
+ * * {@link ~SchemaItemDefinition#allowIn `allowIn`} &ndash; Defines in which other items this item will be allowed.
+ * * {@link ~SchemaItemDefinition#allowAttributes `allowAttributes`} &ndash; Defines allowed attributes of the given item.
+ * * {@link ~SchemaItemDefinition#allowContentOf `allowContentOf`} &ndash; Inherits "allowed children" from other items.
+ * * {@link ~SchemaItemDefinition#allowWhere `allowWhere`} &ndash; Inherits "allowed in" from other items.
+ * * {@link ~SchemaItemDefinition#allowAttributesOf `allowAttributesOf`} &ndash; Inherits attributes from other items.
+ * * {@link ~SchemaItemDefinition#inheritTypesFrom `inheritTypesFrom`} &ndash; Inherits `is*` properties of other items.
+ * * {@link ~SchemaItemDefinition#inheritAllFrom `inheritAllFrom`} &ndash;
+ * A shorthand for `allowContentOf`, `allowWhere`, `allowAttributesOf`, `inheritTypesFrom`.
  *
  *
- * # The is* properties
+ * # The `is*` properties
  *
  *
- * There are 4 commonly used `is*` properties. Their role is to assign additional semantics to schema items.
+ * There are a couple commonly used `is*` properties. Their role is to assign additional semantics to schema items.
  * You can define more properties but you will also need to implement support for them in the existing editor features.
  * You can define more properties but you will also need to implement support for them in the existing editor features.
  *
  *
- * * {@link #isBlock `isBlock`} &ndash; Whether this item is paragraph-like. Generally speaking, content is usually made out of blocks
- * like paragraphs, list items, images, headings, etc. All these elements are marked as blocks. A block
- * should not allow another block inside. Note: There is also the `$block` generic item which has `isBlock` set to `true`.
- * Most block type items will inherit from `$block` (through `inheritAllFrom`).
- * * {@link #isInline `isInline`} &ndash; Whether an item is "text-like" and should be treated as an inline node.
+ * * {@link ~SchemaItemDefinition#isBlock `isBlock`} &ndash; Whether this item is paragraph-like.
+ * Generally speaking, content is usually made out of blocks like paragraphs, list items, images, headings, etc.
+ * * {@link ~SchemaItemDefinition#isInline `isInline`} &ndash; Whether an item is "text-like" and should be treated as an inline node.
  * Examples of inline elements: `$text`, `softBreak` (`<br>`), etc.
  * Examples of inline elements: `$text`, `softBreak` (`<br>`), etc.
- * * {@link #isLimit `isLimit`} &ndash; It can be understood as whether this element should not be split by <kbd>Enter</kbd>.
- * Examples of limit elements: `$root`, table cell, image caption, etc. In other words, all actions that happen inside
- * a limit element are limited to its content. **Note:** All objects (`isObject`) are treated as limit elements, too.
- * * {@link #isObject `isObject`} &ndash; Whether an item is "self-contained" and should be treated as a whole.
- * Examples of object elements: `image`, `table`, `video`, etc. **Note:** An object is also a limit, so
+ * * {@link ~SchemaItemDefinition#isLimit `isLimit`} &ndash; It can be understood as whether this element
+ * should not be split by <kbd>Enter</kbd>. Examples of limit elements: `$root`, table cell, image caption, etc.
+ * In other words, all actions that happen inside a limit element are limited to its content.
+ * All objects are treated as limit elements, too.
+ * * {@link ~SchemaItemDefinition#isObject `isObject`} &ndash; Whether an item is "self-contained" and should be treated as a whole.
+ * Examples of object elements: `image`, `table`, `video`, etc. An object is also a limit, so
  * {@link module:engine/model/schema~Schema#isLimit `isLimit()`} returns `true` for object elements automatically.
  * {@link module:engine/model/schema~Schema#isLimit `isLimit()`} returns `true` for object elements automatically.
  *
  *
+ * Read more about the meaning of these types in the
+ * {@glink framework/guides/deep-dive/schema#defining-additional-semantics Dedicated section of the "Schema" deep dive} guide.
+ *
  * # Generic items
  * # Generic items
  *
  *
  * There are three basic generic items: `$root`, `$block` and `$text`.
  * There are three basic generic items: `$root`, `$block` and `$text`.
@@ -1067,7 +1069,7 @@ mix( Schema, ObservableMixin );
  * (paragraphs, lists items, headings, images) which, in turn, may contain text inside.
  * (paragraphs, lists items, headings, images) which, in turn, may contain text inside.
  *
  *
  * By inheriting from the generic items you can define new items which will get extended by other editor features.
  * By inheriting from the generic items you can define new items which will get extended by other editor features.
- * Read more about generic types in the {@glink framework/guides/deep-dive/schema Defining schema} guide.
+ * Read more about generic types in the {@glink framework/guides/deep-dive/schema Schema deep dive} guide.
  *
  *
  * # Example definitions
  * # Example definitions
  *
  *
@@ -1127,7 +1129,7 @@ mix( Schema, ObservableMixin );
  * * If you want to publish your feature so other developers can use it, try to use
  * * If you want to publish your feature so other developers can use it, try to use
  * generic items as much as possible.
  * generic items as much as possible.
  * * Keep your model clean. Limit it to the actual data and store information in a normalized way.
  * * Keep your model clean. Limit it to the actual data and store information in a normalized way.
- * * Remember about definining the `is*` properties. They do not affect the allowed structures, but they can
+ * * Remember about defining the `is*` properties. They do not affect the allowed structures, but they can
  * affect how the editor features treat your elements.
  * affect how the editor features treat your elements.
  *
  *
  * @typedef {Object} module:engine/model/schema~SchemaItemDefinition
  * @typedef {Object} module:engine/model/schema~SchemaItemDefinition
@@ -1145,17 +1147,25 @@ mix( Schema, ObservableMixin );
  * like paragraphs, list items, images, headings, etc. All these elements are marked as blocks. A block
  * like paragraphs, list items, images, headings, etc. All these elements are marked as blocks. A block
  * should not allow another block inside. Note: There is also the `$block` generic item which has `isBlock` set to `true`.
  * should not allow another block inside. Note: There is also the `$block` generic item which has `isBlock` set to `true`.
  * Most block type items will inherit from `$block` (through `inheritAllFrom`).
  * Most block type items will inherit from `$block` (through `inheritAllFrom`).
+ *
+ * Read more about the block elements in the
+ * {@glink framework/guides/deep-dive/schema#block-elements Block elements} section of the "Schema" deep dive} guide.
+ *
  * @property {Boolean} isInline
  * @property {Boolean} isInline
  * Whether an item is "text-like" and should be treated as an inline node. Examples of inline elements:
  * Whether an item is "text-like" and should be treated as an inline node. Examples of inline elements:
  * `$text`, `softBreak` (`<br>`), etc.
  * `$text`, `softBreak` (`<br>`), etc.
+ *
+ * Read more about the inline elements in the
+ * {@glink framework/guides/deep-dive/schema#inline-elements Inline elements} section of the "Schema" deep dive} guide.
+ *
  * @property {Boolean} isLimit
  * @property {Boolean} isLimit
  * It can be understood as whether this element should not be split by <kbd>Enter</kbd>.
  * It can be understood as whether this element should not be split by <kbd>Enter</kbd>.
  * Examples of limit elements: `$root`, table cell, image caption, etc. In other words, all actions that happen inside
  * Examples of limit elements: `$root`, table cell, image caption, etc. In other words, all actions that happen inside
  * a limit element are limited to its content.
  * a limit element are limited to its content.
  *
  *
- * **Note:** All objects (`isObject`) are treated as limit elements, too.
+ * Read more about the limit elements in the
+ * {@glink framework/guides/deep-dive/schema#limit-elements Limit elements} section of the "Schema" deep dive} guide.
  *
  *
- * See the {@glink framework/guides/deep-dive/schema#declaring-as-a-limit-element Dedicated section in "Schema" deep dive} guide.
  * @property {Boolean} isObject
  * @property {Boolean} isObject
  * Whether an item is "self-contained" and should be treated as a whole. Examples of object elements:
  * Whether an item is "self-contained" and should be treated as a whole. Examples of object elements:
  * `image`, `table`, `video`, etc.
  * `image`, `table`, `video`, etc.
@@ -1163,7 +1173,8 @@ mix( Schema, ObservableMixin );
  * **Note:** An object is also a limit, so
  * **Note:** An object is also a limit, so
  * {@link module:engine/model/schema~Schema#isLimit `isLimit()`} returns `true` for object elements automatically.
  * {@link module:engine/model/schema~Schema#isLimit `isLimit()`} returns `true` for object elements automatically.
  *
  *
- * See the {@glink framework/guides/deep-dive/schema#declaring-as-a-self-sufficient-object Dedicated section in "Schema" deep dive} guide.
+ * Read more about the object elements in the
+ * {@glink framework/guides/deep-dive/schema#object-elements Object elements} section of the "Schema" deep dive} guide.
  */
  */
 
 
 /**
 /**