@ckeditor/ckeditor5-engine 44.2.1 → 44.3.0-alpha.0
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.
- package/dist/index.js +1677 -1258
- package/dist/index.js.map +1 -1
- package/package.json +2 -4
- package/src/conversion/downcasthelpers.js +14 -42
- package/src/conversion/viewconsumable.d.ts +65 -97
- package/src/conversion/viewconsumable.js +217 -215
- package/src/view/attributeelement.d.ts +14 -0
- package/src/view/attributeelement.js +26 -0
- package/src/view/domconverter.js +72 -7
- package/src/view/downcastwriter.d.ts +32 -20
- package/src/view/downcastwriter.js +18 -142
- package/src/view/element.d.ts +309 -17
- package/src/view/element.js +432 -137
- package/src/view/matcher.d.ts +38 -16
- package/src/view/matcher.js +91 -166
- package/src/view/stylesmap.d.ts +68 -6
- package/src/view/stylesmap.js +144 -8
- package/src/view/tokenlist.d.ts +109 -0
- package/src/view/tokenlist.js +196 -0
package/src/view/stylesmap.js
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* @module engine/view/stylesmap
|
|
7
7
|
*/
|
|
8
8
|
import { get, isObject, merge, set, unset } from 'lodash-es';
|
|
9
|
+
import { toArray } from '@ckeditor/ckeditor5-utils';
|
|
10
|
+
import { isPatternMatched } from './matcher.js';
|
|
9
11
|
/**
|
|
10
12
|
* Styles map. Allows handling (adding, removing, retrieving) a set of style rules (usually, of an element).
|
|
11
13
|
*/
|
|
@@ -54,6 +56,7 @@ export default class StylesMap {
|
|
|
54
56
|
for (const [key, value] of parsedStyles) {
|
|
55
57
|
this._styleProcessor.toNormalizedForm(key, value, this._styles);
|
|
56
58
|
}
|
|
59
|
+
return this;
|
|
57
60
|
}
|
|
58
61
|
/**
|
|
59
62
|
* Checks if a given style is set.
|
|
@@ -133,15 +136,17 @@ export default class StylesMap {
|
|
|
133
136
|
* styles.toString(); // -> 'margin-bottom:1px;margin-left:1px;'
|
|
134
137
|
* ```
|
|
135
138
|
*
|
|
136
|
-
* @param
|
|
139
|
+
* @param names Style name or an array of names.
|
|
137
140
|
*/
|
|
138
|
-
remove(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
remove(names) {
|
|
142
|
+
for (const name of toArray(names)) {
|
|
143
|
+
this._cachedStyleNames = null;
|
|
144
|
+
this._cachedExpandedStyleNames = null;
|
|
145
|
+
const path = toPath(name);
|
|
146
|
+
unset(this._styles, path);
|
|
147
|
+
delete this._styles[name];
|
|
148
|
+
this._cleanEmptyObjectsOnPath(path);
|
|
149
|
+
}
|
|
145
150
|
}
|
|
146
151
|
/**
|
|
147
152
|
* Returns a normalized style object or a single value.
|
|
@@ -304,6 +309,12 @@ export default class StylesMap {
|
|
|
304
309
|
this._cachedStyleNames = this._cachedStyleNames || this.getStylesEntries().map(([key]) => key);
|
|
305
310
|
return this._cachedStyleNames;
|
|
306
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Alias for {@link #getStyleNames}.
|
|
314
|
+
*/
|
|
315
|
+
keys() {
|
|
316
|
+
return this.getStyleNames();
|
|
317
|
+
}
|
|
307
318
|
/**
|
|
308
319
|
* Removes all styles.
|
|
309
320
|
*/
|
|
@@ -312,6 +323,20 @@ export default class StylesMap {
|
|
|
312
323
|
this._cachedStyleNames = null;
|
|
313
324
|
this._cachedExpandedStyleNames = null;
|
|
314
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* Returns `true` if both attributes have the same styles.
|
|
328
|
+
*/
|
|
329
|
+
isSimilar(other) {
|
|
330
|
+
if (this.size !== other.size) {
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
for (const property of this.getStyleNames()) {
|
|
334
|
+
if (!other.has(property) || other.getAsString(property) !== this.getAsString(property)) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
315
340
|
/**
|
|
316
341
|
* Returns normalized styles entries for further processing.
|
|
317
342
|
*/
|
|
@@ -323,6 +348,117 @@ export default class StylesMap {
|
|
|
323
348
|
}
|
|
324
349
|
return parsed;
|
|
325
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* Clones the attribute value.
|
|
353
|
+
*
|
|
354
|
+
* @internal
|
|
355
|
+
*/
|
|
356
|
+
_clone() {
|
|
357
|
+
const clone = new this.constructor(this._styleProcessor);
|
|
358
|
+
clone.set(this.getNormalized());
|
|
359
|
+
return clone;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Used by the {@link module:engine/view/matcher~Matcher Matcher} to collect matching styles.
|
|
363
|
+
*
|
|
364
|
+
* @internal
|
|
365
|
+
* @param tokenPattern The matched style name pattern.
|
|
366
|
+
* @param valuePattern The matched style value pattern.
|
|
367
|
+
* @returns An array of matching tokens (style names).
|
|
368
|
+
*/
|
|
369
|
+
_getTokensMatch(tokenPattern, valuePattern) {
|
|
370
|
+
const match = [];
|
|
371
|
+
for (const styleName of this.getStyleNames(true)) {
|
|
372
|
+
if (isPatternMatched(tokenPattern, styleName)) {
|
|
373
|
+
if (valuePattern === true) {
|
|
374
|
+
match.push(styleName);
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
// For now, the reducers are not returning the full tree of properties.
|
|
378
|
+
// Casting to string preserves the old behavior until the root cause is fixed.
|
|
379
|
+
// More can be found in https://github.com/ckeditor/ckeditor5/issues/10399.
|
|
380
|
+
const value = this.getAsString(styleName);
|
|
381
|
+
if (isPatternMatched(valuePattern, value)) {
|
|
382
|
+
match.push(styleName);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return match.length ? match : undefined;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Returns a list of consumables for the attribute. This includes related styles.
|
|
390
|
+
*
|
|
391
|
+
* Could be filtered by the given style name.
|
|
392
|
+
*
|
|
393
|
+
* @internal
|
|
394
|
+
*/
|
|
395
|
+
_getConsumables(name) {
|
|
396
|
+
const result = [];
|
|
397
|
+
if (name) {
|
|
398
|
+
result.push(name);
|
|
399
|
+
for (const relatedName of this._styleProcessor.getRelatedStyles(name)) {
|
|
400
|
+
result.push(relatedName);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
for (const name of this.getStyleNames()) {
|
|
405
|
+
for (const relatedName of this._styleProcessor.getRelatedStyles(name)) {
|
|
406
|
+
result.push(relatedName);
|
|
407
|
+
}
|
|
408
|
+
result.push(name);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return result;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Used by {@link module:engine/view/element~Element#_canMergeAttributesFrom} to verify if the given attribute can be merged without
|
|
415
|
+
* conflicts into the attribute.
|
|
416
|
+
*
|
|
417
|
+
* This method is indirectly used by the {@link module:engine/view/downcastwriter~DowncastWriter} while down-casting
|
|
418
|
+
* an {@link module:engine/view/attributeelement~AttributeElement} to merge it with other AttributeElement.
|
|
419
|
+
*
|
|
420
|
+
* @internal
|
|
421
|
+
*/
|
|
422
|
+
_canMergeFrom(other) {
|
|
423
|
+
for (const key of other.getStyleNames()) {
|
|
424
|
+
if (this.has(key) && this.getAsString(key) !== other.getAsString(key)) {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return true;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Used by {@link module:engine/view/element~Element#_mergeAttributesFrom} to merge a given attribute into the attribute.
|
|
432
|
+
*
|
|
433
|
+
* This method is indirectly used by the {@link module:engine/view/downcastwriter~DowncastWriter} while down-casting
|
|
434
|
+
* an {@link module:engine/view/attributeelement~AttributeElement} to merge it with other AttributeElement.
|
|
435
|
+
*
|
|
436
|
+
* @internal
|
|
437
|
+
*/
|
|
438
|
+
_mergeFrom(other) {
|
|
439
|
+
for (const prop of other.getStyleNames()) {
|
|
440
|
+
if (!this.has(prop)) {
|
|
441
|
+
this.set(prop, other.getAsString(prop));
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Used by {@link module:engine/view/element~Element#_canSubtractAttributesOf} to verify if the given attribute can be fully
|
|
447
|
+
* subtracted from the attribute.
|
|
448
|
+
*
|
|
449
|
+
* This method is indirectly used by the {@link module:engine/view/downcastwriter~DowncastWriter} while down-casting
|
|
450
|
+
* an {@link module:engine/view/attributeelement~AttributeElement} to unwrap the AttributeElement.
|
|
451
|
+
*
|
|
452
|
+
* @internal
|
|
453
|
+
*/
|
|
454
|
+
_isMatching(other) {
|
|
455
|
+
for (const key of other.getStyleNames()) {
|
|
456
|
+
if (!this.has(key) || this.getAsString(key) !== other.getAsString(key)) {
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return true;
|
|
461
|
+
}
|
|
326
462
|
/**
|
|
327
463
|
* Removes empty objects upon removing an entry from internal object.
|
|
328
464
|
*/
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module engine/view/tokenlist
|
|
7
|
+
*/
|
|
8
|
+
import { type ArrayOrItem } from '@ckeditor/ckeditor5-utils';
|
|
9
|
+
import type { ElementAttributeValue } from './element.js';
|
|
10
|
+
/**
|
|
11
|
+
* Token list. Allows handling (adding, removing, retrieving) a set of tokens (for example class names).
|
|
12
|
+
*/
|
|
13
|
+
export default class TokenList implements ElementAttributeValue {
|
|
14
|
+
/**
|
|
15
|
+
* The set of tokens.
|
|
16
|
+
*/
|
|
17
|
+
private _set;
|
|
18
|
+
/**
|
|
19
|
+
* Returns true if token list has no tokens set.
|
|
20
|
+
*/
|
|
21
|
+
get isEmpty(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Number of tokens.
|
|
24
|
+
*/
|
|
25
|
+
get size(): number;
|
|
26
|
+
/**
|
|
27
|
+
* Checks if a given token is set.
|
|
28
|
+
*/
|
|
29
|
+
has(name: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Returns all tokens.
|
|
32
|
+
*/
|
|
33
|
+
keys(): Array<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Resets the value to the given one.
|
|
36
|
+
*/
|
|
37
|
+
setTo(value: string): this;
|
|
38
|
+
/**
|
|
39
|
+
* Sets a given token without affecting other tokens.
|
|
40
|
+
*/
|
|
41
|
+
set(tokens: ArrayOrItem<string>): void;
|
|
42
|
+
/**
|
|
43
|
+
* Removes given token.
|
|
44
|
+
*/
|
|
45
|
+
remove(tokens: ArrayOrItem<string>): void;
|
|
46
|
+
/**
|
|
47
|
+
* Removes all tokens.
|
|
48
|
+
*/
|
|
49
|
+
clear(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Returns a normalized tokens string.
|
|
52
|
+
*/
|
|
53
|
+
toString(): string;
|
|
54
|
+
/**
|
|
55
|
+
* Returns `true` if both attributes have the same tokens.
|
|
56
|
+
*/
|
|
57
|
+
isSimilar(other: TokenList): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Clones the attribute value.
|
|
60
|
+
*
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
_clone(): this;
|
|
64
|
+
/**
|
|
65
|
+
* Used by the {@link module:engine/view/matcher~Matcher Matcher} to collect matching attribute tokens.
|
|
66
|
+
*
|
|
67
|
+
* @internal
|
|
68
|
+
* @param tokenPattern The matched token name pattern.
|
|
69
|
+
* @returns An array of matching tokens.
|
|
70
|
+
*/
|
|
71
|
+
_getTokensMatch(tokenPattern: true | string | RegExp): Array<string> | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* Returns a list of consumables for the attribute.
|
|
74
|
+
*
|
|
75
|
+
* Could be filtered by the given token name.
|
|
76
|
+
*
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
79
|
+
_getConsumables(name?: string): Array<string>;
|
|
80
|
+
/**
|
|
81
|
+
* Used by {@link module:engine/view/element~Element#_canMergeAttributesFrom} to verify if the given attribute
|
|
82
|
+
* can be merged without conflicts into the attribute.
|
|
83
|
+
*
|
|
84
|
+
* This method is indirectly used by the {@link module:engine/view/downcastwriter~DowncastWriter} while downcasting
|
|
85
|
+
* an {@link module:engine/view/attributeelement~AttributeElement} to merge it with other `AttributeElement`.
|
|
86
|
+
*
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
_canMergeFrom(): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Used by {@link module:engine/view/element~Element#_mergeAttributesFrom} to merge a given attribute into the attribute.
|
|
92
|
+
*
|
|
93
|
+
* This method is indirectly used by the {@link module:engine/view/downcastwriter~DowncastWriter} while down-casting
|
|
94
|
+
* an {@link module:engine/view/attributeelement~AttributeElement} to merge it with other AttributeElement.
|
|
95
|
+
*
|
|
96
|
+
* @internal
|
|
97
|
+
*/
|
|
98
|
+
_mergeFrom(other: TokenList): void;
|
|
99
|
+
/**
|
|
100
|
+
* Used by {@link module:engine/view/element~Element#_canSubtractAttributesOf} to verify if the given attribute
|
|
101
|
+
* can be fully subtracted from the attribute.
|
|
102
|
+
*
|
|
103
|
+
* This method is indirectly used by the {@link module:engine/view/downcastwriter~DowncastWriter} while down-casting
|
|
104
|
+
* an {@link module:engine/view/attributeelement~AttributeElement} to unwrap the AttributeElement.
|
|
105
|
+
*
|
|
106
|
+
* @internal
|
|
107
|
+
*/
|
|
108
|
+
_isMatching(other: TokenList): boolean;
|
|
109
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module engine/view/tokenlist
|
|
7
|
+
*/
|
|
8
|
+
import { toArray } from '@ckeditor/ckeditor5-utils';
|
|
9
|
+
/**
|
|
10
|
+
* Token list. Allows handling (adding, removing, retrieving) a set of tokens (for example class names).
|
|
11
|
+
*/
|
|
12
|
+
export default class TokenList {
|
|
13
|
+
constructor() {
|
|
14
|
+
/**
|
|
15
|
+
* The set of tokens.
|
|
16
|
+
*/
|
|
17
|
+
this._set = new Set();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Returns true if token list has no tokens set.
|
|
21
|
+
*/
|
|
22
|
+
get isEmpty() {
|
|
23
|
+
return this._set.size == 0;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Number of tokens.
|
|
27
|
+
*/
|
|
28
|
+
get size() {
|
|
29
|
+
return this._set.size;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Checks if a given token is set.
|
|
33
|
+
*/
|
|
34
|
+
has(name) {
|
|
35
|
+
return this._set.has(name);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns all tokens.
|
|
39
|
+
*/
|
|
40
|
+
keys() {
|
|
41
|
+
return Array.from(this._set.keys());
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resets the value to the given one.
|
|
45
|
+
*/
|
|
46
|
+
setTo(value) {
|
|
47
|
+
this.clear();
|
|
48
|
+
for (const token of value.split(/\s+/)) {
|
|
49
|
+
if (token) {
|
|
50
|
+
this._set.add(token);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Sets a given token without affecting other tokens.
|
|
57
|
+
*/
|
|
58
|
+
set(tokens) {
|
|
59
|
+
for (const token of toArray(tokens)) {
|
|
60
|
+
if (token) {
|
|
61
|
+
this._set.add(token);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Removes given token.
|
|
67
|
+
*/
|
|
68
|
+
remove(tokens) {
|
|
69
|
+
for (const token of toArray(tokens)) {
|
|
70
|
+
this._set.delete(token);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Removes all tokens.
|
|
75
|
+
*/
|
|
76
|
+
clear() {
|
|
77
|
+
this._set.clear();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns a normalized tokens string.
|
|
81
|
+
*/
|
|
82
|
+
toString() {
|
|
83
|
+
return Array.from(this._set).join(' ');
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Returns `true` if both attributes have the same tokens.
|
|
87
|
+
*/
|
|
88
|
+
isSimilar(other) {
|
|
89
|
+
if (this.size !== other.size) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
for (const token of this.keys()) {
|
|
93
|
+
if (!other.has(token)) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Clones the attribute value.
|
|
101
|
+
*
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
_clone() {
|
|
105
|
+
const clone = new this.constructor();
|
|
106
|
+
clone._set = new Set(this._set);
|
|
107
|
+
return clone;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Used by the {@link module:engine/view/matcher~Matcher Matcher} to collect matching attribute tokens.
|
|
111
|
+
*
|
|
112
|
+
* @internal
|
|
113
|
+
* @param tokenPattern The matched token name pattern.
|
|
114
|
+
* @returns An array of matching tokens.
|
|
115
|
+
*/
|
|
116
|
+
_getTokensMatch(tokenPattern) {
|
|
117
|
+
const match = [];
|
|
118
|
+
if (tokenPattern === true) {
|
|
119
|
+
for (const token of this._set.keys()) {
|
|
120
|
+
match.push(token);
|
|
121
|
+
}
|
|
122
|
+
return match;
|
|
123
|
+
}
|
|
124
|
+
if (typeof tokenPattern == 'string') {
|
|
125
|
+
for (const token of tokenPattern.split(/\s+/)) {
|
|
126
|
+
if (this._set.has(token)) {
|
|
127
|
+
match.push(token);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return match;
|
|
134
|
+
}
|
|
135
|
+
for (const token of this._set.keys()) {
|
|
136
|
+
if (token.match(tokenPattern)) {
|
|
137
|
+
match.push(token);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return match.length ? match : undefined;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Returns a list of consumables for the attribute.
|
|
144
|
+
*
|
|
145
|
+
* Could be filtered by the given token name.
|
|
146
|
+
*
|
|
147
|
+
* @internal
|
|
148
|
+
*/
|
|
149
|
+
_getConsumables(name) {
|
|
150
|
+
return name ? [name] : this.keys();
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Used by {@link module:engine/view/element~Element#_canMergeAttributesFrom} to verify if the given attribute
|
|
154
|
+
* can be merged without conflicts into the attribute.
|
|
155
|
+
*
|
|
156
|
+
* This method is indirectly used by the {@link module:engine/view/downcastwriter~DowncastWriter} while downcasting
|
|
157
|
+
* an {@link module:engine/view/attributeelement~AttributeElement} to merge it with other `AttributeElement`.
|
|
158
|
+
*
|
|
159
|
+
* @internal
|
|
160
|
+
*/
|
|
161
|
+
_canMergeFrom() {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Used by {@link module:engine/view/element~Element#_mergeAttributesFrom} to merge a given attribute into the attribute.
|
|
166
|
+
*
|
|
167
|
+
* This method is indirectly used by the {@link module:engine/view/downcastwriter~DowncastWriter} while down-casting
|
|
168
|
+
* an {@link module:engine/view/attributeelement~AttributeElement} to merge it with other AttributeElement.
|
|
169
|
+
*
|
|
170
|
+
* @internal
|
|
171
|
+
*/
|
|
172
|
+
_mergeFrom(other) {
|
|
173
|
+
for (const token of other._set.keys()) {
|
|
174
|
+
if (!this._set.has(token)) {
|
|
175
|
+
this._set.add(token);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Used by {@link module:engine/view/element~Element#_canSubtractAttributesOf} to verify if the given attribute
|
|
181
|
+
* can be fully subtracted from the attribute.
|
|
182
|
+
*
|
|
183
|
+
* This method is indirectly used by the {@link module:engine/view/downcastwriter~DowncastWriter} while down-casting
|
|
184
|
+
* an {@link module:engine/view/attributeelement~AttributeElement} to unwrap the AttributeElement.
|
|
185
|
+
*
|
|
186
|
+
* @internal
|
|
187
|
+
*/
|
|
188
|
+
_isMatching(other) {
|
|
189
|
+
for (const name of other._set.keys()) {
|
|
190
|
+
if (!this._set.has(name)) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
}
|