@ckeditor/ckeditor5-engine 44.2.1-alpha.0 → 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/domconverter.js
CHANGED
|
@@ -509,6 +509,10 @@ export default class DomConverter {
|
|
|
509
509
|
generator.next();
|
|
510
510
|
// Whitespace cleaning.
|
|
511
511
|
this._processDomInlineNodes(null, inlineNodes, options);
|
|
512
|
+
// This was a single block filler so just remove it.
|
|
513
|
+
if (this.blockFillerMode == 'br' && isViewBrFiller(node)) {
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
512
516
|
// Text not got trimmed to an empty string so there is no result node.
|
|
513
517
|
if (node.is('$text') && node.data.length == 0) {
|
|
514
518
|
return null;
|
|
@@ -544,7 +548,10 @@ export default class DomConverter {
|
|
|
544
548
|
if (this._isBlockViewElement(viewChild)) {
|
|
545
549
|
this._processDomInlineNodes(domElement, inlineNodes, options);
|
|
546
550
|
}
|
|
547
|
-
|
|
551
|
+
// Yield only if this is not a block filler.
|
|
552
|
+
if (!(this.blockFillerMode == 'br' && isViewBrFiller(viewChild))) {
|
|
553
|
+
yield viewChild;
|
|
554
|
+
}
|
|
548
555
|
// Trigger children handling.
|
|
549
556
|
generator.next();
|
|
550
557
|
}
|
|
@@ -863,10 +870,9 @@ export default class DomConverter {
|
|
|
863
870
|
if (this.blockFillerMode == 'br') {
|
|
864
871
|
return domNode.isEqualNode(BR_FILLER_REF);
|
|
865
872
|
}
|
|
866
|
-
// Special case for <p><br></p> in which <br> should be treated as filler even when we are not in the 'br' mode.
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
domNode.parentNode.childNodes.length === 1) {
|
|
873
|
+
// Special case for <p><br></p> in which <br> should be treated as filler even when we are not in the 'br' mode.
|
|
874
|
+
// See https://github.com/ckeditor/ckeditor5/issues/5564.
|
|
875
|
+
if (isOnlyBrInBlock(domNode, this.blockElements)) {
|
|
870
876
|
return true;
|
|
871
877
|
}
|
|
872
878
|
// If not in 'br' mode, try recognizing both marked and regular nbsp block fillers.
|
|
@@ -1018,7 +1024,9 @@ export default class DomConverter {
|
|
|
1018
1024
|
* Used later to process whitespaces.
|
|
1019
1025
|
*/
|
|
1020
1026
|
*_domToView(domNode, options, inlineNodes) {
|
|
1021
|
-
|
|
1027
|
+
// Special case for <p><br></p> in which <br> should be treated as filler even when we are not in the 'br' mode.
|
|
1028
|
+
// See https://github.com/ckeditor/ckeditor5/issues/5564.
|
|
1029
|
+
if (this.blockFillerMode != 'br' && isOnlyBrInBlock(domNode, this.blockElements)) {
|
|
1022
1030
|
return null;
|
|
1023
1031
|
}
|
|
1024
1032
|
// When node is inside a UIElement or a RawElement return that parent as it's view representation.
|
|
@@ -1165,6 +1173,21 @@ export default class DomConverter {
|
|
|
1165
1173
|
// This causes a problem because the normal space would be removed in `.replace` calls above. To prevent that,
|
|
1166
1174
|
// the inline filler is removed only after the data is initially processed (by the `.replace` above). See ckeditor5#692.
|
|
1167
1175
|
data = getDataWithoutFiller(data);
|
|
1176
|
+
// Block filler handling.
|
|
1177
|
+
if (this.blockFillerMode != 'br' && node.parent) {
|
|
1178
|
+
if (isViewMarkedNbspFiller(node.parent, data)) {
|
|
1179
|
+
data = '';
|
|
1180
|
+
// Mark block element as it has a block filler and remove the `<span data-cke-filler="true">` element.
|
|
1181
|
+
if (node.parent.parent) {
|
|
1182
|
+
node.parent.parent._setCustomProperty('$hasBlockFiller', true);
|
|
1183
|
+
node.parent._remove();
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
else if (isViewNbspFiller(node.parent, data, this.blockElements)) {
|
|
1187
|
+
data = '';
|
|
1188
|
+
node.parent._setCustomProperty('$hasBlockFiller', true);
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1168
1191
|
// At this point we should have removed all whitespaces from DOM text data.
|
|
1169
1192
|
//
|
|
1170
1193
|
// Now, We will reverse the process that happens in `_processDataFromViewText`.
|
|
@@ -1423,7 +1446,7 @@ function forEachDomElementAncestor(element, callback) {
|
|
|
1423
1446
|
}
|
|
1424
1447
|
}
|
|
1425
1448
|
/**
|
|
1426
|
-
* Checks if given node is a nbsp block filler.
|
|
1449
|
+
* Checks if given DOM node is a nbsp block filler.
|
|
1427
1450
|
*
|
|
1428
1451
|
* A is a block filler only if it is a single child of a block element.
|
|
1429
1452
|
*
|
|
@@ -1442,6 +1465,48 @@ function hasBlockParent(domNode, blockElements) {
|
|
|
1442
1465
|
const parent = domNode.parentNode;
|
|
1443
1466
|
return !!parent && !!parent.tagName && blockElements.includes(parent.tagName.toLowerCase());
|
|
1444
1467
|
}
|
|
1468
|
+
/**
|
|
1469
|
+
* Checks if given view node is a nbsp block filler.
|
|
1470
|
+
*
|
|
1471
|
+
* A is a block filler only if it is a single child of a block element.
|
|
1472
|
+
*/
|
|
1473
|
+
function isViewNbspFiller(parent, data, blockElements) {
|
|
1474
|
+
return (data == '\u00A0' &&
|
|
1475
|
+
parent &&
|
|
1476
|
+
parent.is('element') &&
|
|
1477
|
+
parent.childCount == 1 &&
|
|
1478
|
+
blockElements.includes(parent.name));
|
|
1479
|
+
}
|
|
1480
|
+
/**
|
|
1481
|
+
* Checks if given view node is a marked-nbsp block filler.
|
|
1482
|
+
*
|
|
1483
|
+
* A is a block filler only if it is wrapped in `<span data-cke-filler="true">` element.
|
|
1484
|
+
*/
|
|
1485
|
+
function isViewMarkedNbspFiller(parent, data) {
|
|
1486
|
+
return (data == '\u00A0' &&
|
|
1487
|
+
parent &&
|
|
1488
|
+
parent.is('element', 'span') &&
|
|
1489
|
+
parent.childCount == 1 &&
|
|
1490
|
+
parent.hasAttribute('data-cke-filler'));
|
|
1491
|
+
}
|
|
1492
|
+
/**
|
|
1493
|
+
* Checks if given view node is a br block filler.
|
|
1494
|
+
*
|
|
1495
|
+
* A <br> is a block filler only if it has data-cke-filler attribute set.
|
|
1496
|
+
*/
|
|
1497
|
+
function isViewBrFiller(node) {
|
|
1498
|
+
return (node.is('element', 'br') &&
|
|
1499
|
+
node.hasAttribute('data-cke-filler'));
|
|
1500
|
+
}
|
|
1501
|
+
/**
|
|
1502
|
+
* Special case for `<p><br></p>` in which `<br>` should be treated as filler even when we are not in the 'br' mode.
|
|
1503
|
+
*/
|
|
1504
|
+
function isOnlyBrInBlock(domNode, blockElements) {
|
|
1505
|
+
// See https://github.com/ckeditor/ckeditor5/issues/5564.
|
|
1506
|
+
return (domNode.tagName === 'BR' &&
|
|
1507
|
+
hasBlockParent(domNode, blockElements) &&
|
|
1508
|
+
domNode.parentNode.childNodes.length === 1);
|
|
1509
|
+
}
|
|
1445
1510
|
/**
|
|
1446
1511
|
* Log to console the information about element that was replaced.
|
|
1447
1512
|
* Check UNSAFE_ELEMENTS for all recognized unsafe elements.
|
|
@@ -13,6 +13,7 @@ import AttributeElement from './attributeelement.js';
|
|
|
13
13
|
import EmptyElement from './emptyelement.js';
|
|
14
14
|
import UIElement from './uielement.js';
|
|
15
15
|
import RawElement from './rawelement.js';
|
|
16
|
+
import { type ArrayOrItem } from '@ckeditor/ckeditor5-utils';
|
|
16
17
|
import DocumentFragment from './documentfragment.js';
|
|
17
18
|
import Text from './text.js';
|
|
18
19
|
import EditableElement from './editableelement.js';
|
|
@@ -382,8 +383,25 @@ export default class DowncastWriter {
|
|
|
382
383
|
*
|
|
383
384
|
* @param key The attribute key.
|
|
384
385
|
* @param value The attribute value.
|
|
386
|
+
* @param element The element to set an attribute on.
|
|
385
387
|
*/
|
|
386
388
|
setAttribute(key: string, value: unknown, element: Element): void;
|
|
389
|
+
/**
|
|
390
|
+
* Adds or overwrites the element's attribute with a specified key and value.
|
|
391
|
+
* Note that for tokenized attributes it allows the `reset` parameter to specify if the previous
|
|
392
|
+
* attribute value should be overwritten or a new token (class name, style property) should be added.
|
|
393
|
+
*
|
|
394
|
+
* ```ts
|
|
395
|
+
* writer.setAttribute( 'href', 'http://ckeditor.com', linkElement );
|
|
396
|
+
* writer.setAttribute( 'class', 'foo', false, element );
|
|
397
|
+
* ```
|
|
398
|
+
*
|
|
399
|
+
* @param key The attribute key.
|
|
400
|
+
* @param value The attribute value.
|
|
401
|
+
* @param overwrite Whether tokenized attribute should overwrite the attribute value or just add a token.
|
|
402
|
+
* @param element The element to set an attribute on.
|
|
403
|
+
*/
|
|
404
|
+
setAttribute(key: string, value: unknown, overwrite: boolean, element: Element): void;
|
|
387
405
|
/**
|
|
388
406
|
* Removes attribute from the element.
|
|
389
407
|
*
|
|
@@ -392,8 +410,22 @@ export default class DowncastWriter {
|
|
|
392
410
|
* ```
|
|
393
411
|
*
|
|
394
412
|
* @param key Attribute key.
|
|
413
|
+
* @param element The element to remove an attribute of.
|
|
395
414
|
*/
|
|
396
415
|
removeAttribute(key: string, element: Element): void;
|
|
416
|
+
/**
|
|
417
|
+
* Removes specified tokens from an attribute value (for example class names, style properties).
|
|
418
|
+
* If resulting attribute become empty, the whole attribute is removed.
|
|
419
|
+
*
|
|
420
|
+
* ```ts
|
|
421
|
+
* writer.removeAttribute( 'class', 'foo', linkElement );
|
|
422
|
+
* ```
|
|
423
|
+
*
|
|
424
|
+
* @param key Attribute key.
|
|
425
|
+
* @param tokens Tokens to partly remove from attribute value. For example class names or style property names.
|
|
426
|
+
* @param element The element to remove an attribute of.
|
|
427
|
+
*/
|
|
428
|
+
removeAttribute(key: string, tokens: ArrayOrItem<string>, element: Element): void;
|
|
397
429
|
/**
|
|
398
430
|
* Adds specified class to the element.
|
|
399
431
|
*
|
|
@@ -924,26 +956,6 @@ export default class DowncastWriter {
|
|
|
924
956
|
* @returns New position after wrapping.
|
|
925
957
|
*/
|
|
926
958
|
private _wrapPosition;
|
|
927
|
-
/**
|
|
928
|
-
* Wraps one {@link module:engine/view/attributeelement~AttributeElement AttributeElement} into another by
|
|
929
|
-
* merging them if possible. When merging is possible - all attributes, styles and classes are moved from wrapper
|
|
930
|
-
* element to element being wrapped.
|
|
931
|
-
*
|
|
932
|
-
* @param wrapper Wrapper AttributeElement.
|
|
933
|
-
* @param toWrap AttributeElement to wrap using wrapper element.
|
|
934
|
-
* @returns Returns `true` if elements are merged.
|
|
935
|
-
*/
|
|
936
|
-
private _wrapAttributeElement;
|
|
937
|
-
/**
|
|
938
|
-
* Unwraps {@link module:engine/view/attributeelement~AttributeElement AttributeElement} from another by removing
|
|
939
|
-
* corresponding attributes, classes and styles. All attributes, classes and styles from wrapper should be present
|
|
940
|
-
* inside element being unwrapped.
|
|
941
|
-
*
|
|
942
|
-
* @param wrapper Wrapper AttributeElement.
|
|
943
|
-
* @param toUnwrap AttributeElement to unwrap using wrapper element.
|
|
944
|
-
* @returns Returns `true` if elements are unwrapped.
|
|
945
|
-
**/
|
|
946
|
-
private _unwrapAttributeElement;
|
|
947
959
|
/**
|
|
948
960
|
* Helper function used by other `DowncastWriter` methods. Breaks attribute elements at the boundaries of given range.
|
|
949
961
|
*
|
|
@@ -257,30 +257,21 @@ export default class DowncastWriter {
|
|
|
257
257
|
}
|
|
258
258
|
return rawElement;
|
|
259
259
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
* @param key The attribute key.
|
|
268
|
-
* @param value The attribute value.
|
|
269
|
-
*/
|
|
270
|
-
setAttribute(key, value, element) {
|
|
271
|
-
element._setAttribute(key, value);
|
|
260
|
+
setAttribute(key, value, elementOrOverwrite, element) {
|
|
261
|
+
if (element !== undefined) {
|
|
262
|
+
element._setAttribute(key, value, elementOrOverwrite);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
elementOrOverwrite._setAttribute(key, value);
|
|
266
|
+
}
|
|
272
267
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
* @param key Attribute key.
|
|
281
|
-
*/
|
|
282
|
-
removeAttribute(key, element) {
|
|
283
|
-
element._removeAttribute(key);
|
|
268
|
+
removeAttribute(key, elementOrTokens, element) {
|
|
269
|
+
if (element !== undefined) {
|
|
270
|
+
element._removeAttribute(key, elementOrTokens);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
elementOrTokens._removeAttribute(key);
|
|
274
|
+
}
|
|
284
275
|
}
|
|
285
276
|
/**
|
|
286
277
|
* Adds specified class to the element.
|
|
@@ -1018,7 +1009,8 @@ export default class DowncastWriter {
|
|
|
1018
1009
|
//
|
|
1019
1010
|
// <p><span class="bar">abc</span></p> --> <p><span class="foo bar">abc</span></p>
|
|
1020
1011
|
//
|
|
1021
|
-
if (isAttribute &&
|
|
1012
|
+
if (isAttribute && child._canMergeAttributesFrom(wrapElement)) {
|
|
1013
|
+
child._mergeAttributesFrom(wrapElement);
|
|
1022
1014
|
wrapPositions.push(new Position(parent, i));
|
|
1023
1015
|
}
|
|
1024
1016
|
//
|
|
@@ -1109,7 +1101,8 @@ export default class DowncastWriter {
|
|
|
1109
1101
|
// <p><span class="foo bar">abc</span>xyz</p> --> <p><span class="bar">abc</span>xyz</p>
|
|
1110
1102
|
// <p><i class="foo">abc</i>xyz</p> --> <p><i class="foo">abc</i>xyz</p>
|
|
1111
1103
|
//
|
|
1112
|
-
if (
|
|
1104
|
+
if (child._canSubtractAttributesOf(unwrapElement)) {
|
|
1105
|
+
child._subtractAttributesOf(unwrapElement);
|
|
1113
1106
|
unwrapPositions.push(new Position(parent, i), new Position(parent, i + 1));
|
|
1114
1107
|
i++;
|
|
1115
1108
|
continue;
|
|
@@ -1203,116 +1196,6 @@ export default class DowncastWriter {
|
|
|
1203
1196
|
// If position is next to text node - move position inside.
|
|
1204
1197
|
return movePositionToTextNode(newPosition);
|
|
1205
1198
|
}
|
|
1206
|
-
/**
|
|
1207
|
-
* Wraps one {@link module:engine/view/attributeelement~AttributeElement AttributeElement} into another by
|
|
1208
|
-
* merging them if possible. When merging is possible - all attributes, styles and classes are moved from wrapper
|
|
1209
|
-
* element to element being wrapped.
|
|
1210
|
-
*
|
|
1211
|
-
* @param wrapper Wrapper AttributeElement.
|
|
1212
|
-
* @param toWrap AttributeElement to wrap using wrapper element.
|
|
1213
|
-
* @returns Returns `true` if elements are merged.
|
|
1214
|
-
*/
|
|
1215
|
-
_wrapAttributeElement(wrapper, toWrap) {
|
|
1216
|
-
if (!canBeJoined(wrapper, toWrap)) {
|
|
1217
|
-
return false;
|
|
1218
|
-
}
|
|
1219
|
-
// Can't merge if name or priority differs.
|
|
1220
|
-
if (wrapper.name !== toWrap.name || wrapper.priority !== toWrap.priority) {
|
|
1221
|
-
return false;
|
|
1222
|
-
}
|
|
1223
|
-
// Check if attributes can be merged.
|
|
1224
|
-
for (const key of wrapper.getAttributeKeys()) {
|
|
1225
|
-
// Classes and styles should be checked separately.
|
|
1226
|
-
if (key === 'class' || key === 'style') {
|
|
1227
|
-
continue;
|
|
1228
|
-
}
|
|
1229
|
-
// If some attributes are different we cannot wrap.
|
|
1230
|
-
if (toWrap.hasAttribute(key) && toWrap.getAttribute(key) !== wrapper.getAttribute(key)) {
|
|
1231
|
-
return false;
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
// Check if styles can be merged.
|
|
1235
|
-
for (const key of wrapper.getStyleNames()) {
|
|
1236
|
-
if (toWrap.hasStyle(key) && toWrap.getStyle(key) !== wrapper.getStyle(key)) {
|
|
1237
|
-
return false;
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
// Move all attributes/classes/styles from wrapper to wrapped AttributeElement.
|
|
1241
|
-
for (const key of wrapper.getAttributeKeys()) {
|
|
1242
|
-
// Classes and styles should be checked separately.
|
|
1243
|
-
if (key === 'class' || key === 'style') {
|
|
1244
|
-
continue;
|
|
1245
|
-
}
|
|
1246
|
-
// Move only these attributes that are not present - other are similar.
|
|
1247
|
-
if (!toWrap.hasAttribute(key)) {
|
|
1248
|
-
this.setAttribute(key, wrapper.getAttribute(key), toWrap);
|
|
1249
|
-
}
|
|
1250
|
-
}
|
|
1251
|
-
for (const key of wrapper.getStyleNames()) {
|
|
1252
|
-
if (!toWrap.hasStyle(key)) {
|
|
1253
|
-
this.setStyle(key, wrapper.getStyle(key), toWrap);
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
for (const key of wrapper.getClassNames()) {
|
|
1257
|
-
if (!toWrap.hasClass(key)) {
|
|
1258
|
-
this.addClass(key, toWrap);
|
|
1259
|
-
}
|
|
1260
|
-
}
|
|
1261
|
-
return true;
|
|
1262
|
-
}
|
|
1263
|
-
/**
|
|
1264
|
-
* Unwraps {@link module:engine/view/attributeelement~AttributeElement AttributeElement} from another by removing
|
|
1265
|
-
* corresponding attributes, classes and styles. All attributes, classes and styles from wrapper should be present
|
|
1266
|
-
* inside element being unwrapped.
|
|
1267
|
-
*
|
|
1268
|
-
* @param wrapper Wrapper AttributeElement.
|
|
1269
|
-
* @param toUnwrap AttributeElement to unwrap using wrapper element.
|
|
1270
|
-
* @returns Returns `true` if elements are unwrapped.
|
|
1271
|
-
**/
|
|
1272
|
-
_unwrapAttributeElement(wrapper, toUnwrap) {
|
|
1273
|
-
if (!canBeJoined(wrapper, toUnwrap)) {
|
|
1274
|
-
return false;
|
|
1275
|
-
}
|
|
1276
|
-
// Can't unwrap if name or priority differs.
|
|
1277
|
-
if (wrapper.name !== toUnwrap.name || wrapper.priority !== toUnwrap.priority) {
|
|
1278
|
-
return false;
|
|
1279
|
-
}
|
|
1280
|
-
// Check if AttributeElement has all wrapper attributes.
|
|
1281
|
-
for (const key of wrapper.getAttributeKeys()) {
|
|
1282
|
-
// Classes and styles should be checked separately.
|
|
1283
|
-
if (key === 'class' || key === 'style') {
|
|
1284
|
-
continue;
|
|
1285
|
-
}
|
|
1286
|
-
// If some attributes are missing or different we cannot unwrap.
|
|
1287
|
-
if (!toUnwrap.hasAttribute(key) || toUnwrap.getAttribute(key) !== wrapper.getAttribute(key)) {
|
|
1288
|
-
return false;
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
// Check if AttributeElement has all wrapper classes.
|
|
1292
|
-
if (!toUnwrap.hasClass(...wrapper.getClassNames())) {
|
|
1293
|
-
return false;
|
|
1294
|
-
}
|
|
1295
|
-
// Check if AttributeElement has all wrapper styles.
|
|
1296
|
-
for (const key of wrapper.getStyleNames()) {
|
|
1297
|
-
// If some styles are missing or different we cannot unwrap.
|
|
1298
|
-
if (!toUnwrap.hasStyle(key) || toUnwrap.getStyle(key) !== wrapper.getStyle(key)) {
|
|
1299
|
-
return false;
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
// Remove all wrapper's attributes from unwrapped element.
|
|
1303
|
-
for (const key of wrapper.getAttributeKeys()) {
|
|
1304
|
-
// Classes and styles should be checked separately.
|
|
1305
|
-
if (key === 'class' || key === 'style') {
|
|
1306
|
-
continue;
|
|
1307
|
-
}
|
|
1308
|
-
this.removeAttribute(key, toUnwrap);
|
|
1309
|
-
}
|
|
1310
|
-
// Remove all wrapper's classes from unwrapped element.
|
|
1311
|
-
this.removeClass(Array.from(wrapper.getClassNames()), toUnwrap);
|
|
1312
|
-
// Remove all wrapper's styles from unwrapped element.
|
|
1313
|
-
this.removeStyle(Array.from(wrapper.getStyleNames()), toUnwrap);
|
|
1314
|
-
return true;
|
|
1315
|
-
}
|
|
1316
1199
|
/**
|
|
1317
1200
|
* Helper function used by other `DowncastWriter` methods. Breaks attribute elements at the boundaries of given range.
|
|
1318
1201
|
*
|
|
@@ -1687,10 +1570,3 @@ function validateRangeContainer(range, errorContext) {
|
|
|
1687
1570
|
throw new CKEditorError('view-writer-invalid-range-container', errorContext);
|
|
1688
1571
|
}
|
|
1689
1572
|
}
|
|
1690
|
-
/**
|
|
1691
|
-
* Checks if two attribute elements can be joined together. Elements can be joined together if, and only if
|
|
1692
|
-
* they do not have ids specified.
|
|
1693
|
-
*/
|
|
1694
|
-
function canBeJoined(a, b) {
|
|
1695
|
-
return a.id === null && b.id === null;
|
|
1696
|
-
}
|