@@ -10,16 +10,24 @@ module.exports = function($window) {
10
10
math : "http://www.w3.org/1998/Math/MathML"
11
11
}
12
12
13
+ var hookError , hookThrown
13
14
var onevent
14
15
function setEventCallback ( callback ) { return onevent = callback }
15
16
16
17
function getNameSpace ( vnode ) {
17
18
return vnode . attrs && vnode . attrs . xmlns || nameSpace [ vnode . tag ]
18
19
}
19
20
21
+ function fail ( message ) {
22
+ hookThrown = true
23
+ hookError = new Error ( message )
24
+ }
25
+
20
26
//sanity check to discourage people from doing `vnode.state = ...`
21
27
function checkState ( vnode , original ) {
22
- if ( vnode . state !== original ) throw new Error ( "`vnode.state` must not be modified" )
28
+ if ( vnode . state !== original ) {
29
+ fail ( "`vnode.state` must not be modified" )
30
+ }
23
31
}
24
32
25
33
//Note: the hook is passed as the `this` argument to allow proxying the
@@ -30,6 +38,9 @@ module.exports = function($window) {
30
38
var original = vnode . state
31
39
try {
32
40
return this . apply ( original , arguments )
41
+ } catch ( e ) {
42
+ hookThrown = true
43
+ hookError = e
33
44
} finally {
34
45
checkState ( vnode , original )
35
46
}
@@ -155,7 +166,7 @@ module.exports = function($window) {
155
166
if ( vnode . attrs != null ) initLifecycle ( vnode . attrs , vnode , hooks )
156
167
initLifecycle ( vnode . state , vnode , hooks )
157
168
vnode . instance = Vnode . normalize ( callHook . call ( vnode . state . view , vnode ) )
158
- if ( vnode . instance === vnode ) throw Error ( "A view cannot return the vnode it received as argument" )
169
+ if ( vnode . instance === vnode ) fail ( "A view cannot return the vnode it received as argument" )
159
170
sentinel . $$reentrantLock$$ = null
160
171
}
161
172
function createComponent ( parent , vnode , hooks , ns , nextSibling ) {
@@ -510,7 +521,7 @@ module.exports = function($window) {
510
521
}
511
522
function updateComponent ( parent , old , vnode , hooks , nextSibling , ns ) {
512
523
vnode . instance = Vnode . normalize ( callHook . call ( vnode . state . view , vnode ) )
513
- if ( vnode . instance === vnode ) throw Error ( "A view cannot return the vnode it received as argument" )
524
+ if ( vnode . instance === vnode ) fail ( "A view cannot return the vnode it received as argument" )
514
525
if ( vnode . attrs != null ) updateLifecycle ( vnode . attrs , vnode , hooks )
515
526
updateLifecycle ( vnode . state , vnode , hooks )
516
527
if ( vnode . instance != null ) {
@@ -619,7 +630,7 @@ module.exports = function($window) {
619
630
var content = children [ 0 ] . children
620
631
if ( vnode . dom . innerHTML !== content ) vnode . dom . innerHTML = content
621
632
}
622
- else if ( vnode . text != null || children != null && children . length !== 0 ) throw new Error ( "Child node of a contenteditable must be trusted" )
633
+ else if ( vnode . text != null || children != null && children . length !== 0 ) fail ( "Child node of a contenteditable must be trusted" )
623
634
}
624
635
625
636
//remove
@@ -852,19 +863,22 @@ module.exports = function($window) {
852
863
if ( typeof source . onupdate === "function" ) hooks . push ( callHook . bind ( source . onupdate , vnode ) )
853
864
}
854
865
function shouldNotUpdate ( vnode , old ) {
866
+ var prevHookThrown = hookThrown
855
867
var forceVnodeUpdate , forceComponentUpdate
868
+ hookThrown = false
856
869
if ( vnode . attrs != null && typeof vnode . attrs . onbeforeupdate === "function" ) {
857
870
forceVnodeUpdate = callHook . call ( vnode . attrs . onbeforeupdate , vnode , old )
858
871
}
859
872
if ( typeof vnode . tag !== "string" && typeof vnode . state . onbeforeupdate === "function" ) {
860
873
forceComponentUpdate = callHook . call ( vnode . state . onbeforeupdate , vnode , old )
861
874
}
862
- if ( ! ( forceVnodeUpdate === undefined && forceComponentUpdate === undefined ) && ! forceVnodeUpdate && ! forceComponentUpdate ) {
875
+ if ( hookThrown || ! ( forceVnodeUpdate === undefined && forceComponentUpdate === undefined ) && ! forceVnodeUpdate && ! forceComponentUpdate ) {
863
876
vnode . dom = old . dom
864
877
vnode . domSize = old . domSize
865
878
vnode . instance = old . instance
866
879
return true
867
880
}
881
+ hookThrown = prevHookThrown
868
882
return false
869
883
}
870
884
@@ -878,11 +892,19 @@ module.exports = function($window) {
878
892
if ( dom . vnodes == null ) dom . textContent = ""
879
893
880
894
vnodes = Vnode . normalizeChildren ( Array . isArray ( vnodes ) ? vnodes : [ vnodes ] )
895
+ var prevHookError = hookError
896
+ var prevHookThrown = hookThrown
897
+ hookThrown = false
881
898
updateNodes ( dom , dom . vnodes , vnodes , hooks , null , namespace === "http://www.w3.org/1999/xhtml" ? undefined : namespace )
882
899
dom . vnodes = vnodes
883
900
// document.activeElement can return null in IE https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement
884
901
if ( active != null && activeElement ( ) !== active && typeof active . focus === "function" ) active . focus ( )
885
902
for ( var i = 0 ; i < hooks . length ; i ++ ) hooks [ i ] ( )
903
+ var nextHookThrown = hookThrown
904
+ var nextHookError = hookError
905
+ hookThrown = prevHookThrown
906
+ hookError = prevHookError
907
+ if ( nextHookThrown ) throw nextHookError
886
908
}
887
909
888
910
return { render : render , setEventCallback : setEventCallback }
0 commit comments