From 7c299ab48cd262ad488d9a4285670db65e3e1d67 Mon Sep 17 00:00:00 2001 From: Rasmus Porsager Date: Mon, 26 Nov 2018 15:40:08 +0100 Subject: [PATCH] Allow css vars with uppercase characters (#2311) * Allow css vars with uppercase characters * Remove charAt * Extract dash lowercase lambda * Extract match uppercase regex * Set key and value correctly in updateStyle * Fix domMock style to work like the browser --- render/render.js | 30 +++++++++++++++--------------- render/tests/test-createElement.js | 12 ++++++++++++ test-utils/domMock.js | 11 +++++++---- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/render/render.js b/render/render.js index 0b9322cf..d197a0dd 100644 --- a/render/render.js +++ b/render/render.js @@ -775,28 +775,28 @@ module.exports = function($window) { ) && key in vnode.dom } + var matchUpperCase = /[A-Z]/g + function prependDashAndLowerCase(string){ + return "-" + string.toLowerCase() + } + + function normalizeProp(prop) { + return "-" && prop[1] === "-" + ? prop + : prop.replace(matchUpperCase, prependDashAndLowerCase) + } + //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 - } + function updateStyle(element, old, style) { 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.setProperty(key, style[key]) + if (style[key] !== old[key]) element.style.setProperty(normalizeProp(key), style[key]) } // Remove style properties that no longer exist for (var key in old) { - if (!(key in style)) element.style.removeProperty(key) + if (!(key in style)) element.style.removeProperty(normalizeProp(key)) } return } @@ -806,7 +806,7 @@ module.exports = function($window) { else { if (typeof old === "string") element.style.cssText = "" for (var key in style) { - element.style.setProperty(key, style[key]) + element.style.setProperty(normalizeProp(key), style[key]) } } } diff --git a/render/tests/test-createElement.js b/render/tests/test-createElement.js index ea4d01c8..e40f9186 100644 --- a/render/tests/test-createElement.js +++ b/render/tests/test-createElement.js @@ -33,6 +33,18 @@ o.spec("createElement", function() { o(vnode.dom.nodeName).equals("DIV") o(vnode.dom.style.backgroundColor).equals("red") }) + o("allows css vars in style", function() { + var vnode = {tag: "div", attrs: {style: {"--css-var": "red"}}} + render(root, [vnode]) + + o(vnode.dom.style["--css-var"]).equals("red") + }) + o("allows css vars in style with uppercase letters", function() { + var vnode = {tag: "div", attrs: {style: {"--cssVar": "red"}}} + render(root, [vnode]) + + o(vnode.dom.style["--cssVar"]).equals("red") + }) o("creates children", function() { var vnode = {tag: "div", children: [{tag: "a"}, {tag: "b"}]} render(root, [vnode]) diff --git a/test-utils/domMock.js b/test-utils/domMock.js index e811c4e7..6ccb468e 100644 --- a/test-utils/domMock.js +++ b/test-utils/domMock.js @@ -220,6 +220,9 @@ module.exports = function(options) { parseMarkup(value, root, [], "http://www.w3.org/2000/svg") return {documentElement: root} } + function camelCase(string) { + return string.replace(/-\D/g, function(match) {return match[1].toUpperCase()}) + } var activeElement var $window = { DOMParser: DOMParser, @@ -240,10 +243,10 @@ module.exports = function(options) { 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 key = camelCase(rawKey) var value = rule.slice(colonIndex + 1).trim() if (key !== "cssText") { - style[key] = value + style[key] = style[rawKey] = value buf.push(rawKey + ": " + value + ";") } } @@ -256,10 +259,10 @@ module.exports = function(options) { return style[key] }}, removeProperty: {value: function(key){ - style[key] = "" + style[key] = style[camelCase(key)] = "" }}, setProperty: {value: function(key, value){ - style[key] = value + style[key] = style[camelCase(key)] = value }} }) var events = {}