Fix style updates to avoid unnecessary allocation (#2312)
* Fix style updates to avoid unnecessary allocation - Drive-by: properly censor `cssFloat` -> css `float:` to match DOM behavior * Document `style` syntax + custom property support. [skip ci] * Add a missing test * Add a few more descriptive comments. * Update changelog [skip ci]
This commit is contained in:
parent
b25e8e15a0
commit
8134c51a48
4 changed files with 41 additions and 25 deletions
|
|
@ -72,7 +72,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), [#2250](https://github.com/MithrilJS/mithril.js/pull/2250) [@isiahmeadows](https://github.com/isiahmeadows), [#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)
|
||||
- render/core: CSS vars can now be specified in `{style}` attributes ([#2192](https://github.com/MithrilJS/mithril.js/pull/2192) [@barneycarroll](https://github.com/barneycarroll)), ([#2311](https://github.com/MithrilJS/mithril.js/pull/2311) [@porsager](https://github.com/porsager)), ([#2312](https://github.com/MithrilJS/mithril.js/pull/2312) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||
- request: don't modify params, call `extract`/`serialize`/`deserialize` with correct `this` value ([#2288](https://github.com/MithrilJS/mithril.js/pull/2288))
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -262,6 +262,8 @@ m("div[style=background:red]")
|
|||
|
||||
Using a string as a `style` would overwrite all inline styles in the element if it is redrawn, and not only CSS rules whose values have changed.
|
||||
|
||||
You can use both hyphenated CSS property names (like `background-color`) and camel cased DOM `style` property names (like `backgroundColor`). You can also define [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables), if your browser supports them.
|
||||
|
||||
Mithril does not attempt to add units to number values. It simply stringifies them.
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -775,38 +775,45 @@ 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
|
||||
var uppercaseRegex = /[A-Z]/g
|
||||
function toLowerCase(capital) { return "-" + capital.toLowerCase() }
|
||||
function normalizeKey(key) {
|
||||
return key[0] === "-" && key[1] === "-" ? key :
|
||||
key === "cssFloat" ? "float" :
|
||||
key.replace(uppercaseRegex, toLowerCase)
|
||||
}
|
||||
function updateStyle(element, old, style) {
|
||||
if (old != null && style != null && typeof old === "object" && typeof style === "object" && style !== old) {
|
||||
if (old === style) {
|
||||
// Styles are equivalent, do nothing.
|
||||
} else if (style == null) {
|
||||
// New style is missing, just clear it.
|
||||
element.style.cssText = ""
|
||||
} else if (typeof style !== "object") {
|
||||
// New style is a string, let engine deal with patching.
|
||||
element.style.cssText = style
|
||||
} else if (old == null || typeof old !== "object") {
|
||||
// `old` is missing or a string, `style` is an object.
|
||||
element.style.cssText = ""
|
||||
// Add new style properties
|
||||
for (var key in style) {
|
||||
var value = style[key]
|
||||
if (value != null) element.style.setProperty(normalizeKey(key), String(value))
|
||||
}
|
||||
} else {
|
||||
// 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(normalizeProp(key), style[key])
|
||||
var value = style[key]
|
||||
if (value != null && (value = String(value)) !== String(old[key])) {
|
||||
element.style.setProperty(normalizeKey(key), value)
|
||||
}
|
||||
}
|
||||
// Remove style properties that no longer exist
|
||||
for (var key in old) {
|
||||
if (!(key in style)) element.style.removeProperty(normalizeProp(key))
|
||||
}
|
||||
return
|
||||
}
|
||||
if (old === style) element.style.cssText = "", old = null
|
||||
if (style == null) element.style.cssText = ""
|
||||
else if (typeof style === "string") element.style.cssText = style
|
||||
else {
|
||||
if (typeof old === "string") element.style.cssText = ""
|
||||
for (var key in style) {
|
||||
element.style.setProperty(normalizeProp(key), style[key])
|
||||
if (old[key] != null && style[key] == null) {
|
||||
element.style.removeProperty(normalizeKey(key))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,13 @@ o.spec("createElement", function() {
|
|||
|
||||
o(vnode.dom.style["--cssVar"]).equals("red")
|
||||
})
|
||||
o("censors cssFloat to float", function() {
|
||||
var vnode = {tag: "a", attrs: {style: {cssFloat: "left"}}}
|
||||
|
||||
render(root, [vnode])
|
||||
|
||||
o(vnode.dom.style.float).equals("left")
|
||||
})
|
||||
o("creates children", function() {
|
||||
var vnode = {tag: "div", children: [{tag: "a"}, {tag: "b"}]}
|
||||
render(root, [vnode])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue