@ckeditor/ckeditor5-engine 41.4.2 → 42.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +6 -0
  2. package/dist/index.js +15151 -13052
  3. package/dist/index.js.map +1 -1
  4. package/dist/types/controller/datacontroller.d.ts +1 -1
  5. package/dist/types/controller/editingcontroller.d.ts +1 -1
  6. package/dist/types/conversion/downcastdispatcher.d.ts +1 -1
  7. package/dist/types/conversion/mapper.d.ts +1 -1
  8. package/dist/types/conversion/upcastdispatcher.d.ts +1 -1
  9. package/dist/types/index.d.ts +2 -1
  10. package/dist/types/model/differ.d.ts +134 -42
  11. package/dist/types/model/document.d.ts +1 -1
  12. package/dist/types/model/documentselection.d.ts +1 -1
  13. package/dist/types/model/liveposition.d.ts +1 -1
  14. package/dist/types/model/liverange.d.ts +1 -1
  15. package/dist/types/model/markercollection.d.ts +2 -2
  16. package/dist/types/model/model.d.ts +1 -1
  17. package/dist/types/model/schema.d.ts +32 -6
  18. package/dist/types/model/selection.d.ts +1 -1
  19. package/dist/types/view/document.d.ts +1 -1
  20. package/dist/types/view/documentfragment.d.ts +1 -1
  21. package/dist/types/view/documentselection.d.ts +1 -1
  22. package/dist/types/view/domconverter.d.ts +9 -0
  23. package/dist/types/view/editableelement.d.ts +1 -1
  24. package/dist/types/view/node.d.ts +1 -1
  25. package/dist/types/view/observer/observer.d.ts +1 -1
  26. package/dist/types/view/renderer.d.ts +1 -1
  27. package/dist/types/view/selection.d.ts +1 -1
  28. package/dist/types/view/view.d.ts +1 -1
  29. package/package.json +2 -2
  30. package/src/controller/datacontroller.d.ts +1 -1
  31. package/src/controller/datacontroller.js +1 -1
  32. package/src/controller/editingcontroller.d.ts +1 -1
  33. package/src/controller/editingcontroller.js +1 -1
  34. package/src/conversion/downcastdispatcher.d.ts +1 -1
  35. package/src/conversion/downcastdispatcher.js +1 -1
  36. package/src/conversion/mapper.d.ts +1 -1
  37. package/src/conversion/mapper.js +1 -1
  38. package/src/conversion/upcastdispatcher.d.ts +1 -1
  39. package/src/conversion/upcastdispatcher.js +1 -1
  40. package/src/index.d.ts +2 -1
  41. package/src/index.js +1 -0
  42. package/src/model/differ.d.ts +134 -42
  43. package/src/model/differ.js +247 -125
  44. package/src/model/document.d.ts +1 -1
  45. package/src/model/document.js +1 -1
  46. package/src/model/documentselection.d.ts +1 -1
  47. package/src/model/documentselection.js +1 -1
  48. package/src/model/liveposition.d.ts +1 -1
  49. package/src/model/liveposition.js +1 -1
  50. package/src/model/liverange.d.ts +1 -1
  51. package/src/model/liverange.js +1 -1
  52. package/src/model/markercollection.d.ts +2 -2
  53. package/src/model/markercollection.js +2 -2
  54. package/src/model/model.d.ts +1 -1
  55. package/src/model/model.js +1 -1
  56. package/src/model/schema.d.ts +32 -6
  57. package/src/model/schema.js +208 -101
  58. package/src/model/selection.d.ts +1 -1
  59. package/src/model/selection.js +1 -1
  60. package/src/view/document.d.ts +1 -1
  61. package/src/view/document.js +1 -1
  62. package/src/view/documentfragment.d.ts +1 -1
  63. package/src/view/documentfragment.js +1 -1
  64. package/src/view/documentselection.d.ts +1 -1
  65. package/src/view/documentselection.js +1 -1
  66. package/src/view/domconverter.d.ts +9 -0
  67. package/src/view/domconverter.js +27 -5
  68. package/src/view/editableelement.d.ts +1 -1
  69. package/src/view/editableelement.js +1 -1
  70. package/src/view/node.d.ts +1 -1
  71. package/src/view/node.js +1 -1
  72. package/src/view/observer/observer.d.ts +1 -1
  73. package/src/view/observer/observer.js +1 -1
  74. package/src/view/renderer.d.ts +1 -1
  75. package/src/view/renderer.js +1 -1
  76. package/src/view/selection.d.ts +1 -1
  77. package/src/view/selection.js +1 -1
  78. package/src/view/view.d.ts +1 -1
  79. package/src/view/view.js +1 -1
@@ -20,7 +20,7 @@ import { CKEditorError, EmitterMixin } from '@ckeditor/ckeditor5-utils';
20
20
  * have to be unbound.
21
21
  * Use {@link module:engine/model/liveposition~LivePosition#detach} whenever you don't need `LivePosition` anymore.
22
22
  */
23
- export default class LivePosition extends EmitterMixin(Position) {
23
+ export default class LivePosition extends /* #__PURE__ */ EmitterMixin(Position) {
24
24
  /**
25
25
  * Creates a live position.
26
26
  *
@@ -19,7 +19,7 @@ declare const LiveRange_base: import("@ckeditor/ckeditor5-utils").Mixed<typeof R
19
19
  * **Note:** Be very careful when dealing with `LiveRange`. Each `LiveRange` instance bind events that might
20
20
  * have to be unbound. Use {@link module:engine/model/liverange~LiveRange#detach detach} whenever you don't need `LiveRange` anymore.
21
21
  */
22
- export default class LiveRange extends LiveRange_base {
22
+ export default class LiveRange extends /* #__PURE__ */ LiveRange_base {
23
23
  /**
24
24
  * Creates a live range.
25
25
  *
@@ -15,7 +15,7 @@ import { EmitterMixin } from '@ckeditor/ckeditor5-utils';
15
15
  * **Note:** Be very careful when dealing with `LiveRange`. Each `LiveRange` instance bind events that might
16
16
  * have to be unbound. Use {@link module:engine/model/liverange~LiveRange#detach detach} whenever you don't need `LiveRange` anymore.
17
17
  */
18
- export default class LiveRange extends EmitterMixin(Range) {
18
+ export default class LiveRange extends /* #__PURE__ */ EmitterMixin(Range) {
19
19
  /**
20
20
  * Creates a live range.
21
21
  *
@@ -27,7 +27,7 @@ declare const MarkerCollection_base: {
27
27
  *
28
28
  * @see module:engine/model/markercollection~Marker
29
29
  */
30
- export default class MarkerCollection extends MarkerCollection_base implements Iterable<Marker> {
30
+ export default class MarkerCollection extends /* #__PURE__ */ MarkerCollection_base implements Iterable<Marker> {
31
31
  /**
32
32
  * Stores {@link ~Marker markers} added to the collection.
33
33
  */
@@ -205,7 +205,7 @@ declare const Marker_base: import("@ckeditor/ckeditor5-utils").Mixed<typeof Type
205
205
  *
206
206
  * `Marker` instances are created and destroyed only by {@link ~MarkerCollection MarkerCollection}.
207
207
  */
208
- declare class Marker extends Marker_base {
208
+ declare class Marker extends /* #__PURE__ */ Marker_base {
209
209
  /**
210
210
  * Marker's name.
211
211
  */
@@ -22,7 +22,7 @@ import { CKEditorError, EmitterMixin } from '@ckeditor/ckeditor5-utils';
22
22
  *
23
23
  * @see module:engine/model/markercollection~Marker
24
24
  */
25
- export default class MarkerCollection extends EmitterMixin() {
25
+ export default class MarkerCollection extends /* #__PURE__ */ EmitterMixin() {
26
26
  constructor() {
27
27
  super(...arguments);
28
28
  /**
@@ -282,7 +282,7 @@ export default class MarkerCollection extends EmitterMixin() {
282
282
  *
283
283
  * `Marker` instances are created and destroyed only by {@link ~MarkerCollection MarkerCollection}.
284
284
  */
285
- class Marker extends EmitterMixin(TypeCheckable) {
285
+ class Marker extends /* #__PURE__ */ EmitterMixin(TypeCheckable) {
286
286
  /**
287
287
  * Creates a marker instance.
288
288
  *
@@ -28,7 +28,7 @@ declare const Model_base: {
28
28
  * Editor's data model. Read about the model in the
29
29
  * {@glink framework/architecture/editing-engine engine architecture} guide.
30
30
  */
31
- export default class Model extends Model_base {
31
+ export default class Model extends /* #__PURE__ */ Model_base {
32
32
  /**
33
33
  * Model's marker collection.
34
34
  */
@@ -30,7 +30,7 @@ import { CKEditorError, ObservableMixin } from '@ckeditor/ckeditor5-utils';
30
30
  * Editor's data model. Read about the model in the
31
31
  * {@glink framework/architecture/editing-engine engine architecture} guide.
32
32
  */
33
- export default class Model extends ObservableMixin() {
33
+ export default class Model extends /* #__PURE__ */ ObservableMixin() {
34
34
  // @if CK_DEBUG_ENGINE // private _operationLogs: Array<string>;
35
35
  // @if CK_DEBUG_ENGINE // private _appliedOperations: Array<Operation>;
36
36
  constructor() {
@@ -31,7 +31,7 @@ declare const Schema_base: {
31
31
  * {@glink framework/architecture/editing-engine Introduction to the Editing engine architecture} guide.
32
32
  * * The {@glink framework/deep-dive/schema Schema deep-dive} guide.
33
33
  */
34
- export default class Schema extends Schema_base {
34
+ export default class Schema extends /* #__PURE__ */ Schema_base {
35
35
  private readonly _sourceDefinitions;
36
36
  /**
37
37
  * A dictionary containing attribute properties.
@@ -673,9 +673,15 @@ export type SchemaCheckAttributeEvent = {
673
673
  * * {@link ~SchemaItemDefinition#allowIn `allowIn`} &ndash; Defines in which other items this item will be allowed.
674
674
  * * {@link ~SchemaItemDefinition#allowChildren `allowChildren`} &ndash; Defines which other items are allowed inside this item.
675
675
  * * {@link ~SchemaItemDefinition#allowAttributes `allowAttributes`} &ndash; Defines allowed attributes of the given item.
676
- * * {@link ~SchemaItemDefinition#allowContentOf `allowContentOf`} &ndash; Inherits "allowed children" from other items.
677
- * * {@link ~SchemaItemDefinition#allowWhere `allowWhere`} &ndash; Inherits "allowed in" from other items.
678
- * * {@link ~SchemaItemDefinition#allowAttributesOf `allowAttributesOf`} &ndash; Inherits attributes from other items.
676
+ * * {@link ~SchemaItemDefinition#disallowIn `disallowIn`} &ndash; Defines in which other items this item will be disallowed.
677
+ * * {@link ~SchemaItemDefinition#disallowChildren `disallowChildren`} &ndash; Defines which other items are disallowed inside this item.
678
+ * * {@link ~SchemaItemDefinition#disallowAttributes `disallowAttributes`} &ndash; Defines disallowed attributes of the given item.
679
+ * * {@link ~SchemaItemDefinition#allowContentOf `allowContentOf`} &ndash; Makes this item allow children that are also allowed in the
680
+ * specified items. This acknowledges disallow rules.
681
+ * * {@link ~SchemaItemDefinition#allowWhere `allowWhere`} &ndash; Makes this item allowed where the specified items are allowed. This
682
+ * acknowledges disallow rules.
683
+ * * {@link ~SchemaItemDefinition#allowAttributesOf `allowAttributesOf`} &ndash; Inherits attributes from other items. This acknowledges
684
+ * disallow rules.
679
685
  * * {@link ~SchemaItemDefinition#inheritTypesFrom `inheritTypesFrom`} &ndash; Inherits `is*` properties of other items.
680
686
  * * {@link ~SchemaItemDefinition#inheritAllFrom `inheritAllFrom`} &ndash;
681
687
  * A shorthand for `allowContentOf`, `allowWhere`, `allowAttributesOf`, `inheritTypesFrom`.
@@ -683,7 +689,6 @@ export type SchemaCheckAttributeEvent = {
683
689
  * # The `is*` properties
684
690
  *
685
691
  * There are a couple commonly used `is*` properties. Their role is to assign additional semantics to schema items.
686
- * You can define more properties but you will also need to implement support for them in the existing editor features.
687
692
  *
688
693
  * * {@link ~SchemaItemDefinition#isBlock `isBlock`} &ndash; Whether this item is paragraph-like.
689
694
  * Generally speaking, content is usually made out of blocks like paragraphs, list items, images, headings, etc.
@@ -804,6 +809,15 @@ export type SchemaCheckAttributeEvent = {
804
809
  * } );
805
810
  * ```
806
811
  *
812
+ * Register `inlineImage` as a kind of an inline object but disallow it inside captions:
813
+ *
814
+ * ```ts
815
+ * schema.register( 'imageInline', {
816
+ * inheritAllFrom: '$inlineObject',
817
+ * disallowIn: [ 'caption' ]
818
+ * } );
819
+ * ```
820
+ *
807
821
  * Make `listItem` inherit all from `$block` but also allow additional attributes:
808
822
  *
809
823
  * ```ts
@@ -847,6 +861,18 @@ export interface SchemaItemDefinition {
847
861
  * Defines allowed attributes of the given item.
848
862
  */
849
863
  allowAttributes?: string | Array<string>;
864
+ /**
865
+ * Defines in which other items this item will be disallowed. Takes precedence over allow rules.
866
+ */
867
+ disallowIn?: string | Array<string>;
868
+ /**
869
+ * Defines which other items are disallowed inside this item. Takes precedence over allow rules.
870
+ */
871
+ disallowChildren?: string | Array<string>;
872
+ /**
873
+ * Defines disallowed attributes for this item. Takes precedence over allow rules.
874
+ */
875
+ disallowAttributes?: string | Array<string>;
850
876
  /**
851
877
  * Inherits "allowed children" from other items.
852
878
  */
@@ -856,7 +882,7 @@ export interface SchemaItemDefinition {
856
882
  */
857
883
  allowWhere?: string | Array<string>;
858
884
  /**
859
- * Inherits attributes from other items.
885
+ * Inherits "allowed attributes" from other items.
860
886
  */
861
887
  allowAttributesOf?: string | Array<string>;
862
888
  /**
@@ -24,7 +24,7 @@ import { CKEditorError, first, ObservableMixin } from '@ckeditor/ckeditor5-utils
24
24
  * {@glink framework/architecture/editing-engine Introduction to the Editing engine architecture} guide.
25
25
  * * The {@glink framework/deep-dive/schema Schema deep-dive} guide.
26
26
  */
27
- export default class Schema extends ObservableMixin() {
27
+ export default class Schema extends /* #__PURE__ */ ObservableMixin() {
28
28
  /**
29
29
  * Creates a schema instance.
30
30
  */
@@ -812,31 +812,54 @@ export default class Schema extends ObservableMixin() {
812
812
  this._compiledDefinitions = null;
813
813
  }
814
814
  _compile() {
815
- const compiledDefinitions = {};
815
+ const definitions = {};
816
816
  const sourceRules = this._sourceDefinitions;
817
817
  const itemNames = Object.keys(sourceRules);
818
818
  for (const itemName of itemNames) {
819
- compiledDefinitions[itemName] = compileBaseItemRule(sourceRules[itemName], itemName);
819
+ definitions[itemName] = compileBaseItemRule(sourceRules[itemName], itemName);
820
820
  }
821
- for (const itemName of itemNames) {
822
- compileAllowChildren(compiledDefinitions, itemName);
821
+ const items = Object.values(definitions);
822
+ // Sometimes features add rules (allows, disallows) for items that has not been registered yet. We allow that, to make it easier
823
+ // to put the schema together. However, sometimes these items are never registered. To prevent operating
824
+ // removeUnregisteredEntries( definitions, items );
825
+ // 1. Propagate `childItem.allowIn` to `parentItem.allowChildren` and vice versa, so that these properties are completely mirrored
826
+ // for all children and parents. Do the same for `disallowIn` and `disallowChildren`.
827
+ for (const item of items) {
828
+ propagateAllowIn(definitions, item);
829
+ propagateAllowChildren(definitions, item);
830
+ propagateDisallowIn(definitions, item);
831
+ propagateDisallowChildren(definitions, item);
823
832
  }
824
- for (const itemName of itemNames) {
825
- compileAllowContentOf(compiledDefinitions, itemName);
833
+ // 2. Remove from `allowIn` and `allowChildren` these items which where disallowed by `disallowIn` and `disallowChildren`.
834
+ // Do the same for attributes. Now we have a clear situation where which item/attribute is allowed. Inheritance is in next steps.
835
+ for (const item of items) {
836
+ resolveDisallows(definitions, item);
826
837
  }
827
- for (const itemName of itemNames) {
828
- compileAllowWhere(compiledDefinitions, itemName);
838
+ // 3. Compile `item.allowContentOf` property. For each entry in `allowContentOf`, we want to take `allowChildren` and rewrite
839
+ // them into `item.allowChildren`. `item.disallowChildren` is used to filter out some entries. This way "own rules" have higher
840
+ // priority than "inherited rules". Mirroring from step 1. is maintained.
841
+ for (const item of items) {
842
+ compileAllowContentOf(definitions, item);
829
843
  }
830
- for (const itemName of itemNames) {
831
- compileAllowAttributesOf(compiledDefinitions, itemName);
832
- compileInheritPropertiesFrom(compiledDefinitions, itemName);
844
+ // 4. Compile `item.allowWhere` property. For each entry in `allowWhere`, we want to take `allowIn` and rewrite them into
845
+ // `item.allowIn`. `item.disallowIn` is used to filter out some entries. This way "own rules" have higher priority than
846
+ // "inherited rules". Mirroring from step 1. is maintained.
847
+ for (const item of items) {
848
+ compileAllowWhere(definitions, item);
833
849
  }
834
- for (const itemName of itemNames) {
835
- cleanUpAllowIn(compiledDefinitions, itemName);
836
- setupAllowChildren(compiledDefinitions, itemName);
837
- cleanUpAllowAttributes(compiledDefinitions, itemName);
850
+ // 5. Compile `item.allowAttributesOf`. For each entry in `allowAttributesOf`, we want to take `allowAttributes` and rewrite them
851
+ // into `item.allowAttributes`. `item.disallowAttributes` is used to filter out some entries. This way "own rules" have higher
852
+ // priority than "inherited rules".
853
+ for (const item of items) {
854
+ compileAllowAttributesOf(definitions, item);
855
+ }
856
+ // 6. Compile `item.inheritTypesFrom` property. For each entry in `inheritTypesFrom`, we want to take `is*` properties and
857
+ // set them on `item` (if they are not set yet).
858
+ for (const item of items) {
859
+ compileInheritPropertiesFrom(definitions, item);
838
860
  }
839
- this._compiledDefinitions = compiledDefinitions;
861
+ // Compile final definitions. Unnecessary properties are removed and some additional cleaning is applied.
862
+ this._compiledDefinitions = compileDefinitions(definitions);
840
863
  }
841
864
  _checkContextMatch(def, context, contextItemIndex = context.length - 1) {
842
865
  const contextItem = context.getItem(contextItemIndex);
@@ -1073,76 +1096,185 @@ export class SchemaContext {
1073
1096
  function compileBaseItemRule(sourceItemRules, itemName) {
1074
1097
  const itemRule = {
1075
1098
  name: itemName,
1076
- allowIn: [],
1077
- allowContentOf: [],
1078
- allowWhere: [],
1079
- allowAttributes: [],
1080
- allowAttributesOf: [],
1081
- allowChildren: [],
1082
- inheritTypesFrom: []
1099
+ allowIn: new Set(),
1100
+ allowChildren: new Set(),
1101
+ disallowIn: new Set(),
1102
+ disallowChildren: new Set(),
1103
+ allowContentOf: new Set(),
1104
+ allowWhere: new Set(),
1105
+ allowAttributes: new Set(),
1106
+ disallowAttributes: new Set(),
1107
+ allowAttributesOf: new Set(),
1108
+ inheritTypesFrom: new Set()
1083
1109
  };
1084
1110
  copyTypes(sourceItemRules, itemRule);
1085
1111
  copyProperty(sourceItemRules, itemRule, 'allowIn');
1112
+ copyProperty(sourceItemRules, itemRule, 'allowChildren');
1113
+ copyProperty(sourceItemRules, itemRule, 'disallowIn');
1114
+ copyProperty(sourceItemRules, itemRule, 'disallowChildren');
1086
1115
  copyProperty(sourceItemRules, itemRule, 'allowContentOf');
1087
1116
  copyProperty(sourceItemRules, itemRule, 'allowWhere');
1088
1117
  copyProperty(sourceItemRules, itemRule, 'allowAttributes');
1118
+ copyProperty(sourceItemRules, itemRule, 'disallowAttributes');
1089
1119
  copyProperty(sourceItemRules, itemRule, 'allowAttributesOf');
1090
- copyProperty(sourceItemRules, itemRule, 'allowChildren');
1091
1120
  copyProperty(sourceItemRules, itemRule, 'inheritTypesFrom');
1092
- makeInheritAllWork(sourceItemRules, itemRule);
1121
+ resolveInheritAll(sourceItemRules, itemRule);
1093
1122
  return itemRule;
1094
1123
  }
1095
- function compileAllowChildren(compiledDefinitions, itemName) {
1096
- const item = compiledDefinitions[itemName];
1097
- for (const allowChildrenItem of item.allowChildren) {
1098
- const allowedChildren = compiledDefinitions[allowChildrenItem];
1099
- // The allowChildren property may point to an unregistered element.
1100
- if (!allowedChildren) {
1101
- continue;
1124
+ function propagateAllowIn(definitions, item) {
1125
+ for (const parentName of item.allowIn) {
1126
+ const parentItem = definitions[parentName];
1127
+ if (parentItem) {
1128
+ parentItem.allowChildren.add(item.name);
1129
+ }
1130
+ else {
1131
+ item.allowIn.delete(parentName);
1102
1132
  }
1103
- allowedChildren.allowIn.push(itemName);
1104
1133
  }
1105
- // The allowIn property already includes correct items, reset the allowChildren property
1106
- // to avoid duplicates later when setting up compilation results.
1107
- item.allowChildren.length = 0;
1108
1134
  }
1109
- function compileAllowContentOf(compiledDefinitions, itemName) {
1110
- for (const allowContentOfItemName of compiledDefinitions[itemName].allowContentOf) {
1111
- // The allowContentOf property may point to an unregistered element.
1112
- if (compiledDefinitions[allowContentOfItemName]) {
1113
- const allowedChildren = getAllowedChildren(compiledDefinitions, allowContentOfItemName);
1114
- allowedChildren.forEach(allowedItem => {
1115
- allowedItem.allowIn.push(itemName);
1116
- });
1135
+ function propagateAllowChildren(definitions, item) {
1136
+ for (const childName of item.allowChildren) {
1137
+ const childItem = definitions[childName];
1138
+ if (childItem) {
1139
+ childItem.allowIn.add(item.name);
1140
+ }
1141
+ else {
1142
+ item.allowChildren.delete(childName);
1117
1143
  }
1118
1144
  }
1119
- delete compiledDefinitions[itemName].allowContentOf;
1120
1145
  }
1121
- function compileAllowWhere(compiledDefinitions, itemName) {
1122
- for (const allowWhereItemName of compiledDefinitions[itemName].allowWhere) {
1123
- const inheritFrom = compiledDefinitions[allowWhereItemName];
1124
- // The allowWhere property may point to an unregistered element.
1125
- if (inheritFrom) {
1126
- const allowedIn = inheritFrom.allowIn;
1127
- compiledDefinitions[itemName].allowIn.push(...allowedIn);
1146
+ function propagateDisallowIn(definitions, item) {
1147
+ for (const parentName of item.disallowIn) {
1148
+ const parentItem = definitions[parentName];
1149
+ if (parentItem) {
1150
+ parentItem.disallowChildren.add(item.name);
1151
+ }
1152
+ else {
1153
+ item.disallowIn.delete(parentName);
1128
1154
  }
1129
1155
  }
1130
- delete compiledDefinitions[itemName].allowWhere;
1131
1156
  }
1132
- function compileAllowAttributesOf(compiledDefinitions, itemName) {
1133
- for (const allowAttributeOfItem of compiledDefinitions[itemName].allowAttributesOf) {
1134
- const inheritFrom = compiledDefinitions[allowAttributeOfItem];
1135
- if (inheritFrom) {
1136
- const inheritAttributes = inheritFrom.allowAttributes;
1137
- compiledDefinitions[itemName].allowAttributes.push(...inheritAttributes);
1157
+ function propagateDisallowChildren(definitions, item) {
1158
+ for (const childName of item.disallowChildren) {
1159
+ const childItem = definitions[childName];
1160
+ if (childItem) {
1161
+ childItem.disallowIn.add(item.name);
1162
+ }
1163
+ else {
1164
+ item.disallowChildren.delete(childName);
1165
+ }
1166
+ }
1167
+ }
1168
+ function resolveDisallows(definitions, item) {
1169
+ for (const childName of item.disallowChildren) {
1170
+ item.allowChildren.delete(childName);
1171
+ }
1172
+ for (const parentName of item.disallowIn) {
1173
+ item.allowIn.delete(parentName);
1174
+ }
1175
+ for (const attributeName of item.disallowAttributes) {
1176
+ item.allowAttributes.delete(attributeName);
1177
+ }
1178
+ }
1179
+ function compileAllowContentOf(definitions, item) {
1180
+ for (const allowContentOfItemName of item.allowContentOf) {
1181
+ const baseItem = definitions[allowContentOfItemName];
1182
+ if (!baseItem) {
1183
+ continue;
1184
+ }
1185
+ // Copy `disallowChildren` to propagate this "knowledge" down the inheritance chain. The inheritance may involve multiple items and
1186
+ // if this is not propagated, then items down the chain may start to allow for items that were disallowed by previous base items.
1187
+ //
1188
+ // The scenarios were it is important involves multiple inherits both on parent items side and on the child items side.
1189
+ baseItem.disallowChildren.forEach(childName => {
1190
+ // Own item's rules takes precedence before inherited.
1191
+ // If the item directly allows for given child, ignore that base item disallowed that child.
1192
+ if (item.allowChildren.has(childName)) {
1193
+ return;
1194
+ }
1195
+ item.disallowChildren.add(childName);
1196
+ definitions[childName].disallowIn.add(item.name);
1197
+ });
1198
+ // Copy `allowChildren` from the base item to allow for the same items.
1199
+ baseItem.allowChildren.forEach(childName => {
1200
+ // Own item's rules takes precedence before inherited.
1201
+ // Also, `item.disallowChildren` might get some new items during inheritance process.
1202
+ if (item.disallowChildren.has(childName)) {
1203
+ return;
1204
+ }
1205
+ item.allowChildren.add(childName);
1206
+ definitions[childName].allowIn.add(item.name);
1207
+ });
1208
+ }
1209
+ }
1210
+ function compileAllowWhere(definitions, item) {
1211
+ for (const allowWhereItemName of item.allowWhere) {
1212
+ const baseItem = definitions[allowWhereItemName];
1213
+ if (!baseItem) {
1214
+ continue;
1138
1215
  }
1216
+ // Copy `disallowIn` to propagate this "knowledge" down the inheritance chain. The inheritance may involve multiple items and
1217
+ // if this is not propagated, then items down the chain may start to be allowed in items in which they were disallowed previously.
1218
+ //
1219
+ // The scenarios were it is important involves multiple inherits both on parent items side and on the child items side.
1220
+ baseItem.disallowIn.forEach(parentName => {
1221
+ // Own item's rules takes precedence before inherited.
1222
+ // If the item is directly allowed in given parent, ignore that base item was disallowed in it.
1223
+ if (item.allowIn.has(parentName)) {
1224
+ return;
1225
+ }
1226
+ item.disallowIn.add(parentName);
1227
+ definitions[parentName].disallowChildren.add(item.name);
1228
+ });
1229
+ // Copy `allowIn` from the base item to allow item in same parents.
1230
+ baseItem.allowIn.forEach(parentName => {
1231
+ // Own item's rules takes precedence before inherited.
1232
+ // Also, `item.disallowIn` might get some new items during inheritance process.
1233
+ if (item.disallowIn.has(parentName)) {
1234
+ return;
1235
+ }
1236
+ item.allowIn.add(parentName);
1237
+ definitions[parentName].allowChildren.add(item.name);
1238
+ });
1139
1239
  }
1140
- delete compiledDefinitions[itemName].allowAttributesOf;
1141
1240
  }
1142
- function compileInheritPropertiesFrom(compiledDefinitions, itemName) {
1143
- const item = compiledDefinitions[itemName];
1144
- for (const inheritPropertiesOfItem of item.inheritTypesFrom) {
1145
- const inheritFrom = compiledDefinitions[inheritPropertiesOfItem];
1241
+ function compileDefinitions(definitions) {
1242
+ const finalDefinitions = {};
1243
+ for (const item of Object.values(definitions)) {
1244
+ finalDefinitions[item.name] = {
1245
+ name: item.name,
1246
+ // `is*` properties may not be set - convert `undefined` to `false`.
1247
+ isBlock: !!item.isBlock,
1248
+ isContent: !!item.isContent,
1249
+ isInline: !!item.isInline,
1250
+ isLimit: !!item.isLimit,
1251
+ isObject: !!item.isObject,
1252
+ isSelectable: !!item.isSelectable,
1253
+ // Filter out non-existing items.
1254
+ allowIn: Array.from(item.allowIn).filter(name => !!definitions[name]),
1255
+ allowChildren: Array.from(item.allowChildren).filter(name => !!definitions[name]),
1256
+ allowAttributes: Array.from(item.allowAttributes)
1257
+ };
1258
+ }
1259
+ return finalDefinitions;
1260
+ }
1261
+ function compileAllowAttributesOf(definitions, item) {
1262
+ for (const allowAttributeOfItemName of item.allowAttributesOf) {
1263
+ const baseItem = definitions[allowAttributeOfItemName];
1264
+ if (!baseItem) {
1265
+ return;
1266
+ }
1267
+ baseItem.allowAttributes.forEach(attributeName => {
1268
+ if (item.disallowAttributes.has(attributeName)) {
1269
+ return;
1270
+ }
1271
+ item.allowAttributes.add(attributeName);
1272
+ });
1273
+ }
1274
+ }
1275
+ function compileInheritPropertiesFrom(definitions, item) {
1276
+ for (const inheritPropertiesOfItemName of item.inheritTypesFrom) {
1277
+ const inheritFrom = definitions[inheritPropertiesOfItemName];
1146
1278
  if (inheritFrom) {
1147
1279
  const typeNames = Object.keys(inheritFrom).filter(name => name.startsWith('is'));
1148
1280
  for (const name of typeNames) {
@@ -1152,26 +1284,6 @@ function compileInheritPropertiesFrom(compiledDefinitions, itemName) {
1152
1284
  }
1153
1285
  }
1154
1286
  }
1155
- delete item.inheritTypesFrom;
1156
- }
1157
- // Remove items which weren't registered (because it may break some checks or we'd need to complicate them).
1158
- // Make sure allowIn doesn't contain repeated values.
1159
- function cleanUpAllowIn(compiledDefinitions, itemName) {
1160
- const itemRule = compiledDefinitions[itemName];
1161
- const existingItems = itemRule.allowIn.filter(itemToCheck => compiledDefinitions[itemToCheck]);
1162
- itemRule.allowIn = Array.from(new Set(existingItems));
1163
- }
1164
- // Setup allowChildren items based on allowIn.
1165
- function setupAllowChildren(compiledDefinitions, itemName) {
1166
- const itemRule = compiledDefinitions[itemName];
1167
- for (const allowedParentItemName of itemRule.allowIn) {
1168
- const allowedParentItem = compiledDefinitions[allowedParentItemName];
1169
- allowedParentItem.allowChildren.push(itemName);
1170
- }
1171
- }
1172
- function cleanUpAllowAttributes(compiledDefinitions, itemName) {
1173
- const itemRule = compiledDefinitions[itemName];
1174
- itemRule.allowAttributes = Array.from(new Set(itemRule.allowAttributes));
1175
1287
  }
1176
1288
  function copyTypes(sourceItemRules, itemRule) {
1177
1289
  for (const sourceItemRule of sourceItemRules) {
@@ -1183,33 +1295,28 @@ function copyTypes(sourceItemRules, itemRule) {
1183
1295
  }
1184
1296
  function copyProperty(sourceItemRules, itemRule, propertyName) {
1185
1297
  for (const sourceItemRule of sourceItemRules) {
1186
- const value = sourceItemRule[propertyName];
1298
+ let value = sourceItemRule[propertyName];
1299
+ // `value` can be a string, an array or undefined.
1300
+ // Convert a string to an array with one item, then handle an array. Skip undefined this way.
1187
1301
  if (typeof value == 'string') {
1188
- itemRule[propertyName].push(value);
1302
+ value = [value];
1189
1303
  }
1190
- else if (Array.isArray(value)) {
1191
- itemRule[propertyName].push(...value);
1304
+ if (Array.isArray(value)) {
1305
+ value.forEach(singleValue => itemRule[propertyName].add(singleValue));
1192
1306
  }
1193
1307
  }
1194
1308
  }
1195
- function makeInheritAllWork(sourceItemRules, itemRule) {
1309
+ function resolveInheritAll(sourceItemRules, itemRule) {
1196
1310
  for (const sourceItemRule of sourceItemRules) {
1197
1311
  const inheritFrom = sourceItemRule.inheritAllFrom;
1198
1312
  if (inheritFrom) {
1199
- itemRule.allowContentOf.push(inheritFrom);
1200
- itemRule.allowWhere.push(inheritFrom);
1201
- itemRule.allowAttributesOf.push(inheritFrom);
1202
- itemRule.inheritTypesFrom.push(inheritFrom);
1313
+ itemRule.allowContentOf.add(inheritFrom);
1314
+ itemRule.allowWhere.add(inheritFrom);
1315
+ itemRule.allowAttributesOf.add(inheritFrom);
1316
+ itemRule.inheritTypesFrom.add(inheritFrom);
1203
1317
  }
1204
1318
  }
1205
1319
  }
1206
- function getAllowedChildren(compiledDefinitions, itemName) {
1207
- const itemRule = compiledDefinitions[itemName];
1208
- return getValues(compiledDefinitions).filter(def => def.allowIn.includes(itemRule.name));
1209
- }
1210
- function getValues(obj) {
1211
- return Object.keys(obj).map(key => obj[key]);
1212
- }
1213
1320
  function mapContextItem(ctxItem) {
1214
1321
  if (typeof ctxItem == 'string' || ctxItem.is('documentFragment')) {
1215
1322
  return {
@@ -20,7 +20,7 @@ declare const Selection_base: import("@ckeditor/ckeditor5-utils").Mixed<typeof T
20
20
  * Additionally, selection may have its own attributes (think – whether text typed in in this selection
21
21
  * should have those attributes – e.g. whether you type a bolded text).
22
22
  */
23
- export default class Selection extends Selection_base {
23
+ export default class Selection extends /* #__PURE__ */ Selection_base {
24
24
  /**
25
25
  * Specifies whether the last added range was added as a backward or forward range.
26
26
  */
@@ -17,7 +17,7 @@ import { CKEditorError, EmitterMixin, isIterable } from '@ckeditor/ckeditor5-uti
17
17
  * Additionally, selection may have its own attributes (think – whether text typed in in this selection
18
18
  * should have those attributes – e.g. whether you type a bolded text).
19
19
  */
20
- export default class Selection extends EmitterMixin(TypeCheckable) {
20
+ export default class Selection extends /* #__PURE__ */ EmitterMixin(TypeCheckable) {
21
21
  /**
22
22
  * Creates a new selection instance based on the given {@link module:engine/model/selection~Selectable selectable}
23
23
  * or creates an empty selection if no arguments were passed.
@@ -18,7 +18,7 @@ declare const Document_base: import("@ckeditor/ckeditor5-utils").Mixed<{
18
18
  * Document class creates an abstract layer over the content editable area, contains a tree of view elements and
19
19
  * {@link module:engine/view/documentselection~DocumentSelection view selection} associated with this document.
20
20
  */
21
- export default class Document extends Document_base {
21
+ export default class Document extends /* #__PURE__ */ Document_base {
22
22
  /**
23
23
  * Selection done on this document.
24
24
  */
@@ -13,7 +13,7 @@ import { Collection, ObservableMixin } from '@ckeditor/ckeditor5-utils';
13
13
  * Document class creates an abstract layer over the content editable area, contains a tree of view elements and
14
14
  * {@link module:engine/view/documentselection~DocumentSelection view selection} associated with this document.
15
15
  */
16
- export default class Document extends BubblingEmitterMixin(ObservableMixin()) {
16
+ export default class Document extends /* #__PURE__ */ BubblingEmitterMixin(/* #__PURE__ */ ObservableMixin()) {
17
17
  /**
18
18
  * Creates a Document instance.
19
19
  *
@@ -17,7 +17,7 @@ declare const DocumentFragment_base: import("@ckeditor/ckeditor5-utils").Mixed<t
17
17
  * {@link module:engine/view/upcastwriter~UpcastWriter#createDocumentFragment `UpcastWriter#createDocumentFragment()`}
18
18
  * method.
19
19
  */
20
- export default class DocumentFragment extends DocumentFragment_base implements Iterable<Node> {
20
+ export default class DocumentFragment extends /* #__PURE__ */ DocumentFragment_base implements Iterable<Node> {
21
21
  /**
22
22
  * The document to which this document fragment belongs.
23
23
  */
@@ -16,7 +16,7 @@ import { EmitterMixin, isIterable } from '@ckeditor/ckeditor5-utils';
16
16
  * {@link module:engine/view/upcastwriter~UpcastWriter#createDocumentFragment `UpcastWriter#createDocumentFragment()`}
17
17
  * method.
18
18
  */
19
- export default class DocumentFragment extends EmitterMixin(TypeCheckable) {
19
+ export default class DocumentFragment extends /* #__PURE__ */ EmitterMixin(TypeCheckable) {
20
20
  /**
21
21
  * Creates new DocumentFragment instance.
22
22
  *
@@ -24,7 +24,7 @@ declare const DocumentSelection_base: import("@ckeditor/ckeditor5-utils").Mixed<
24
24
  * the {@link module:engine/view/view~View#change `View#change()`} block
25
25
  * (so via {@link module:engine/view/downcastwriter~DowncastWriter#setSelection `DowncastWriter#setSelection()`}).
26
26
  */
27
- export default class DocumentSelection extends DocumentSelection_base {
27
+ export default class DocumentSelection extends /* #__PURE__ */ DocumentSelection_base {
28
28
  /**
29
29
  * Selection is used internally (`DocumentSelection` is a proxy to that selection).
30
30
  */
@@ -18,7 +18,7 @@ import { EmitterMixin } from '@ckeditor/ckeditor5-utils';
18
18
  * the {@link module:engine/view/view~View#change `View#change()`} block
19
19
  * (so via {@link module:engine/view/downcastwriter~DowncastWriter#setSelection `DowncastWriter#setSelection()`}).
20
20
  */
21
- export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
21
+ export default class DocumentSelection extends /* #__PURE__ */ EmitterMixin(TypeCheckable) {
22
22
  constructor(...args) {
23
23
  super();
24
24
  this._selection = new Selection();