|
| 1 | +library testability.get_testability; |
| 2 | + |
| 3 | +import './testability.dart'; |
| 4 | + |
| 5 | +import 'dart:html'; |
| 6 | +import 'dart:js' as js; |
| 7 | + |
| 8 | +// Work around http://dartbug.com/17752, copied from |
| 9 | +// https://github.com/angular/angular.dart/blob/master/lib/introspection.dart |
| 10 | +// Proxies a Dart function that accepts up to 10 parameters. |
| 11 | +js.JsFunction _jsFunction(Function fn) { |
| 12 | + const Object X = __varargSentinel; |
| 13 | + return new js.JsFunction.withThis( |
| 14 | + (thisArg, [o1=X, o2=X, o3=X, o4=X, o5=X, o6=X, o7=X, o8=X, o9=X, o10=X]) { |
| 15 | + return __invokeFn(fn, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10); |
| 16 | + }); |
| 17 | +} |
| 18 | + |
| 19 | + |
| 20 | +const Object __varargSentinel = const Object(); |
| 21 | + |
| 22 | + |
| 23 | +__invokeFn(fn, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10) { |
| 24 | + var args = [o1, o2, o3, o4, o5, o6, o7, o8, o9, o10]; |
| 25 | + while (args.length > 0 && identical(args.last, __varargSentinel)) { |
| 26 | + args.removeLast(); |
| 27 | + } |
| 28 | + return _jsify(Function.apply(fn, args)); |
| 29 | +} |
| 30 | + |
| 31 | + |
| 32 | +// Helper function to JSify a Dart object. While this is *required* to JSify |
| 33 | +// the result of a scope.eval(), other uses are not required and are used to |
| 34 | +// work around http://dartbug.com/17752 in a convenient way (that bug affects |
| 35 | +// dart2js in checked mode.) |
| 36 | +_jsify(var obj) { |
| 37 | + if (obj == null || obj is js.JsObject) { |
| 38 | + return obj; |
| 39 | + } |
| 40 | + if (obj is _JsObjectProxyable) { |
| 41 | + return obj._toJsObject(); |
| 42 | + } |
| 43 | + if (obj is Function) { |
| 44 | + return _jsFunction(obj); |
| 45 | + } |
| 46 | + if ((obj is Map) || (obj is Iterable)) { |
| 47 | + var mappedObj = (obj is Map) ? |
| 48 | + new Map.fromIterables(obj.keys, obj.values.map(_jsify)) : obj.map(_jsify); |
| 49 | + if (obj is List) { |
| 50 | + return new js.JsArray.from(mappedObj); |
| 51 | + } else { |
| 52 | + return new js.JsObject.jsify(mappedObj); |
| 53 | + } |
| 54 | + } |
| 55 | + return obj; |
| 56 | +} |
| 57 | + |
| 58 | +abstract class _JsObjectProxyable { |
| 59 | + js.JsObject _toJsObject(); |
| 60 | +} |
| 61 | + |
| 62 | +class PublicTestability implements _JsObjectProxyable { |
| 63 | + Testability _testability; |
| 64 | + PublicTestability(Testability testability) { |
| 65 | + this._testability = testability; |
| 66 | + } |
| 67 | + |
| 68 | + whenStable(Function callback) { |
| 69 | + return this._testability.whenStable(callback); |
| 70 | + } |
| 71 | + |
| 72 | + findBindings(Element elem, String binding, bool exactMatch) { |
| 73 | + return this._testability.findBindings(elem, binding, exactMatch); |
| 74 | + } |
| 75 | + |
| 76 | + js.JsObject _toJsObject() { |
| 77 | + return _jsify({ |
| 78 | + 'findBindings': (bindingString, [exactMatch, allowNonElementNodes]) => |
| 79 | + findBindings(bindingString, exactMatch, allowNonElementNodes), |
| 80 | + 'whenStable': (callback) => |
| 81 | + whenStable(() => callback.apply([])), |
| 82 | + })..['_dart_'] = this; |
| 83 | + } |
| 84 | +} |
| 85 | + |
| 86 | +class GetTestability { |
| 87 | + static addToWindow(TestabilityRegistry registry) { |
| 88 | + js.context['angular2'] = _jsify({ |
| 89 | + 'getTestability': (Element elem) { |
| 90 | + Testability testability = registry.findTestabilityInTree(elem); |
| 91 | + return _jsify(new PublicTestability(testability)); |
| 92 | + }, |
| 93 | + 'resumeBootstrap': ([arg]) {}, |
| 94 | + }); |
| 95 | + } |
| 96 | +} |
0 commit comments