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,20 +102,25 @@ 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 (data.$trusted) {
|
if (!editable || editable !== window.document.activeElement) {
|
||||||
var current = cached.nodes[0], nodes = [current]
|
if (data.$trusted) {
|
||||||
if (current) {
|
var current = cached.nodes[0], nodes = [current]
|
||||||
while (current = current.nextSibling) nodes.push(current)
|
if (current) {
|
||||||
clear(nodes)
|
while (current = current.nextSibling) nodes.push(current)
|
||||||
node = injectHTML(parentElement, index, data)
|
clear(nodes)
|
||||||
|
node = injectHTML(parentElement, index, data)
|
||||||
|
}
|
||||||
|
else parentElement.innerHTML = data
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node = cached.nodes[0]
|
||||||
|
if (parentTag === "textarea") parentElement.value = data
|
||||||
|
else if (editable) editable.innerHTML = data
|
||||||
|
else {
|
||||||
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
|
node.nodeValue = data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else parentElement.innerHTML = data
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
node = cached.nodes[0]
|
|
||||||
if (parentTag === "textarea") parentElement.value = data
|
|
||||||
else parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
|
||||||
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,20 +102,25 @@ 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 (data.$trusted) {
|
if (!editable || editable !== window.document.activeElement) {
|
||||||
var current = cached.nodes[0], nodes = [current]
|
if (data.$trusted) {
|
||||||
if (current) {
|
var current = cached.nodes[0], nodes = [current]
|
||||||
while (current = current.nextSibling) nodes.push(current)
|
if (current) {
|
||||||
clear(nodes)
|
while (current = current.nextSibling) nodes.push(current)
|
||||||
node = injectHTML(parentElement, index, data)
|
clear(nodes)
|
||||||
|
node = injectHTML(parentElement, index, data)
|
||||||
|
}
|
||||||
|
else parentElement.innerHTML = data
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node = cached.nodes[0]
|
||||||
|
if (parentTag === "textarea") parentElement.value = data
|
||||||
|
else if (editable) editable.innerHTML = data
|
||||||
|
else {
|
||||||
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
|
node.nodeValue = data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else parentElement.innerHTML = data
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
node = cached.nodes[0]
|
|
||||||
if (parentTag === "textarea") parentElement.value = data
|
|
||||||
else parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
|
||||||
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.
42
mithril.js
42
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,20 +102,25 @@ 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 (data.$trusted) {
|
if (!editable || editable !== window.document.activeElement) {
|
||||||
var current = cached.nodes[0], nodes = [current]
|
if (data.$trusted) {
|
||||||
if (current) {
|
var current = cached.nodes[0], nodes = [current]
|
||||||
while (current = current.nextSibling) nodes.push(current)
|
if (current) {
|
||||||
clear(nodes)
|
while (current = current.nextSibling) nodes.push(current)
|
||||||
node = injectHTML(parentElement, index, data)
|
clear(nodes)
|
||||||
|
node = injectHTML(parentElement, index, data)
|
||||||
|
}
|
||||||
|
else parentElement.innerHTML = data
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node = cached.nodes[0]
|
||||||
|
if (parentTag === "textarea") parentElement.value = data
|
||||||
|
else if (editable) editable.innerHTML = data
|
||||||
|
else {
|
||||||
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
|
node.nodeValue = data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else parentElement.innerHTML = data
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
node = cached.nodes[0]
|
|
||||||
if (parentTag === "textarea") parentElement.value = data
|
|
||||||
else parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
|
||||||
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) {
|
||||||
|
|
|
||||||
|
|
@ -17,20 +17,25 @@ app.view = function(ctrl) {
|
||||||
onkeyup: m.withAttr("value", ctrl.title),
|
onkeyup: m.withAttr("value", ctrl.title),
|
||||||
value: ctrl.title()
|
value: ctrl.title()
|
||||||
}),
|
}),
|
||||||
m("br"),
|
m("br"),
|
||||||
m("textarea", {
|
m("textarea", {
|
||||||
onkeyup: m.withAttr("value", ctrl.title),
|
onkeyup: m.withAttr("value", ctrl.title),
|
||||||
value: ctrl.title()
|
value: ctrl.title()
|
||||||
}),
|
}),
|
||||||
m("br"),
|
m("br"),
|
||||||
m("textarea", {
|
m("textarea", {
|
||||||
onkeyup: m.withAttr("value", ctrl.title)
|
onkeyup: m.withAttr("value", ctrl.title)
|
||||||
}, ctrl.title()),
|
}, ctrl.title()),
|
||||||
m("br"),
|
m("br"),
|
||||||
m("div[contenteditable]", {
|
m("div[contenteditable]", {
|
||||||
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