-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
/
utils.js
85 lines (73 loc) · 2.47 KB
/
utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
* @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module typing/utils/utils
*/
import diff from '@ckeditor/ckeditor5-utils/src/diff';
import diffToChanges from '@ckeditor/ckeditor5-utils/src/difftochanges';
/**
* Returns true if container children have mutated or more than a single text node was changed.
*
* @private
* @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|
* module:engine/view/observer/mutationobserver~MutatedChildren>} mutations
* @returns {Boolean}
*/
export function containerChildrenMutated( mutations ) {
if ( mutations.length == 0 ) {
return false;
}
// Check if there is any mutation of `children` type or any mutation that changes more than one text node.
for ( const mutation of mutations ) {
if ( mutation.type === 'children' && !getSingleTextNodeChange( mutation ) ) {
return true;
}
}
return false;
}
/**
* Returns change made to a single text node.
*
* @private
* @param {module:engine/view/observer/mutationobserver~MutatedText|
* module:engine/view/observer/mutationobserver~MutatedChildren} mutation
* @returns {Object|undefined} Change object (see {@link module:utils/difftochanges~diffToChanges} output)
* or undefined if more than a single text node was changed.
*/
export function getSingleTextNodeChange( mutation ) {
// One new node.
if ( mutation.newChildren.length - mutation.oldChildren.length != 1 ) {
return;
}
// Which is text.
const diffResult = diff( mutation.oldChildren, mutation.newChildren, compareChildNodes );
const changes = diffToChanges( diffResult, mutation.newChildren );
// In case of [ delete, insert, insert ] the previous check will not exit.
if ( changes.length > 1 ) {
return;
}
const change = changes[ 0 ];
// Which is text.
if ( !( !!change.values[ 0 ] && change.values[ 0 ].is( 'text' ) ) ) {
return;
}
return change;
}
/**
* Checks whether two view nodes are identical, which means they are the same object
* or contain exactly same data (in case of text nodes).
*
* @private
* @param {module:engine/view/node~Node} oldChild
* @param {module:engine/view/node~Node} newChild
* @returns {Boolean}
*/
export function compareChildNodes( oldChild, newChild ) {
if ( !!oldChild && oldChild.is( 'text' ) && !!newChild && newChild.is( 'text' ) ) {
return oldChild.data === newChild.data;
} else {
return oldChild === newChild;
}
}