blob: 9e4670ba6d66488ba4a73511159270531a281462 [file] [log] [blame]
// 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);
}