change onbeforeremove and make state inherit from prototype
This commit is contained in:
parent
e8f36e4e26
commit
1222a9a3ab
4 changed files with 41 additions and 76 deletions
|
|
@ -97,7 +97,9 @@ module.exports = function($window) {
|
||||||
function createComponent(vnode, hooks, ns) {
|
function createComponent(vnode, hooks, ns) {
|
||||||
// For object literals since `Vnode()` always sets the `state` field.
|
// For object literals since `Vnode()` always sets the `state` field.
|
||||||
if (!vnode.state) vnode.state = {}
|
if (!vnode.state) vnode.state = {}
|
||||||
assign(vnode.state, vnode.tag)
|
var constructor = function() {}
|
||||||
|
constructor.prototype = vnode.tag
|
||||||
|
vnode.state = new constructor
|
||||||
|
|
||||||
var view = vnode.tag.view
|
var view = vnode.tag.view
|
||||||
if (view.reentrantLock != null) return $emptyFragment
|
if (view.reentrantLock != null) return $emptyFragment
|
||||||
|
|
@ -380,12 +382,18 @@ module.exports = function($window) {
|
||||||
function removeNode(vnode, context) {
|
function removeNode(vnode, context) {
|
||||||
var expected = 1, called = 0
|
var expected = 1, called = 0
|
||||||
if (vnode.attrs && vnode.attrs.onbeforeremove) {
|
if (vnode.attrs && vnode.attrs.onbeforeremove) {
|
||||||
expected++
|
var result = vnode.attrs.onbeforeremove.call(vnode.state, vnode)
|
||||||
vnode.attrs.onbeforeremove.call(vnode.state, vnode, once(continuation))
|
if (result != null && typeof result.then === "function") {
|
||||||
|
expected++
|
||||||
|
result.then(continuation, continuation)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (typeof vnode.tag !== "string" && vnode.tag.onbeforeremove) {
|
if (typeof vnode.tag !== "string" && vnode.tag.onbeforeremove) {
|
||||||
expected++
|
var result = vnode.tag.onbeforeremove.call(vnode.state, vnode)
|
||||||
vnode.tag.onbeforeremove.call(vnode.state, vnode, once(continuation))
|
if (result != null && typeof result.then === "function") {
|
||||||
|
expected++
|
||||||
|
result.then(continuation, continuation)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continuation()
|
continuation()
|
||||||
function continuation() {
|
function continuation() {
|
||||||
|
|
@ -559,10 +567,6 @@ module.exports = function($window) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
function assign(target, source) {
|
|
||||||
Object.keys(source).forEach(function(k){target[k] = source[k]})
|
|
||||||
}
|
|
||||||
|
|
||||||
function render(dom, vnodes) {
|
function render(dom, vnodes) {
|
||||||
if (!dom) throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.")
|
if (!dom) throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.")
|
||||||
var hooks = []
|
var hooks = []
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
<script src="../../render/fragment.js"></script>
|
<script src="../../render/fragment.js"></script>
|
||||||
<script src="../../render/hyperscript.js"></script>
|
<script src="../../render/hyperscript.js"></script>
|
||||||
<script src="../../render/render.js"></script>
|
<script src="../../render/render.js"></script>
|
||||||
|
<script src="../../promise/promise.js"></script>
|
||||||
<script src="test-hyperscript.js"></script>
|
<script src="test-hyperscript.js"></script>
|
||||||
<script src="test-trust.js"></script>
|
<script src="test-trust.js"></script>
|
||||||
<script src="test-fragment.js"></script>
|
<script src="test-fragment.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -588,14 +588,12 @@ o.spec("component", function() {
|
||||||
o("calls onbeforeremove", function() {
|
o("calls onbeforeremove", function() {
|
||||||
var called = 0
|
var called = 0
|
||||||
var component = {
|
var component = {
|
||||||
onbeforeremove: function(vnode, done) {
|
onbeforeremove: function(vnode) {
|
||||||
called++
|
called++
|
||||||
|
|
||||||
o(vnode.dom).notEquals(undefined)
|
o(vnode.dom).notEquals(undefined)
|
||||||
o(vnode.dom).equals(root.firstChild)
|
o(vnode.dom).equals(root.firstChild)
|
||||||
o(root.childNodes.length).equals(1)
|
o(root.childNodes.length).equals(1)
|
||||||
|
|
||||||
done()
|
|
||||||
},
|
},
|
||||||
view: function() {
|
view: function() {
|
||||||
return {tag: "div", attrs: {id: "a"}, text: "b"}
|
return {tag: "div", attrs: {id: "a"}, text: "b"}
|
||||||
|
|
@ -614,14 +612,12 @@ o.spec("component", function() {
|
||||||
o("calls onbeforeremove when returning fragment", function() {
|
o("calls onbeforeremove when returning fragment", function() {
|
||||||
var called = 0
|
var called = 0
|
||||||
var component = {
|
var component = {
|
||||||
onbeforeremove: function(vnode, done) {
|
onbeforeremove: function(vnode) {
|
||||||
called++
|
called++
|
||||||
|
|
||||||
o(vnode.dom).notEquals(undefined)
|
o(vnode.dom).notEquals(undefined)
|
||||||
o(vnode.dom).equals(root.firstChild)
|
o(vnode.dom).equals(root.firstChild)
|
||||||
o(root.childNodes.length).equals(1)
|
o(root.childNodes.length).equals(1)
|
||||||
|
|
||||||
done()
|
|
||||||
},
|
},
|
||||||
view: function() {
|
view: function() {
|
||||||
return [{tag: "div", attrs: {id: "a"}, text: "b"}]
|
return [{tag: "div", attrs: {id: "a"}, text: "b"}]
|
||||||
|
|
@ -672,6 +668,10 @@ o.spec("component", function() {
|
||||||
function init(vnode) {
|
function init(vnode) {
|
||||||
o(vnode.state.data).deepEquals(data)
|
o(vnode.state.data).deepEquals(data)
|
||||||
o(vnode.state.data).equals(data)
|
o(vnode.state.data).equals(data)
|
||||||
|
|
||||||
|
//inherits state via prototype
|
||||||
|
component.x = 1
|
||||||
|
o(vnode.state.x).equals(1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
o("state copy is shallow", function() {
|
o("state copy is shallow", function() {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ var o = require("../../ospec/ospec")
|
||||||
var callAsync = require("../../test-utils/callAsync")
|
var callAsync = require("../../test-utils/callAsync")
|
||||||
var domMock = require("../../test-utils/domMock")
|
var domMock = require("../../test-utils/domMock")
|
||||||
var vdom = require("../../render/render")
|
var vdom = require("../../render/render")
|
||||||
|
var Promise = require("../../promise/promise")
|
||||||
|
|
||||||
o.spec("onbeforeremove", function() {
|
o.spec("onbeforeremove", function() {
|
||||||
var $window, root, render
|
var $window, root, render
|
||||||
|
|
@ -43,17 +44,13 @@ o.spec("onbeforeremove", function() {
|
||||||
render(root, [vnode])
|
render(root, [vnode])
|
||||||
render(root, [])
|
render(root, [])
|
||||||
|
|
||||||
function remove(node, complete) {
|
function remove(node) {
|
||||||
o(node).equals(vnode)
|
o(node).equals(vnode)
|
||||||
o(this).equals(vnode.state)
|
o(this).equals(vnode.state)
|
||||||
o(root.childNodes.length).equals(1)
|
o(root.childNodes.length).equals(1)
|
||||||
o(root.firstChild).equals(vnode.dom)
|
o(root.firstChild).equals(vnode.dom)
|
||||||
|
|
||||||
callAsync(function() {
|
callAsync(function() {
|
||||||
o(root.childNodes.length).equals(1)
|
|
||||||
|
|
||||||
complete()
|
|
||||||
|
|
||||||
o(root.childNodes.length).equals(0)
|
o(root.childNodes.length).equals(0)
|
||||||
|
|
||||||
done()
|
done()
|
||||||
|
|
@ -66,16 +63,12 @@ o.spec("onbeforeremove", function() {
|
||||||
render(root, [vnode])
|
render(root, [vnode])
|
||||||
render(root, [])
|
render(root, [])
|
||||||
|
|
||||||
function remove(node, complete) {
|
function remove(node) {
|
||||||
o(node).equals(vnode)
|
o(node).equals(vnode)
|
||||||
o(root.childNodes.length).equals(1)
|
o(root.childNodes.length).equals(1)
|
||||||
o(root.firstChild).equals(vnode.dom)
|
o(root.firstChild).equals(vnode.dom)
|
||||||
|
|
||||||
callAsync(function() {
|
callAsync(function() {
|
||||||
o(root.childNodes.length).equals(1)
|
|
||||||
|
|
||||||
complete()
|
|
||||||
|
|
||||||
o(root.childNodes.length).equals(0)
|
o(root.childNodes.length).equals(0)
|
||||||
|
|
||||||
done()
|
done()
|
||||||
|
|
@ -88,16 +81,12 @@ o.spec("onbeforeremove", function() {
|
||||||
render(root, [vnode])
|
render(root, [vnode])
|
||||||
render(root, [])
|
render(root, [])
|
||||||
|
|
||||||
function remove(node, complete) {
|
function remove(node) {
|
||||||
o(node).equals(vnode)
|
o(node).equals(vnode)
|
||||||
o(root.childNodes.length).equals(1)
|
o(root.childNodes.length).equals(1)
|
||||||
o(root.firstChild).equals(vnode.dom)
|
o(root.firstChild).equals(vnode.dom)
|
||||||
|
|
||||||
callAsync(function() {
|
callAsync(function() {
|
||||||
o(root.childNodes.length).equals(1)
|
|
||||||
|
|
||||||
complete()
|
|
||||||
|
|
||||||
o(root.childNodes.length).equals(0)
|
o(root.childNodes.length).equals(0)
|
||||||
|
|
||||||
done()
|
done()
|
||||||
|
|
@ -110,16 +99,12 @@ o.spec("onbeforeremove", function() {
|
||||||
render(root, [vnode])
|
render(root, [vnode])
|
||||||
render(root, [])
|
render(root, [])
|
||||||
|
|
||||||
function remove(node, complete) {
|
function remove(node) {
|
||||||
o(node).equals(vnode)
|
o(node).equals(vnode)
|
||||||
o(root.childNodes.length).equals(1)
|
o(root.childNodes.length).equals(1)
|
||||||
o(root.firstChild).equals(vnode.dom)
|
o(root.firstChild).equals(vnode.dom)
|
||||||
|
|
||||||
callAsync(function() {
|
callAsync(function() {
|
||||||
o(root.childNodes.length).equals(1)
|
|
||||||
|
|
||||||
complete()
|
|
||||||
|
|
||||||
o(root.childNodes.length).equals(0)
|
o(root.childNodes.length).equals(0)
|
||||||
|
|
||||||
done()
|
done()
|
||||||
|
|
@ -133,17 +118,12 @@ o.spec("onbeforeremove", function() {
|
||||||
render(root, [vnode])
|
render(root, [vnode])
|
||||||
render(root, [])
|
render(root, [])
|
||||||
|
|
||||||
function remove(node, complete) {
|
function remove(node) {
|
||||||
o(node).equals(vnode)
|
o(node).equals(vnode)
|
||||||
o(root.childNodes.length).equals(1)
|
o(root.childNodes.length).equals(1)
|
||||||
o(root.firstChild).equals(vnode.dom)
|
o(root.firstChild).equals(vnode.dom)
|
||||||
|
|
||||||
callAsync(function() {
|
callAsync(function() {
|
||||||
o(root.childNodes.length).equals(1)
|
|
||||||
o(spy.callCount).equals(0)
|
|
||||||
|
|
||||||
complete()
|
|
||||||
|
|
||||||
o(root.childNodes.length).equals(0)
|
o(root.childNodes.length).equals(0)
|
||||||
o(spy.callCount).equals(1)
|
o(spy.callCount).equals(1)
|
||||||
|
|
||||||
|
|
@ -161,7 +141,7 @@ o.spec("onbeforeremove", function() {
|
||||||
o(vnode.dom.attributes["onbeforeremove"]).equals(undefined)
|
o(vnode.dom.attributes["onbeforeremove"]).equals(undefined)
|
||||||
})
|
})
|
||||||
o("does not recycle when there's an onbeforeremove", function() {
|
o("does not recycle when there's an onbeforeremove", function() {
|
||||||
var remove = function(vnode, done) {done()}
|
var remove = function(vnode) {}
|
||||||
var vnode = {tag: "div", key: 1, attrs: {onbeforeremove: remove}}
|
var vnode = {tag: "div", key: 1, attrs: {onbeforeremove: remove}}
|
||||||
var updated = {tag: "div", key: 1, attrs: {onbeforeremove: remove}}
|
var updated = {tag: "div", key: 1, attrs: {onbeforeremove: remove}}
|
||||||
|
|
||||||
|
|
@ -171,9 +151,8 @@ o.spec("onbeforeremove", function() {
|
||||||
|
|
||||||
o(vnode.dom).notEquals(updated.dom)
|
o(vnode.dom).notEquals(updated.dom)
|
||||||
})
|
})
|
||||||
o("does not leave elements out of order during removal", function() {
|
o("does not leave elements out of order during removal", function(done) {
|
||||||
var finish
|
var remove = function(vnode) {return Promise.resolve()}
|
||||||
var remove = function(vnode, done) {finish = done}
|
|
||||||
var vnodes = [{tag: "div", key: 1, attrs: {onbeforeremove: remove}, text: "1"}, {tag: "div", key: 2, attrs: {onbeforeremove: remove}, text: "2"}]
|
var vnodes = [{tag: "div", key: 1, attrs: {onbeforeremove: remove}, text: "1"}, {tag: "div", key: 2, attrs: {onbeforeremove: remove}, text: "2"}]
|
||||||
var updated = {tag: "div", key: 2, attrs: {onbeforeremove: remove}, text: "2"}
|
var updated = {tag: "div", key: 2, attrs: {onbeforeremove: remove}, text: "2"}
|
||||||
|
|
||||||
|
|
@ -183,14 +162,16 @@ o.spec("onbeforeremove", function() {
|
||||||
o(root.childNodes.length).equals(2)
|
o(root.childNodes.length).equals(2)
|
||||||
o(root.firstChild.firstChild.nodeValue).equals("1")
|
o(root.firstChild.firstChild.nodeValue).equals("1")
|
||||||
|
|
||||||
finish()
|
callAsync(function() {
|
||||||
|
o(root.childNodes.length).equals(1)
|
||||||
o(root.childNodes.length).equals(1)
|
o(root.firstChild.firstChild.nodeValue).equals("2")
|
||||||
o(root.firstChild.firstChild.nodeValue).equals("2")
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
o("finalizes the remove phase only once when `done()` is called synchronously from both attrs- and tag.onbeforeremove", function() {
|
o("finalizes the remove phase asynchronously when promise is returned synchronously from both attrs- and tag.onbeforeremove", function(done) {
|
||||||
var onremove = o.spy()
|
var onremove = o.spy()
|
||||||
var onbeforeremove = function(vnode, done){done()}
|
var onbeforeremove = function(){return Promise.resolve()}
|
||||||
var component = {
|
var component = {
|
||||||
onbeforeremove: onbeforeremove,
|
onbeforeremove: onbeforeremove,
|
||||||
onremove: onremove,
|
onremove: onremove,
|
||||||
|
|
@ -198,30 +179,9 @@ o.spec("onbeforeremove", function() {
|
||||||
}
|
}
|
||||||
render(root, [{tag: component, attrs: {onbeforeremove: onbeforeremove, onremove: onremove}}])
|
render(root, [{tag: component, attrs: {onbeforeremove: onbeforeremove, onremove: onremove}}])
|
||||||
render(root, [])
|
render(root, [])
|
||||||
o(onremove.callCount).equals(2) // once for `tag`, once for `attrs`
|
callAsync(function() {
|
||||||
})
|
o(onremove.callCount).equals(2) // once for `tag`, once for `attrs`
|
||||||
o("doesn't finalize prematurely if `done` is called twice in the `tag` hook", function(done) {
|
done()
|
||||||
var async = false
|
})
|
||||||
var component = {
|
|
||||||
view: function() {},
|
|
||||||
onbeforeremove: function(vnode, doneRemoving){
|
|
||||||
doneRemoving()
|
|
||||||
doneRemoving()
|
|
||||||
},
|
|
||||||
onremove: function() {
|
|
||||||
o(async).equals(true)
|
|
||||||
done()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
render(root, [{
|
|
||||||
tag:component,
|
|
||||||
attrs: {
|
|
||||||
onbeforeremove: function(vnode, doneRemoving){
|
|
||||||
callAsync(doneRemoving)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}])
|
|
||||||
render(root, [])
|
|
||||||
async = true
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue