From 45c6b473b8be5993d8c1f9b5b754261d44f04e8d Mon Sep 17 00:00:00 2001 From: Barney Carroll Date: Fri, 16 Dec 2016 10:34:12 +0000 Subject: [PATCH 1/4] Revert #1449 --- .npmignore | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/.npmignore b/.npmignore index 48873c87..bf023d92 100644 --- a/.npmignore +++ b/.npmignore @@ -1,20 +1,8 @@ -# Configuration files +# Development-specific files .deploy.env .editorconfig .eslintrc.js .gitattributes .gitignore .travis.yml - -# Tests -test-utils/ -tests/ - -# Documentation -docs/ -examples/ CONTRIBUTING.md - -# Browser stub (use index.js w/ a bundler or mithril.js w/o one instead) -module/ -browser.js From 15c28066d7b8a1a702144ec37aecd2bd4b8b68b9 Mon Sep 17 00:00:00 2001 From: James Date: Sun, 18 Dec 2016 22:07:33 +1100 Subject: [PATCH 2/4] Spy on setAttribute to test customElement support --- render/render.js | 7 ++-- render/tests/test-attributes.js | 61 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/render/render.js b/render/render.js index 8d9bd366..731ebdf3 100644 --- a/render/render.js +++ b/render/render.js @@ -435,14 +435,14 @@ module.exports = function($window) { } function setAttr(vnode, key, old, value, ns) { var element = vnode.dom - if (key === "key" || (old === value && !isFormAttribute(vnode, key)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key)) return + if (key === "key" || key === "is" || (old === value && !isFormAttribute(vnode, key)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key)) return var nsLastIndex = key.indexOf(":") if (nsLastIndex > -1 && key.substr(0, nsLastIndex) === "xlink") { element.setAttributeNS("http://www.w3.org/1999/xlink", key.slice(nsLastIndex + 1), value) } else if (key[0] === "o" && key[1] === "n" && typeof value === "function") updateEvent(vnode, key, value) else if (key === "style") updateStyle(element, old, value) - else if (key in element && !isAttribute(key) && ns === undefined) { + else if (key in element && !isAttribute(key) && ns === undefined && !isCustomElement(vnode)) { //setting input[value] to same value by typing on focused element moves cursor to end in Chrome if (vnode.tag === "input" && key === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return //setting select[value] to same value while having select open blinks select dropdown in Chrome @@ -491,6 +491,9 @@ module.exports = function($window) { function isAttribute(attr) { return attr === "href" || attr === "list" || attr === "form" || attr === "width" || attr === "height"// || attr === "type" } + function isCustomElement(vnode){ + return vnode.attrs.is || vnode.tag.indexOf("-") > -1 + } function hasIntegrationMethods(source) { return source != null && (source.oncreate || source.onupdate || source.onbeforeremove || source.onremove) } diff --git a/render/tests/test-attributes.js b/render/tests/test-attributes.js index 73cbd685..8159d0d3 100644 --- a/render/tests/test-attributes.js +++ b/render/tests/test-attributes.js @@ -11,7 +11,68 @@ o.spec("attributes", function() { root = $window.document.body render = vdom($window).render }) + o.spec("customElements", function(){ + + o("when vnode is customElement, custom setAttribute called", function(){ + var normalFirstDraw = [ + { tag: "input", attrs: { wow: 'text' } }, + { tag: "input", attrs: { wow: 'text' } }, + { tag: "input", attrs: { wow: 'text' } }, + ] + + var normalSecondDraw = [ + { tag: "input", attrs: { wow: 'text' } }, + { tag: "input", attrs: { wow: 'text' } }, + { tag: "input", attrs: { wow: 'text' } }, + ] + + var customFirstDraw = [ + { tag: "custom-element", attrs: { custom: 'x' } }, + { tag: "input", attrs: { is: 'something-special', custom: 'x' } }, + { tag: "custom-element", attrs: { is: 'something-special', custom: 'x' } } + ] + + var customSecondDraw = [ + { tag: "custom-element", attrs: { custom: 'y' } }, + { tag: "input", attrs: { is: 'something-special', custom: 'y' } }, + { tag: "custom-element", attrs: { is: 'something-special', custom: 'y' } } + ] + + var draws = [ + normalFirstDraw, normalSecondDraw, + customFirstDraw, customSecondDraw + ] + + var customRedraws = 2 + var customSetAttrCalls = customFirstDraw.length * customRedraws; + var innerHTMLCalls = normalFirstDraw.length + + var f = $window.document.createElement + var spy + + $window.document.createElement = function(tag, is){ + var el = f(tag, is) + if(!spy){ + spy = o.spy(el.setAttribute) + } + el.setAttribute = spy + + return el + } + + draws.forEach( + function(view) { + render(root, view) + } + ) + + o(spy.callCount).equals( + customSetAttrCalls + innerHTMLCalls + ) + }) + + }) o.spec("input readonly", function() { o("when input readonly is true, attribute is present", function() { var a = {tag: "input", attrs: {readonly: true}} From 39b6f1e0feddcb97ec43e89e3d50e9da83d80911 Mon Sep 17 00:00:00 2001 From: James Date: Sun, 18 Dec 2016 22:21:53 +1100 Subject: [PATCH 3/4] Simplify draw routine --- render/tests/test-attributes.js | 43 +++++++-------------------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/render/tests/test-attributes.js b/render/tests/test-attributes.js index 8159d0d3..2d08007b 100644 --- a/render/tests/test-attributes.js +++ b/render/tests/test-attributes.js @@ -15,38 +15,19 @@ o.spec("attributes", function() { o("when vnode is customElement, custom setAttribute called", function(){ - var normalFirstDraw = [ - { tag: "input", attrs: { wow: 'text' } }, - { tag: "input", attrs: { wow: 'text' } }, - { tag: "input", attrs: { wow: 'text' } }, + var normal = [ + { tag: "input", attrs: { value: 'hello' } }, + { tag: "input", attrs: { value: 'hello' } }, + { tag: "input", attrs: { value: 'hello' } } ] - - var normalSecondDraw = [ - { tag: "input", attrs: { wow: 'text' } }, - { tag: "input", attrs: { wow: 'text' } }, - { tag: "input", attrs: { wow: 'text' } }, - ] - - var customFirstDraw = [ + + var custom = [ { tag: "custom-element", attrs: { custom: 'x' } }, { tag: "input", attrs: { is: 'something-special', custom: 'x' } }, { tag: "custom-element", attrs: { is: 'something-special', custom: 'x' } } ] - var customSecondDraw = [ - { tag: "custom-element", attrs: { custom: 'y' } }, - { tag: "input", attrs: { is: 'something-special', custom: 'y' } }, - { tag: "custom-element", attrs: { is: 'something-special', custom: 'y' } } - ] - - var draws = [ - normalFirstDraw, normalSecondDraw, - customFirstDraw, customSecondDraw - ] - - var customRedraws = 2 - var customSetAttrCalls = customFirstDraw.length * customRedraws; - var innerHTMLCalls = normalFirstDraw.length + var view = normal.concat(custom) var f = $window.document.createElement var spy @@ -61,15 +42,9 @@ o.spec("attributes", function() { return el } - draws.forEach( - function(view) { - render(root, view) - } - ) + render(root, view) - o(spy.callCount).equals( - customSetAttrCalls + innerHTMLCalls - ) + o(spy.callCount).equals( custom.length ) }) }) From 0bab044bba9221579d4835e6ad0b71a7a489e360 Mon Sep 17 00:00:00 2001 From: Gandalf-the-Bot Date: Sun, 18 Dec 2016 15:34:16 +0000 Subject: [PATCH 4/4] Bundled output for commit 23ce6031299aebf58d101bb4d5477ad51f2da162 [skip ci] --- README.md | 2 +- mithril.js | 7 +++++-- mithril.min.js | 20 ++++++++++---------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ac65b7f1..9664d8f4 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,6 @@ There are over 4000 assertions in the test suite, and tests cover even difficult ## Modularity -Despite the huge improvements in performance and modularity, the new codebase is smaller than v0.2.x, currently clocking at 7.53 KB min+gzip +Despite the huge improvements in performance and modularity, the new codebase is smaller than v0.2.x, currently clocking at 7.54 KB min+gzip In addition, Mithril is now completely modular: you can import only the modules that you need and easily integrate 3rd party modules if you wish to use a different library for routing, ajax, and even rendering diff --git a/mithril.js b/mithril.js index 43523644..715ecc63 100644 --- a/mithril.js +++ b/mithril.js @@ -759,14 +759,14 @@ var coreRenderer = function($window) { } function setAttr(vnode, key2, old, value, ns) { var element = vnode.dom - if (key2 === "key" || (old === value && !isFormAttribute(vnode, key2)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key2)) return + if (key2 === "key" || key2 === "is" || (old === value && !isFormAttribute(vnode, key2)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key2)) return var nsLastIndex = key2.indexOf(":") if (nsLastIndex > -1 && key2.substr(0, nsLastIndex) === "xlink") { element.setAttributeNS("http://www.w3.org/1999/xlink", key2.slice(nsLastIndex + 1), value) } else if (key2[0] === "o" && key2[1] === "n" && typeof value === "function") updateEvent(vnode, key2, value) else if (key2 === "style") updateStyle(element, old, value) - else if (key2 in element && !isAttribute(key2) && ns === undefined) { + else if (key2 in element && !isAttribute(key2) && ns === undefined && !isCustomElement(vnode)) { //setting input[value] to same value by typing on focused element moves cursor to end in Chrome if (vnode.tag === "input" && key2 === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return //setting select[value] to same value while having select open blinks select dropdown in Chrome @@ -815,6 +815,9 @@ var coreRenderer = function($window) { function isAttribute(attr) { return attr === "href" || attr === "list" || attr === "form" || attr === "width" || attr === "height"// || attr === "type" } + function isCustomElement(vnode){ + return vnode.attrs.is || vnode.tag.indexOf("-") > -1 + } function hasIntegrationMethods(source) { return source != null && (source.oncreate || source.onupdate || source.onbeforeremove || source.onremove) } diff --git a/mithril.min.js b/mithril.min.js index 5242bdcd..811aaac4 100644 --- a/mithril.min.js +++ b/mithril.min.js @@ -26,16 +26,16 @@ null!=b.text&&(b.children=[u("#",void 0,void 0,b.text,void 0,void 0)]),g(q,f.chi b.dom){var e=y.createDocumentFragment();if(0