diff --git a/docs/change-log.md b/docs/change-log.md index a6b93ab2..f8d11ff1 100644 --- a/docs/change-log.md +++ b/docs/change-log.md @@ -69,6 +69,7 @@ - docs: tweaks: ([#2104](https://github.com/MithrilJS/mithril.js/pull/2104) [@mikeyb](https://github.com/mikeyb), [#2205](https://github.com/MithrilJS/mithril.js/pull/2205), [@cavemansspa](https://github.com/cavemansspa), [#2265](https://github.com/MithrilJS/mithril.js/pull/2265), [@isiahmeadows](https://github.com/isiahmeadows)) - render/core: avoid touching `Object.prototype.__proto__` setter with `key: "__proto__"` in certain situations ([#2251](https://github.com/MithrilJS/mithril.js/pull/2251)) - render/core: Vnodes stored in the dom node supplied to `m.render()` are now normalized [#2266](https://github.com/MithrilJS/mithril.js/pull/2266) +- render/core: CSS vars can now be specified in `{style}` attributes [#2192](https://github.com/MithrilJS/mithril.js/pull/2192) --- diff --git a/render/render.js b/render/render.js index 44ce338e..0b9322cf 100644 --- a/render/render.js +++ b/render/render.js @@ -776,16 +776,27 @@ module.exports = function($window) { } //style - function updateStyle(element, old, style) { + function updateStyle(element, old, input) { + if(typeof input === "object") { + var style = {} + for(var key in input) { + style[key] = String(input[key]).replace(/[A-Z]/g, function(capital){ + return "-" + capital.toLowerCase() + }) + } + } + else { + var style = input + } if (old != null && style != null && typeof old === "object" && typeof style === "object" && style !== old) { // Both old & new are (different) objects. // Update style properties that have changed for (var key in style) { - if (style[key] !== old[key]) element.style[key] = style[key] + if (style[key] !== old[key]) element.style.setProperty(key, style[key]) } // Remove style properties that no longer exist for (var key in old) { - if (!(key in style)) element.style[key] = "" + if (!(key in style)) element.style.removeProperty(key) } return } @@ -795,7 +806,7 @@ module.exports = function($window) { else { if (typeof old === "string") element.style.cssText = "" for (var key in style) { - element.style[key] = style[key] + element.style.setProperty(key, style[key]) } } } diff --git a/render/tests/test-updateElement.js b/render/tests/test-updateElement.js index 8a190a4c..c1eb573f 100644 --- a/render/tests/test-updateElement.js +++ b/render/tests/test-updateElement.js @@ -179,19 +179,6 @@ o.spec("updateElement", function() { o(updated.dom.style.backgroundColor).equals("red") o(updated.dom.style.border).equals("") }) - o("updates style when it's same object but mutated", function() { - var style = {backgroundColor: "red", color: "gold"} - var vnode = {tag: "a", attrs: {style: style}} - - render(root, [vnode]) - - delete style.backgroundColor - var updated = {tag: "a", attrs: {style: style}} - render(root, [updated]) - - o(updated.dom.style.backgroundColor).equals("") - o(updated.dom.style.color).equals("gold") - }) o("does not re-render element styles for equivalent style objects", function() { var style = {color: "gold"} var vnode = {tag: "a", attrs: {style: style}} diff --git a/test-utils/domMock.js b/test-utils/domMock.js index ce494683..e811c4e7 100644 --- a/test-utils/domMock.js +++ b/test-utils/domMock.js @@ -227,29 +227,40 @@ module.exports = function(options) { createElement: function(tag) { var cssText = "" var style = {} - Object.defineProperty(style, "cssText", { - get: function() {return cssText}, - set: function (value) { - var buf = [] - if (typeof value === "string") { - for (var key in style) style[key] = "" - var rules = splitDeclList(value) - for (var i = 0; i < rules.length; i++) { - var rule = rules[i] - var colonIndex = rule.indexOf(":") - if (colonIndex > -1) { - var rawKey = rule.slice(0, colonIndex).trim() - var key = rawKey.replace(/-\D/g, function(match) {return match[1].toUpperCase()}) - var value = rule.slice(colonIndex + 1).trim() - if (key !== "cssText") { - style[key] = value - buf.push(rawKey + ": " + value + ";") + Object.defineProperties(style, { + cssText: { + get: function() {return cssText}, + set: function (value) { + var buf = [] + if (typeof value === "string") { + for (var key in style) style[key] = "" + var rules = splitDeclList(value) + for (var i = 0; i < rules.length; i++) { + var rule = rules[i] + var colonIndex = rule.indexOf(":") + if (colonIndex > -1) { + var rawKey = rule.slice(0, colonIndex).trim() + var key = rawKey.replace(/-\D/g, function(match) {return match[1].toUpperCase()}) + var value = rule.slice(colonIndex + 1).trim() + if (key !== "cssText") { + style[key] = value + buf.push(rawKey + ": " + value + ";") + } } } + element.setAttribute("style", cssText = buf.join(" ")) } - element.setAttribute("style", cssText = buf.join(" ")) } - } + }, + getPropertyValue: {value: function(key){ + return style[key] + }}, + removeProperty: {value: function(key){ + style[key] = "" + }}, + setProperty: {value: function(key, value){ + style[key] = value + }} }) var events = {} var element = {