fix contenteditable diffing
This commit is contained in:
parent
10229546eb
commit
42a33b074c
7 changed files with 82 additions and 59 deletions
|
|
@ -32,7 +32,7 @@ Mithril = m = new function app(window) {
|
||||||
}
|
}
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
function build(parentElement, parentTag, data, cached, shouldReattach, index, namespace) {
|
function build(parentElement, parentTag, data, cached, shouldReattach, index, editable, namespace) {
|
||||||
if (data === null || data === undefined) {
|
if (data === null || data === undefined) {
|
||||||
if (cached) clear(cached.nodes)
|
if (cached) clear(cached.nodes)
|
||||||
return
|
return
|
||||||
|
|
@ -49,7 +49,7 @@ Mithril = m = new function app(window) {
|
||||||
if (dataType == "[object Array]") {
|
if (dataType == "[object Array]") {
|
||||||
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
||||||
for (var i = 0, cacheCount = 0; i < data.length; i++) {
|
for (var i = 0, cacheCount = 0; i < data.length; i++) {
|
||||||
var item = build(parentElement, null, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, namespace)
|
var item = build(parentElement, null, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, editable, namespace)
|
||||||
if (item === undefined) continue
|
if (item === undefined) continue
|
||||||
if (!item.nodes.intact) intact = false
|
if (!item.nodes.intact) intact = false
|
||||||
subArrayCount += item instanceof Array ? item.length : 1
|
subArrayCount += item instanceof Array ? item.length : 1
|
||||||
|
|
@ -74,7 +74,7 @@ Mithril = m = new function app(window) {
|
||||||
cached = {
|
cached = {
|
||||||
tag: data.tag,
|
tag: data.tag,
|
||||||
attrs: setAttributes(node, data.tag, data.attrs, {}, namespace),
|
attrs: setAttributes(node, data.tag, data.attrs, {}, namespace),
|
||||||
children: build(node, data.tag, data.children, cached.children, true, 0, namespace),
|
children: build(node, data.tag, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace),
|
||||||
nodes: [node]
|
nodes: [node]
|
||||||
}
|
}
|
||||||
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
|
|
@ -82,7 +82,7 @@ Mithril = m = new function app(window) {
|
||||||
else {
|
else {
|
||||||
node = cached.nodes[0]
|
node = cached.nodes[0]
|
||||||
setAttributes(node, data.tag, data.attrs, cached.attrs, namespace)
|
setAttributes(node, data.tag, data.attrs, cached.attrs, namespace)
|
||||||
cached.children = build(node, data.tag, data.children, cached.children, false, 0, namespace)
|
cached.children = build(node, data.tag, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace)
|
||||||
cached.nodes.intact = true
|
cached.nodes.intact = true
|
||||||
if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +102,7 @@ Mithril = m = new function app(window) {
|
||||||
cached.nodes = [node]
|
cached.nodes = [node]
|
||||||
}
|
}
|
||||||
else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) {
|
else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) {
|
||||||
|
if (!editable || editable !== window.document.activeElement) {
|
||||||
if (data.$trusted) {
|
if (data.$trusted) {
|
||||||
var current = cached.nodes[0], nodes = [current]
|
var current = cached.nodes[0], nodes = [current]
|
||||||
if (current) {
|
if (current) {
|
||||||
|
|
@ -114,9 +115,13 @@ Mithril = m = new function app(window) {
|
||||||
else {
|
else {
|
||||||
node = cached.nodes[0]
|
node = cached.nodes[0]
|
||||||
if (parentTag === "textarea") parentElement.value = data
|
if (parentTag === "textarea") parentElement.value = data
|
||||||
else parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
else if (editable) editable.innerHTML = data
|
||||||
|
else {
|
||||||
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
node.nodeValue = data
|
node.nodeValue = data
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
cached = new data.constructor(data)
|
cached = new data.constructor(data)
|
||||||
cached.nodes = [node]
|
cached.nodes = [node]
|
||||||
}
|
}
|
||||||
|
|
@ -137,6 +142,7 @@ Mithril = m = new function app(window) {
|
||||||
}
|
}
|
||||||
else if (attrName === "style") {
|
else if (attrName === "style") {
|
||||||
for (var rule in dataAttr) {
|
for (var rule in dataAttr) {
|
||||||
|
console.log(node)
|
||||||
if (cachedAttr === undefined || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule]
|
if (cachedAttr === undefined || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +208,7 @@ Mithril = m = new function app(window) {
|
||||||
var index = nodeCache.indexOf(root)
|
var index = nodeCache.indexOf(root)
|
||||||
var id = index < 0 ? nodeCache.push(root) - 1 : index
|
var id = index < 0 ? nodeCache.push(root) - 1 : index
|
||||||
var node = root == window.document || root == window.document.documentElement ? documentNode : root
|
var node = root == window.document || root == window.document.documentElement ? documentNode : root
|
||||||
cellCache[id] = build(node, null, cell, cellCache[id], false, 0)
|
cellCache[id] = build(node, null, cell, cellCache[id], false, 0, null, undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
m.trust = function(value) {
|
m.trust = function(value) {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ Mithril = m = new function app(window) {
|
||||||
}
|
}
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
function build(parentElement, parentTag, data, cached, shouldReattach, index, namespace) {
|
function build(parentElement, parentTag, data, cached, shouldReattach, index, editable, namespace) {
|
||||||
if (data === null || data === undefined) {
|
if (data === null || data === undefined) {
|
||||||
if (cached) clear(cached.nodes)
|
if (cached) clear(cached.nodes)
|
||||||
return
|
return
|
||||||
|
|
@ -49,7 +49,7 @@ Mithril = m = new function app(window) {
|
||||||
if (dataType == "[object Array]") {
|
if (dataType == "[object Array]") {
|
||||||
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
||||||
for (var i = 0, cacheCount = 0; i < data.length; i++) {
|
for (var i = 0, cacheCount = 0; i < data.length; i++) {
|
||||||
var item = build(parentElement, null, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, namespace)
|
var item = build(parentElement, null, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, editable, namespace)
|
||||||
if (item === undefined) continue
|
if (item === undefined) continue
|
||||||
if (!item.nodes.intact) intact = false
|
if (!item.nodes.intact) intact = false
|
||||||
subArrayCount += item instanceof Array ? item.length : 1
|
subArrayCount += item instanceof Array ? item.length : 1
|
||||||
|
|
@ -74,7 +74,7 @@ Mithril = m = new function app(window) {
|
||||||
cached = {
|
cached = {
|
||||||
tag: data.tag,
|
tag: data.tag,
|
||||||
attrs: setAttributes(node, data.tag, data.attrs, {}, namespace),
|
attrs: setAttributes(node, data.tag, data.attrs, {}, namespace),
|
||||||
children: build(node, data.tag, data.children, cached.children, true, 0, namespace),
|
children: build(node, data.tag, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace),
|
||||||
nodes: [node]
|
nodes: [node]
|
||||||
}
|
}
|
||||||
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
|
|
@ -82,7 +82,7 @@ Mithril = m = new function app(window) {
|
||||||
else {
|
else {
|
||||||
node = cached.nodes[0]
|
node = cached.nodes[0]
|
||||||
setAttributes(node, data.tag, data.attrs, cached.attrs, namespace)
|
setAttributes(node, data.tag, data.attrs, cached.attrs, namespace)
|
||||||
cached.children = build(node, data.tag, data.children, cached.children, false, 0, namespace)
|
cached.children = build(node, data.tag, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace)
|
||||||
cached.nodes.intact = true
|
cached.nodes.intact = true
|
||||||
if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +102,7 @@ Mithril = m = new function app(window) {
|
||||||
cached.nodes = [node]
|
cached.nodes = [node]
|
||||||
}
|
}
|
||||||
else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) {
|
else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) {
|
||||||
|
if (!editable || editable !== window.document.activeElement) {
|
||||||
if (data.$trusted) {
|
if (data.$trusted) {
|
||||||
var current = cached.nodes[0], nodes = [current]
|
var current = cached.nodes[0], nodes = [current]
|
||||||
if (current) {
|
if (current) {
|
||||||
|
|
@ -114,9 +115,13 @@ Mithril = m = new function app(window) {
|
||||||
else {
|
else {
|
||||||
node = cached.nodes[0]
|
node = cached.nodes[0]
|
||||||
if (parentTag === "textarea") parentElement.value = data
|
if (parentTag === "textarea") parentElement.value = data
|
||||||
else parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
else if (editable) editable.innerHTML = data
|
||||||
|
else {
|
||||||
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
node.nodeValue = data
|
node.nodeValue = data
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
cached = new data.constructor(data)
|
cached = new data.constructor(data)
|
||||||
cached.nodes = [node]
|
cached.nodes = [node]
|
||||||
}
|
}
|
||||||
|
|
@ -137,6 +142,7 @@ Mithril = m = new function app(window) {
|
||||||
}
|
}
|
||||||
else if (attrName === "style") {
|
else if (attrName === "style") {
|
||||||
for (var rule in dataAttr) {
|
for (var rule in dataAttr) {
|
||||||
|
console.log(node)
|
||||||
if (cachedAttr === undefined || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule]
|
if (cachedAttr === undefined || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +208,7 @@ Mithril = m = new function app(window) {
|
||||||
var index = nodeCache.indexOf(root)
|
var index = nodeCache.indexOf(root)
|
||||||
var id = index < 0 ? nodeCache.push(root) - 1 : index
|
var id = index < 0 ? nodeCache.push(root) - 1 : index
|
||||||
var node = root == window.document || root == window.document.documentElement ? documentNode : root
|
var node = root == window.document || root == window.document.documentElement ? documentNode : root
|
||||||
cellCache[id] = build(node, null, cell, cellCache[id], false, 0)
|
cellCache[id] = build(node, null, cell, cellCache[id], false, 0, null, undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
m.trust = function(value) {
|
m.trust = function(value) {
|
||||||
|
|
|
||||||
2
archive/v0.1.11/mithril.min.js
vendored
2
archive/v0.1.11/mithril.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
18
mithril.js
18
mithril.js
|
|
@ -32,7 +32,7 @@ Mithril = m = new function app(window) {
|
||||||
}
|
}
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
function build(parentElement, parentTag, data, cached, shouldReattach, index, namespace) {
|
function build(parentElement, parentTag, data, cached, shouldReattach, index, editable, namespace) {
|
||||||
if (data === null || data === undefined) {
|
if (data === null || data === undefined) {
|
||||||
if (cached) clear(cached.nodes)
|
if (cached) clear(cached.nodes)
|
||||||
return
|
return
|
||||||
|
|
@ -49,7 +49,7 @@ Mithril = m = new function app(window) {
|
||||||
if (dataType == "[object Array]") {
|
if (dataType == "[object Array]") {
|
||||||
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
||||||
for (var i = 0, cacheCount = 0; i < data.length; i++) {
|
for (var i = 0, cacheCount = 0; i < data.length; i++) {
|
||||||
var item = build(parentElement, null, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, namespace)
|
var item = build(parentElement, null, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, editable, namespace)
|
||||||
if (item === undefined) continue
|
if (item === undefined) continue
|
||||||
if (!item.nodes.intact) intact = false
|
if (!item.nodes.intact) intact = false
|
||||||
subArrayCount += item instanceof Array ? item.length : 1
|
subArrayCount += item instanceof Array ? item.length : 1
|
||||||
|
|
@ -74,7 +74,7 @@ Mithril = m = new function app(window) {
|
||||||
cached = {
|
cached = {
|
||||||
tag: data.tag,
|
tag: data.tag,
|
||||||
attrs: setAttributes(node, data.tag, data.attrs, {}, namespace),
|
attrs: setAttributes(node, data.tag, data.attrs, {}, namespace),
|
||||||
children: build(node, data.tag, data.children, cached.children, true, 0, namespace),
|
children: build(node, data.tag, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace),
|
||||||
nodes: [node]
|
nodes: [node]
|
||||||
}
|
}
|
||||||
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
|
|
@ -82,7 +82,7 @@ Mithril = m = new function app(window) {
|
||||||
else {
|
else {
|
||||||
node = cached.nodes[0]
|
node = cached.nodes[0]
|
||||||
setAttributes(node, data.tag, data.attrs, cached.attrs, namespace)
|
setAttributes(node, data.tag, data.attrs, cached.attrs, namespace)
|
||||||
cached.children = build(node, data.tag, data.children, cached.children, false, 0, namespace)
|
cached.children = build(node, data.tag, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace)
|
||||||
cached.nodes.intact = true
|
cached.nodes.intact = true
|
||||||
if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +102,7 @@ Mithril = m = new function app(window) {
|
||||||
cached.nodes = [node]
|
cached.nodes = [node]
|
||||||
}
|
}
|
||||||
else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) {
|
else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) {
|
||||||
|
if (!editable || editable !== window.document.activeElement) {
|
||||||
if (data.$trusted) {
|
if (data.$trusted) {
|
||||||
var current = cached.nodes[0], nodes = [current]
|
var current = cached.nodes[0], nodes = [current]
|
||||||
if (current) {
|
if (current) {
|
||||||
|
|
@ -114,9 +115,13 @@ Mithril = m = new function app(window) {
|
||||||
else {
|
else {
|
||||||
node = cached.nodes[0]
|
node = cached.nodes[0]
|
||||||
if (parentTag === "textarea") parentElement.value = data
|
if (parentTag === "textarea") parentElement.value = data
|
||||||
else parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
else if (editable) editable.innerHTML = data
|
||||||
|
else {
|
||||||
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
node.nodeValue = data
|
node.nodeValue = data
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
cached = new data.constructor(data)
|
cached = new data.constructor(data)
|
||||||
cached.nodes = [node]
|
cached.nodes = [node]
|
||||||
}
|
}
|
||||||
|
|
@ -137,6 +142,7 @@ Mithril = m = new function app(window) {
|
||||||
}
|
}
|
||||||
else if (attrName === "style") {
|
else if (attrName === "style") {
|
||||||
for (var rule in dataAttr) {
|
for (var rule in dataAttr) {
|
||||||
|
console.log(node)
|
||||||
if (cachedAttr === undefined || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule]
|
if (cachedAttr === undefined || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +208,7 @@ Mithril = m = new function app(window) {
|
||||||
var index = nodeCache.indexOf(root)
|
var index = nodeCache.indexOf(root)
|
||||||
var id = index < 0 ? nodeCache.push(root) - 1 : index
|
var id = index < 0 ? nodeCache.push(root) - 1 : index
|
||||||
var node = root == window.document || root == window.document.documentElement ? documentNode : root
|
var node = root == window.document || root == window.document.documentElement ? documentNode : root
|
||||||
cellCache[id] = build(node, null, cell, cellCache[id], false, 0)
|
cellCache[id] = build(node, null, cell, cellCache[id], false, 0, null, undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
m.trust = function(value) {
|
m.trust = function(value) {
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,11 @@ app.view = function(ctrl) {
|
||||||
style: {border: "1px solid #888"},
|
style: {border: "1px solid #888"},
|
||||||
onkeyup: m.withAttr("innerHTML", ctrl.title)
|
onkeyup: m.withAttr("innerHTML", ctrl.title)
|
||||||
}, ctrl.title()),
|
}, ctrl.title()),
|
||||||
|
m("br"),
|
||||||
|
m("div[contenteditable]", {
|
||||||
|
style: {border: "1px solid #888"},
|
||||||
|
onkeyup: m.withAttr("innerHTML", ctrl.title)
|
||||||
|
}, m.trust(ctrl.title())),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue