[render/hyperscript] have the attrs take precedence over the selector, improve class normalization

fix #1773
fix #2172
This commit is contained in:
Pierre-Yves Gérardy 2018-06-02 23:09:50 +02:00 committed by Pierre-Yves Gérardy
parent 1a87cc44cd
commit 92b22fe8e6
2 changed files with 35 additions and 35 deletions

View file

@ -31,7 +31,8 @@ function compileSelector(selector) {
function execSelector(state, attrs, children) { function execSelector(state, attrs, children) {
var hasAttrs = false, childList, text var hasAttrs = false, childList, text
var className = attrs.className || attrs.class var classAttr = hasOwn.call(attrs, "class") ? "class" : "className"
var className = attrs[classAttr]
if (!isEmpty(state.attrs) && !isEmpty(attrs)) { if (!isEmpty(state.attrs) && !isEmpty(attrs)) {
var newAttrs = {} var newAttrs = {}
@ -46,21 +47,18 @@ function execSelector(state, attrs, children) {
} }
for (var key in state.attrs) { for (var key in state.attrs) {
if (hasOwn.call(state.attrs, key)) { if (hasOwn.call(state.attrs, key) && key !== "className" && !hasOwn.call(attrs, key)){
attrs[key] = state.attrs[key] attrs[key] = state.attrs[key]
} }
} }
if (className || state.attrs.className) attrs[classAttr] =
if (className !== undefined) { className
if (attrs.class !== undefined) { ? state.attrs.className
attrs.class = undefined ? state.attrs.className + " " + className
attrs.className = className : className
} : state.attrs.className
? state.attrs.className
if (state.attrs.className != null) { : null
attrs.className = state.attrs.className + " " + className
}
}
for (var key in attrs) { for (var key in attrs) {
if (hasOwn.call(attrs, key) && key !== "key") { if (hasOwn.call(attrs, key) && key !== "key") {
@ -75,7 +73,7 @@ function execSelector(state, attrs, children) {
childList = children childList = children
} }
return Vnode(state.tag, attrs.key, hasAttrs ? attrs : undefined, childList, text) return Vnode(state.tag, attrs.key, hasAttrs ? attrs : null, childList, text)
} }
function hyperscript(selector) { function hyperscript(selector) {

View file

@ -16,53 +16,46 @@ o.spec("hyperscript", function() {
o(vnode.tag).equals("a") o(vnode.tag).equals("a")
}) })
o("v1.0.1 bug-for-bug regression suite", function(){ o("class and className normalization", function(){
o(m("a", { o(m("a", {
class: null class: null
}).attrs).deepEquals({ }).attrs).deepEquals({
class: undefined, class: null
className: null
}) })
o(m("a", { o(m("a", {
class: undefined class: undefined
}).attrs).deepEquals({ }).attrs).deepEquals({
class: undefined, class: undefined
}) })
o(m("a", { o(m("a", {
class: false class: false
}).attrs).deepEquals({ }).attrs).deepEquals({
class: undefined, class: false
className: false
}) })
o(m("a", { o(m("a", {
class: true class: true
}).attrs).deepEquals({ }).attrs).deepEquals({
class: undefined, class: true
className: true
}) })
o(m("a.x", { o(m("a.x", {
class: null class: null
}).attrs).deepEquals({ }).attrs).deepEquals({
class: undefined, class: "x"
className: "x null"
}) })
o(m("a.x", { o(m("a.x", {
class: undefined class: undefined
}).attrs).deepEquals({ }).attrs).deepEquals({
class: undefined, class: "x"
className: "x"
}) })
o(m("a.x", { o(m("a.x", {
class: false class: false
}).attrs).deepEquals({ }).attrs).deepEquals({
class: undefined, class: "x"
className: "x false"
}) })
o(m("a.x", { o(m("a.x", {
class: true class: true
}).attrs).deepEquals({ }).attrs).deepEquals({
class: undefined, class: "x true"
className: "x true"
}) })
o(m("a", { o(m("a", {
className: null className: null
@ -272,7 +265,7 @@ o.spec("hyperscript", function() {
var vnode = m("div", {key:"a"}) var vnode = m("div", {key:"a"})
o(vnode.tag).equals("div") o(vnode.tag).equals("div")
o(vnode.attrs).equals(undefined) o(vnode.attrs).equals(null)
o(vnode.key).equals("a") o(vnode.key).equals("a")
}) })
o("handles many attrs", function() { o("handles many attrs", function() {
@ -295,7 +288,7 @@ o.spec("hyperscript", function() {
o("handles merging classes w/ class property", function() { o("handles merging classes w/ class property", function() {
var vnode = m(".a", {class: "b"}) var vnode = m(".a", {class: "b"})
o(vnode.attrs.className).equals("a b") o(vnode.attrs.class).equals("a b")
}) })
o("handles merging classes w/ className property", function() { o("handles merging classes w/ className property", function() {
var vnode = m(".a", {className: "b"}) var vnode = m(".a", {className: "b"})
@ -490,20 +483,20 @@ o.spec("hyperscript", function() {
o("handles children without attr", function() { o("handles children without attr", function() {
var vnode = m("div", [m("i"), m("s")]) var vnode = m("div", [m("i"), m("s")])
o(vnode.attrs).equals(undefined) o(vnode.attrs).equals(null)
o(vnode.children[0].tag).equals("i") o(vnode.children[0].tag).equals("i")
o(vnode.children[1].tag).equals("s") o(vnode.children[1].tag).equals("s")
}) })
o("handles child without attr unwrapped", function() { o("handles child without attr unwrapped", function() {
var vnode = m("div", m("i")) var vnode = m("div", m("i"))
o(vnode.attrs).equals(undefined) o(vnode.attrs).equals(null)
o(vnode.children[0].tag).equals("i") o(vnode.children[0].tag).equals("i")
}) })
o("handles children without attr unwrapped", function() { o("handles children without attr unwrapped", function() {
var vnode = m("div", m("i"), m("s")) var vnode = m("div", m("i"), m("s"))
o(vnode.attrs).equals(undefined) o(vnode.attrs).equals(null)
o(vnode.children[0].tag).equals("i") o(vnode.children[0].tag).equals("i")
o(vnode.children[1].tag).equals("s") o(vnode.children[1].tag).equals("s")
}) })
@ -524,6 +517,15 @@ o.spec("hyperscript", function() {
m(".a", attrs) m(".a", attrs)
o(attrs).deepEquals({a: "b"}) o(attrs).deepEquals({a: "b"})
}) })
o("non-nullish attr takes precedence over selector", function() {
o(m("[a=b]", {a: "c"}).attrs).deepEquals({a: "c"})
})
o("null attr takes precedence over selector", function() {
o(m("[a=b]", {a: null}).attrs).deepEquals({a: null})
})
o("undefined attr takes precedence over selector", function() {
o(m("[a=b]", {a: undefined}).attrs).deepEquals({a: undefined})
})
o("handles fragment children without attr unwrapped", function() { o("handles fragment children without attr unwrapped", function() {
var vnode = m("div", [m("i")], [m("s")]) var vnode = m("div", [m("i")], [m("s")])