git ssb

1+

Matt McKegg / mutant



Commit b588b1cbc0c0e85d0288a7fa484660bf8225a915

html-element: new algorithm for replacing nodes, takes existing nodes into account

Matt McKegg committed on 7/27/2016, 4:41:35 AM
Parent: 3bfb6e65a932b5fb11b3c2260c7582699eb17ae5

Files changed

html-element.jschanged
html-element.jsView
@@ -111,29 +111,42 @@
111111 }
112112 })
113113 }
114114
115 +function indexOf (target, item) {
116 + return Array.prototype.indexOf.call(target, item)
117 +}
118 +
115119 function replace (oldNodes, newNodes) {
116- // TODO: optmize to not reinsert nodes that are already in correct position!
117120 var parent = oldNodes[oldNodes.length - 1].parentNode
118- var marker = oldNodes[oldNodes.length - 1].nextSibling
121 + var nodes = parent.childNodes
122 + var startIndex = indexOf(nodes, oldNodes[0])
123 +
124 + // avoid reinserting nodes that are already in correct position!
125 + for (var i = 0; i < newNodes.length; i++) {
126 + if (nodes[i + startIndex] === newNodes[i]) {
127 + continue
128 + } else if (nodes[i + startIndex + 1] === newNodes[i]) {
129 + parent.removeChild(nodes[i + startIndex])
130 + continue
131 + } else if (nodes[i + startIndex] === newNodes[i + 1] && newNodes[i + 1]) {
132 + parent.insertBefore(newNodes[i], nodes[i + startIndex])
133 + } else if (nodes[i + startIndex]) {
134 + parent.insertBefore(newNodes[i], nodes[i + startIndex])
135 + } else {
136 + parent.appendChild(newNodes[i])
137 + }
138 + walk(newNodes[i], rebind)
139 + }
140 +
119141 oldNodes.filter(function (node) {
120142 return !~newNodes.indexOf(node)
121143 }).forEach(function (node) {
122- parent.removeChild(node)
144 + if (node.parentNode) {
145 + parent.removeChild(node)
146 + }
123147 walk(node, unbind)
124148 })
125- if (marker) {
126- newNodes.forEach(function (node) {
127- parent.insertBefore(node, marker)
128- walk(node, rebind)
129- })
130- } else {
131- newNodes.forEach(function (node) {
132- parent.appendChild(node)
133- walk(node, rebind)
134- })
135- }
136149 }
137150
138151 function isText (value) {
139152 return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean'
@@ -152,15 +165,16 @@
152165 function getNodes (document, nodeOrNodes) {
153166 if (Array.isArray(nodeOrNodes)) {
154167 if (nodeOrNodes.length) {
155168 var result = []
156- nodeOrNodes.forEach(function (item) {
169 + for (var i = 0; i < nodeOrNodes.length; i++) {
170 + var item = nodeOrNodes[i]
157171 if (Array.isArray(item)) {
158172 getNodes(document, item).forEach(push, result)
159173 } else {
160174 result.push(getNode(document, item))
161175 }
162- })
176 + }
163177 return result.map(getNode.bind(this, document))
164178 } else {
165179 return [getNode(document, null)]
166180 }

Built with git-ssb-web