leaner 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core.js +23 -2
- package/dist/web.js +96 -6
- package/package.json +1 -1
package/dist/core.js
CHANGED
|
@@ -92,6 +92,9 @@ function withScope( scope, callback ) {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
function createWatcher( deps, callback, async ) {
|
|
95
|
+
if ( async )
|
|
96
|
+
callback = createSafeCallback( callback );
|
|
97
|
+
|
|
95
98
|
const watcher = {
|
|
96
99
|
deps,
|
|
97
100
|
callback,
|
|
@@ -99,7 +102,7 @@ function createWatcher( deps, callback, async ) {
|
|
|
99
102
|
};
|
|
100
103
|
|
|
101
104
|
if ( current != null )
|
|
102
|
-
current.push( watcher );
|
|
105
|
+
current.watchers.push( watcher );
|
|
103
106
|
|
|
104
107
|
if ( deps != null ) {
|
|
105
108
|
for ( const dep of deps ) {
|
|
@@ -110,6 +113,24 @@ function createWatcher( deps, callback, async ) {
|
|
|
110
113
|
return watcher;
|
|
111
114
|
}
|
|
112
115
|
|
|
116
|
+
function createSafeCallback( callback ) {
|
|
117
|
+
if ( current != null && current.errorHandler != null ) {
|
|
118
|
+
const handler = current.errorHandler;
|
|
119
|
+
|
|
120
|
+
return safeCallback;
|
|
121
|
+
|
|
122
|
+
function safeCallback() {
|
|
123
|
+
try {
|
|
124
|
+
callback();
|
|
125
|
+
} catch ( err ) {
|
|
126
|
+
handler( err );
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return callback;
|
|
132
|
+
}
|
|
133
|
+
|
|
113
134
|
function updateWatcher( watcher, deps ) {
|
|
114
135
|
for ( const dep of deps ) {
|
|
115
136
|
dep.add( watcher );
|
|
@@ -126,7 +147,7 @@ function updateWatcher( watcher, deps ) {
|
|
|
126
147
|
}
|
|
127
148
|
|
|
128
149
|
function destroyScope( scope ) {
|
|
129
|
-
for ( const watcher of scope ) {
|
|
150
|
+
for ( const watcher of scope.watchers ) {
|
|
130
151
|
watcher.callback = null;
|
|
131
152
|
|
|
132
153
|
if ( watcher.deps != null ) {
|
package/dist/web.js
CHANGED
|
@@ -37,15 +37,21 @@ function createComponent( template ) {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
function createContext( parent ) {
|
|
40
|
-
|
|
40
|
+
const context = {
|
|
41
41
|
parent,
|
|
42
42
|
children: null,
|
|
43
|
-
scope:
|
|
43
|
+
scope: {
|
|
44
|
+
watchers: [],
|
|
45
|
+
errorHandler: err => handleError( context, err ),
|
|
46
|
+
},
|
|
44
47
|
mount: null,
|
|
45
48
|
destroy: null,
|
|
46
49
|
refs: null,
|
|
47
50
|
services: null,
|
|
51
|
+
errorHandler: null,
|
|
48
52
|
};
|
|
53
|
+
|
|
54
|
+
return context;
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
function createChildContext() {
|
|
@@ -141,9 +147,9 @@ function destroyContext( context ) {
|
|
|
141
147
|
|
|
142
148
|
context.mount = null;
|
|
143
149
|
|
|
144
|
-
if ( context.scope.length > 0 ) {
|
|
150
|
+
if ( context.scope.watchers.length > 0 ) {
|
|
145
151
|
destroyScope( context.scope );
|
|
146
|
-
context.scope = [];
|
|
152
|
+
context.scope.watchers = [];
|
|
147
153
|
}
|
|
148
154
|
|
|
149
155
|
if ( context.children != null ) {
|
|
@@ -155,6 +161,25 @@ function destroyContext( context ) {
|
|
|
155
161
|
context.services = null;
|
|
156
162
|
}
|
|
157
163
|
|
|
164
|
+
function cleanUpContext( context ) {
|
|
165
|
+
context.destroy = null;
|
|
166
|
+
context.refs = null;
|
|
167
|
+
context.mount = null;
|
|
168
|
+
|
|
169
|
+
if ( context.scope.watchers.length > 0 ) {
|
|
170
|
+
destroyScope( context.scope );
|
|
171
|
+
context.scope.watchers = [];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if ( context.children != null ) {
|
|
175
|
+
for ( const child of context.children )
|
|
176
|
+
cleanUpContext( child );
|
|
177
|
+
context.children = null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
context.services = null;
|
|
181
|
+
}
|
|
182
|
+
|
|
158
183
|
function provide( key, value ) {
|
|
159
184
|
if ( current == null )
|
|
160
185
|
throw new Error( 'provide() cannot be called outside of a component' );
|
|
@@ -175,6 +200,35 @@ function inject( key ) {
|
|
|
175
200
|
}
|
|
176
201
|
}
|
|
177
202
|
|
|
203
|
+
function handleError( context, err ) {
|
|
204
|
+
while ( context != null) {
|
|
205
|
+
if ( context.errorHandler != null ) {
|
|
206
|
+
context.errorHandler( err );
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
context = context.parent;
|
|
210
|
+
}
|
|
211
|
+
throw err;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function createSafeHandler( callback ) {
|
|
215
|
+
if ( current != null ) {
|
|
216
|
+
const context = current;
|
|
217
|
+
|
|
218
|
+
return safeHandler;
|
|
219
|
+
|
|
220
|
+
function safeHandler( e ) {
|
|
221
|
+
try {
|
|
222
|
+
callback( e );
|
|
223
|
+
} catch ( err ) {
|
|
224
|
+
handleError( context, err );
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return callback;
|
|
230
|
+
}
|
|
231
|
+
|
|
178
232
|
function setClasses( element, classes ) {
|
|
179
233
|
if ( typeof classes == 'function' ) {
|
|
180
234
|
reactive( classes, value => {
|
|
@@ -643,7 +697,7 @@ function createForDirective( template ) {
|
|
|
643
697
|
|
|
644
698
|
if ( containsMatchedByValue && !watchingContent ) {
|
|
645
699
|
destroyScope( context.scope );
|
|
646
|
-
context.scope = [];
|
|
700
|
+
context.scope.watchers = [];
|
|
647
701
|
withScope( context.scope, () => {
|
|
648
702
|
// clone the array to watch all elements
|
|
649
703
|
reactive( () => [ ...itemsGetter() ], updateContent );
|
|
@@ -844,6 +898,41 @@ function createSwitchDirective( template ) {
|
|
|
844
898
|
}
|
|
845
899
|
}
|
|
846
900
|
|
|
901
|
+
function createTryDirective( template ) {
|
|
902
|
+
if ( template.length != 3 || typeof template[ 2 ] != 'function' )
|
|
903
|
+
throw new TypeError( 'Invalid try template' );
|
|
904
|
+
|
|
905
|
+
const result = new DynamicNode( null );
|
|
906
|
+
|
|
907
|
+
const context = createChildContext();
|
|
908
|
+
|
|
909
|
+
try {
|
|
910
|
+
updateDynamicNode( result, context, template[ 1 ] );
|
|
911
|
+
} catch ( err ) {
|
|
912
|
+
updateErrorState( err );
|
|
913
|
+
return result;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
context.errorHandler = asyncErrorHandler;
|
|
917
|
+
|
|
918
|
+
return result;
|
|
919
|
+
|
|
920
|
+
function asyncErrorHandler( err ) {
|
|
921
|
+
try {
|
|
922
|
+
updateErrorState( err );
|
|
923
|
+
} catch ( err ) {
|
|
924
|
+
handleError( context, err );
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
function updateErrorState( err ) {
|
|
929
|
+
context.errorHandler = null;
|
|
930
|
+
if ( result.content == null )
|
|
931
|
+
cleanUpContext( context );
|
|
932
|
+
updateDynamicNode( result, context, template[ 2 ]( err ) );
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
847
936
|
const Directives = {
|
|
848
937
|
dynamic: createDynamicDirective,
|
|
849
938
|
else: unexpectedDirective,
|
|
@@ -851,6 +940,7 @@ const Directives = {
|
|
|
851
940
|
if: createIfDirective,
|
|
852
941
|
repeat: createRepeatDirective,
|
|
853
942
|
switch: createSwitchDirective,
|
|
943
|
+
try: createTryDirective,
|
|
854
944
|
};
|
|
855
945
|
|
|
856
946
|
const Properties = new Set( [ 'value', 'checked', 'textContent', 'innerHTML' ] );
|
|
@@ -943,7 +1033,7 @@ function setElementProperties( element, properties ) {
|
|
|
943
1033
|
|
|
944
1034
|
function setElementProperty( element, key, value ) {
|
|
945
1035
|
if ( key.startsWith( 'on' ) ) {
|
|
946
|
-
element.addEventListener( key.substring( 2 ), value );
|
|
1036
|
+
element.addEventListener( key.substring( 2 ), createSafeHandler( value ) );
|
|
947
1037
|
} else if ( Properties.has( key ) ) {
|
|
948
1038
|
if ( typeof value == 'function' )
|
|
949
1039
|
reactive( value, value => element[ key ] = value != null ? value : '' );
|