Fix custom elements attribute application, improve key checking
- Fix custom elements attribute application to acknowledge that not all custom elements operate purely based on attributes. (Plus, those blasted things are verbose as heck when you're working with them in raw form. It's also not that uncommon for functionality to be exposed via property and *not* attribute.) - Don't memoize the normalized value when we 1. only use it once in each branch, and 2. only use it for a few special cases. - Centralize the "has property key" code, so it's easier to tune and read. I also inlined a couple functions while I was at it since they were small and only used once. - Actually test for how attributes are applied to raw DOM elements vs when we choose to use keys. When I first developed the patch, it silently worked, when I should've been breaking things.
This commit is contained in:
parent
f844cc8134
commit
1ecc30a064
6 changed files with 217 additions and 41 deletions
|
|
@ -52,38 +52,84 @@ o.spec("attributes", function() {
|
|||
})
|
||||
o.spec("customElements", function(){
|
||||
|
||||
o("when vnode is customElement, custom setAttribute called", function(){
|
||||
|
||||
var normal = [
|
||||
{tag: "input", attrs: {value: "hello"}},
|
||||
{tag: "input", attrs: {value: "hello"}},
|
||||
{tag: "input", attrs: {value: "hello"}}
|
||||
]
|
||||
|
||||
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 view = normal.concat(custom)
|
||||
|
||||
o("when vnode is customElement without property, custom setAttribute called", function(){
|
||||
var f = $window.document.createElement
|
||||
var spy
|
||||
var spies = []
|
||||
|
||||
$window.document.createElement = function(tag, is){
|
||||
var el = f(tag, is)
|
||||
if(!spy){
|
||||
spy = o.spy(el.setAttribute)
|
||||
}
|
||||
var spy = o.spy(el.setAttribute)
|
||||
el.setAttribute = spy
|
||||
|
||||
spies.push(spy)
|
||||
spy.elem = el
|
||||
return el
|
||||
}
|
||||
|
||||
render(root, view)
|
||||
render(root, [
|
||||
{tag: "input", attrs: {value: "hello"}},
|
||||
{tag: "input", attrs: {value: "hello"}},
|
||||
{tag: "input", attrs: {value: "hello"}},
|
||||
{tag: "custom-element", attrs: {custom: "x"}},
|
||||
{tag: "input", attrs: {is: "something-special", custom: "x"}},
|
||||
{tag: "custom-element", attrs: {is: "something-special", custom: "x"}}
|
||||
])
|
||||
|
||||
o(spy.callCount).equals(custom.length)
|
||||
o(spies[0].callCount).equals(0)
|
||||
o(spies[1].callCount).equals(0)
|
||||
o(spies[2].callCount).equals(0)
|
||||
o(spies[3].calls).deepEquals([{this: spies[3].elem, args: ["custom", "x"]}])
|
||||
o(spies[4].calls).deepEquals([{this: spies[4].elem, args: ["custom", "x"]}])
|
||||
o(spies[5].calls).deepEquals([{this: spies[5].elem, args: ["custom", "x"]}])
|
||||
})
|
||||
|
||||
o("when vnode is customElement with property, custom setAttribute not called", function(){
|
||||
var f = $window.document.createElement
|
||||
var spies = []
|
||||
var getters = []
|
||||
var setters = []
|
||||
|
||||
$window.document.createElement = function(tag, is){
|
||||
var el = f(tag, is)
|
||||
var spy = o.spy(el.setAttribute)
|
||||
el.setAttribute = spy
|
||||
spies.push(spy)
|
||||
spy.elem = el
|
||||
if (tag === "custom-element" || is && is.is === "something-special") {
|
||||
var custom = "foo"
|
||||
var getter, setter
|
||||
Object.defineProperty(el, "custom", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: getter = o.spy(function () { return custom }),
|
||||
set: setter = o.spy(function (value) { custom = value })
|
||||
})
|
||||
getters.push(getter)
|
||||
setters.push(setter)
|
||||
}
|
||||
return el
|
||||
}
|
||||
|
||||
render(root, [
|
||||
{tag: "input", attrs: {value: "hello"}},
|
||||
{tag: "input", attrs: {value: "hello"}},
|
||||
{tag: "input", attrs: {value: "hello"}},
|
||||
{tag: "custom-element", attrs: {custom: "x"}},
|
||||
{tag: "input", attrs: {is: "something-special", custom: "x"}},
|
||||
{tag: "custom-element", attrs: {is: "something-special", custom: "x"}}
|
||||
])
|
||||
|
||||
o(spies[0].callCount).equals(0)
|
||||
o(spies[1].callCount).equals(0)
|
||||
o(spies[2].callCount).equals(0)
|
||||
o(spies[3].callCount).equals(0)
|
||||
o(spies[4].callCount).equals(0)
|
||||
o(spies[5].callCount).equals(0)
|
||||
o(getters[0].callCount).equals(0)
|
||||
o(getters[1].callCount).equals(0)
|
||||
o(getters[2].callCount).equals(0)
|
||||
o(setters[0].calls).deepEquals([{this: spies[3].elem, args: ["x"]}])
|
||||
o(setters[1].calls).deepEquals([{this: spies[4].elem, args: ["x"]}])
|
||||
o(setters[2].calls).deepEquals([{this: spies[5].elem, args: ["x"]}])
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue