Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of html; | 5 part of html; |
| 6 | 6 |
| 7 class _Property { | 7 class _Property { |
| 8 _Property(this.name) : | 8 _Property(this.name) : |
| 9 _hasValue = false, | 9 _hasValue = false, |
| 10 writable = false, | 10 writable = false, |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 static Element getAndValidateNativeType(Type type, String tagName) { | 182 static Element getAndValidateNativeType(Type type, String tagName) { |
| 183 var element = new Element.tag(tagName); | 183 var element = new Element.tag(tagName); |
| 184 if (!isTypeSubclassOf(type, element.runtimeType)) { | 184 if (!isTypeSubclassOf(type, element.runtimeType)) { |
| 185 return null; | 185 return null; |
| 186 } | 186 } |
| 187 return element; | 187 return element; |
| 188 } | 188 } |
| 189 | 189 |
| 190 static window() => _blink.Blink_Utils.window(); | 190 static window() => _blink.Blink_Utils.window(); |
| 191 static forwardingPrint(String message) => _blink.Blink_Utils.forwardingPrint(m essage); | 191 static forwardingPrint(String message) => _blink.Blink_Utils.forwardingPrint(m essage); |
| 192 static void spawnDomFunction(Function f, int replyTo) | |
| 193 native "Utils_spawnDomFunction"; | |
|
vsm
2015/02/24 20:29:02
Actually, we've moved all native methods to the _b
Alan Knight
2015/02/26 15:52:19
Done.
| |
| 194 | |
| 192 // TODO(vsm): Make this API compatible with spawnUri. It should also | 195 // TODO(vsm): Make this API compatible with spawnUri. It should also |
| 193 // return a Future<Isolate>. | 196 // return a Future<Isolate>. |
| 194 static spawnDomUri(String uri) => _blink.Blink_Utils.spawnDomUri(uri); | 197 static spawnDomUri(String uri) => _blink.Blink_Utils.spawnDomUri(uri); |
| 195 | 198 |
| 196 // The following methods were added for debugger integration to make working | 199 // The following methods were added for debugger integration to make working |
| 197 // with the Dart C mirrors API simpler. | 200 // with the Dart C mirrors API simpler. |
| 198 // TODO(jacobr): consider moving them to a separate library. | 201 // TODO(jacobr): consider moving them to a separate library. |
| 199 // If Dart supported dynamic code injection, we would only inject this code | 202 // If Dart supported dynamic code injection, we would only inject this code |
| 200 // when the debugger is invoked. | 203 // when the debugger is invoked. |
| 201 | 204 |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 * in user libraries as side effect free. | 503 * in user libraries as side effect free. |
| 501 */ | 504 */ |
| 502 static bool _isSideEffectFreeGetter(MethodMirror methodMirror, | 505 static bool _isSideEffectFreeGetter(MethodMirror methodMirror, |
| 503 LibraryMirror libraryMirror) { | 506 LibraryMirror libraryMirror) { |
| 504 // This matches JavaScript behavior. We should consider displaying | 507 // This matches JavaScript behavior. We should consider displaying |
| 505 // getters for all dart platform libraries rather than just the DOM | 508 // getters for all dart platform libraries rather than just the DOM |
| 506 // libraries. | 509 // libraries. |
| 507 return libraryMirror.uri.scheme == 'dart' && | 510 return libraryMirror.uri.scheme == 'dart' && |
| 508 SIDE_EFFECT_FREE_LIBRARIES.contains(libraryMirror.uri.toString()); | 511 SIDE_EFFECT_FREE_LIBRARIES.contains(libraryMirror.uri.toString()); |
| 509 } | 512 } |
| 510 | 513 |
| 511 /** | 514 /** |
| 512 * Whether we should treat a property as a field for the purposes of the | 515 * Whether we should treat a property as a field for the purposes of the |
| 513 * debugger. | 516 * debugger. |
| 514 */ | 517 */ |
| 515 static bool treatPropertyAsField(MethodMirror methodMirror, | 518 static bool treatPropertyAsField(MethodMirror methodMirror, |
| 516 LibraryMirror libraryMirror) { | 519 LibraryMirror libraryMirror) { |
| 517 return (methodMirror.isGetter || methodMirror.isSetter) && | 520 return (methodMirror.isGetter || methodMirror.isSetter) && |
| 518 (methodMirror.isSynthetic || | 521 (methodMirror.isSynthetic || |
| 519 _isSideEffectFreeGetter(methodMirror,libraryMirror)); | 522 _isSideEffectFreeGetter(methodMirror,libraryMirror)); |
| 520 } | 523 } |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 718 property.getter, | 721 property.getter, |
| 719 property.value, | 722 property.value, |
| 720 property.hasValue, | 723 property.hasValue, |
| 721 property.writable, | 724 property.writable, |
| 722 property.isMethod, | 725 property.isMethod, |
| 723 property.isOwn, | 726 property.isOwn, |
| 724 property.wasThrown]); | 727 property.wasThrown]); |
| 725 } | 728 } |
| 726 return ret; | 729 return ret; |
| 727 } | 730 } |
| 728 | 731 |
| 729 /** | 732 /** |
| 730 * Get a property, returning null if the property does not exist. | 733 * Get a property, returning null if the property does not exist. |
| 731 * For private property names, we attempt to resolve the property in the | 734 * For private property names, we attempt to resolve the property in the |
| 732 * context of each library that the property name could be associated with. | 735 * context of each library that the property name could be associated with. |
| 733 */ | 736 */ |
| 734 static getObjectPropertySafe(o, String propertyName) { | 737 static getObjectPropertySafe(o, String propertyName) { |
| 735 var objectMirror = reflect(o); | 738 var objectMirror = reflect(o); |
| 736 var classMirror = objectMirror.type; | 739 var classMirror = objectMirror.type; |
| 737 if (propertyName.startsWith("_")) { | 740 if (propertyName.startsWith("_")) { |
| 738 var attemptedLibraries = new Set<LibraryMirror>(); | 741 var attemptedLibraries = new Set<LibraryMirror>(); |
| 739 while (classMirror != null) { | 742 while (classMirror != null) { |
| 740 LibraryMirror library = classMirror.owner; | 743 LibraryMirror library = classMirror.owner; |
| 741 if (!attemptedLibraries.contains(library)) { | 744 if (!attemptedLibraries.contains(library)) { |
| 742 try { | 745 try { |
| 743 return objectMirror.getField( | 746 return objectMirror.getField( |
| 744 MirrorSystem.getSymbol(propertyName, library)).reflectee; | 747 MirrorSystem.getSymbol(propertyName, library)).reflectee; |
| 745 } catch (e) { } | 748 } catch (e) { } |
| 746 attemptedLibraries.add(library); | 749 attemptedLibraries.add(library); |
| 747 } | 750 } |
| 748 classMirror = classMirror.superclass; | 751 classMirror = classMirror.superclass; |
| 749 } | 752 } |
| 750 return null; | 753 return null; |
| 751 } | 754 } |
| 752 try { | 755 try { |
| 753 return objectMirror.getField( | 756 return objectMirror.getField( |
| 754 MirrorSystem.getSymbol(propertyName)).reflectee; | 757 MirrorSystem.getSymbol(propertyName)).reflectee; |
| 755 } catch (e) { | 758 } catch (e) { |
| 756 return null; | 759 return null; |
| 757 } | 760 } |
| 758 } | 761 } |
| 759 | 762 |
| 760 /** | 763 /** |
| 761 * Helper to wrap the inspect method on InjectedScriptHost to provide the | 764 * Helper to wrap the inspect method on InjectedScriptHost to provide the |
| 762 * inspect method required for the | 765 * inspect method required for the |
| 763 */ | 766 */ |
| 764 static List consoleApi(host) { | 767 static List consoleApi(host) { |
| 765 return [ | 768 return [ |
| 766 "inspect", | 769 "inspect", |
| 767 (o) { | 770 (o) { |
| 768 host.inspect(o, null); | 771 host.inspect(o, null); |
| 769 return o; | 772 return o; |
| 770 }, | 773 }, |
| 771 "dir", | 774 "dir", |
| 772 window().console.dir, | 775 window().console.dir, |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 887 Iterable<String> get keys => _blink.Blink_DOMStringMap.get_keys(this); | 890 Iterable<String> get keys => _blink.Blink_DOMStringMap.get_keys(this); |
| 888 Iterable<String> get values => Maps.getValues(this); | 891 Iterable<String> get values => Maps.getValues(this); |
| 889 int get length => Maps.length(this); | 892 int get length => Maps.length(this); |
| 890 bool get isEmpty => Maps.isEmpty(this); | 893 bool get isEmpty => Maps.isEmpty(this); |
| 891 bool get isNotEmpty => Maps.isNotEmpty(this); | 894 bool get isNotEmpty => Maps.isNotEmpty(this); |
| 892 void addAll(Map<String, String> other) { | 895 void addAll(Map<String, String> other) { |
| 893 other.forEach((key, value) => this[key] = value); | 896 other.forEach((key, value) => this[key] = value); |
| 894 } | 897 } |
| 895 } | 898 } |
| 896 | 899 |
| 900 // TODO(vsm): Remove DOM isolate code. This is only used to support | |
| 901 // printing and timers in background isolates. Background isolates | |
| 902 // should just forward to the main DOM isolate instead of requiring a | |
| 903 // special DOM isolate. | |
|
vsm
2015/02/24 20:24:19
Perhaps update this comment to remove once Workers
Alan Knight
2015/02/26 15:52:19
Done.
| |
| 904 | |
| 905 _makeSendPortFuture(spawnRequest) { | |
| 906 final completer = new Completer<SendPort>.sync(); | |
| 907 final port = new ReceivePort(); | |
| 908 port.listen((result) { | |
| 909 completer.complete(result); | |
| 910 port.close(); | |
| 911 }); | |
| 912 // TODO: SendPort.hashCode is ugly way to access port id. | |
| 913 spawnRequest(port.sendPort.hashCode); | |
| 914 return completer.future; | |
| 915 } | |
| 916 | |
| 917 Future<SendPort> _spawnDomFunction(Function f) => | |
| 918 _makeSendPortFuture((portId) { _Utils.spawnDomFunction(f, portId); }); | |
| 919 | |
| 920 final Future<SendPort> __HELPER_ISOLATE_PORT = | |
| 921 _spawnDomFunction(_helperIsolateMain); | |
| 922 | |
| 923 // Tricky part. | |
| 924 // Once __HELPER_ISOLATE_PORT gets resolved, it will still delay in .then | |
| 925 // and to delay Timer.run is used. However, Timer.run will try to register | |
| 926 // another Timer and here we got stuck: event cannot be posted as then | |
| 927 // callback is not executed because it's delayed with timer. | |
| 928 // Therefore once future is resolved, it's unsafe to call .then on it | |
| 929 // in Timer code. | |
| 930 SendPort __SEND_PORT; | |
| 931 | |
| 932 _sendToHelperIsolate(msg, SendPort replyTo) { | |
| 933 if (__SEND_PORT != null) { | |
| 934 __SEND_PORT.send([msg, replyTo]); | |
| 935 } else { | |
| 936 __HELPER_ISOLATE_PORT.then((port) { | |
| 937 __SEND_PORT = port; | |
| 938 __SEND_PORT.send([msg, replyTo]); | |
| 939 }); | |
| 940 } | |
| 941 } | |
| 942 | |
| 943 final _TIMER_REGISTRY = new Map<SendPort, Timer>(); | |
| 944 | |
| 945 const _NEW_TIMER = 'NEW_TIMER'; | |
| 946 const _CANCEL_TIMER = 'CANCEL_TIMER'; | |
| 947 const _TIMER_PING = 'TIMER_PING'; | |
| 948 const _PRINT = 'PRINT'; | |
| 949 | |
| 950 _helperIsolateMain(originalSendPort) { | |
| 951 var port = new ReceivePort(); | |
| 952 originalSendPort.send(port.sendPort); | |
| 953 port.listen((args) { | |
| 954 var msg = args.first; | |
| 955 var replyTo = args.last; | |
| 956 final cmd = msg[0]; | |
| 957 if (cmd == _NEW_TIMER) { | |
| 958 final duration = new Duration(milliseconds: msg[1]); | |
| 959 bool periodic = msg[2]; | |
| 960 ping() { replyTo.send(_TIMER_PING); }; | |
| 961 _TIMER_REGISTRY[replyTo] = periodic ? | |
| 962 new Timer.periodic(duration, (_) { ping(); }) : | |
| 963 new Timer(duration, ping); | |
| 964 } else if (cmd == _CANCEL_TIMER) { | |
| 965 _TIMER_REGISTRY.remove(replyTo).cancel(); | |
| 966 } else if (cmd == _PRINT) { | |
| 967 final message = msg[1]; | |
| 968 // TODO(antonm): we need somehow identify those isolates. | |
| 969 print('[From isolate] $message'); | |
| 970 } | |
| 971 }); | |
| 972 } | |
| 973 | |
| 897 final _printClosure = (s) => window.console.log(s); | 974 final _printClosure = (s) => window.console.log(s); |
| 898 final _pureIsolatePrintClosure = (s) { | 975 final _pureIsolatePrintClosure = (s) { |
| 899 throw new UnimplementedError("Printing from a background isolate " | 976 _sendToHelperIsolate([_PRINT, s], null); |
| 900 "is not supported in the browser"); | |
| 901 }; | 977 }; |
| 902 | 978 |
| 903 final _forwardingPrintClosure = _Utils.forwardingPrint; | 979 final _forwardingPrintClosure = _Utils.forwardingPrint; |
| 904 | 980 |
| 905 final _uriBaseClosure = () => Uri.parse(window.location.href); | 981 final _uriBaseClosure = () => Uri.parse(window.location.href); |
| 906 | 982 |
| 907 final _pureIsolateUriBaseClosure = () { | 983 final _pureIsolateUriBaseClosure = () { |
| 908 throw new UnimplementedError("Uri.base on a background isolate " | 984 throw new UnimplementedError("Uri.base on a background isolate " |
| 909 "is not supported in the browser"); | 985 "is not supported in the browser"); |
| 910 }; | 986 }; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 939 } | 1015 } |
| 940 | 1016 |
| 941 bool get isActive => _state != null; | 1017 bool get isActive => _state != null; |
| 942 } | 1018 } |
| 943 | 1019 |
| 944 get _timerFactoryClosure => | 1020 get _timerFactoryClosure => |
| 945 (int milliSeconds, void callback(Timer timer), bool repeating) { | 1021 (int milliSeconds, void callback(Timer timer), bool repeating) { |
| 946 return new _Timer(milliSeconds, callback, repeating); | 1022 return new _Timer(milliSeconds, callback, repeating); |
| 947 }; | 1023 }; |
| 948 | 1024 |
| 1025 class _PureIsolateTimer implements Timer { | |
| 1026 bool _isActive = true; | |
| 1027 final ReceivePort _port = new ReceivePort(); | |
| 1028 SendPort _sendPort; // Effectively final. | |
| 1029 | |
| 1030 // static SendPort _SEND_PORT; | |
| 1031 | |
| 1032 _PureIsolateTimer(int milliSeconds, callback, repeating) { | |
| 1033 _sendPort = _port.sendPort; | |
| 1034 _port.listen((msg) { | |
| 1035 assert(msg == _TIMER_PING); | |
| 1036 _isActive = repeating; | |
| 1037 callback(this); | |
| 1038 if (!repeating) _cancel(); | |
| 1039 }); | |
| 1040 | |
| 1041 _send([_NEW_TIMER, milliSeconds, repeating]); | |
| 1042 } | |
| 1043 | |
| 1044 void cancel() { | |
| 1045 _cancel(); | |
| 1046 _send([_CANCEL_TIMER]); | |
| 1047 } | |
| 1048 | |
| 1049 void _cancel() { | |
| 1050 _isActive = false; | |
| 1051 _port.close(); | |
| 1052 } | |
| 1053 | |
| 1054 _send(msg) { | |
| 1055 _sendToHelperIsolate(msg, _sendPort); | |
| 1056 } | |
| 1057 | |
| 1058 bool get isActive => _isActive; | |
| 1059 } | |
| 1060 | |
| 949 get _pureIsolateTimerFactoryClosure => | 1061 get _pureIsolateTimerFactoryClosure => |
| 950 ((int milliSeconds, void callback(Timer time), bool repeating) => | 1062 ((int milliSeconds, void callback(Timer time), bool repeating) => |
| 951 throw new UnimplementedError("Timers on background isolates " | 1063 new _PureIsolateTimer(milliSeconds, callback, repeating)); |
| 952 "are not supported in the browser")); | |
| 953 | 1064 |
| 954 class _ScheduleImmediateHelper { | 1065 class _ScheduleImmediateHelper { |
| 955 MutationObserver _observer; | 1066 MutationObserver _observer; |
| 956 final DivElement _div = new DivElement(); | 1067 final DivElement _div = new DivElement(); |
| 957 Function _callback; | 1068 Function _callback; |
| 958 | 1069 |
| 959 _ScheduleImmediateHelper() { | 1070 _ScheduleImmediateHelper() { |
| 960 // Run in the root-zone as the DOM callback would otherwise execute in the | 1071 // Run in the root-zone as the DOM callback would otherwise execute in the |
| 961 // current zone. | 1072 // current zone. |
| 962 Zone.ROOT.run(() { | 1073 Zone.ROOT.run(() { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 995 throw new UnimplementedError("scheduleMicrotask in background isolates " | 1106 throw new UnimplementedError("scheduleMicrotask in background isolates " |
| 996 "are not supported in the browser")); | 1107 "are not supported in the browser")); |
| 997 | 1108 |
| 998 void _initializeCustomElement(Element e) { | 1109 void _initializeCustomElement(Element e) { |
| 999 _Utils.initializeCustomElement(e); | 1110 _Utils.initializeCustomElement(e); |
| 1000 } | 1111 } |
| 1001 | 1112 |
| 1002 // Class for unsupported native browser 'DOM' objects. | 1113 // Class for unsupported native browser 'DOM' objects. |
| 1003 class _UnsupportedBrowserObject extends NativeFieldWrapperClass2 { | 1114 class _UnsupportedBrowserObject extends NativeFieldWrapperClass2 { |
| 1004 } | 1115 } |
| OLD | NEW |