@@ -137,7 +137,7 @@ List<Object> ngDirectives(nodeOrSelector) => ngProbe(nodeOrSelector).directives;
137
137
138
138
139
139
js.JsObject _jsProbe (ElementProbe probe) {
140
- return new js. JsObject . jsify ({
140
+ return _jsify ({
141
141
"element" : probe.element,
142
142
"injector" : _jsInjector (probe.injector),
143
143
"scope" : _jsScopeFromProbe (probe),
@@ -149,15 +149,84 @@ js.JsObject _jsProbe(ElementProbe probe) {
149
149
150
150
151
151
js.JsObject _jsInjector (Injector injector) =>
152
- new js. JsObject . jsify ({"get" : injector.get })..['_dart_' ] = injector;
152
+ _jsify ({"get" : injector.get })..['_dart_' ] = injector;
153
153
154
154
155
155
js.JsObject _jsScopeFromProbe (ElementProbe probe) =>
156
156
_jsScope (probe.scope, probe.injector.getByKey (SCOPE_STATS_CONFIG_KEY ));
157
157
158
158
159
+
160
+ // Work around http://dartbug.com/17752
161
+ // Proxies a Dart function that accepts up to 10 parameters.
162
+ js.JsFunction _jsFunction (Function fn) {
163
+ const Object X = __varargSentinel;
164
+ Function fnCopy = fn; // workaround a bug.
165
+ return new js.JsFunction .withThis (
166
+ (thisArg, [o1= X , o2= X , o3= X , o4= X , o5= X , o6= X , o7= X , o8= X , o9= X , o10= X ]) {
167
+ // Work around a bug in dart 1.4.0 where the closurized variable, fn,
168
+ // gets mysteriously replaced with our own closure function leading to a
169
+ // stack overflow.
170
+ fn = fnCopy;
171
+ if (o10 == null && identical (o9, X )) {
172
+ // Work around another bug in dart 1.4.0. This bug is not present in
173
+ // dart 1.5.0-dev.2.0.
174
+ // In dart 1.4.0, when running in Dartium (not dart2js), if you invoke
175
+ // a JsFunction from Dart code (either by calling .apply([args]) on it
176
+ // or by calling .callMethod(jsFuncName, [args]) on a JsObject
177
+ // containing the JsFunction, regardless of whether you specified the
178
+ // thisArg keyword parameter, the Dart function is called with the
179
+ // first argument in the thisArg param causing all the arguments to be
180
+ // shifted by one. We can detect this by the fact that o10 is null
181
+ // but o9 is X (should only happen when o9 got a default value) and
182
+ // work around it by using thisArg as the first parameter.
183
+ return __invokeFn (fn, thisArg, o1, o2, o3, o4, o5, o6, o7, o8, o9);
184
+ } else {
185
+ return __invokeFn (fn, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10);
186
+ }
187
+ }
188
+ );
189
+ }
190
+
191
+
192
+ const Object __varargSentinel = const Object ();
193
+
194
+
195
+ __invokeFn (fn, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10) {
196
+ var args = [o1, o2, o3, o4, o5, o6, o7, o8, o9, o10];
197
+ while (args.length > 0 && identical (args.last, __varargSentinel)) {
198
+ args.removeLast ();
199
+ }
200
+ return _jsify (Function .apply (fn, args));
201
+ }
202
+
203
+
204
+ // Helper function to JSify a Dart object. While this is *required* to JSify
205
+ // the result of a scope.eval(), other uses are not required and are used to
206
+ // work around http://dartbug.com/17752 in a convenient way (that bug affects
207
+ // dart2js in checked mode.)
208
+ _jsify (var obj) {
209
+ if (obj == null || obj is js.JsObject ) {
210
+ return obj;
211
+ }
212
+ if (obj is Function ) {
213
+ return _jsFunction (obj);
214
+ }
215
+ if ((obj is Map ) || (obj is Iterable )) {
216
+ var mappedObj = (obj is Map ) ?
217
+ new Map .fromIterables (obj.keys, obj.values.map (_jsify)) : obj.map (_jsify);
218
+ if (obj is List ) {
219
+ return new js.JsArray .from (mappedObj);
220
+ } else {
221
+ return new js.JsObject .jsify (mappedObj);
222
+ }
223
+ }
224
+ return obj;
225
+ }
226
+
227
+
159
228
js.JsObject _jsScope (Scope scope, ScopeStatsConfig config) {
160
- return new js. JsObject . jsify ({
229
+ return _jsify ({
161
230
"apply" : scope.apply,
162
231
"broadcast" : scope.broadcast,
163
232
"context" : scope.context,
@@ -176,18 +245,6 @@ js.JsObject _jsScope(Scope scope, ScopeStatsConfig config) {
176
245
}
177
246
178
247
179
- // Helper function to JSify the result of a scope.eval() for simple cases.
180
- _jsify (var obj) {
181
- if (obj is js.JsObject ) {
182
- return obj;
183
- } else if (obj is Iterable ) {
184
- return new js.JsObject .jsify (obj)..['_dart_' ] = obj;
185
- } else {
186
- return obj;
187
- }
188
- }
189
-
190
-
191
248
_jsDirective (directive) => directive;
192
249
193
250
@@ -261,7 +318,7 @@ class _Testability implements _JsObjectProxyable {
261
318
}
262
319
263
320
js.JsObject _toJsObject () {
264
- return new js. JsObject . jsify ({
321
+ return _jsify ({
265
322
'allowAnimations' : allowAnimations,
266
323
'findBindings' : (bindingString, [exactMatch]) =>
267
324
findBindings (bindingString, exactMatch),
@@ -280,14 +337,18 @@ class _Testability implements _JsObjectProxyable {
280
337
281
338
282
339
void publishToJavaScript () {
283
- var C = js.context ;
284
- C ['ngProbe' ] = (nodeOrSelector) => _jsProbe (ngProbe (nodeOrSelector));
285
- C ['ngInjector' ] = (nodeOrSelector) => _jsInjector (ngInjector (nodeOrSelector));
286
- C ['ngScope' ] = (nodeOrSelector) => _jsScopeFromProbe (ngProbe (nodeOrSelector));
287
- C ['ngQuery' ] = (dom.Node node, String selector, [String containsText]) =>
288
- new js. JsArray . from ( ngQuery (node, selector, containsText) );
289
- C ['angular' ] = new js. JsObject . jsify ( {
340
+ var D = {} ;
341
+ D ['ngProbe' ] = (nodeOrSelector) => _jsProbe (ngProbe (nodeOrSelector));
342
+ D ['ngInjector' ] = (nodeOrSelector) => _jsInjector (ngInjector (nodeOrSelector));
343
+ D ['ngScope' ] = (nodeOrSelector) => _jsScopeFromProbe (ngProbe (nodeOrSelector));
344
+ D ['ngQuery' ] = (dom.Node node, String selector, [String containsText]) =>
345
+ ngQuery (node, selector, containsText);
346
+ D ['angular' ] = {
290
347
'resumeBootstrap' : ([arg]) {},
291
348
'getTestability' : (node) => new _Testability .fromNode (node)._toJsObject (),
292
- });
349
+ };
350
+ js.JsObject J = _jsify (D );
351
+ for (String key in D .keys) {
352
+ js.context[key] = J [key];
353
+ }
293
354
}
0 commit comments