-
Notifications
You must be signed in to change notification settings - Fork 47.5k
/
Copy pathDOMLazyTree.js
132 lines (117 loc) · 3.73 KB
/
DOMLazyTree.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
* Copyright 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule DOMLazyTree
*/
'use strict';
var DOMNamespaces = require('DOMNamespaces');
var setInnerHTML = require('setInnerHTML');
var createMicrosoftUnsafeLocalFunction = require('createMicrosoftUnsafeLocalFunction');
var setTextContent = require('setTextContent');
var ELEMENT_NODE_TYPE = 1;
var DOCUMENT_FRAGMENT_NODE_TYPE = 11;
/**
* In IE (8-11) and Edge, appending nodes with no children is dramatically
* faster than appending a full subtree, so we essentially queue up the
* .appendChild calls here and apply them so each node is added to its parent
* before any children are added.
*
* In other browsers, doing so is slower or neutral compared to the other order
* (in Firefox, twice as slow) so we only do this inversion in IE.
*
* See https://github.com/spicyj/innerhtml-vs-createelement-vs-clonenode.
*/
var enableLazy = (
typeof document !== 'undefined' &&
typeof document.documentMode === 'number'
||
typeof navigator !== 'undefined' &&
typeof navigator.userAgent === 'string' &&
/\bEdge\/\d/.test(navigator.userAgent)
);
function insertTreeChildren(tree) {
if (!enableLazy) {
return;
}
var node = tree.node;
var children = tree.children;
if (children.length) {
for (var i = 0; i < children.length; i++) {
insertTreeBefore(node, children[i], null);
}
} else if (tree.html != null) {
setInnerHTML(node, tree.html);
} else if (tree.text != null) {
setTextContent(node, tree.text);
}
}
var insertTreeBefore = createMicrosoftUnsafeLocalFunction(
function(parentNode, tree, referenceNode) {
// DocumentFragments aren't actually part of the DOM after insertion so
// appending children won't update the DOM. We need to ensure the fragment
// is properly populated first, breaking out of our lazy approach for just
// this level. Also, some <object> plugins (like Flash Player) will read
// <param> nodes immediately upon insertion into the DOM, so <object>
// must also be populated prior to insertion into the DOM.
if (tree.node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE
||
tree.node.nodeType === ELEMENT_NODE_TYPE &&
tree.node.nodeName.toLowerCase() === 'object' &&
(tree.node.namespaceURI == null ||
tree.node.namespaceURI === DOMNamespaces.html)) {
insertTreeChildren(tree);
parentNode.insertBefore(tree.node, referenceNode);
} else {
parentNode.insertBefore(tree.node, referenceNode);
insertTreeChildren(tree);
}
}
);
function replaceChildWithTree(oldNode, newTree) {
oldNode.parentNode.replaceChild(newTree.node, oldNode);
insertTreeChildren(newTree);
}
function queueChild(parentTree, childTree) {
if (enableLazy) {
parentTree.children.push(childTree);
} else {
parentTree.node.appendChild(childTree.node);
}
}
function queueHTML(tree, html) {
if (enableLazy) {
tree.html = html;
} else {
setInnerHTML(tree.node, html);
}
}
function queueText(tree, text) {
if (enableLazy) {
tree.text = text;
} else {
setTextContent(tree.node, text);
}
}
function toString() {
return this.node.nodeName;
}
function DOMLazyTree(node) {
return {
node: node,
children: [],
html: null,
text: null,
toString,
};
}
DOMLazyTree.insertTreeBefore = insertTreeBefore;
DOMLazyTree.replaceChildWithTree = replaceChildWithTree;
DOMLazyTree.queueChild = queueChild;
DOMLazyTree.queueHTML = queueHTML;
DOMLazyTree.queueText = queueText;
module.exports = DOMLazyTree;