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>
 ```
 
-## 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
 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>
-    "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>
 
-## 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.
-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
 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>
-    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>
 
+### 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
 
 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' );
 	 *		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
 	 */
 	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
 	 * {@link module:engine/model/schema~SchemaItemDefinition}'s
 	 * {@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( '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
 	 */
@@ -255,7 +252,7 @@ export default class Schema {
 
 	/**
 	 * 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
 	 * {@link module:engine/model/schema~SchemaItemDefinition}'s
 	 * {@link module:engine/model/schema~SchemaItemDefinition#isObject `isObject`} property
@@ -267,7 +264,8 @@ export default class Schema {
 	 *		const imageElement = writer.createElement( 'image' );
 	 *		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
 	 */
@@ -287,6 +285,9 @@ export default class Schema {
 	 *		const text = writer.createText('foo' );
 	 *		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
 	 */
 	isInline( item ) {
@@ -1018,34 +1019,35 @@ mix( Schema, ObservableMixin );
  *
  * 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.
  *
- * * {@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.
- * * {@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.
  *
+ * 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
  *
  * 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.
  *
  * 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
  *
@@ -1127,7 +1129,7 @@ mix( Schema, ObservableMixin );
  * * If you want to publish your feature so other developers can use it, try to use
  * generic items as much as possible.
  * * 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.
  *
  * @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
  * 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`).
+ *
+ * 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
  * Whether an item is "text-like" and should be treated as an inline node. Examples of inline elements:
  * `$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
  * 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.
+ * 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
  * Whether an item is "self-contained" and should be treated as a whole. Examples of object elements:
  * `image`, `table`, `video`, etc.
@@ -1163,7 +1173,8 @@ mix( Schema, ObservableMixin );
  * **Note:** An object is also a limit, so
  * {@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.
  */
 
 /**