| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| // Patch file for the dart:async library. |
| |
| import 'dart:_js_helper' show |
| patch, |
| Primitives; |
| import 'dart:_isolate_helper' show |
| IsolateNatives, |
| TimerImpl, |
| global, |
| leaveJsAsync, |
| enterJsAsync, |
| isWorker; |
| |
| import 'dart:_foreign_helper' show JS; |
| |
| typedef void _Callback(); |
| typedef void _TakeCallback(_Callback callback); |
| |
| @patch |
| class _AsyncRun { |
| @patch |
| static void _scheduleImmediate(void callback()) { |
| _scheduleImmediateClosure(callback); |
| } |
| |
| // Lazily initialized. |
| static final _TakeCallback _scheduleImmediateClosure = |
| _initializeScheduleImmediate(); |
| |
| static _TakeCallback _initializeScheduleImmediate() { |
| // TODO(rnystrom): Not needed by dev_compiler. |
| // requiresPreamble(); |
| if (JS('', '#.scheduleImmediate', global) != null) { |
| return _scheduleImmediateJsOverride; |
| } |
| if (JS('', '#.MutationObserver', global) != null && |
| JS('', '#.document', global) != null) { |
| // Use mutationObservers. |
| var div = JS('', '#.document.createElement("div")', global); |
| var span = JS('', '#.document.createElement("span")', global); |
| _Callback storedCallback; |
| |
| internalCallback(_) { |
| leaveJsAsync(); |
| var f = storedCallback; |
| storedCallback = null; |
| f(); |
| }; |
| |
| var observer = JS('', 'new #.MutationObserver(#)', global, internalCallback); |
| JS('', '#.observe(#, { childList: true })', |
| observer, div); |
| |
| return (void callback()) { |
| assert(storedCallback == null); |
| enterJsAsync(); |
| storedCallback = callback; |
| // Because of a broken shadow-dom polyfill we have to change the |
| // children instead a cheap property. |
| // See https://github.com/Polymer/ShadowDOM/issues/468 |
| JS('', '#.firstChild ? #.removeChild(#): #.appendChild(#)', |
| div, div, span, div, span); |
| }; |
| } else if (JS('', '#.setImmediate', global) != null) { |
| return _scheduleImmediateWithSetImmediate; |
| } |
| // TODO(20055): We should use DOM promises when available. |
| return _scheduleImmediateWithTimer; |
| } |
| |
| static void _scheduleImmediateJsOverride(void callback()) { |
| internalCallback() { |
| leaveJsAsync(); |
| callback(); |
| }; |
| enterJsAsync(); |
| JS('void', '#.scheduleImmediate(#)', global, internalCallback); |
| } |
| |
| static void _scheduleImmediateWithSetImmediate(void callback()) { |
| internalCallback() { |
| leaveJsAsync(); |
| callback(); |
| }; |
| enterJsAsync(); |
| JS('void', '#.setImmediate(#)', global, internalCallback); |
| } |
| |
| static void _scheduleImmediateWithTimer(void callback()) { |
| Timer._createTimer(Duration.ZERO, callback); |
| } |
| } |
| |
| @patch |
| class DeferredLibrary { |
| @patch |
| Future<Null> load() { |
| throw 'DeferredLibrary not supported. ' |
| 'please use the `import "lib.dart" deferred as lib` syntax.'; |
| } |
| } |
| |
| @patch |
| class Timer { |
| @patch |
| static Timer _createTimer(Duration duration, void callback()) { |
| int milliseconds = duration.inMilliseconds; |
| if (milliseconds < 0) milliseconds = 0; |
| return new TimerImpl(milliseconds, callback); |
| } |
| |
| @patch |
| static Timer _createPeriodicTimer(Duration duration, |
| void callback(Timer timer)) { |
| int milliseconds = duration.inMilliseconds; |
| if (milliseconds < 0) milliseconds = 0; |
| return new TimerImpl.periodic(milliseconds, callback); |
| } |
| } |
| |
| @patch |
| void _rethrow(Object error, StackTrace stackTrace) { |
| // TODO(rnystrom): Not needed by dev_compiler. |
| // error = wrapException(error); |
| JS("void", "#.stack = #", error, stackTrace.toString()); |
| JS("void", "throw #", error); |
| } |