From 42a33b074c97a395530b2925c333894ed2b43877 Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Thu, 1 May 2014 22:32:10 -0400 Subject: [PATCH] fix contenteditable diffing --- archive/v0.1.11/mithril-tests.js | 42 ++++++++++++++++++------------- archive/v0.1.11/mithril.js | 42 ++++++++++++++++++------------- archive/v0.1.11/mithril.min.js | 2 +- archive/v0.1.11/mithril.min.map | 2 +- archive/v0.1.11/mithril.min.zip | Bin 41212 -> 42018 bytes mithril.js | 42 ++++++++++++++++++------------- tests/input-cursor.html | 11 +++++--- 7 files changed, 82 insertions(+), 59 deletions(-) diff --git a/archive/v0.1.11/mithril-tests.js b/archive/v0.1.11/mithril-tests.js index 8b40890c..bac8917b 100644 --- a/archive/v0.1.11/mithril-tests.js +++ b/archive/v0.1.11/mithril-tests.js @@ -32,7 +32,7 @@ Mithril = m = new function app(window) { } 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 (cached) clear(cached.nodes) return @@ -49,7 +49,7 @@ Mithril = m = new function app(window) { if (dataType == "[object Array]") { var nodes = [], intact = cached.length === data.length, subArrayCount = 0 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.nodes.intact) intact = false subArrayCount += item instanceof Array ? item.length : 1 @@ -74,7 +74,7 @@ Mithril = m = new function app(window) { cached = { tag: data.tag, 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] } parentElement.insertBefore(node, parentElement.childNodes[index] || null) @@ -82,7 +82,7 @@ Mithril = m = new function app(window) { else { node = cached.nodes[0] 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 if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null) } @@ -102,20 +102,25 @@ Mithril = m = new function app(window) { cached.nodes = [node] } else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) { - if (data.$trusted) { - var current = cached.nodes[0], nodes = [current] - if (current) { - while (current = current.nextSibling) nodes.push(current) - clear(nodes) - node = injectHTML(parentElement, index, data) + if (!editable || editable !== window.document.activeElement) { + if (data.$trusted) { + var current = cached.nodes[0], nodes = [current] + if (current) { + while (current = current.nextSibling) nodes.push(current) + 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.nodes = [node] @@ -137,6 +142,7 @@ Mithril = m = new function app(window) { } else if (attrName === "style") { for (var rule in dataAttr) { + console.log(node) 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 id = index < 0 ? nodeCache.push(root) - 1 : index 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) { diff --git a/archive/v0.1.11/mithril.js b/archive/v0.1.11/mithril.js index f07d8197..a66726c4 100644 --- a/archive/v0.1.11/mithril.js +++ b/archive/v0.1.11/mithril.js @@ -32,7 +32,7 @@ Mithril = m = new function app(window) { } 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 (cached) clear(cached.nodes) return @@ -49,7 +49,7 @@ Mithril = m = new function app(window) { if (dataType == "[object Array]") { var nodes = [], intact = cached.length === data.length, subArrayCount = 0 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.nodes.intact) intact = false subArrayCount += item instanceof Array ? item.length : 1 @@ -74,7 +74,7 @@ Mithril = m = new function app(window) { cached = { tag: data.tag, 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] } parentElement.insertBefore(node, parentElement.childNodes[index] || null) @@ -82,7 +82,7 @@ Mithril = m = new function app(window) { else { node = cached.nodes[0] 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 if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null) } @@ -102,20 +102,25 @@ Mithril = m = new function app(window) { cached.nodes = [node] } else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) { - if (data.$trusted) { - var current = cached.nodes[0], nodes = [current] - if (current) { - while (current = current.nextSibling) nodes.push(current) - clear(nodes) - node = injectHTML(parentElement, index, data) + if (!editable || editable !== window.document.activeElement) { + if (data.$trusted) { + var current = cached.nodes[0], nodes = [current] + if (current) { + while (current = current.nextSibling) nodes.push(current) + 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.nodes = [node] @@ -137,6 +142,7 @@ Mithril = m = new function app(window) { } else if (attrName === "style") { for (var rule in dataAttr) { + console.log(node) 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 id = index < 0 ? nodeCache.push(root) - 1 : index 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) { diff --git a/archive/v0.1.11/mithril.min.js b/archive/v0.1.11/mithril.min.js index d5b8b899..bba919ab 100644 --- a/archive/v0.1.11/mithril.min.js +++ b/archive/v0.1.11/mithril.min.js @@ -4,5 +4,5 @@ http://github.com/lhorie/mithril.js (c) Leo Horie License: MIT */ -Mithril=m=new function(a){function b(){var a=arguments,b="[object Object]"==u.call(a[1]),c=b?a[1]:{},d="class"in c?"class":"className",e=t[a[0]];if(void 0===e){t[a[0]]=e={tag:"div",attrs:{}};for(var f,h=[];f=v.exec(a[0]);)if(""==f[1])e.tag=f[2];else if("#"==f[1])e.attrs.id=f[2];else if("."==f[1])h.push(f[2]);else if("["==f[3][0]){var i=w.exec(f[3]);e.attrs[i[1]]=i[3]||!0}h.length>0&&(e.attrs[d]=h.join(" "))}e=g(e),e.attrs=g(e.attrs),e.children=b?a[2]:a[1];for(var j in c)e.attrs[j]=j==d?(e.attrs[j]||"")+" "+c[j]:c[j];return e}function c(b,g,h,i,j,k,l){if(null===h||void 0===h)return void(i&&e(i.nodes));if("retain"!==h.subtree){var m=u.call(i),n=u.call(h);if(m!=n&&(null!==i&&void 0!==i&&e(i.nodes),i=new h.constructor,i.nodes=[]),"[object Array]"==n){for(var o=[],p=i.length===h.length,q=0,r=0,s=0;r-1?new h.constructor(h):h,i.nodes=[v];else if(i.valueOf()!==h.valueOf()||j===!0){if(h.$trusted){var x=i.nodes[0],o=[x];if(x){for(;x=x.nextSibling;)o.push(x);e(o),v=f(b,k,h)}else b.innerHTML=h}else v=i.nodes[0],"textarea"===g?b.value=h:b.insertBefore(v,b.childNodes[k]||null),v.nodeValue=h;i=new h.constructor(h),i.nodes=[v]}else i.nodes.intact=!0}return i}}function d(b,c,d,e,f){for(var g in d){var i=d[g],j=e[g];if(!(g in e)||j!==i||b===a.document.activeElement){if(e[g]=i,"config"===g)continue;if("function"==typeof i&&0==g.indexOf("on"))b[g]=h(i,b);else if("style"===g)for(var k in i)(void 0===j||j[k]!==i[k])&&(b.style[k]=i[k]);else void 0!==f?"href"===g?b.setAttributeNS("http://www.w3.org/1999/xlink","href",i):"className"===g?b.setAttribute("class",i):b.setAttribute(g,i):"value"===g&&"input"===c?b.value!==i&&(b.value=i):g in b?b[g]=i:b.setAttribute(g,i)}}return e}function e(a){for(var b=0;b0&&("GET"==a.method?a.url=a.url+(a.url.indexOf("?")<0?"?":"&")+o(b):a.data=c(b)),a}function q(a,b){var c=a.match(/:[a-z]\w+/gi);if(c&&b)for(var d=0;de?y.push(b)-1:e,g=b==a.document||b==a.document.documentElement?x:b;z[f]=c(g,null,d,z[f],!1,0)},b.trust=function(a){return a=new String(a),a.$trusted=!0,a};var A=[],B=[],C=[],D=0,E=0,F=0,G=null;b.module=function(a,c){b.startComputation();var d=A.indexOf(a);0>d&&(d=A.length),A[d]=a,B[d]=c,C[d]=new c.controller,b.endComputation()},b.redraw=function(){if(D=a.performance&&a.performance.now?a.performance.now():(new a.Date).getTime(),D-E>16)i();else{var b=a.cancelAnimationFrame||a.clearTimeout,c=a.requestAnimationFrame||a.setTimeout;b(F),F=c(i,0)}};var H=0;b.startComputation=function(){H++},b.endComputation=function(){H=Math.max(H-1,0),0==H&&b.redraw()},b.withAttr=function(a,b){return function(c){b(a in c.currentTarget?c.currentTarget[a]:c.currentTarget.getAttribute(a))}};var I,J={pathname:"",hash:"#",search:"?"},K=function(){},L={};return b.route=function(){if(0===arguments.length)return I;if(3===arguments.length){I=a.location[b.route.mode].slice(J[b.route.mode].length);var c=arguments[0],d=arguments[1],e=arguments[2];K=function(a){var f=a.slice(J[b.route.mode].length);j(c,e,f)||b.route(d,!0)};var f="hash"==b.route.mode?"onhashchange":"onpopstate";a[f]=function(){K(a.location[b.route.mode])},G=l,a[f]()}else if(arguments[0].addEventListener){var g=arguments[0],h=arguments[1];g.href=J[b.route.mode]+g.pathname,h||(g.removeEventListener("click",k),g.addEventListener("click",k))}else if("string"==typeof arguments[0]){I=arguments[0];var i=arguments[1]===!0;a.history.pushState?(G=function(){a.history[i?"replaceState":"pushState"](null,a.document.title,J[b.route.mode]+I),l()},K(J[b.route.mode]+I)):a.location[b.route.mode]=I}},b.route.param=function(a){return L[a]},b.route.mode="search",b.prop=function(a){var b=function(){return arguments.length&&(a=arguments[0]),a};return b.toJSON=function(){return a},b},b.deferred=function(){var a=[],c=[],d={resolve:function(b){for(var c=0;c0&&(e.attrs[d]=h.join(" "))}e=g(e),e.attrs=g(e.attrs),e.children=b?a[2]:a[1];for(var j in c)e.attrs[j]=j==d?(e.attrs[j]||"")+" "+c[j]:c[j];return e}function c(b,g,h,i,j,k,l,m){if(null===h||void 0===h)return void(i&&e(i.nodes));if("retain"!==h.subtree){var n=u.call(i),o=u.call(h);if(n!=o&&(null!==i&&void 0!==i&&e(i.nodes),i=new h.constructor,i.nodes=[]),"[object Array]"==o){for(var p=[],q=i.length===h.length,r=0,s=0,t=0;s-1?new h.constructor(h):h,i.nodes=[w];else if(i.valueOf()!==h.valueOf()||j===!0){if(!l||l!==a.document.activeElement)if(h.$trusted){var y=i.nodes[0],p=[y];if(y){for(;y=y.nextSibling;)p.push(y);e(p),w=f(b,k,h)}else b.innerHTML=h}else w=i.nodes[0],"textarea"===g?b.value=h:l?l.innerHTML=h:(b.insertBefore(w,b.childNodes[k]||null),w.nodeValue=h);i=new h.constructor(h),i.nodes=[w]}else i.nodes.intact=!0}return i}}function d(b,c,d,e,f){for(var g in d){var i=d[g],j=e[g];if(!(g in e)||j!==i||b===a.document.activeElement){if(e[g]=i,"config"===g)continue;if("function"==typeof i&&0==g.indexOf("on"))b[g]=h(i,b);else if("style"===g)for(var k in i)console.log(b),(void 0===j||j[k]!==i[k])&&(b.style[k]=i[k]);else void 0!==f?"href"===g?b.setAttributeNS("http://www.w3.org/1999/xlink","href",i):"className"===g?b.setAttribute("class",i):b.setAttribute(g,i):"value"===g&&"input"===c?b.value!==i&&(b.value=i):g in b?b[g]=i:b.setAttribute(g,i)}}return e}function e(a){for(var b=0;b0&&("GET"==a.method?a.url=a.url+(a.url.indexOf("?")<0?"?":"&")+o(b):a.data=c(b)),a}function q(a,b){var c=a.match(/:[a-z]\w+/gi);if(c&&b)for(var d=0;de?y.push(b)-1:e,g=b==a.document||b==a.document.documentElement?x:b;z[f]=c(g,null,d,z[f],!1,0,null,void 0)},b.trust=function(a){return a=new String(a),a.$trusted=!0,a};var A=[],B=[],C=[],D=0,E=0,F=0,G=null;b.module=function(a,c){b.startComputation();var d=A.indexOf(a);0>d&&(d=A.length),A[d]=a,B[d]=c,C[d]=new c.controller,b.endComputation()},b.redraw=function(){if(D=a.performance&&a.performance.now?a.performance.now():(new a.Date).getTime(),D-E>16)i();else{var b=a.cancelAnimationFrame||a.clearTimeout,c=a.requestAnimationFrame||a.setTimeout;b(F),F=c(i,0)}};var H=0;b.startComputation=function(){H++},b.endComputation=function(){H=Math.max(H-1,0),0==H&&b.redraw()},b.withAttr=function(a,b){return function(c){b(a in c.currentTarget?c.currentTarget[a]:c.currentTarget.getAttribute(a))}};var I,J={pathname:"",hash:"#",search:"?"},K=function(){},L={};return b.route=function(){if(0===arguments.length)return I;if(3===arguments.length){I=a.location[b.route.mode].slice(J[b.route.mode].length);var c=arguments[0],d=arguments[1],e=arguments[2];K=function(a){var f=a.slice(J[b.route.mode].length);j(c,e,f)||b.route(d,!0)};var f="hash"==b.route.mode?"onhashchange":"onpopstate";a[f]=function(){K(a.location[b.route.mode])},G=l,a[f]()}else if(arguments[0].addEventListener){var g=arguments[0],h=arguments[1];g.href=J[b.route.mode]+g.pathname,h||(g.removeEventListener("click",k),g.addEventListener("click",k))}else if("string"==typeof arguments[0]){I=arguments[0];var i=arguments[1]===!0;a.history.pushState?(G=function(){a.history[i?"replaceState":"pushState"](null,a.document.title,J[b.route.mode]+I),l()},K(J[b.route.mode]+I)):a.location[b.route.mode]=I}},b.route.param=function(a){return L[a]},b.route.mode="search",b.prop=function(a){var b=function(){return arguments.length&&(a=arguments[0]),a};return b.toJSON=function(){return a},b},b.deferred=function(){var a=[],c=[],d={resolve:function(b){for(var c=0;cMr& zt*h&ucQ5?L(WAZvU3NcOEm!*+ z>8h&|SXx##0|igfF6HX^Kp>EJek#?#kW$0{dSGa(cB?ZyRT~&^KccOTK&F31DQy*t zN`9%ftQ3~&%gUOvK2Ux9xT+MD4fj-|T*$hHdIN#R&71uVPpO=>Yo0>8R8ME>k01AM z270}2r8*F3xC*6OJzdJ!!5zqQ%P6tQauU-Zr*H) zcb>awHV?~iHttKR9FzfE56f8bq$?G>l-2WvVz$32UOMi*T6yxsF4k-ptn6DVudLab zy369P<-P!1mp%T?V@+jS{Lk_0M>d4(#MKwK@ANkV(qx>lA)+U4Vdm`$PIHocs4yOrOU>mc z%8CbWva5B?26{F`Y;<3ooP-J;)P|N781u~01xE$QDtI~?fIFl?-xWu}Pd{C>PYxWR zV=jq5KY8m+Q|aAyGe%6nra05xce)u^1r67gyc?Q`JKbO64S9V2efLnixA^!mc`)tC zmNQ!$u+IbT6&kitwCTzXu=Ael_3Bm)mP=x{4%&kNX)ROqv?TAQT7j0QWN+8wg_UBV zl$&x_Je93l9`jRnf5olr>jOQd?mX&GjGlY@{|3aK=TiJF22}g z{w<`7TXq0ZE7W6WU+B*ha_on|QgiobJv~QWgtKbpqU|Y`bNwrBW%qwiz43)F$Y5kX z>^?mI(ep1*miU*SpZd2SO>}krXkvHu+V36d?)Z1N=f-)KbI|GH^38{*4*?{$ZkEJ{ zH_x7SPV7_qaOUo@*M9ZXc|%nbx)M_L#xy?Fv|_31{H*vbuj^(+!K67$pO%U7kXKW} zs=BEuNmX6b?$bmhCjQBL?v*v2FLWh>p{7QX;&B>E7R8z2OQ|@GWOQuTr|E>nc^Vkk zN}3YK)dugVY0sXhdxKGu!rQ|^+7n4CDOE3O3p8$-;>*LHBa7nQ;R{DL#a|D*PiI+? zIXWa(6CV#>NZ|}DHCaQO6f_N9lOb{86_&%l)BHQ9@yb|&rVE-%^Y%P_0w+V&w`Urf zk^o5SqA+s%rEQIlB3t!FkWIES;!j4#^+SpE}#F1 zDHeV1dyHKKr{H{ReNQr7HFefNIuf=)&j{p^R<;rY2IKNVE@+6q^-a7YB^)4%?we6^ znyNmyFRqSVoGcT+RMRA3IpTo2tx3_Kl~mqTfft}ziSdb04dZrAY>vGWtxC|gSeYSB zQq8IbX?#es`Z#bvt;E#92{N zIQa>MUvFD99r^{;&WEKm>81z~fSFF=2e!ztHF?c1VvVI5;``%)BQ5dsad-QWJ;Y!A zf%HCbiL3e?2M|~XeUlX#y{xu10}w;ox)Vi%Jk@b`T(Lo%5@)nJat$_rhGy+UKtr{v z!OP=H6Vz>L8%!-5CxaF-VsL~$!YcoyETpCu={JY2?wyu;P@+`hDSR3aXlK|l6G4C- z8ITz&MK*P%4L_%$sKgP2rlKRe7_=#3kl>U`ztcz>nC%#t0^xN(M^v~jg)v@gg0|x@ z($S>Pgq(I_jK^8`IARbfK{O`aLo%35Y=at+bqWi8Er?Ot<1dMx1K1whLq3jfYZ2Zs=9JiN$Q)&y zodhDu85v_6lkAi9HiNelWN$L|^8|4!7ZlyMF1Pbk%k-)y6H%Ipms(@^5&D!%*!QVI zkaiU`W`)fKFpXpfTEq|Yo@k-kpny>iL3B{%I46;SASE4ppBTSV#3^l6MLLbCIuaLT z;rBYFYb?VRvKaPwHCl*sP!SOJF(`#{kmM0Hd<{B8>rr1Qjwh9wKzC38@E|Pgu>6 zHnGk;a;DEH8Kgm$i-sPjWVpgLd{d(#*dIZrwF$BTSdNIG?0lcp8VnMY3=9l5BU5oJ*qK8zOv^c+4*9SyBX^_PQSY#>NklWl!I!{WqiC=d@D9O|GsJiASSLCE zCez~MJD0T)KEW8BCN3j?0K7136_>=QOmmJa@G^i5TLF@VP{B^fG{(j9-D~X%AHbO@ z#0rH$T4-mE$O>Mgh|$+{&M~S{2oZCDGcBpgy<2=0W9!sVlQ|z@6H}ZJ44*zkgZc~w zxvugtNL{9C?1+!=X1hlygh`=w_3LfGfC~#^=!iV?-=rS6q}4)XQc4EF1YbmEh;2z) z8zSL(2i$`OC1^H+fFsVcJ!pHlRY*Z+np>bFLoEX;T|r#}lqOGDC{LiV-+=W}!{5}3 z*LN6TV@#?h>zy&c?$3CgIq_5LVjFECq<0o(h@mFZRYEn^q<5QSgPtN!=QaN)SA!Hh zXpPNKNXOX(bK;pXU}8NxW~y6;_WQ#w;EDu)J&9fb!xf^oPBY+a$Bl00US zk+U|!lr50gXr@FVs($KNS-c+nuhWe%ImTqc!(z~w?XD6y`a(^7#n@IQL@}qYV@NB; zs3Z?$V=L~lC0ib8m-V|RVy;wRI}OoROv zqeHpia6U8na-9P$Rj0EI@AN1;DG3c|Ei`~W2|n8x(ME+8y3}Uc>!^Q(@c<|Fc!g7A zc!aGqsrNw+q|hE9t zY^WtZ483+mUWBtGEz+XMLdpf(phIwh2?(H zJUk^ghN{8Akdj92&al1@NJ?D;m5B044Dw)#2`!CiH9~*@Q*=WQ3Rkp2W{8urxhIJ8 z4F@Gvh}x0FlLa?6&QwqMLli|Zu7J8%gTFH%Lz);dXVYiOS?D8Ap@utzz)X0DBipAt zagN#te#Evzw2i!kL`|L9;Xz7kWno6Hv?uP-l*!K&Iyaqkh6&~pyB(RLhPeN&& z%YaGuf1z!IZ$ypUEKwoGsO^xgAw;mLPNVYB;q(z6VnZ!2Ls5d?U!gPRJJm#AAU#6d z%Y|Fwzax4ZDGeKqajt+8PJUKo63jpo1qmV!7i6C_H^+I*9OM*5;39^zByA3u!I~tO z#F(=Tl^3n5UmKRY@|^18^C(Z)w#tv8VrUPrJ&rVpu{HU0C{>YzG!vEy(%Ll8OrR>3 zSXE=3y9HxrLN*Tr;*5EoI%ooOW0nYM%awFR{PMGYRJEKX&LHI$K8M?H)hdg1(;ukI zhi6-}N)5zsY7KeaB+2@q&VG#T$ibmmWeba1npa*Ai+?ol-0;tmR00u?qNt}r3!g&M zfvm8mW0DXa7kc#WMdxB*8ZHa@wLxi7&J^E{{ad(ee0qNl~M~KCBA2+S! zn=*^DEAl`d+G2p?4XG+Aw_|LWB7Wa{`*TjvH&}RD28e{0gMUy%aUrb6#Gl>2(Y?b5 z;^Kq*mxhozpoG=ro8}bJqo{E*i&sD0%<G+f_TKeT1CzX0)mq2ZP( zvAwqn8L7nw|_w@MZId`;kAv-;$ zPOM38MGgOSPJCiz2zj561Nw{cFZI>=>Ct{qhy-T=(_w8DHJ?1z62BjJUxzk?002dT zj14gHV{1_f8?yVFUWkgH#Rt20B=2itVBXsAg37}r3)3|iLH3x$<&0f_%<18tzsamqVvF-7&uAhN=xUO zqLh63;s|%t3Fm<=k|Ek5uU0U{(`0{phxVahIsRA;qIy739NMPm2iW*zoqHCe7Nsa( zNl+GzRGCW$8G#2|up$EadtO88b4FW?cL?1IsW;B`ERBOiXtA%y@m|3a)y3=Ai(HR8 z1rSf;DE*;(f>wK)h(BKZ@~Kjke4o>DQ8ArbaKmA^SMUX8%bezB(P`k>c}^2;j)}iW z89j&$Xi|XN&OUgfJu%BPLQ@M9k`-}9>35`sZJ;Gmp;W?h(F87IVmG1_7ocGhN z{?1YEy@U2&Zn^?4G8a<#AMYVC@}Ky|dQ`k#xq7Up=ZW}6?VPxlxw5-a`N7dI9(<=s zkhpjIYA^SEQE~C#7`V1dS$nlmva{mWP2kT5r(bCoEx6d8=-F z=xW(D;OZ=@r0e-odc)rR;H%Tehv_`qlc`sW5xd2Jdp7KPdheo{FJ$trK)^NZc2({A zR<$I&Z+pcXUm4nMzWp~Zoj&vj93uL3@ao~0wOw5=@*jG1K7Jy;^Ym30t=XqtSC{-_ Ukj|RFTNdv>y?kQncWL1N0JT&2?EnA( delta 7954 zcmaJ`du&@-T2I<(o3yl)ZKp}6k7?7##N;-%s_4F~=JF=%!f@etY-qcB1O!LmX;hSx4aNFWUekYePTBTw-ldef-*c{+{KoL+Y1e{iK!ay{56SBIOa>ZNkv{;E<5 zd1)e0UfOe(!*;?sbSkn?tXPu$=|Q7 zDg~uDvi0!cmSVeRn&tfZCC}wRpnm=OaDB8?UeDA<^QC$xm99U0I9v%__PUgNiI#scNQFUxWeIuQ$av+JoNaejd)j zC!ETAdBCep@yRpidYfYKkhixi<_}%yEs5NrpE=l6TH=2XUG>_5py_4R!Wo$gTg*M)N6}34__E+D!I{mDvQrlyN>)+ zs;mz`%{%YN0JHpPR|LR7A}${CDjvlazjI^+)`Fk-pCd1wY$}&qu16WWmSN;H#X{fE z@n&EH_$ewmk|-YZ-Ea>4eqR*dzR>Tna-&!4)kdwJS(k`w@6`*)ZLbon+Y%Bp?Ld39 zlxf#v`87LV%FejTqm@Q2hy9t%aM`6a#ryq3;QY7!*G_(l<%1`i9Q~D)-N*!TGx>n{ zkG|95{?Vho&E1Wo{k^-d9((23?!TV-?;korsn;Jm`r{u>_Vj!-x%;12ez|w|-D{_M z#Ru1uV(f+DrF1>t%ouiN6R;UlhEk0>9K2plweV1F*qPnmec>mMo(!q_grS5~HKkap zx;!uLja|APRt!}&=jqdmU_Ip3l(4F9X-Yy>3)&)WL@e>n*t6$yIzQ-21WPTAIK`s0 zlqiVrkDX0MX(g@WxIRk~?k>^7q*l_D7@juyL`{2IqV5eY5SJKHhlBJPi7QD}x3y(j zw<1FGjrOjHE#CmZ{1u<;_!=v+L_(rl;yb>9n61&0$r@%zLDOKG6f?cYeE55czh^b3 zjIzwUrqX_937`5@sIDn-xF;{%<1d|VY9u5^JIx^dQLU7CZG7^|J{8zy4b9DluES8G zONtN22m5l}hfl_T^x1V{miEY{g8UN^GyawHQp1R1Li2r8*bo8#l`~bQPB%1oMorF< zLiU_3KK4)aM#RONu6g!V1WaMPRg}Ep6?$suB-fIGgGJCT0xM}PqeN9Tep5b3g1UI? z=2Se-WP5<2`{$IbrmFWAIYJNwn1ISujRM774R7kSW17T2%S&xdN&~XkF!B7vKmpJK zK~kC2R6VDc2^IPr<7`W-=meGZ8k2Z5i8yO3NUJejNyB@YH*oY#~Cc9)QpKv3-{C+@zUhsJV8X?F${87 zGzmkEjIF3F2ANq?vnEa}7zg+Cd7i zYAup-iBDDTyvd5$vyxIeI6~26uu|?I^fKpU6hBvA@!M0O-j+Bp?dt4Pl(4AZ<1CNB z-k7Q{t+8rp`b^j|;Uc^=2j_&^x`Vwb-s*-Xs$`I1016DRqdeg7XXtZSI#B$^^x3{V zhdg78znVVNp_-s3SHMAyQo`!qSt)|bmKsaq)40b#bSx<9bRu11stC}D$fTfx^b0gF z6ij8>QRI~oCLuPc;1V<(X2f)moAjOW|9bTdsC2z7$2?~bvWSB#h;84XU_*7NP zvP)9Dm}JoD6Rd=(62s&q2RyGC^pxTDlG>s445+dF7)2>Ufyt0R>LI8UR5`bZDNIeu zsNNxmuDNyb?}5P%mcX>kOud?$&56}?vO5YtptH&HPt}%K$Xb+Ows9x{#3F;h0(BHn zSOXb=vqUS>5t~8sM06f2dT4^n;Kn428%NXX5SBtj5$6UT3$ycKJ~kqg(hE!t4p_oI z3X{;1841@^psVT2Yf;OgDncsRX=Wuv$KjuQ?tR$5iXcGV7QSDfPV8WC2ENRw<&> z&XUK%tW=Eg7t75Oaw0dmy}+|D6^^k0dz^%+hDUryy^<}k03O;xtWQ{?*lfy{h-d+v z1>MUk8#j6MgKwd~Y0I-n5IjXI{1k%4B$vsPunCpIuQxXYB_HjNEDh$>du~6hz@qz`v}vLJOu41?+8g{ zQdm#Y_nfx#|EUpaUbMF7C^s?pzyj0z)EazfJ-ueC4dVnnMN(v_+v0{XFt^RFgv$ZE zHL^(p!JLvjN9HKqQG;m5Jx716Pg~21uNgl$UJ6tEOcv4*Z_O_B704(0N>O|?+rBOP zSCqSq#g42P;}Qp8jgtrk&5_H15d@XBF$Q4L$A7Fz@r$9$9XC~L!=5AOSwJW$=Ht^5 zurMHlOq^s@VJU){lx{cSvyf_WhA)QUTtqdBG64@-kLO=-Gx_omBc!a+Ci)0NJb}Pk zs(5Km>8*<5+;g3*Y%EX(#lkz=Vvi*tjQkH_5FKYRhEL;7r=qaVS-SfW(iqs(m&lMY zskWRL!%a5Q1denJ%ao*JROQq->^0OSsE0M#4di8p7&@6a8KMUZ5!r)r>X#@?B&o&u zBqwrfiXTEXu@Zjaf_wX@+RFI+3FQ!UzDV5F56)cQO~bajFJ79XFdNpi&&Z_N)JE-p+3 zC&S{~^UrnaWI38WrUrZWtgun`bD9zEZm*RvWGxQ~SmssAS<_VZ_ z?XukRrt5H)Hww}PV^9KB6PZp`B<;8mo7dqZ~+QLl+qPn*)5@BK_ zq@^NXEaD*J93V{KTgV-hMaCHC@iWSFOXN(wgK`F~3=hE>BQdGVFDOj%EnJ9(15Nff*0!`9g^u(_qDzmG zfOX=w1V_P!1dES4Wayw#^ck(erO)&;kJ$1SJ?a}g@kgiRqKDTC8ee0RIj$~pTE`Cf zTR4=UuIFZ#86NKX#vC$}bR83~E}o$TB^QoF2w)jWNlyeSycvRi<`WWUkqQe52xEuj zWX0btP6TXrh_$(()PVMuR+7)<1#rf6#?gyb3tIOwxFs)nHb{2>oIT5d4 zXf(nEmCSQzEa=!Itv%vB>-M1YfPxcOLlc@$S~R{O`tSUCA4gp^w#DDy8Muq79bt{* zA_c9v@md~o2QDyV+%|t!HUGjsGL*}l&U9*KN~(yuPEnWb70l7rS3jez<9duRf_oU9 zf*b@tkrM2)EWZoM@r1zY2C6)P}VcbMqfBx`CK0K`1a_YQ=yMRiwiYf=+phT6(K zG;BYyA+%|7(BS9Ct;UcOMZEHu48>?mz6#QyD7%CsAvKH|l;>7~gK2gx7t^tI6Xg|H zUU*rz7ne_ueL66@PK4NKi%<|k#h2LK7JsySW60)q(;XVqY%_d1 zrfr~>QzW;e0F!6_fTg@Kn#jwTEk_E@USV~PCVbAXCyegqWzGpx?k4DP7?>b~SrwcUuf6Q`cXg&Rm*iT9 z6G)&bT_Pv}c=D?yoHQLbdc?oHyy$m4yls)u7Q>$*Z!ws5h>IG-E-+{7US_(uEefln zCw=^Y+d0jfE8~{<)zzW%erxE_{-12W`L$<$?OS?J&$sm5k5|_Y?JlK%>%i`*jmn|j z_ljEY?&ZzCgQ8d(5I<3w5WiPBBmSnMih-@u;`Ng6NdKebNBjHx#ZPSyhz{1?FP#%X z`&seFTeroV+h@g(RbLcuSI_N!Q2nO^yMNI5LcjR<)$i^8b?4YYar+Igc)xQ+G~f7@ zQxBNS=BWHhYS@KG@!{)N#L2IoIWX)J$G&<|e6Mq)uV0FLwEM!Ba?k93@MZOoxc&7T z;!nSH;_y(en%NlI{e`dp+3Dl^euozIUvjVR|9PyZ=ZE?C>h8xPey`rl*K^gpJ-V4M ljc%qYcOtz9PWL?dS^J5PdYskn;a6V%>37c`_P;~V{|5!y>a+j= diff --git a/mithril.js b/mithril.js index f07d8197..a66726c4 100644 --- a/mithril.js +++ b/mithril.js @@ -32,7 +32,7 @@ Mithril = m = new function app(window) { } 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 (cached) clear(cached.nodes) return @@ -49,7 +49,7 @@ Mithril = m = new function app(window) { if (dataType == "[object Array]") { var nodes = [], intact = cached.length === data.length, subArrayCount = 0 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.nodes.intact) intact = false subArrayCount += item instanceof Array ? item.length : 1 @@ -74,7 +74,7 @@ Mithril = m = new function app(window) { cached = { tag: data.tag, 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] } parentElement.insertBefore(node, parentElement.childNodes[index] || null) @@ -82,7 +82,7 @@ Mithril = m = new function app(window) { else { node = cached.nodes[0] 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 if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null) } @@ -102,20 +102,25 @@ Mithril = m = new function app(window) { cached.nodes = [node] } else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) { - if (data.$trusted) { - var current = cached.nodes[0], nodes = [current] - if (current) { - while (current = current.nextSibling) nodes.push(current) - clear(nodes) - node = injectHTML(parentElement, index, data) + if (!editable || editable !== window.document.activeElement) { + if (data.$trusted) { + var current = cached.nodes[0], nodes = [current] + if (current) { + while (current = current.nextSibling) nodes.push(current) + 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.nodes = [node] @@ -137,6 +142,7 @@ Mithril = m = new function app(window) { } else if (attrName === "style") { for (var rule in dataAttr) { + console.log(node) 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 id = index < 0 ? nodeCache.push(root) - 1 : index 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) { diff --git a/tests/input-cursor.html b/tests/input-cursor.html index 92fbe6a9..75aa76a5 100644 --- a/tests/input-cursor.html +++ b/tests/input-cursor.html @@ -17,20 +17,25 @@ app.view = function(ctrl) { onkeyup: m.withAttr("value", ctrl.title), value: ctrl.title() }), - m("br"), + m("br"), m("textarea", { onkeyup: m.withAttr("value", ctrl.title), value: ctrl.title() }), - m("br"), + m("br"), m("textarea", { onkeyup: m.withAttr("value", ctrl.title) }, ctrl.title()), - m("br"), + m("br"), m("div[contenteditable]", { style: {border: "1px solid #888"}, onkeyup: m.withAttr("innerHTML", ctrl.title) }, ctrl.title()), + m("br"), + m("div[contenteditable]", { + style: {border: "1px solid #888"}, + onkeyup: m.withAttr("innerHTML", ctrl.title) + }, m.trust(ctrl.title())), ]); }