Skip to content

Commit

Permalink
Fix #2192 (#2308)
Browse files Browse the repository at this point in the history
* Fix #2192

* Fix mock style property definitions

* Re-instate camelCased style property key declaration support

* Fix removeProperty, eslint fix

* Stringify style keys: fix perf tests

* Fix weird uncaught mixed whitespace

* Fix weird uncaught mixed whitespace
  • Loading branch information
barneycarroll authored and dead-claudia committed Nov 26, 2018
1 parent d1c090e commit 4c5968a
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 36 deletions.
1 change: 1 addition & 0 deletions docs/change-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

---

Expand Down
19 changes: 15 additions & 4 deletions render/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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])
}
}
}
Expand Down
13 changes: 0 additions & 13 deletions render/tests/test-updateElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
49 changes: 30 additions & 19 deletions test-utils/domMock.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down

0 comments on commit 4c5968a

Please sign in to comment.