Skip to content

Commit

Permalink
Implement basic error tolerance
Browse files Browse the repository at this point in the history
  • Loading branch information
dead-claudia committed Nov 9, 2018
1 parent 4ac33fa commit 7fc6fba
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions render/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,24 @@ module.exports = function($window) {
math: "http://www.w3.org/1998/Math/MathML"
}

var hookError, hookThrown
var onevent
function setEventCallback(callback) {return onevent = callback}

function getNameSpace(vnode) {
return vnode.attrs && vnode.attrs.xmlns || nameSpace[vnode.tag]
}

function fail(message) {
hookThrown = true
hookError = new Error(message)
}

//sanity check to discourage people from doing `vnode.state = ...`
function checkState(vnode, original) {
if (vnode.state !== original) throw new Error("`vnode.state` must not be modified")
if (vnode.state !== original) {
fail("`vnode.state` must not be modified")
}
}

//Note: the hook is passed as the `this` argument to allow proxying the
Expand All @@ -30,6 +38,9 @@ module.exports = function($window) {
var original = vnode.state
try {
return this.apply(original, arguments)
} catch (e) {
hookThrown = true
hookError = e
} finally {
checkState(vnode, original)
}
Expand Down Expand Up @@ -155,7 +166,7 @@ module.exports = function($window) {
if (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks)
initLifecycle(vnode.state, vnode, hooks)
vnode.instance = Vnode.normalize(callHook.call(vnode.state.view, vnode))
if (vnode.instance === vnode) throw Error("A view cannot return the vnode it received as argument")
if (vnode.instance === vnode) fail("A view cannot return the vnode it received as argument")
sentinel.$$reentrantLock$$ = null
}
function createComponent(parent, vnode, hooks, ns, nextSibling) {
Expand Down Expand Up @@ -510,7 +521,7 @@ module.exports = function($window) {
}
function updateComponent(parent, old, vnode, hooks, nextSibling, ns) {
vnode.instance = Vnode.normalize(callHook.call(vnode.state.view, vnode))
if (vnode.instance === vnode) throw Error("A view cannot return the vnode it received as argument")
if (vnode.instance === vnode) fail("A view cannot return the vnode it received as argument")
if (vnode.attrs != null) updateLifecycle(vnode.attrs, vnode, hooks)
updateLifecycle(vnode.state, vnode, hooks)
if (vnode.instance != null) {
Expand Down Expand Up @@ -619,7 +630,7 @@ module.exports = function($window) {
var content = children[0].children
if (vnode.dom.innerHTML !== content) vnode.dom.innerHTML = content
}
else if (vnode.text != null || children != null && children.length !== 0) throw new Error("Child node of a contenteditable must be trusted")
else if (vnode.text != null || children != null && children.length !== 0) fail("Child node of a contenteditable must be trusted")
}

//remove
Expand Down Expand Up @@ -852,19 +863,22 @@ module.exports = function($window) {
if (typeof source.onupdate === "function") hooks.push(callHook.bind(source.onupdate, vnode))
}
function shouldNotUpdate(vnode, old) {
var prevHookThrown = hookThrown
var forceVnodeUpdate, forceComponentUpdate
hookThrown = false
if (vnode.attrs != null && typeof vnode.attrs.onbeforeupdate === "function") {
forceVnodeUpdate = callHook.call(vnode.attrs.onbeforeupdate, vnode, old)
}
if (typeof vnode.tag !== "string" && typeof vnode.state.onbeforeupdate === "function") {
forceComponentUpdate = callHook.call(vnode.state.onbeforeupdate, vnode, old)
}
if (!(forceVnodeUpdate === undefined && forceComponentUpdate === undefined) && !forceVnodeUpdate && !forceComponentUpdate) {
if (hookThrown || !(forceVnodeUpdate === undefined && forceComponentUpdate === undefined) && !forceVnodeUpdate && !forceComponentUpdate) {
vnode.dom = old.dom
vnode.domSize = old.domSize
vnode.instance = old.instance
return true
}
hookThrown = prevHookThrown
return false
}

Expand All @@ -878,11 +892,19 @@ module.exports = function($window) {
if (dom.vnodes == null) dom.textContent = ""

vnodes = Vnode.normalizeChildren(Array.isArray(vnodes) ? vnodes : [vnodes])
var prevHookError = hookError
var prevHookThrown = hookThrown
hookThrown = false
updateNodes(dom, dom.vnodes, vnodes, hooks, null, namespace === "http://www.w3.org/1999/xhtml" ? undefined : namespace)
dom.vnodes = vnodes
// document.activeElement can return null in IE https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement
if (active != null && activeElement() !== active && typeof active.focus === "function") active.focus()
for (var i = 0; i < hooks.length; i++) hooks[i]()
var nextHookThrown = hookThrown
var nextHookError = hookError
hookThrown = prevHookThrown
hookError = prevHookError
if (nextHookThrown) throw nextHookError
}

return {render: render, setEventCallback: setEventCallback}
Expand Down

0 comments on commit 7fc6fba

Please sign in to comment.