Version 1.18.0-dev.4.3
Cherry-pick 30b489578d9ee587d2ca622346e2051a869fb994 to dev
Cherry-pick bde8d3efc6f7558edda6a1cad879ff4a264ddabe to dev
Cherry-pick 69a8b11f6717d4cc8e55f9bc0123eac4f90db849 to dev
diff --git a/sdk/lib/async/timer.dart b/sdk/lib/async/timer.dart
index 135c868..1bbb65b 100644
--- a/sdk/lib/async/timer.dart
+++ b/sdk/lib/async/timer.dart
@@ -4,84 +4,6 @@
part of dart.async;
-abstract class _TimerTask implements Timer {
- final Zone _zone;
- final Timer _nativeTimer;
-
- _TimerTask(this._nativeTimer, this._zone);
-
- void cancel() {
- _nativeTimer.cancel();
- }
-
- bool get isActive => _nativeTimer.isActive;
-}
-
-class _SingleShotTimerTask extends _TimerTask {
- // TODO(floitsch): the generic argument should be 'void'.
- final ZoneCallback<dynamic> _callback;
-
- _SingleShotTimerTask(Timer timer, this._callback, Zone zone)
- : super(timer, zone);
-}
-
-class _PeriodicTimerTask extends _TimerTask {
- // TODO(floitsch): the first generic argument should be 'void'.
- final ZoneUnaryCallback<dynamic, Timer> _callback;
-
- _PeriodicTimerTask(Timer timer, this._callback, Zone zone)
- : super(timer, zone);
-}
-
-/**
- * A task specification for a single-shot timer.
- *
- * *Experimental*. Might disappear without notice.
- */
-class SingleShotTimerTaskSpecification implements TaskSpecification {
- static const String specificationName = "dart.async.timer";
-
- /** The duration after which the timer should invoke the [callback]. */
- final Duration duration;
-
- /** The callback that should be run when the timer triggers. */
- // TODO(floitsch): the generic argument should be void.
- final ZoneCallback<dynamic> callback;
-
- SingleShotTimerTaskSpecification(this.duration, void this.callback());
-
- @override
- String get name => specificationName;
-
- @override
- bool get isOneShot => true;
-}
-
-/**
- * A task specification for a periodic timer.
- *
- * *Experimental*. Might disappear without notice.
- */
-class PeriodicTimerTaskSpecification implements TaskSpecification {
- static const String specificationName = "dart.async.periodic-timer";
-
- /** The interval at which the periodic timer should invoke the [callback]. */
- final Duration duration;
-
- /** The callback that should be run when the timer triggers. */
- // TODO(floitsch): the first generic argument should be void.
- final ZoneUnaryCallback<dynamic, Timer> callback;
-
- PeriodicTimerTaskSpecification(
- this.duration, void this.callback(Timer timer));
-
- @override
- String get name => specificationName;
-
- @override
- bool get isOneShot => false;
-}
-
/**
* A count-down timer that can be configured to fire once or repeatedly.
*
@@ -125,15 +47,10 @@
if (Zone.current == Zone.ROOT) {
// No need to bind the callback. We know that the root's timer will
// be invoked in the root zone.
- return Timer._createTimer(duration, callback);
+ return Zone.current.createTimer(duration, callback);
}
- return Zone.current.createTimer(duration, callback);
- }
-
- factory Timer._task(Zone zone, Duration duration, void callback()) {
- SingleShotTimerTaskSpecification specification =
- new SingleShotTimerTaskSpecification(duration, callback);
- return zone.createTask(_createSingleShotTimerTask, specification);
+ return Zone.current.createTimer(
+ duration, Zone.current.bindCallback(callback, runGuarded: true));
}
/**
@@ -153,65 +70,17 @@
* scheduled for - even if the actual callback was delayed.
*/
factory Timer.periodic(Duration duration,
- void callback(Timer timer)) {
+ void callback(Timer timer)) {
if (Zone.current == Zone.ROOT) {
// No need to bind the callback. We know that the root's timer will
// be invoked in the root zone.
- return Timer._createPeriodicTimer(duration, callback);
+ return Zone.current.createPeriodicTimer(duration, callback);
}
- return Zone.current.createPeriodicTimer(duration, callback);
- }
-
- factory Timer._periodicTask(Zone zone, Duration duration,
- void callback(Timer timer)) {
- PeriodicTimerTaskSpecification specification =
- new PeriodicTimerTaskSpecification(duration, callback);
- return zone.createTask(_createPeriodicTimerTask, specification);
- }
-
- static Timer _createSingleShotTimerTask(
- SingleShotTimerTaskSpecification specification, Zone zone) {
- ZoneCallback registeredCallback = identical(_ROOT_ZONE, zone)
- ? specification.callback
- : zone.registerCallback(specification.callback);
-
- _TimerTask timerTask;
-
- Timer nativeTimer = Timer._createTimer(specification.duration, () {
- timerTask._zone.runTask(_runSingleShotCallback, timerTask, null);
- });
-
- timerTask = new _SingleShotTimerTask(nativeTimer, registeredCallback, zone);
- return timerTask;
- }
-
- static void _runSingleShotCallback(_SingleShotTimerTask timerTask, Object _) {
- timerTask._callback();
- }
-
- static Timer _createPeriodicTimerTask(
- PeriodicTimerTaskSpecification specification, Zone zone) {
// TODO(floitsch): the return type should be 'void', and the type
// should be inferred.
- ZoneUnaryCallback<dynamic, Timer> registeredCallback =
- identical(_ROOT_ZONE, zone)
- ? specification.callback
- : zone.registerUnaryCallback/*<dynamic, Timer>*/(
- specification.callback);
-
- _TimerTask timerTask;
-
- Timer nativeTimer =
- Timer._createPeriodicTimer(specification.duration, (Timer _) {
- timerTask._zone.runTask(_runPeriodicCallback, timerTask, null);
- });
-
- timerTask = new _PeriodicTimerTask(nativeTimer, registeredCallback, zone);
- return timerTask;
- }
-
- static void _runPeriodicCallback(_PeriodicTimerTask timerTask, Object _) {
- timerTask._callback(timerTask);
+ var boundCallback = Zone.current.bindUnaryCallback/*<dynamic, Timer>*/(
+ callback, runGuarded: true);
+ return Zone.current.createPeriodicTimer(duration, boundCallback);
}
/**
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index e0c3e4b..24f83f8 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -8,13 +8,6 @@
typedef R ZoneUnaryCallback<R, T>(T arg);
typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2);
-/// *Experimental*. Might disappear without warning.
-typedef T TaskCreate<T, S extends TaskSpecification>(
- S specification, Zone zone);
-/// *Experimental*. Might disappear without warning.
-typedef void TaskRun<T, A>(T task, A arg);
-
-
// TODO(floitsch): we are abusing generic typedefs as typedefs for generic
// functions.
/*ABUSE*/
@@ -40,30 +33,18 @@
Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2));
typedef AsyncError ErrorCallbackHandler(Zone self, ZoneDelegate parent,
Zone zone, Object error, StackTrace stackTrace);
-/// *Experimental*. Might disappear without warning.
-/*ABUSE*/
-typedef T CreateTaskHandler<T, S extends TaskSpecification>(
- Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate<T, S> create, S taskSpecification);
-/// *Experimental*. Might disappear without warning.
-/*ABUSE*/
-typedef void RunTaskHandler<T, A>(Zone self, ZoneDelegate parent, Zone zone,
- TaskRun<T, A> run, T task, A arg);
typedef void ScheduleMicrotaskHandler(
Zone self, ZoneDelegate parent, Zone zone, void f());
-typedef void PrintHandler(
- Zone self, ZoneDelegate parent, Zone zone, String line);
-typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone,
- ZoneSpecification specification,
- Map zoneValues);
-
-// The following typedef declarations are used by functionality which
-// will be removed and replaced by tasksif the task experiment is successful.
typedef Timer CreateTimerHandler(
Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f());
typedef Timer CreatePeriodicTimerHandler(
Zone self, ZoneDelegate parent, Zone zone,
Duration period, void f(Timer timer));
+typedef void PrintHandler(
+ Zone self, ZoneDelegate parent, Zone zone, String line);
+typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone,
+ ZoneSpecification specification,
+ Map zoneValues);
/** Pair of error and stack trace. Returned by [Zone.errorCallback]. */
class AsyncError implements Error {
@@ -75,41 +56,10 @@
String toString() => '$error';
}
-/**
- * A task specification contains the necessary information to create a task.
- *
- * See [Zone.createTask] for how a specification is used to create a task.
- *
- * Task specifications should be public and it should be possible to create
- * new instances as a user. That is, custom zones should be able to replace
- * an existing specification with a modified one.
- *
- * *Experimental*. This class might disappear without warning.
- */
-abstract class TaskSpecification {
- /**
- * Description of the task.
- *
- * This string is unused by the root-zone, but might be used for debugging,
- * and testing. As such, it should be relatively unique in its category.
- *
- * As a general guideline we recommend: "package-name.library.action".
- */
- String get name;
-
- /**
- * Whether the scheduled task triggers at most once.
- *
- * If the task is not a one-shot task, it may need to be canceled to prevent
- * further iterations of the task.
- */
- bool get isOneShot;
-}
class _ZoneFunction<T extends Function> {
final _Zone zone;
final T function;
-
const _ZoneFunction(this.zone, this.function);
}
@@ -135,9 +85,6 @@
abstract class ZoneSpecification {
/**
* Creates a specification with the provided handlers.
- *
- * The task-related parameters ([createTask] and [runTask]) are experimental
- * and might be removed without warning.
*/
const factory ZoneSpecification({
HandleUncaughtErrorHandler handleUncaughtError,
@@ -149,11 +96,7 @@
RegisterBinaryCallbackHandler registerBinaryCallback,
ErrorCallbackHandler errorCallback,
ScheduleMicrotaskHandler scheduleMicrotask,
- CreateTaskHandler createTask,
- RunTaskHandler runTask,
- // TODO(floitsch): mark as deprecated once tasks are non-experimental.
CreateTimerHandler createTimer,
- // TODO(floitsch): mark as deprecated once tasks are non-experimental.
CreatePeriodicTimerHandler createPeriodicTimer,
PrintHandler print,
ForkHandler fork
@@ -162,9 +105,6 @@
/**
* Creates a specification from [other] with the provided handlers overriding
* the ones in [other].
- *
- * The task-related parameters ([createTask] and [runTask]) are experimental
- * and might be removed without warning.
*/
factory ZoneSpecification.from(ZoneSpecification other, {
HandleUncaughtErrorHandler handleUncaughtError: null,
@@ -176,11 +116,7 @@
RegisterBinaryCallbackHandler registerBinaryCallback: null,
ErrorCallbackHandler errorCallback: null,
ScheduleMicrotaskHandler scheduleMicrotask: null,
- CreateTaskHandler createTask: null,
- RunTaskHandler runTask: null,
- // TODO(floitsch): mark as deprecated once tasks are non-experimental.
CreateTimerHandler createTimer: null,
- // TODO(floitsch): mark as deprecated once tasks are non-experimental.
CreatePeriodicTimerHandler createPeriodicTimer: null,
PrintHandler print: null,
ForkHandler fork: null
@@ -196,14 +132,11 @@
registerBinaryCallback: registerBinaryCallback ??
other.registerBinaryCallback,
errorCallback: errorCallback ?? other.errorCallback,
-
- createTask: createTask ?? other.createTask,
- runTask: runTask ?? other.runTask,
- print : print ?? other.print,
- fork: fork ?? other.fork,
scheduleMicrotask: scheduleMicrotask ?? other.scheduleMicrotask,
createTimer : createTimer ?? other.createTimer,
- createPeriodicTimer: createPeriodicTimer ?? other.createPeriodicTimer);
+ createPeriodicTimer: createPeriodicTimer ?? other.createPeriodicTimer,
+ print : print ?? other.print,
+ fork: fork ?? other.fork);
}
HandleUncaughtErrorHandler get handleUncaughtError;
@@ -215,17 +148,10 @@
RegisterBinaryCallbackHandler get registerBinaryCallback;
ErrorCallbackHandler get errorCallback;
ScheduleMicrotaskHandler get scheduleMicrotask;
- /// *Experimental*. Might disappear without warning.
- CreateTaskHandler get createTask;
- /// *Experimental*. Might disappear without warning.
- RunTaskHandler get runTask;
+ CreateTimerHandler get createTimer;
+ CreatePeriodicTimerHandler get createPeriodicTimer;
PrintHandler get print;
ForkHandler get fork;
-
- // TODO(floitsch): deprecate once tasks are non-experimental.
- CreateTimerHandler get createTimer;
- // TODO(floitsch): deprecate once tasks are non-experimental.
- CreatePeriodicTimerHandler get createPeriodicTimer;
}
/**
@@ -246,14 +172,10 @@
this.registerBinaryCallback: null,
this.errorCallback: null,
this.scheduleMicrotask: null,
- this.createTask: null,
- this.runTask: null,
- this.print: null,
- this.fork: null,
- // TODO(floitsch): deprecate once tasks are non-experimental.
this.createTimer: null,
- // TODO(floitsch): deprecate once tasks are non-experimental.
- this.createPeriodicTimer: null
+ this.createPeriodicTimer: null,
+ this.print: null,
+ this.fork: null
});
final HandleUncaughtErrorHandler handleUncaughtError;
@@ -265,15 +187,10 @@
final RegisterBinaryCallbackHandler registerBinaryCallback;
final ErrorCallbackHandler errorCallback;
final ScheduleMicrotaskHandler scheduleMicrotask;
- final CreateTaskHandler createTask;
- final RunTaskHandler runTask;
+ final CreateTimerHandler createTimer;
+ final CreatePeriodicTimerHandler createPeriodicTimer;
final PrintHandler print;
final ForkHandler fork;
-
- // TODO(floitsch): deprecate once tasks are non-experimental.
- final CreateTimerHandler createTimer;
- // TODO(floitsch): deprecate once tasks are non-experimental.
- final CreatePeriodicTimerHandler createPeriodicTimer;
}
/**
@@ -300,23 +217,10 @@
Zone zone, /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2));
AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace);
void scheduleMicrotask(Zone zone, void f());
-
- /// *Experimental*. Might disappear without notice.
- Object/*=T*/ createTask/*<T, S extends TaskSpecification>*/(
- Zone zone, TaskCreate/*<T, S>*/ create,
- TaskSpecification/*=S*/ specification);
- /// *Experimental*. Might disappear without notice.
- void runTask/*<T, A>*/(
- Zone zone, TaskRun/*<T, A>*/ run, Object/*=T*/ task,
- Object/*=A*/ argument);
-
+ Timer createTimer(Zone zone, Duration duration, void f());
+ Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer));
void print(Zone zone, String line);
Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues);
-
- // TODO(floitsch): deprecate once tasks are non-experimental.
- Timer createTimer(Zone zone, Duration duration, void f());
- // TODO(floitsch): deprecate once tasks are non-experimental.
- Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer));
}
/**
@@ -507,102 +411,13 @@
void scheduleMicrotask(void f());
/**
- * Creates a task in the current zone.
- *
- * A task represents an asynchronous operation or process that reports back
- * through the event loop.
- *
- * This function allows the zone to intercept the initialization of the
- * task while the [runTask] function is invoked when the task reports back.
- *
- * By default, in the root zone, the [create] function is invoked with the
- * [specification] as argument. It returns a task object which is used for all
- * future interactions between the zone and the task. The object is
- * a unique instance representing the task. It is generally returned to
- * whoever initiated the task.
- * For example, the HTML library uses the returned [StreamSubscription] as
- * task object when users register an event listener.
- *
- * Tasks are created when the program starts an operation that reports back
- * through the event loop. For example, a timer or an HTTP request both
- * return through the event loop and are therefore tasks.
- *
- * If the [create] function is not invoked (because a custom zone has
- * replaced or intercepted it), then the operation is *not* started. This
- * means that a custom zone can intercept tasks, like HTTP requests.
- *
- * A task goes through the following steps:
- * - a user invokes a library function that should eventually return through
- * the event loop.
- * - the library function creates a [TaskSpecification] that contains the
- * necessary information to start the operation, and invokes
- * `Zone.current.createTask` with the specification and a [create] closure.
- * The closure, when invoked, uses the specification to start the operation
- * (usually by interacting with the underlying system, or as a native
- * extension), and returns a task object that identifies the running task.
- * - custom zones handle the request and (unless completely intercepted and
- * aborted), end up calling the root zone's [createTask] which runs the
- * provided `create` closure, which may have been replaced at this point.
- * - later, the asynchronous operation returns through the event loop.
- * It invokes [Zone.runTask] on the zone in which the task should run
- * (and which was originally passed to the `create` function by
- * `createTask`). The [runTask] function receives the
- * task object, a `run` function and an argument. As before, custom zones
- * may intercept this call. Eventually (unless aborted), the `run` function
- * is invoked. This last step may happen multiple times for tasks that are
- * not oneshot tasks (see [ZoneSpecification.isOneShot]).
- *
- * Custom zones may replace the [specification] with a different one, thus
- * modifying the task parameters. An operation that wishes to be an
- * interceptable task must publicly specify the types that intercepting code
- * sees:
- * - The specification type (extending [TaskSpecification]) which holds the
- * information available when intercepting the `createTask` call.
- * - The task object type, returned by `createTask` and [create]. This object
- * may simply be typed as [Object].
- * - The argument type, if [runTask] takes a meaningful argument.
- *
- * *Experimental*. Might disappear without notice.
- */
- Object/*=T*/ createTask/*<T, S extends TaskSpecification>*/(
- /*=T*/ create(TaskSpecification/*=S*/ specification, Zone zone),
- TaskSpecification/*=S*/ specification);
-
- /**
- * Runs a task callback.
- *
- * This function is invoked when an operation, started through [createTask],
- * generates an event.
- *
- * Generally, tasks schedule Dart code in the global event loop when the
- * [createTask] function is invoked. Since the
- * event loop does not expect any return value from the code it runs, the
- * [runTask] function is a void function.
- *
- * The [task] object must be the same as the one created with [createTask].
- *
- * It is good practice that task operations provide a meaningful [argument],
- * so that custom zones can interact with it. They might want to log or
- * replace the argument before calling the [run] function.
- *
- * See [createTask].
- *
- * *Experimental*. Might disappear without notice.
- */
- void runTask/*<T, A>*/(
- /*=T*/ run(/*=T*/ task, /*=A*/ argument), Object/*=T*/ task,
- Object/*=A*/ argument);
-
- /**
* Creates a Timer where the callback is executed in this zone.
*/
- // TODO(floitsch): deprecate once tasks are non-experimental.
Timer createTimer(Duration duration, void callback());
/**
* Creates a periodic Timer where the callback is executed in this zone.
*/
- // TODO(floitsch): deprecate once tasks are non-experimental.
Timer createPeriodicTimer(Duration period, void callback(Timer timer));
/**
@@ -708,7 +523,7 @@
// TODO(floitsch): make this a generic method call on '<R>' once it's
// supported. Remove the unnecessary cast.
return handler(implZone, _parentDelegate(implZone), zone, f)
- as dynamic/*=ZoneCallback<R>*/;
+ as Object/*=ZoneCallback<R>*/;
}
ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
@@ -719,7 +534,7 @@
// TODO(floitsch): make this a generic method call on '<R, T>' once it's
// supported. Remove the unnecessary cast.
return handler(implZone, _parentDelegate(implZone), zone, f)
- as dynamic/*=ZoneUnaryCallback<R, T>*/;
+ as Object/*=ZoneUnaryCallback<R, T>*/;
}
ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
@@ -730,7 +545,7 @@
// TODO(floitsch): make this a generic method call on '<R, T1, T2>' once
// it's supported. Remove the unnecessary cast.
return handler(implZone, _parentDelegate(implZone), zone, f)
- as dynamic/*=ZoneBinaryCallback<R, T1, T2>*/;
+ as Object/*=ZoneBinaryCallback<R, T1, T2>*/;
}
AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) {
@@ -749,25 +564,18 @@
handler(implZone, _parentDelegate(implZone), zone, f);
}
- Object/*=T*/ createTask/*<T, S extends TaskSpecification>*/(
- Zone zone, TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ specification) {
- var implementation = _delegationTarget._createTask;
+ Timer createTimer(Zone zone, Duration duration, void f()) {
+ var implementation = _delegationTarget._createTimer;
_Zone implZone = implementation.zone;
- // TODO(floitsch): make the handler call a generic method call on '<T, S>'
- // once it's supported. Remove the unnecessary cast.
- var handler =
- implementation.function as CreateTaskHandler/*<T, S>*/;
- return handler(
- implZone, _parentDelegate(implZone), zone, create, specification);
+ CreateTimerHandler handler = implementation.function;
+ return handler(implZone, _parentDelegate(implZone), zone, duration, f);
}
- void runTask/*<T, A>*/(Zone zone, TaskRun run, Object /*=T*/ task,
- Object /*=A*/ argument) {
- var implementation = _delegationTarget._runTask;
+ Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) {
+ var implementation = _delegationTarget._createPeriodicTimer;
_Zone implZone = implementation.zone;
- RunTaskHandler handler = implementation.function;
- // TODO(floitsch): make this a generic call on '<T, A>'.
- handler(implZone, _parentDelegate(implZone), zone, run, task, argument);
+ CreatePeriodicTimerHandler handler = implementation.function;
+ return handler(implZone, _parentDelegate(implZone), zone, period, f);
}
void print(Zone zone, String line) {
@@ -785,22 +593,6 @@
return handler(
implZone, _parentDelegate(implZone), zone, specification, zoneValues);
}
-
- // TODO(floitsch): deprecate once tasks are non-experimental.
- Timer createTimer(Zone zone, Duration duration, void f()) {
- var implementation = _delegationTarget._createTimer;
- _Zone implZone = implementation.zone;
- CreateTimerHandler handler = implementation.function;
- return handler(implZone, _parentDelegate(implZone), zone, duration, f);
- }
-
- // TODO(floitsch): deprecate once tasks are non-experimental.
- Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) {
- var implementation = _delegationTarget._createPeriodicTimer;
- _Zone implZone = implementation.zone;
- CreatePeriodicTimerHandler handler = implementation.function;
- return handler(implZone, _parentDelegate(implZone), zone, period, f);
- }
}
@@ -818,17 +610,11 @@
_ZoneFunction<RegisterBinaryCallbackHandler> get _registerBinaryCallback;
_ZoneFunction<ErrorCallbackHandler> get _errorCallback;
_ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask;
- _ZoneFunction<CreateTaskHandler> get _createTask;
- _ZoneFunction<RunTaskHandler> get _runTask;
+ _ZoneFunction<CreateTimerHandler> get _createTimer;
+ _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer;
_ZoneFunction<PrintHandler> get _print;
_ZoneFunction<ForkHandler> get _fork;
_ZoneFunction<HandleUncaughtErrorHandler> get _handleUncaughtError;
-
- // TODO(floitsch): deprecate once tasks are non-experimental.
- _ZoneFunction<CreateTimerHandler> get _createTimer;
- // TODO(floitsch): deprecate once tasks are non-experimental.
- _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer;
-
_Zone get parent;
ZoneDelegate get _delegate;
Map get _map;
@@ -850,17 +636,12 @@
_ZoneFunction<RegisterBinaryCallbackHandler> _registerBinaryCallback;
_ZoneFunction<ErrorCallbackHandler> _errorCallback;
_ZoneFunction<ScheduleMicrotaskHandler> _scheduleMicrotask;
- _ZoneFunction<CreateTaskHandler> _createTask;
- _ZoneFunction<RunTaskHandler> _runTask;
+ _ZoneFunction<CreateTimerHandler> _createTimer;
+ _ZoneFunction<CreatePeriodicTimerHandler> _createPeriodicTimer;
_ZoneFunction<PrintHandler> _print;
_ZoneFunction<ForkHandler> _fork;
_ZoneFunction<HandleUncaughtErrorHandler> _handleUncaughtError;
- // TODO(floitsch): deprecate once tasks are non-experimental.
- _ZoneFunction<CreateTimerHandler> _createTimer;
- // TODO(floitsch): deprecate once tasks are non-experimental.
- _ZoneFunction<CreatePeriodicTimerHandler> _createPeriodicTimer;
-
// A cached delegate to this zone.
ZoneDelegate _delegateCache;
@@ -911,14 +692,13 @@
? new _ZoneFunction<ScheduleMicrotaskHandler>(
this, specification.scheduleMicrotask)
: parent._scheduleMicrotask;
- _createTask = (specification.createTask != null)
- ? new _ZoneFunction<CreateTaskHandler>(
- this, specification.createTask)
- : parent._createTask;
- _runTask = (specification.runTask != null)
- ? new _ZoneFunction<RunTaskHandler>(
- this, specification.runTask)
- : parent._runTask;
+ _createTimer = (specification.createTimer != null)
+ ? new _ZoneFunction<CreateTimerHandler>(this, specification.createTimer)
+ : parent._createTimer;
+ _createPeriodicTimer = (specification.createPeriodicTimer != null)
+ ? new _ZoneFunction<CreatePeriodicTimerHandler>(
+ this, specification.createPeriodicTimer)
+ : parent._createPeriodicTimer;
_print = (specification.print != null)
? new _ZoneFunction<PrintHandler>(this, specification.print)
: parent._print;
@@ -929,16 +709,6 @@
? new _ZoneFunction<HandleUncaughtErrorHandler>(
this, specification.handleUncaughtError)
: parent._handleUncaughtError;
-
- // Deprecated fields, once tasks are non-experimental.
- _createTimer = (specification.createTimer != null)
- ? new _ZoneFunction<CreateTimerHandler>(
- this, specification.createTimer)
- : parent._createTimer;
- _createPeriodicTimer = (specification.createPeriodicTimer != null)
- ? new _ZoneFunction<CreatePeriodicTimerHandler>(
- this, specification.createPeriodicTimer)
- : parent._createPeriodicTimer;
}
/**
@@ -1089,7 +859,7 @@
// TODO(floitsch): make this a generic method call on '<R>' once it's
// supported. Remove the unnecessary cast.
return handler(implementation.zone, parentDelegate, this, callback)
- as dynamic/*=ZoneCallback<R>*/;
+ as Object/*=ZoneCallback<R>*/;
}
ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
@@ -1101,7 +871,7 @@
// TODO(floitsch): make this a generic method call on '<R, T>' once it's
// supported. Remove the unnecessary cast.
return handler(implementation.zone, parentDelegate, this, callback)
- as dynamic/*=ZoneUnaryCallback<R, T>*/;
+ as Object/*=ZoneUnaryCallback<R, T>*/;
}
ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
@@ -1113,7 +883,7 @@
// TODO(floitsch): make this a generic method call on '<R, T1, T2>' once
// it's supported. Remove the unnecessary cast.
return handler(implementation.zone, parentDelegate, this, callback)
- as dynamic/*=ZoneBinaryCallback<R, T1, T2>*/;
+ as Object/*=ZoneBinaryCallback<R, T1, T2>*/;
}
AsyncError errorCallback(Object error, StackTrace stackTrace) {
@@ -1132,40 +902,9 @@
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
ScheduleMicrotaskHandler handler = implementation.function;
- handler(implementation.zone, parentDelegate, this, f);
+ return handler(implementation.zone, parentDelegate, this, f);
}
- Object/*=T*/ createTask/*<T, S extends TaskSpecification>*/(
- TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ specification) {
- var implementation = this._createTask;
- ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
- // TODO(floitsch): make the handler call a generic method call on '<T, S>'
- // once it's supported. Remove the unnecessary cast.
- var handler =
- implementation.function as CreateTaskHandler/*<T, S>*/;
- return handler(
- implementation.zone, parentDelegate, this, create, specification);
- }
-
- void runTask/*<T, A>*/(
- TaskRun/*<T, A>*/ run, Object/*=T*/ task, Object/*=A*/ arg1) {
- var implementation = this._runTask;
- ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
- RunTaskHandler handler = implementation.function;
- // TODO(floitsch): make this a generic method call on '<T, A>' once it's
- // supported.
- handler(implementation.zone, parentDelegate, this, run, task, arg1);
- }
-
- void print(String line) {
- var implementation = this._print;
- assert(implementation != null);
- ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
- PrintHandler handler = implementation.function;
- return handler(implementation.zone, parentDelegate, this, line);
- }
-
- // TODO(floitsch): deprecate once tasks are non-experimental.
Timer createTimer(Duration duration, void f()) {
var implementation = this._createTimer;
assert(implementation != null);
@@ -1174,7 +913,6 @@
return handler(implementation.zone, parentDelegate, this, duration, f);
}
- // TODO(floitsch): deprecate once tasks are non-experimental.
Timer createPeriodicTimer(Duration duration, void f(Timer timer)) {
var implementation = this._createPeriodicTimer;
assert(implementation != null);
@@ -1183,6 +921,14 @@
return handler(
implementation.zone, parentDelegate, this, duration, f);
}
+
+ void print(String line) {
+ var implementation = this._print;
+ assert(implementation != null);
+ ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
+ PrintHandler handler = implementation.function;
+ return handler(implementation.zone, parentDelegate, this, line);
+ }
}
/*=R*/ _rootHandleUncaughtError/*<R>*/(
@@ -1260,39 +1006,22 @@
_scheduleAsyncCallback(f);
}
-Object/*=T*/ _rootCreateTask/*<T, S extends TaskSpecification>*/(
- Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ specification) {
- return create(specification, zone);
-}
-
-void _rootRunTask/*<T, A>*/(
- Zone self, ZoneDelegate parent, Zone zone, TaskRun run/*<T, A>*/,
- Object/*=T*/ task, Object/*=A*/ arg) {
- if (Zone._current == zone) {
- run(task, arg);
- return;
- }
-
- Zone old = Zone._enter(zone);
- try {
- run(task, arg);
- } catch (e, s) {
- zone.handleUncaughtError/*<dynamic>*/(e, s);
- } finally {
- Zone._leave(old);
- }
-}
-
Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone,
Duration duration, void callback()) {
- return new Timer._task(zone, duration, callback);
+ if (!identical(_ROOT_ZONE, zone)) {
+ callback = zone.bindCallback(callback);
+ }
+ return Timer._createTimer(duration, callback);
}
Timer _rootCreatePeriodicTimer(
Zone self, ZoneDelegate parent, Zone zone,
Duration duration, void callback(Timer timer)) {
- return new Timer._periodicTask(zone, duration, callback);
+ if (!identical(_ROOT_ZONE, zone)) {
+ // TODO(floitsch): the return type should be 'void'.
+ callback = zone.bindUnaryCallback/*<dynamic, Timer>*/(callback);
+ }
+ return Timer._createPeriodicTimer(duration, callback);
}
void _rootPrint(Zone self, ZoneDelegate parent, Zone zone, String line) {
@@ -1353,10 +1082,10 @@
_ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask =>
const _ZoneFunction<ScheduleMicrotaskHandler>(
_ROOT_ZONE, _rootScheduleMicrotask);
- _ZoneFunction<CreateTaskHandler> get _createTask =>
- const _ZoneFunction<CreateTaskHandler>(_ROOT_ZONE, _rootCreateTask);
- _ZoneFunction<RunTaskHandler> get _runTask =>
- const _ZoneFunction<RunTaskHandler>(_ROOT_ZONE, _rootRunTask);
+ _ZoneFunction<CreateTimerHandler> get _createTimer =>
+ const _ZoneFunction<CreateTimerHandler>(_ROOT_ZONE, _rootCreateTimer);
+ _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer =>
+ const _ZoneFunction<CreatePeriodicTimerHandler>(_ROOT_ZONE, _rootCreatePeriodicTimer);
_ZoneFunction<PrintHandler> get _print =>
const _ZoneFunction<PrintHandler>(_ROOT_ZONE, _rootPrint);
_ZoneFunction<ForkHandler> get _fork =>
@@ -1365,14 +1094,6 @@
const _ZoneFunction<HandleUncaughtErrorHandler>(
_ROOT_ZONE, _rootHandleUncaughtError);
- // TODO(floitsch): deprecate once tasks are non-experimental.
- _ZoneFunction<CreateTimerHandler> get _createTimer =>
- const _ZoneFunction<CreateTimerHandler>(_ROOT_ZONE, _rootCreateTimer);
- // TODO(floitsch): deprecate once tasks are non-experimental.
- _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer =>
- const _ZoneFunction<CreatePeriodicTimerHandler>(
- _ROOT_ZONE, _rootCreatePeriodicTimer);
-
// The parent zone.
_Zone get parent => null;
@@ -1504,16 +1225,6 @@
_rootScheduleMicrotask(null, null, this, f);
}
- Object/*=T*/ createTask/*<T, S extends TaskSpecification>*/(
- TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ specification) {
- return _rootCreateTask/*<T, S>*/(null, null, this, create, specification);
- }
-
- void runTask/*<T, A>*/(
- TaskRun/*<T, A>*/ run, Object/*=T*/ task, Object/*=A*/ arg) {
- _rootRunTask/*<T, A>*/(null, null, this, run, task, arg);
- }
-
Timer createTimer(Duration duration, void f()) {
return Timer._createTimer(duration, f);
}
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 17f290d..b43b3ad 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -4207,7 +4207,7 @@
if (fragment != null) {
fragment = _Uri._makeFragment(fragment, 0, fragment.length);
} else if (_fragmentStart < _uri.length) {
- fragment = _uri.substring(_fragmentStart);
+ fragment = _uri.substring(_fragmentStart + 1);
}
return new _Uri._internal(
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index c9cd5cb..0bc3749 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -19240,109 +19240,6 @@
// BSD-style license that can be found in the LICENSE file.
-/**
- * A task specification for HTTP requests.
- *
- * This specification is not available when an HTTP request is sent through
- * direct use of [HttpRequest.send]. See [HttpRequestSendTaskSpecification].
- *
- * A task created from this specification is a `Future<HttpRequest>`.
- *
- * *Experimental*. This class may disappear without notice.
- */
-class HttpRequestTaskSpecification extends TaskSpecification {
- /// The URL of the request.
- final String url;
-
- /// The HTTP request method.
- ///
- /// By default (when `null`) this is a `"GET"` request. Alternatively, the
- /// method can be `"POST"`, `"PUT"`, `"DELETE"`, etc.
- final String method;
-
- /// Whether the request should send credentials. Credentials are only useful
- /// for cross-origin requests.
- ///
- /// See [HttpRequest.request] for more information.
- final bool withCredentials;
-
- /// The desired response format.
- ///
- /// Supported types are:
- /// - `""`: (same as `"text"`),
- /// - `"arraybuffer"`,
- /// - `"blob"`,
- /// - `"document"`,
- /// - `"json"`,
- /// - `"text"`
- ///
- /// When no value is provided (when equal to `null`) defaults to `""`.
- final String responseType;
-
- /// The desired MIME type.
- ///
- /// This overrides the default MIME type which is set up to transfer textual
- /// data.
- final String mimeType;
-
- /// The request headers that should be sent with the request.
- final Map<String, String> requestHeaders;
-
- /// The data that is sent with the request.
- ///
- /// When data is provided (the value is not `null`), it must be a
- /// [ByteBuffer], [Blob], [Document], [String], or [FormData].
- final dynamic sendData;
-
- /// The function that is invoked on progress updates. This function is
- /// registered as an event listener on the created [HttpRequest] object, and
- /// thus has its own task. Further invocations of the progress function do
- /// *not* use the HTTP request task as task object.
- ///
- /// Creating an HTTP request automatically registers the on-progress listener.
- final ZoneUnaryCallback<dynamic, ProgressEvent> onProgress;
-
- HttpRequestTaskSpecification(this.url,
- {String this.method, bool this.withCredentials, String this.responseType,
- String this.mimeType, Map<String, String> this.requestHeaders,
- this.sendData,
- void this.onProgress(ProgressEvent e)});
-
- String get name => "dart.html.http-request";
- bool get isOneShot => true;
-}
-
-/**
- * A task specification for HTTP requests that are initiated through a direct
- * invocation of [HttpRequest.send].
- *
- * This specification serves as signal to zones that an HTTP request has been
- * initiated. The created task is the [request] object itself, and
- * no callback is ever executed in this task.
- *
- * Note that event listeners on the HTTP request are also registered in the
- * zone (although with their own task creations), and that a zone can thus
- * detect when the HTTP request returns.
- *
- * HTTP requests that are initiated through `request` methods don't use
- * this class but use [HttpRequestTaskSpecification].
- *
- * *Experimental*. This class may disappear without notice.
- */
-class HttpRequestSendTaskSpecification extends TaskSpecification {
- final HttpRequest request;
- final dynamic sendData;
-
- HttpRequestSendTaskSpecification(this.request, this.sendData);
-
- String get name => "dart.html.http-request-send";
-
- /**
- * No callback is ever executed in an HTTP request send task.
- */
- bool get isOneShot => false;
-}
-
/**
* A client-side XHR request for getting data from a URL,
* formally known as XMLHttpRequest.
@@ -19531,34 +19428,7 @@
{String method, bool withCredentials, String responseType,
String mimeType, Map<String, String> requestHeaders, sendData,
void onProgress(ProgressEvent e)}) {
- var spec = new HttpRequestTaskSpecification(
- url, method: method,
- withCredentials: withCredentials,
- responseType: responseType,
- mimeType: mimeType,
- requestHeaders: requestHeaders,
- sendData: sendData,
- onProgress: onProgress);
-
- if (identical(Zone.current, Zone.ROOT)) {
- return _createHttpRequestTask(spec, null);
- }
- return Zone.current.createTask(_createHttpRequestTask, spec);
- }
-
- static Future<HttpRequest> _createHttpRequestTask(
- HttpRequestTaskSpecification spec, Zone zone) {
- String url = spec.url;
- String method = spec.method;
- bool withCredentials = spec.withCredentials;
- String responseType = spec.responseType;
- String mimeType = spec.mimeType;
- Map<String, String> requestHeaders = spec.requestHeaders;
- var sendData = spec.sendData;
- var onProgress = spec.onProgress;
-
var completer = new Completer<HttpRequest>();
- var task = completer.future;
var xhr = new HttpRequest();
if (method == null) {
@@ -19598,42 +19468,23 @@
// redirect case will be handled by the browser before it gets to us,
// so if we see it we should pass it through to the user.
var unknownRedirect = xhr.status > 307 && xhr.status < 400;
-
- var isSuccessful = accepted || fileUri || notModified || unknownRedirect;
-
- if (zone == null && isSuccessful) {
+
+ if (accepted || fileUri || notModified || unknownRedirect) {
completer.complete(xhr);
- } else if (zone == null) {
- completer.completeError(e);
- } else if (isSuccessful) {
- zone.runTask((task, value) {
- completer.complete(value);
- }, task, xhr);
} else {
- zone.runTask((task, error) {
- completer.completeError(error);
- }, task, e);
+ completer.completeError(e);
}
});
- if (zone == null) {
- xhr.onError.listen(completer.completeError);
- } else {
- xhr.onError.listen((error) {
- zone.runTask((task, error) {
- completer.completeError(error);
- }, task, error);
- });
- }
+ xhr.onError.listen(completer.completeError);
if (sendData != null) {
- // TODO(floitsch): should we go through 'send()' and have nested tasks?
- xhr._send(sendData);
+ xhr.send(sendData);
} else {
- xhr._send();
+ xhr.send();
}
- return task;
+ return completer.future;
}
/**
@@ -19687,9 +19538,6 @@
return xhr.responseText;
});
}
- // TODO(floitsch): the following code doesn't go through task zones.
- // Since 'XDomainRequest' is an IE9 feature we should probably just remove
- // it.
var completer = new Completer<String>();
if (method == null) {
method = 'GET';
@@ -19768,43 +19616,13 @@
*
* Note: Most simple HTTP requests can be accomplished using the [getString],
* [request], [requestCrossOrigin], or [postFormData] methods. Use of this
- * `open` method is intended only for more complex HTTP requests where
+ * `open` method is intended only for more complext HTTP requests where
* finer-grained control is needed.
*/
@DomName('XMLHttpRequest.open')
@DocsEditable()
void open(String method, String url, {bool async, String user, String password}) native;
- /**
- * Sends the request with any given `data`.
- *
- * Note: Most simple HTTP requests can be accomplished using the [getString],
- * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
- * `send` method is intended only for more complex HTTP requests where
- * finer-grained control is needed.
- *
- * ## Other resources
- *
- * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
- * from MDN.
- */
- @DomName('XMLHttpRequest.send')
- @DocsEditable()
- void send([body_OR_data]) {
- if (identical(Zone.current, Zone.ROOT)) {
- _send(body_OR_data);
- } else {
- Zone.current.createTask(_createHttpRequestSendTask,
- new HttpRequestSendTaskSpecification(this, body_OR_data));
- }
- }
-
- static HttpRequest _createHttpRequestSendTask(
- HttpRequestSendTaskSpecification spec, Zone zone) {
- spec.request._send(spec.sendData);
- return spec.request;
- }
-
// To suppress missing implicit constructor warnings.
factory HttpRequest._() { throw new UnsupportedError("Not supported"); }
@@ -20075,13 +19893,12 @@
@SupportedBrowser(SupportedBrowser.SAFARI)
void overrideMimeType(String mime) native;
- @JSName('send')
/**
* Send the request with any given `data`.
*
* Note: Most simple HTTP requests can be accomplished using the [getString],
* [request], [requestCrossOrigin], or [postFormData] methods. Use of this
- * `send` method is intended only for more complex HTTP requests where
+ * `send` method is intended only for more complext HTTP requests where
* finer-grained control is needed.
*
* ## Other resources
@@ -20091,7 +19908,7 @@
*/
@DomName('XMLHttpRequest.send')
@DocsEditable()
- void _send([body_OR_data]) native;
+ void send([body_OR_data]) native;
/**
* Sets the value of an HTTP requst header.
@@ -34668,99 +34485,6 @@
// BSD-style license that can be found in the LICENSE file.
-typedef void RemoveFrameRequestMapping(int id);
-
-/**
- * The task object representing animation-frame requests.
- *
- * For historical reasons, [Window.requestAnimationFrame] returns an integer
- * to users. However, zone tasks must be unique objects, and an integer can
- * therefore not be used as task object. The [Window] class thus keeps a mapping
- * from the integer ID to the corresponding task object. All zone related
- * operations work on this task object, whereas users of
- * [Window.requestAnimationFrame] only see the integer ID.
- *
- * Since this mapping takes up space, it must be removed when the
- * animation-frame task has triggered. The default implementation does this
- * automatically, but intercepting implementations of `requestAnimationFrame`
- * must make sure to call the [AnimationFrameTask.removeMapping]
- * function that is provided in the task specification.
- *
- * *Experimental*. This class may disappear without notice.
- */
-abstract class AnimationFrameTask {
- /** The ID that is returned to users. */
- int get id;
-
- /** The zone in which the task will run. */
- Zone get zone;
-
- /**
- * Cancels the animation-frame request.
- *
- * A call to [Window.cancelAnimationFrame] with an `id` argument equal to [id]
- * forwards the request to this function.
- *
- * Zones that intercept animation-frame requests implement this method so
- * that they can react to cancelation requests.
- */
- void cancel(Window window);
-
- /**
- * Maps animation-frame request IDs to their task objects.
- */
- static final Map<int, _AnimationFrameTask> _tasks = {};
-
- /**
- * Removes the mapping from [id] to [AnimationFrameTask].
- *
- * This function must be invoked by user-implemented animation-frame
- * tasks, before running [callback].
- *
- * See [AnimationFrameTask].
- */
- static void removeMapping(int id) {
- _tasks.remove(id);
- }
-}
-
-class _AnimationFrameTask implements AnimationFrameTask {
- final int id;
- final Zone zone;
- final FrameRequestCallback _callback;
-
- _AnimationFrameTask(this.id, this.zone, this._callback);
-
- void cancel(Window window) {
- window._cancelAnimationFrame(this.id);
- }
-}
-
-/**
- * The task specification for an animation-frame request.
- *
- * *Experimental*. This class may disappear without notice.
- */
-class AnimationFrameRequestSpecification implements TaskSpecification {
- /**
- * The window on which [Window.requestAnimationFrame] was invoked.
- */
- final Window window;
-
- /**
- * The callback that is executed when the animation-frame is ready.
- *
- * Note that the callback hasn't been registered in any zone when the `create`
- * function (passed to [Zone.createTask]) is invoked.
- */
- final FrameRequestCallback callback;
-
- AnimationFrameRequestSpecification(this.window, this.callback);
-
- String get name => "dart.html.request-animation-frame";
- bool get isOneShot => true;
-}
-
@DocsEditable()
/**
* Top-level container for the current browser tab or window.
@@ -34816,7 +34540,9 @@
*/
Future<num> get animationFrame {
var completer = new Completer<num>.sync();
- requestAnimationFrame(completer.complete);
+ requestAnimationFrame((time) {
+ completer.complete(time);
+ });
return completer.future;
}
@@ -34880,7 +34606,6 @@
JS('void', '#.location = #', this, value);
}
-
/**
* Called to draw an animation frame and then request the window to repaint
* after [callback] has finished (creating the animation).
@@ -34900,30 +34625,7 @@
@DomName('Window.requestAnimationFrame')
int requestAnimationFrame(FrameRequestCallback callback) {
_ensureRequestAnimationFrame();
- if (identical(Zone.current, Zone.ROOT)) {
- return _requestAnimationFrame(callback);
- }
- var spec = new AnimationFrameRequestSpecification(this, callback);
- var task = Zone.current.createTask/*<AnimationFrameTask>*/(
- _createAnimationFrameTask, spec);
- AnimationFrameTask._tasks[task.id] = task;
- return task.id;
- }
-
- static _AnimationFrameTask _createAnimationFrameTask(
- AnimationFrameRequestSpecification spec, Zone zone) {
- var task;
- var id = spec.window._requestAnimationFrame((num time) {
- AnimationFrameTask.removeMapping(task.id);
- zone.runTask(_runAnimationFrame, task, time);
- });
- var callback = zone.registerUnaryCallback(spec.callback);
- task = new _AnimationFrameTask(id, zone, callback);
- return task;
- }
-
- static void _runAnimationFrame(_AnimationFrameTask task, num time) {
- task._callback(time);
+ return _requestAnimationFrame(_wrapZone/*<num, dynamic>*/(callback));
}
/**
@@ -34934,16 +34636,9 @@
* * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame)
* from MDN.
*/
- @DomName('Window.cancelAnimationFrame')
void cancelAnimationFrame(int id) {
_ensureRequestAnimationFrame();
- var task = AnimationFrameTask._tasks.remove(id);
- if (task == null) {
- // Assume that the animation frame request wasn't intercepted by a zone.
- _cancelAnimationFrame(id);
- return;
- }
- task.cancel(this);
+ _cancelAnimationFrame(id);
}
@JSName('requestAnimationFrame')
@@ -34997,6 +34692,7 @@
@DomName('Window.console')
Console get console => Console._safeConsole;
+
/**
* Access a sandboxed file system of the specified `size`. If `persistent` is
* true, the application will request permission from the user to create
@@ -40268,41 +39964,6 @@
StreamSubscription<T> capture(void onData(T event));
}
-/// Task specification for DOM Events.
-///
-/// *Experimental*. May disappear without notice.
-class EventSubscriptionSpecification<T extends Event>
- implements TaskSpecification {
- @override
- final String name;
- @override
- final bool isOneShot;
-
- final EventTarget target;
- /// The event-type of the event. For example 'click' for click events.
- final String eventType;
- // TODO(floitsch): the first generic argument should be 'void'.
- final ZoneUnaryCallback<dynamic, T> onData;
- final bool useCapture;
-
- EventSubscriptionSpecification({this.name, this.isOneShot, this.target,
- this.eventType, void this.onData(T event), this.useCapture});
-
- /// Returns a copy of this instance, with every non-null argument replaced
- /// by the given value.
- EventSubscriptionSpecification<T> replace(
- {String name, bool isOneShot, EventTarget target,
- String eventType, void onData(T event), bool useCapture}) {
- return new EventSubscriptionSpecification<T>(
- name: name ?? this.name,
- isOneShot: isOneShot ?? this.isOneShot,
- target: target ?? this.target,
- eventType: eventType ?? this.eventType,
- onData: onData ?? this.onData,
- useCapture: useCapture ?? this.useCapture);
- }
-}
-
/**
* Adapter for exposing DOM events as Dart streams.
*/
@@ -40310,16 +39971,8 @@
final EventTarget _target;
final String _eventType;
final bool _useCapture;
- /// The name that is used in the task specification.
- final String _name;
- /// Whether the stream can trigger multiple times.
- final bool _isOneShot;
- _EventStream(this._target, String eventType, this._useCapture,
- {String name, bool isOneShot: false})
- : _eventType = eventType,
- _isOneShot = isOneShot,
- _name = name ?? "dart.html.event.$eventType";
+ _EventStream(this._target, this._eventType, this._useCapture);
// DOM events are inherently multi-subscribers.
Stream<T> asBroadcastStream({void onListen(StreamSubscription<T> subscription),
@@ -40327,31 +39980,13 @@
=> this;
bool get isBroadcast => true;
- StreamSubscription<T> _listen(
- void onData(T event), {bool useCapture}) {
-
- if (identical(Zone.current, Zone.ROOT)) {
- return new _EventStreamSubscription<T>(
- this._target, this._eventType, onData, this._useCapture,
- Zone.current);
- }
-
- var specification = new EventSubscriptionSpecification<T>(
- name: this._name, isOneShot: this._isOneShot,
- target: this._target, eventType: this._eventType,
- onData: onData, useCapture: useCapture);
- // We need to wrap the _createStreamSubscription call, since a tear-off
- // would not bind the generic type 'T'.
- return Zone.current.createTask((spec, Zone zone) {
- return _createStreamSubscription/*<T>*/(spec, zone);
- }, specification);
- }
-
StreamSubscription<T> listen(void onData(T event),
{ Function onError,
void onDone(),
bool cancelOnError}) {
- return _listen(onData, useCapture: this._useCapture);
+
+ return new _EventStreamSubscription<T>(
+ this._target, this._eventType, onData, this._useCapture);
}
}
@@ -40366,9 +40001,8 @@
*/
class _ElementEventStreamImpl<T extends Event> extends _EventStream<T>
implements ElementStream<T> {
- _ElementEventStreamImpl(target, eventType, useCapture,
- {String name, bool isOneShot: false}) :
- super(target, eventType, useCapture, name: name, isOneShot: isOneShot);
+ _ElementEventStreamImpl(target, eventType, useCapture) :
+ super(target, eventType, useCapture);
Stream<T> matches(String selector) => this.where(
(event) => _matchesWithAncestors(event, selector)).map((e) {
@@ -40376,9 +40010,9 @@
return e;
});
- StreamSubscription<T> capture(void onData(T event)) {
- return _listen(onData, useCapture: true);
- }
+ StreamSubscription<T> capture(void onData(T event)) =>
+ new _EventStreamSubscription<T>(
+ this._target, this._eventType, onData, true);
}
/**
@@ -40427,13 +40061,7 @@
bool get isBroadcast => true;
}
-StreamSubscription/*<T>*/ _createStreamSubscription/*<T>*/(
- EventSubscriptionSpecification/*<T>*/ spec, Zone zone) {
- return new _EventStreamSubscription/*<T>*/(spec.target, spec.eventType,
- spec.onData, spec.useCapture, zone);
-}
-
-// We would like this to just be EventListener<T> but that typedef cannot
+// We would like this to just be EventListener<T> but that typdef cannot
// use generics until dartbug/26276 is fixed.
typedef _EventListener<T extends Event>(T event);
@@ -40442,19 +40070,15 @@
EventTarget _target;
final String _eventType;
EventListener _onData;
- EventListener _domCallback;
final bool _useCapture;
- final Zone _zone;
// TODO(jacobr): for full strong mode correctness we should write
- // _onData = onData == null ? null : _wrapZone/*<dynamic, Event>*/((e) => onData(e as T))
+ // _onData = onData == null ? null : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
// but that breaks 114 co19 tests as well as multiple html tests as it is reasonable
// to pass the wrong type of event object to an event listener as part of a
// test.
_EventStreamSubscription(this._target, this._eventType, void onData(T event),
- this._useCapture, Zone zone)
- : _zone = zone,
- _onData = _registerZone/*<dynamic, Event>*/(zone, onData) {
+ this._useCapture) : _onData = _wrapZone/*<Event, dynamic>*/(onData) {
_tryResume();
}
@@ -40476,7 +40100,7 @@
}
// Remove current event listener.
_unlisten();
- _onData = _registerZone/*<dynamic, Event>*/(_zone, handleData);
+ _onData = _wrapZone/*<Event, dynamic>*/(handleData);
_tryResume();
}
@@ -40505,25 +40129,14 @@
}
void _tryResume() {
- if (_onData == null || isPaused) return;
- if (identical(_zone, Zone.ROOT)) {
- _domCallback = _onData;
- } else {
- _domCallback = (event) {
- _zone.runTask(_runEventNotification, this, event);
- };
+ if (_onData != null && !isPaused) {
+ _target.addEventListener(_eventType, _onData, _useCapture);
}
- _target.addEventListener(_eventType, _domCallback, _useCapture);
- }
-
- static void _runEventNotification/*<T>*/(
- _EventStreamSubscription/*<T>*/ subscription, /*=T*/ event) {
- subscription._onData(event);
}
void _unlisten() {
if (_onData != null) {
- _target.removeEventListener(_eventType, _domCallback, _useCapture);
+ _target.removeEventListener(_eventType, _onData, _useCapture);
}
}
@@ -43757,26 +43370,31 @@
// BSD-style license that can be found in the LICENSE file.
-ZoneUnaryCallback/*<R, T>*/ _registerZone/*<R, T>*/(Zone zone,
- ZoneUnaryCallback/*<R, T>*/ callback) {
- // For performance reasons avoid registering if we are in the root zone.
- if (identical(zone, Zone.ROOT)) return callback;
- if (callback == null) return null;
- return zone.registerUnaryCallback(callback);
-}
+// TODO(jacobr): remove these typedefs when dart:async supports generic types.
+typedef R _wrapZoneCallback<A, R>(A a);
+typedef R _wrapZoneBinaryCallback<A, B, R>(A a, B b);
-ZoneUnaryCallback/*<R, T>*/ _wrapZone/*<R, T>*/(ZoneUnaryCallback/*<R, T>*/ callback) {
+_wrapZoneCallback/*<A, R>*/ _wrapZone/*<A, R>*/(_wrapZoneCallback/*<A, R>*/ callback) {
// For performance reasons avoid wrapping if we are in the root zone.
- if (identical(Zone.current, Zone.ROOT)) return callback;
+ if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
- return Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ // TODO(jacobr): we cast to _wrapZoneCallback/*<A, R>*/ to hack around missing
+ // generic method support in zones.
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneCallback/*<A, R>*/ wrapped =
+ Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ return wrapped;
}
-ZoneBinaryCallback/*<R, A, B>*/ _wrapBinaryZone/*<R, A, B>*/(
- ZoneBinaryCallback/*<R, A, B>*/ callback) {
- if (identical(Zone.current, Zone.ROOT)) return callback;
+_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
+ if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
- return Zone.current.bindBinaryCallback(callback, runGuarded: true);
+ // We cast to _wrapZoneBinaryCallback/*<A, B, R>*/ to hack around missing
+ // generic method support in zones.
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneBinaryCallback/*<A, B, R>*/ wrapped =
+ Zone.current.bindBinaryCallback(callback, runGuarded: true);
+ return wrapped;
}
/**
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index b9da2c4..bc92d6d 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -20997,109 +20997,6 @@
// BSD-style license that can be found in the LICENSE file.
-/**
- * A task specification for HTTP requests.
- *
- * This specification is not available when an HTTP request is sent through
- * direct use of [HttpRequest.send]. See [HttpRequestSendTaskSpecification].
- *
- * A task created from this specification is a `Future<HttpRequest>`.
- *
- * *Experimental*. This class may disappear without notice.
- */
-class HttpRequestTaskSpecification extends TaskSpecification {
- /// The URL of the request.
- final String url;
-
- /// The HTTP request method.
- ///
- /// By default (when `null`) this is a `"GET"` request. Alternatively, the
- /// method can be `"POST"`, `"PUT"`, `"DELETE"`, etc.
- final String method;
-
- /// Whether the request should send credentials. Credentials are only useful
- /// for cross-origin requests.
- ///
- /// See [HttpRequest.request] for more information.
- final bool withCredentials;
-
- /// The desired response format.
- ///
- /// Supported types are:
- /// - `""`: (same as `"text"`),
- /// - `"arraybuffer"`,
- /// - `"blob"`,
- /// - `"document"`,
- /// - `"json"`,
- /// - `"text"`
- ///
- /// When no value is provided (when equal to `null`) defaults to `""`.
- final String responseType;
-
- /// The desired MIME type.
- ///
- /// This overrides the default MIME type which is set up to transfer textual
- /// data.
- final String mimeType;
-
- /// The request headers that should be sent with the request.
- final Map<String, String> requestHeaders;
-
- /// The data that is sent with the request.
- ///
- /// When data is provided (the value is not `null`), it must be a
- /// [ByteBuffer], [Blob], [Document], [String], or [FormData].
- final dynamic sendData;
-
- /// The function that is invoked on progress updates. This function is
- /// registered as an event listener on the created [HttpRequest] object, and
- /// thus has its own task. Further invocations of the progress function do
- /// *not* use the HTTP request task as task object.
- ///
- /// Creating an HTTP request automatically registers the on-progress listener.
- final ZoneUnaryCallback<dynamic, ProgressEvent> onProgress;
-
- HttpRequestTaskSpecification(this.url,
- {String this.method, bool this.withCredentials, String this.responseType,
- String this.mimeType, Map<String, String> this.requestHeaders,
- this.sendData,
- void this.onProgress(ProgressEvent e)});
-
- String get name => "dart.html.http-request";
- bool get isOneShot => true;
-}
-
-/**
- * A task specification for HTTP requests that are initiated through a direct
- * invocation of [HttpRequest.send].
- *
- * This specification serves as signal to zones that an HTTP request has been
- * initiated. The created task is the [request] object itself, and
- * no callback is ever executed in this task.
- *
- * Note that event listeners on the HTTP request are also registered in the
- * zone (although with their own task creations), and that a zone can thus
- * detect when the HTTP request returns.
- *
- * HTTP requests that are initiated through `request` methods don't use
- * this class but use [HttpRequestTaskSpecification].
- *
- * *Experimental*. This class may disappear without notice.
- */
-class HttpRequestSendTaskSpecification extends TaskSpecification {
- final HttpRequest request;
- final dynamic sendData;
-
- HttpRequestSendTaskSpecification(this.request, this.sendData);
-
- String get name => "dart.html.http-request-send";
-
- /**
- * No callback is ever executed in an HTTP request send task.
- */
- bool get isOneShot => false;
-}
-
/**
* A client-side XHR request for getting data from a URL,
* formally known as XMLHttpRequest.
@@ -21287,34 +21184,7 @@
{String method, bool withCredentials, String responseType,
String mimeType, Map<String, String> requestHeaders, sendData,
void onProgress(ProgressEvent e)}) {
- var spec = new HttpRequestTaskSpecification(
- url, method: method,
- withCredentials: withCredentials,
- responseType: responseType,
- mimeType: mimeType,
- requestHeaders: requestHeaders,
- sendData: sendData,
- onProgress: onProgress);
-
- if (identical(Zone.current, Zone.ROOT)) {
- return _createHttpRequestTask(spec, null);
- }
- return Zone.current.createTask(_createHttpRequestTask, spec);
- }
-
- static Future<HttpRequest> _createHttpRequestTask(
- HttpRequestTaskSpecification spec, Zone zone) {
- String url = spec.url;
- String method = spec.method;
- bool withCredentials = spec.withCredentials;
- String responseType = spec.responseType;
- String mimeType = spec.mimeType;
- Map<String, String> requestHeaders = spec.requestHeaders;
- var sendData = spec.sendData;
- var onProgress = spec.onProgress;
-
var completer = new Completer<HttpRequest>();
- var task = completer.future;
var xhr = new HttpRequest();
if (method == null) {
@@ -21354,42 +21224,23 @@
// redirect case will be handled by the browser before it gets to us,
// so if we see it we should pass it through to the user.
var unknownRedirect = xhr.status > 307 && xhr.status < 400;
-
- var isSuccessful = accepted || fileUri || notModified || unknownRedirect;
-
- if (zone == null && isSuccessful) {
+
+ if (accepted || fileUri || notModified || unknownRedirect) {
completer.complete(xhr);
- } else if (zone == null) {
- completer.completeError(e);
- } else if (isSuccessful) {
- zone.runTask((task, value) {
- completer.complete(value);
- }, task, xhr);
} else {
- zone.runTask((task, error) {
- completer.completeError(error);
- }, task, e);
+ completer.completeError(e);
}
});
- if (zone == null) {
- xhr.onError.listen(completer.completeError);
- } else {
- xhr.onError.listen((error) {
- zone.runTask((task, error) {
- completer.completeError(error);
- }, task, error);
- });
- }
+ xhr.onError.listen(completer.completeError);
if (sendData != null) {
- // TODO(floitsch): should we go through 'send()' and have nested tasks?
- xhr._send(sendData);
+ xhr.send(sendData);
} else {
- xhr._send();
+ xhr.send();
}
- return task;
+ return completer.future;
}
/**
@@ -21439,9 +21290,6 @@
return xhr.responseText;
});
}
- // TODO(floitsch): the following code doesn't go through task zones.
- // Since 'XDomainRequest' is an IE9 feature we should probably just remove
- // it.
}
/**
@@ -21492,7 +21340,7 @@
*
* Note: Most simple HTTP requests can be accomplished using the [getString],
* [request], [requestCrossOrigin], or [postFormData] methods. Use of this
- * `open` method is intended only for more complex HTTP requests where
+ * `open` method is intended only for more complext HTTP requests where
* finer-grained control is needed.
*/
@DomName('XMLHttpRequest.open')
@@ -21505,36 +21353,6 @@
}
}
- /**
- * Sends the request with any given `data`.
- *
- * Note: Most simple HTTP requests can be accomplished using the [getString],
- * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
- * `send` method is intended only for more complex HTTP requests where
- * finer-grained control is needed.
- *
- * ## Other resources
- *
- * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
- * from MDN.
- */
- @DomName('XMLHttpRequest.send')
- @DocsEditable()
- void send([body_OR_data]) {
- if (identical(Zone.current, Zone.ROOT)) {
- _send(body_OR_data);
- } else {
- Zone.current.createTask(_createHttpRequestSendTask,
- new HttpRequestSendTaskSpecification(this, body_OR_data));
- }
- }
-
- static HttpRequest _createHttpRequestSendTask(
- HttpRequestSendTaskSpecification spec, Zone zone) {
- spec.request._send(spec.sendData);
- return spec.request;
- }
-
// To suppress missing implicit constructor warnings.
factory HttpRequest._() { throw new UnsupportedError("Not supported"); }
@@ -21838,7 +21656,7 @@
@SupportedBrowser(SupportedBrowser.SAFARI)
void overrideMimeType(String mime) => _blink.BlinkXMLHttpRequest.instance.overrideMimeType_Callback_1_(this, mime);
- void _send([body_OR_data]) {
+ void send([body_OR_data]) {
if (body_OR_data != null) {
_blink.BlinkXMLHttpRequest.instance.send_Callback_1_(this, body_OR_data);
return;
@@ -37844,10 +37662,10 @@
if ((blob_OR_source_OR_stream is Blob || blob_OR_source_OR_stream == null)) {
return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
}
- if ((blob_OR_source_OR_stream is MediaSource)) {
+ if ((blob_OR_source_OR_stream is MediaStream)) {
return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
}
- if ((blob_OR_source_OR_stream is MediaStream)) {
+ if ((blob_OR_source_OR_stream is MediaSource)) {
return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
}
throw new ArgumentError("Incorrect number or type of arguments");
@@ -39313,99 +39131,6 @@
// BSD-style license that can be found in the LICENSE file.
-typedef void RemoveFrameRequestMapping(int id);
-
-/**
- * The task object representing animation-frame requests.
- *
- * For historical reasons, [Window.requestAnimationFrame] returns an integer
- * to users. However, zone tasks must be unique objects, and an integer can
- * therefore not be used as task object. The [Window] class thus keeps a mapping
- * from the integer ID to the corresponding task object. All zone related
- * operations work on this task object, whereas users of
- * [Window.requestAnimationFrame] only see the integer ID.
- *
- * Since this mapping takes up space, it must be removed when the
- * animation-frame task has triggered. The default implementation does this
- * automatically, but intercepting implementations of `requestAnimationFrame`
- * must make sure to call the [AnimationFrameTask.removeMapping]
- * function that is provided in the task specification.
- *
- * *Experimental*. This class may disappear without notice.
- */
-abstract class AnimationFrameTask {
- /** The ID that is returned to users. */
- int get id;
-
- /** The zone in which the task will run. */
- Zone get zone;
-
- /**
- * Cancels the animation-frame request.
- *
- * A call to [Window.cancelAnimationFrame] with an `id` argument equal to [id]
- * forwards the request to this function.
- *
- * Zones that intercept animation-frame requests implement this method so
- * that they can react to cancelation requests.
- */
- void cancel(Window window);
-
- /**
- * Maps animation-frame request IDs to their task objects.
- */
- static final Map<int, _AnimationFrameTask> _tasks = {};
-
- /**
- * Removes the mapping from [id] to [AnimationFrameTask].
- *
- * This function must be invoked by user-implemented animation-frame
- * tasks, before running [callback].
- *
- * See [AnimationFrameTask].
- */
- static void removeMapping(int id) {
- _tasks.remove(id);
- }
-}
-
-class _AnimationFrameTask implements AnimationFrameTask {
- final int id;
- final Zone zone;
- final FrameRequestCallback _callback;
-
- _AnimationFrameTask(this.id, this.zone, this._callback);
-
- void cancel(Window window) {
- window._cancelAnimationFrame(this.id);
- }
-}
-
-/**
- * The task specification for an animation-frame request.
- *
- * *Experimental*. This class may disappear without notice.
- */
-class AnimationFrameRequestSpecification implements TaskSpecification {
- /**
- * The window on which [Window.requestAnimationFrame] was invoked.
- */
- final Window window;
-
- /**
- * The callback that is executed when the animation-frame is ready.
- *
- * Note that the callback hasn't been registered in any zone when the `create`
- * function (passed to [Zone.createTask]) is invoked.
- */
- final FrameRequestCallback callback;
-
- AnimationFrameRequestSpecification(this.window, this.callback);
-
- String get name => "dart.html.request-animation-frame";
- bool get isOneShot => true;
-}
-
@DocsEditable()
/**
* Top-level container for the current browser tab or window.
@@ -39460,11 +39185,12 @@
*/
Future<num> get animationFrame {
var completer = new Completer<num>.sync();
- requestAnimationFrame(completer.complete);
+ requestAnimationFrame((time) {
+ completer.complete(time);
+ });
return completer.future;
}
-
/**
* Called to draw an animation frame and then request the window to repaint
* after [callback] has finished (creating the animation).
@@ -39483,52 +39209,9 @@
*/
@DomName('Window.requestAnimationFrame')
int requestAnimationFrame(FrameRequestCallback callback) {
- if (identical(Zone.current, Zone.ROOT)) {
- return _requestAnimationFrame(callback);
- }
- var spec = new AnimationFrameRequestSpecification(this, callback);
- var task = Zone.current.createTask/*<AnimationFrameTask>*/(
- _createAnimationFrameTask, spec);
- AnimationFrameTask._tasks[task.id] = task;
- return task.id;
+ return _requestAnimationFrame(_wrapZone(callback));
}
- static _AnimationFrameTask _createAnimationFrameTask(
- AnimationFrameRequestSpecification spec, Zone zone) {
- var task;
- var id = spec.window._requestAnimationFrame((num time) {
- AnimationFrameTask.removeMapping(task.id);
- zone.runTask(_runAnimationFrame, task, time);
- });
- var callback = zone.registerUnaryCallback(spec.callback);
- task = new _AnimationFrameTask(id, zone, callback);
- return task;
- }
-
- static void _runAnimationFrame(_AnimationFrameTask task, num time) {
- task._callback(time);
- }
-
- /**
- * Cancels an animation frame request.
- *
- * ## Other resources
- *
- * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame)
- * from MDN.
- */
- @DomName('Window.cancelAnimationFrame')
- void cancelAnimationFrame(int id) {
- var task = AnimationFrameTask._tasks.remove(id);
- if (task == null) {
- // Assume that the animation frame request wasn't intercepted by a zone.
- _cancelAnimationFrame(id);
- return;
- }
- task.cancel(this);
- }
-
-
/**
* Access a sandboxed file system of the specified `size`. If `persistent` is
* true, the application will request permission from the user to create
@@ -40295,7 +39978,7 @@
@DomName('Window.cancelAnimationFrame')
@DocsEditable()
- void _cancelAnimationFrame(int handle) => _blink.BlinkWindow.instance.cancelAnimationFrame_Callback_1_(this, handle);
+ void cancelAnimationFrame(int handle) => _blink.BlinkWindow.instance.cancelAnimationFrame_Callback_1_(this, handle);
@DomName('Window.close')
@DocsEditable()
@@ -44809,41 +44492,6 @@
StreamSubscription<T> capture(void onData(T event));
}
-/// Task specification for DOM Events.
-///
-/// *Experimental*. May disappear without notice.
-class EventSubscriptionSpecification<T extends Event>
- implements TaskSpecification {
- @override
- final String name;
- @override
- final bool isOneShot;
-
- final EventTarget target;
- /// The event-type of the event. For example 'click' for click events.
- final String eventType;
- // TODO(floitsch): the first generic argument should be 'void'.
- final ZoneUnaryCallback<dynamic, T> onData;
- final bool useCapture;
-
- EventSubscriptionSpecification({this.name, this.isOneShot, this.target,
- this.eventType, void this.onData(T event), this.useCapture});
-
- /// Returns a copy of this instance, with every non-null argument replaced
- /// by the given value.
- EventSubscriptionSpecification<T> replace(
- {String name, bool isOneShot, EventTarget target,
- String eventType, void onData(T event), bool useCapture}) {
- return new EventSubscriptionSpecification<T>(
- name: name ?? this.name,
- isOneShot: isOneShot ?? this.isOneShot,
- target: target ?? this.target,
- eventType: eventType ?? this.eventType,
- onData: onData ?? this.onData,
- useCapture: useCapture ?? this.useCapture);
- }
-}
-
/**
* Adapter for exposing DOM events as Dart streams.
*/
@@ -44851,16 +44499,8 @@
final EventTarget _target;
final String _eventType;
final bool _useCapture;
- /// The name that is used in the task specification.
- final String _name;
- /// Whether the stream can trigger multiple times.
- final bool _isOneShot;
- _EventStream(this._target, String eventType, this._useCapture,
- {String name, bool isOneShot: false})
- : _eventType = eventType,
- _isOneShot = isOneShot,
- _name = name ?? "dart.html.event.$eventType";
+ _EventStream(this._target, this._eventType, this._useCapture);
// DOM events are inherently multi-subscribers.
Stream<T> asBroadcastStream({void onListen(StreamSubscription<T> subscription),
@@ -44868,31 +44508,13 @@
=> this;
bool get isBroadcast => true;
- StreamSubscription<T> _listen(
- void onData(T event), {bool useCapture}) {
-
- if (identical(Zone.current, Zone.ROOT)) {
- return new _EventStreamSubscription<T>(
- this._target, this._eventType, onData, this._useCapture,
- Zone.current);
- }
-
- var specification = new EventSubscriptionSpecification<T>(
- name: this._name, isOneShot: this._isOneShot,
- target: this._target, eventType: this._eventType,
- onData: onData, useCapture: useCapture);
- // We need to wrap the _createStreamSubscription call, since a tear-off
- // would not bind the generic type 'T'.
- return Zone.current.createTask((spec, Zone zone) {
- return _createStreamSubscription/*<T>*/(spec, zone);
- }, specification);
- }
-
StreamSubscription<T> listen(void onData(T event),
{ Function onError,
void onDone(),
bool cancelOnError}) {
- return _listen(onData, useCapture: this._useCapture);
+
+ return new _EventStreamSubscription<T>(
+ this._target, this._eventType, onData, this._useCapture);
}
}
@@ -44907,9 +44529,8 @@
*/
class _ElementEventStreamImpl<T extends Event> extends _EventStream<T>
implements ElementStream<T> {
- _ElementEventStreamImpl(target, eventType, useCapture,
- {String name, bool isOneShot: false}) :
- super(target, eventType, useCapture, name: name, isOneShot: isOneShot);
+ _ElementEventStreamImpl(target, eventType, useCapture) :
+ super(target, eventType, useCapture);
Stream<T> matches(String selector) => this.where(
(event) => _matchesWithAncestors(event, selector)).map((e) {
@@ -44917,9 +44538,9 @@
return e;
});
- StreamSubscription<T> capture(void onData(T event)) {
- return _listen(onData, useCapture: true);
- }
+ StreamSubscription<T> capture(void onData(T event)) =>
+ new _EventStreamSubscription<T>(
+ this._target, this._eventType, onData, true);
}
/**
@@ -44968,13 +44589,7 @@
bool get isBroadcast => true;
}
-StreamSubscription/*<T>*/ _createStreamSubscription/*<T>*/(
- EventSubscriptionSpecification/*<T>*/ spec, Zone zone) {
- return new _EventStreamSubscription/*<T>*/(spec.target, spec.eventType,
- spec.onData, spec.useCapture, zone);
-}
-
-// We would like this to just be EventListener<T> but that typedef cannot
+// We would like this to just be EventListener<T> but that typdef cannot
// use generics until dartbug/26276 is fixed.
typedef _EventListener<T extends Event>(T event);
@@ -44983,19 +44598,15 @@
EventTarget _target;
final String _eventType;
EventListener _onData;
- EventListener _domCallback;
final bool _useCapture;
- final Zone _zone;
// TODO(jacobr): for full strong mode correctness we should write
- // _onData = onData == null ? null : _wrapZone/*<dynamic, Event>*/((e) => onData(e as T))
+ // _onData = onData == null ? null : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
// but that breaks 114 co19 tests as well as multiple html tests as it is reasonable
// to pass the wrong type of event object to an event listener as part of a
// test.
_EventStreamSubscription(this._target, this._eventType, void onData(T event),
- this._useCapture, Zone zone)
- : _zone = zone,
- _onData = _registerZone/*<dynamic, Event>*/(zone, onData) {
+ this._useCapture) : _onData = _wrapZone/*<Event, dynamic>*/(onData) {
_tryResume();
}
@@ -45017,7 +44628,7 @@
}
// Remove current event listener.
_unlisten();
- _onData = _registerZone/*<dynamic, Event>*/(_zone, handleData);
+ _onData = _wrapZone/*<Event, dynamic>*/(handleData);
_tryResume();
}
@@ -45046,25 +44657,14 @@
}
void _tryResume() {
- if (_onData == null || isPaused) return;
- if (identical(_zone, Zone.ROOT)) {
- _domCallback = _onData;
- } else {
- _domCallback = (event) {
- _zone.runTask(_runEventNotification, this, event);
- };
+ if (_onData != null && !isPaused) {
+ _target.addEventListener(_eventType, _onData, _useCapture);
}
- _target.addEventListener(_eventType, _domCallback, _useCapture);
- }
-
- static void _runEventNotification/*<T>*/(
- _EventStreamSubscription/*<T>*/ subscription, /*=T*/ event) {
- subscription._onData(event);
}
void _unlisten() {
if (_onData != null) {
- _target.removeEventListener(_eventType, _domCallback, _useCapture);
+ _target.removeEventListener(_eventType, _onData, _useCapture);
}
}
@@ -48256,26 +47856,31 @@
// BSD-style license that can be found in the LICENSE file.
-ZoneUnaryCallback/*<R, T>*/ _registerZone/*<R, T>*/(Zone zone,
- ZoneUnaryCallback/*<R, T>*/ callback) {
- // For performance reasons avoid registering if we are in the root zone.
- if (identical(zone, Zone.ROOT)) return callback;
- if (callback == null) return null;
- return zone.registerUnaryCallback(callback);
-}
+// TODO(jacobr): remove these typedefs when dart:async supports generic types.
+typedef R _wrapZoneCallback<A, R>(A a);
+typedef R _wrapZoneBinaryCallback<A, B, R>(A a, B b);
-ZoneUnaryCallback/*<R, T>*/ _wrapZone/*<R, T>*/(ZoneUnaryCallback/*<R, T>*/ callback) {
+_wrapZoneCallback/*<A, R>*/ _wrapZone/*<A, R>*/(_wrapZoneCallback/*<A, R>*/ callback) {
// For performance reasons avoid wrapping if we are in the root zone.
- if (identical(Zone.current, Zone.ROOT)) return callback;
+ if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
- return Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ // TODO(jacobr): we cast to _wrapZoneCallback/*<A, R>*/ to hack around missing
+ // generic method support in zones.
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneCallback/*<A, R>*/ wrapped =
+ Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ return wrapped;
}
-ZoneBinaryCallback/*<R, A, B>*/ _wrapBinaryZone/*<R, A, B>*/(
- ZoneBinaryCallback/*<R, A, B>*/ callback) {
- if (identical(Zone.current, Zone.ROOT)) return callback;
+_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
+ if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
- return Zone.current.bindBinaryCallback(callback, runGuarded: true);
+ // We cast to _wrapZoneBinaryCallback/*<A, B, R>*/ to hack around missing
+ // generic method support in zones.
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneBinaryCallback/*<A, B, R>*/ wrapped =
+ Zone.current.bindBinaryCallback(callback, runGuarded: true);
+ return wrapped;
}
/**
diff --git a/tests/corelib/uri_test.dart b/tests/corelib/uri_test.dart
index a9166be..3d24e2d 100644
--- a/tests/corelib/uri_test.dart
+++ b/tests/corelib/uri_test.dart
@@ -32,6 +32,11 @@
Expect.equals(uri,
Uri.parse(uriText + "#fragment").removeFragment());
}
+
+ // Test uri.replace on uri with fragment
+ uri = Uri.parse('http://hello.com/fake#fragment');
+ uri = uri.replace(path: "D/E/E");
+ Expect.stringEquals('http://hello.com/D/E/E#fragment', uri.toString());
}
testEncodeDecode(String orig, String encoded) {
diff --git a/tests/html/event_subscription_specification_test.dart b/tests/html/event_subscription_specification_test.dart
deleted file mode 100644
index 406ed37..0000000
--- a/tests/html/event_subscription_specification_test.dart
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2016, 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.
-
-library EventTaskZoneTest;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import 'dart:async';
-import 'dart:html';
-
-// Tests event-subscription specifications.
-
-main() {
- useHtmlConfiguration();
-
- var defaultTarget = new Element.div();
- var defaultOnData = (x) => null;
-
- EventSubscriptionSpecification createSpec({useCapture, isOneShot}) {
- return new EventSubscriptionSpecification(
- name: "name",
- target: defaultTarget,
- useCapture: useCapture,
- isOneShot: isOneShot,
- onData: defaultOnData,
- eventType: "eventType");
- }
-
- for (var useCapture in [true, false]) {
- for (var isOneShot in [true, false]) {
- var spec = createSpec(useCapture: useCapture, isOneShot: isOneShot);
-
- test(
- "EventSubscriptionSpecification - constructor "
- "useCapture: $useCapture isOneShot: $isOneShot", () {
- var replaced = spec.replace(eventType: 'replace-eventType');
- expect(replaced.name, "name");
- expect(replaced.target, defaultTarget);
- expect(replaced.useCapture, useCapture);
- expect(replaced.isOneShot, isOneShot);
- expect(replaced.onData, equals(defaultOnData));
- expect(replaced.eventType, "replace-eventType");
- });
-
- test(
- "replace name "
- "useCapture: $useCapture isOneShot: $isOneShot", () {
- var replaced = spec.replace(name: 'replace-name');
- expect(replaced.name, "replace-name");
- expect(replaced.target, defaultTarget);
- expect(replaced.useCapture, useCapture);
- expect(replaced.isOneShot, isOneShot);
- expect(replaced.onData, equals(defaultOnData));
- expect(replaced.eventType, "eventType");
- });
-
- test(
- "replace target "
- "useCapture: $useCapture isOneShot: $isOneShot", () {
- var replacementTarget = new Element.a();
- var replaced = spec.replace(target: replacementTarget);
- expect(replaced.name, "name");
- expect(replaced.target, replacementTarget);
- expect(replaced.useCapture, useCapture);
- expect(replaced.isOneShot, isOneShot);
- expect(replaced.onData, equals(defaultOnData));
- expect(replaced.eventType, "eventType");
- });
-
- test(
- "replace useCapture "
- "useCapture: $useCapture isOneShot: $isOneShot", () {
- var replaced = spec.replace(useCapture: !useCapture);
- expect(replaced.name, "name");
- expect(replaced.target, defaultTarget);
- expect(replaced.useCapture, !useCapture);
- expect(replaced.isOneShot, isOneShot);
- expect(replaced.onData, equals(defaultOnData));
- expect(replaced.eventType, "eventType");
- });
-
- test(
- "replace isOneShot "
- "useCapture: $useCapture isOneShot: $isOneShot", () {
- var replaced = spec.replace(isOneShot: !isOneShot);
- expect(replaced.name, "name");
- expect(replaced.target, defaultTarget);
- expect(replaced.useCapture, useCapture);
- expect(replaced.isOneShot, !isOneShot);
- expect(replaced.onData, equals(defaultOnData));
- expect(replaced.eventType, "eventType");
- });
-
- test(
- "replace onData "
- "useCapture: $useCapture isOneShot: $isOneShot", () {
- var replacementOnData = (x) {};
- var replaced = spec.replace(onData: replacementOnData);
- expect(replaced.name, "name");
- expect(replaced.target, defaultTarget);
- expect(replaced.useCapture, useCapture);
- expect(replaced.isOneShot, isOneShot);
- expect(replaced.onData, equals(replacementOnData));
- expect(replaced.eventType, "eventType");
- });
-
- test(
- "replace eventType "
- "useCapture: $useCapture isOneShot: $isOneShot", () {
- var replaced = spec.replace(eventType: 'replace-eventType');
- expect(replaced.name, "name");
- expect(replaced.target, defaultTarget);
- expect(replaced.useCapture, useCapture);
- expect(replaced.isOneShot, isOneShot);
- expect(replaced.onData, equals(defaultOnData));
- expect(replaced.eventType, "replace-eventType");
- });
- }
- }
-}
diff --git a/tests/html/event_zone_task_test.dart b/tests/html/event_zone_task_test.dart
deleted file mode 100644
index a0e85c8..0000000
--- a/tests/html/event_zone_task_test.dart
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright (c) 2016, 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.
-
-library EventTaskZoneTest;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import 'dart:async';
-import 'dart:html';
-
-// Tests zone tasks with DOM events.
-
-class AbortedEventStreamSubscription implements StreamSubscription<Event> {
- final Zone zone;
-
- AbortedEventStreamSubscription(this.zone);
-
- @override
- Future asFuture([futureValue]) {
- throw new UnsupportedError("asFuture");
- }
-
- @override
- Future cancel() {
- return null;
- }
-
- @override
- bool get isPaused => throw new UnsupportedError("pause");
-
- @override
- void onData(void handleData(Event data)) {
- throw new UnsupportedError("cancel");
- }
-
- @override
- void onDone(void handleDone()) {
- throw new UnsupportedError("onDone");
- }
-
- @override
- void onError(Function handleError) {
- throw new UnsupportedError("onError");
- }
-
- @override
- void pause([Future resumeSignal]) {
- throw new UnsupportedError("pause");
- }
-
- @override
- void resume() {
- throw new UnsupportedError("resume");
- }
-
- static AbortedEventStreamSubscription _create(
- EventSubscriptionSpecification spec, Zone zone) {
- return new AbortedEventStreamSubscription(zone);
- }
-}
-
-eventTest(String name, Event eventFn(), void validate(Event event),
- void validateSpec(EventSubscriptionSpecification spec),
- {String type: 'foo',
- bool abortCreation: false,
- EventSubscriptionSpecification modifySpec(
- EventSubscriptionSpecification spec),
- bool abortEvent: false,
- Event modifyEvent(Event event)}) {
- test(name, () {
- var lastSpec;
- var lastTask;
- var lastEvent;
-
- Object createTaskHandler(Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate create, TaskSpecification specification) {
- if (specification is EventSubscriptionSpecification) {
- if (abortCreation) {
- create = AbortedEventStreamSubscription._create;
- }
- if (modifySpec != null) {
- specification = modifySpec(specification);
- }
- lastSpec = specification;
- return lastTask = parent.createTask(zone, create, specification);
- }
- return parent.createTask(zone, create, specification);
- }
-
- void runTaskHandler(Zone self, ZoneDelegate parent, Zone zone, TaskRun run,
- Object task, Object arg) {
- if (identical(task, lastTask)) {
- if (abortEvent) return;
- if (modifyEvent != null) {
- arg = modifyEvent(arg);
- }
- parent.runTask(zone, run, task, arg);
- return;
- }
- parent.runTask(zone, run, task, arg);
- }
-
- runZoned(() {
- final el = new Element.tag('div');
- var fired = false;
- var sub = el.on[type].listen((ev) {
- lastEvent = ev;
- fired = true;
- });
- el.dispatchEvent(eventFn());
-
- validateSpec(lastSpec);
- validate(lastEvent);
-
- if (abortEvent || abortCreation) {
- expect(fired, isFalse, reason: 'Expected event to be intercepted.');
- } else {
- expect(fired, isTrue, reason: 'Expected event to be dispatched.');
- }
-
- sub.cancel();
- },
- zoneSpecification: new ZoneSpecification(
- createTask: createTaskHandler,
- runTask: runTaskHandler));
- });
-}
-
-Function checkSpec(
- [String expectedType = 'foo', bool expectedUseCapture = false]) {
- return (EventSubscriptionSpecification spec) {
- expect(spec.eventType, expectedType);
- expect(spec.useCapture, expectedUseCapture);
- };
-}
-
-main() {
- useHtmlConfiguration();
-
- eventTest('Event', () => new Event('foo'), (ev) {
- expect(ev.type, equals('foo'));
- }, checkSpec('foo'));
-
- eventTest(
- 'WheelEvent',
- () => new WheelEvent("mousewheel",
- deltaX: 1,
- deltaY: 0,
- detail: 4,
- screenX: 3,
- screenY: 4,
- clientX: 5,
- clientY: 6,
- ctrlKey: true,
- altKey: true,
- shiftKey: true,
- metaKey: true), (ev) {
- expect(ev.deltaX, 1);
- expect(ev.deltaY, 0);
- expect(ev.screen.x, 3);
- expect(ev.screen.y, 4);
- expect(ev.client.x, 5);
- expect(ev.client.y, 6);
- expect(ev.ctrlKey, isTrue);
- expect(ev.altKey, isTrue);
- expect(ev.shiftKey, isTrue);
- expect(ev.metaKey, isTrue);
- }, checkSpec('mousewheel'), type: 'mousewheel');
-
- eventTest('Event - no-create', () => new Event('foo'), (ev) {
- expect(ev, isNull);
- }, checkSpec('foo'), abortCreation: true);
-
- eventTest(
- 'WheelEvent - no-create',
- () => new WheelEvent("mousewheel",
- deltaX: 1,
- deltaY: 0,
- detail: 4,
- screenX: 3,
- screenY: 4,
- clientX: 5,
- clientY: 6,
- ctrlKey: true,
- altKey: true,
- shiftKey: true,
- metaKey: true), (ev) {
- expect(ev, isNull);
- }, checkSpec('mousewheel'), type: 'mousewheel', abortCreation: true);
-
- eventTest('Event - no-run', () => new Event('foo'), (ev) {
- expect(ev, isNull);
- }, checkSpec('foo'), abortEvent: true);
-
- eventTest(
- 'WheelEvent - no-run',
- () => new WheelEvent("mousewheel",
- deltaX: 1,
- deltaY: 0,
- detail: 4,
- screenX: 3,
- screenY: 4,
- clientX: 5,
- clientY: 6,
- ctrlKey: true,
- altKey: true,
- shiftKey: true,
- metaKey: true), (ev) {
- expect(ev, isNull);
- }, checkSpec('mousewheel'), type: 'mousewheel', abortEvent: true);
-
- // Register for 'foo', but receive a 'bar' event, because the specification
- // is rewritten.
- eventTest(
- 'Event - replace eventType',
- () => new Event('bar'),
- (ev) {
- expect(ev.type, equals('bar'));
- },
- checkSpec('bar'),
- type: 'foo',
- modifySpec: (EventSubscriptionSpecification spec) {
- return spec.replace(eventType: 'bar');
- });
-
- // Intercept the 'foo' event and replace it with a 'bar' event.
- eventTest(
- 'Event - intercept result',
- () => new Event('foo'),
- (ev) {
- expect(ev.type, equals('bar'));
- },
- checkSpec('foo'),
- type: 'foo',
- modifyEvent: (Event event) {
- return new Event('bar');
- });
-}
diff --git a/tests/html/html.status b/tests/html/html.status
index 65ff46f..4d57f42 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -142,7 +142,6 @@
event_test: RuntimeError # Issue 23437. Only three failures, but hard to break them out.
wheelevent_test: RuntimeError # Issue 23437
text_event_test: RuntimeError # Issue 23437
-event_zone_task_test: RuntimeError # Issue 23437
transition_event_test/functional: Skip # Times out. Issue 22167
request_animation_frame_test: Skip # Times out. Issue 22167
@@ -186,7 +185,6 @@
webgl_1_test/supported: Fail
websql_test/supported: Fail
xhr_test/json: Fail # IE10 returns string, not JSON object
-xhr_task_test/json: Fail # IE10 returns string, not JSON object
xhr_test/supported_overrideMimeType: Fail
xsltprocessor_test/supported: Fail
worker_test/functional: Fail # IE uses incorrect security context for Blob URIs.
@@ -244,8 +242,7 @@
touchevent_test/supported: Fail # IE does not support TouchEvents
webgl_1_test/functional: Fail
websql_test/supported: Fail
-xhr_test/json: Fail # IE11 returns string, not JSON object
-xhr_task_test/json: Fail # IE11 returns string, not JSON object
+xhr_test/json: Fail # IE10 returns string, not JSON object
xsltprocessor_test/supported: Fail
[ $runtime == ie10 ]
@@ -364,7 +361,6 @@
[ (($runtime == dartium || $runtime == drt) && $system == macos) || $system == windows ]
xhr_test/xhr: Skip # Times out. Issue 21527
-xhr_task_test/xhr: Skip # Times out. Issue 21527
[ $compiler == dart2analyzer ]
custom/document_register_basic_test: StaticWarning
diff --git a/tests/html/request_animation_task_test.dart b/tests/html/request_animation_task_test.dart
deleted file mode 100644
index 3d388dd..0000000
--- a/tests/html/request_animation_task_test.dart
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) 2016, 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.
-
-library EventTaskZoneTest;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import 'dart:async';
-import 'dart:html';
-
-// Tests zone tasks with window.requestAnimationFrame.
-
-class MockAnimationFrameTask implements AnimationFrameTask {
- static int taskId = 499;
-
- final int id;
- final Zone zone;
- bool _isCanceled = false;
- Function _callback;
-
- MockAnimationFrameTask(
- this.id, this.zone, this._callback);
-
- void cancel(Window window) {
- _isCanceled = true;
- }
-
- trigger(num stamp) {
- zone.runTask(run, this, stamp);
- }
-
- static create(AnimationFrameRequestSpecification spec, Zone zone) {
- var callback = zone.registerUnaryCallback(spec.callback);
- return new MockAnimationFrameTask(
- taskId++, zone, callback);
- }
-
- static run(MockAnimationFrameTask task, num arg) {
- AnimationFrameTask.removeMapping(task.id);
- task._callback(arg);
- }
-}
-
-animationFrameTest() {
- test("animationFrameTest - no intercept", () async {
- AnimationFrameTask lastTask;
- bool sawRequest = false;
- int id;
- num providedArg;
-
- Object createTaskHandler(Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate create, TaskSpecification specification) {
- if (specification is AnimationFrameRequestSpecification) {
- sawRequest = true;
- lastTask = parent.createTask(zone, create, specification);
- id = lastTask.id;
- return lastTask;
- }
- return parent.createTask(zone, create, specification);
- }
-
- void runTaskHandler(Zone self, ZoneDelegate parent, Zone zone, TaskRun run,
- Object task, Object arg) {
- if (identical(task, lastTask)) {
- providedArg = arg;
- }
- parent.runTask(zone, run, task, arg);
- }
-
- var completer = new Completer();
- var publicId;
- runZoned(() {
- publicId = window.requestAnimationFrame((num stamp) {
- completer.complete(stamp);
- });
- },
- zoneSpecification: new ZoneSpecification(
- createTask: createTaskHandler, runTask: runTaskHandler));
-
- var referenceCompleter = new Completer();
- window.requestAnimationFrame((num stamp) {
- referenceCompleter.complete(stamp);
- });
-
- var callbackStamp = await completer.future;
- var referenceStamp = await referenceCompleter.future;
-
- expect(callbackStamp, equals(referenceStamp));
- expect(providedArg, equals(callbackStamp));
- expect(sawRequest, isTrue);
- expect(publicId, isNotNull);
- expect(publicId, equals(id));
- });
-}
-
-interceptedAnimationFrameTest() {
- test("animationFrameTest - intercepted", () {
- List<MockAnimationFrameTask> tasks = [];
- List<num> loggedRuns = [];
- int executedTaskId;
- num executedStamp;
-
- Object createTaskHandler(Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate create, TaskSpecification specification) {
- if (specification is AnimationFrameRequestSpecification) {
- var task = parent.createTask(
- zone, MockAnimationFrameTask.create, specification);
- tasks.add(task);
- return task;
- }
- return parent.createTask(zone, create, specification);
- }
-
- void runTaskHandler(Zone self, ZoneDelegate parent, Zone zone, TaskRun run,
- Object task, Object arg) {
- if (tasks.contains(task)) {
- loggedRuns.add(arg);
- }
- parent.runTask(zone, run, task, arg);
- }
-
- var id0, id1, id2;
-
- runZoned(() {
- id0 = window.requestAnimationFrame((num stamp) {
- executedTaskId = id0;
- executedStamp = stamp;
- });
- id1 = window.requestAnimationFrame((num stamp) {
- executedTaskId = id1;
- executedStamp = stamp;
- });
- id2 = window.requestAnimationFrame((num stamp) {
- executedTaskId = id2;
- executedStamp = stamp;
- });
- },
- zoneSpecification: new ZoneSpecification(
- createTask: createTaskHandler, runTask: runTaskHandler));
-
- expect(tasks.length, 3);
- expect(executedTaskId, isNull);
- expect(executedStamp, isNull);
- expect(loggedRuns.isEmpty, isTrue);
-
- tasks[0].trigger(123.1);
- expect(executedTaskId, id0);
- expect(executedStamp, 123.1);
-
- tasks[1].trigger(123.2);
- expect(executedTaskId, id1);
- expect(executedStamp, 123.2);
-
- expect(loggedRuns, equals([123.1, 123.2]));
-
- window.cancelAnimationFrame(id2);
- expect(tasks[2]._isCanceled, isTrue);
- // Cancel it a second time. Should not crash.
- window.cancelAnimationFrame(id2);
- expect(tasks[2]._isCanceled, isTrue);
- });
-}
-
-main() {
- useHtmlConfiguration();
-
- animationFrameTest();
- interceptedAnimationFrameTest();
-}
diff --git a/tests/html/xhr_task2_test.dart b/tests/html/xhr_task2_test.dart
deleted file mode 100644
index 6dee69e..0000000
--- a/tests/html/xhr_task2_test.dart
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright (c) 2016, 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.
-
-library XHRTask2Test;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:html';
-import 'dart:typed_data';
-import 'package:unittest/html_individual_config.dart';
-import 'package:unittest/unittest.dart';
-
-class MockProgressEvent implements ProgressEvent {
- final target;
- MockProgressEvent(this.target);
-
- noSuchMethod(Invocation invocation) {
- throw "missing function in MockProgressEvent";
- }
-}
-
-class MockHttpRequestTask implements Future<HttpRequest> {
- final Completer completer = new Completer<HttpRequest>();
- final HttpRequestTaskSpecification spec;
- final Zone zone;
-
- MockHttpRequestTask(this.spec, this.zone);
-
- void trigger(response) {
- var xhr = new MockHttpRequest(spec, response);
- var arg;
- if (spec.url == "NonExistingFile") {
- arg = new MockProgressEvent(xhr);
- } else {
- arg = xhr;
- }
- zone.runTask(run, this, arg);
- }
-
- then(onData, {onError}) => completer.future.then(onData, onError: onError);
- catchError(f, {test}) => completer.future.catchError(f, test: test);
- whenComplete(f) => completer.future.whenComplete(f);
- asStream() => completer.future.asStream();
- timeout(timeLimit, {onTimeout}) =>
- completer.future.timeout(timeLimit, onTimeout: onTimeout);
-
- static create(HttpRequestTaskSpecification spec, Zone zone) {
- return new MockHttpRequestTask(spec, zone);
- }
-
- static run(MockHttpRequestTask task, value) {
- if (value is HttpRequest) {
- task.completer.complete(value);
- } else {
- task.completer.completeError(value);
- }
- }
-}
-
-class MockHttpRequest implements HttpRequest {
- final HttpRequestTaskSpecification spec;
- final response;
-
- MockHttpRequest(this.spec, this.response);
-
- noSuchMethod(Invocation invocation) {
- print("isGetter: ${invocation.isGetter}");
- print("isMethod: ${invocation.isMethod}");
- print("memberName: ${invocation.memberName}");
- }
-
- int get status => spec.url == "NonExistingFile" ? 404 : 200;
-
- get readyState => HttpRequest.DONE;
- get responseText => "$response";
-
- Map get responseHeaders => {'content-type': 'text/plain; charset=utf-8',};
-}
-
-main() {
- useHtmlIndividualConfiguration();
- unittestConfiguration.timeout = const Duration(milliseconds: 800);
-
- var urlExpando = new Expando();
-
- var url = 'some/url.html';
-
- Function buildCreateTaskHandler(List log, List tasks) {
- Object createTaskHandler(Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate create, TaskSpecification spec) {
- if (spec is HttpRequestTaskSpecification) {
- var url = spec.url;
- var method = spec.method;
- var withCredentials = spec.withCredentials;
- var responseType = spec.responseType;
- var mimeType = spec.mimeType;
- var data = spec.sendData;
-
- log.add("request $url");
- var dataLog = data is List<int> ? "binary ${data.length}" : "$data";
- log.add(" method: $method withCredentials: $withCredentials "
- "responseType: $responseType mimeType: $mimeType data: $dataLog");
- var task = parent.createTask(zone, MockHttpRequestTask.create, spec);
- urlExpando[task] = url;
- tasks.add(task);
- return task;
- }
- if (spec is EventSubscriptionSpecification) {
- EventSubscriptionSpecification eventSpec = spec;
- if (eventSpec.target is HttpRequest) {
- HttpRequest target = eventSpec.target;
- log.add("event listener on http-request ${eventSpec.eventType}");
- if (eventSpec.eventType == "readystatechange") {
- var oldOnData = eventSpec.onData;
- spec = eventSpec.replace(onData: (event) {
- oldOnData(event);
- if (target.readyState == HttpRequest.DONE) {
- log.add("unknown request done");
- }
- });
- }
- }
- }
- return parent.createTask(zone, create, spec);
- }
-
- return createTaskHandler;
- }
-
- Function buildRunTaskHandler(List log, List tasks) {
- void runTaskHandler(Zone self, ZoneDelegate parent, Zone zone, TaskRun run,
- Object task, Object arg) {
- if (tasks.contains(task)) {
- var url = urlExpando[task];
- if (arg is Error || arg is Exception) {
- log.add("failed $url");
- } else {
- if (arg is ProgressEvent) {
- log.add("success $url with progress-event");
- } else if (arg is HttpRequest) {
- log.add("success $url with http-request");
- } else {
- log.add("success $url (unknown arg)");
- }
- }
- }
- parent.runTask(zone, run, task, arg);
- }
-
- return runTaskHandler;
- }
-
- Future<List> runMocked(response, fun) async {
- var log = [];
- var tasks = [];
- var future = runZoned(fun,
- zoneSpecification: new ZoneSpecification(
- createTask: buildCreateTaskHandler(log, tasks),
- runTask: buildRunTaskHandler(log, tasks)));
- // Wait a full cycle to make sure things settle.
- await new Future(() {});
- var beforeTriggerLog = log.toList();
- log.clear();
- expect(tasks.length, 1);
- tasks.single.trigger(response);
- await future;
- return [beforeTriggerLog, log];
- }
-
- void validate200Response(xhr) {
- expect(xhr.status, equals(200));
- var data = JSON.decode(xhr.responseText);
- expect(data, contains('feed'));
- expect(data['feed'], contains('entry'));
- expect(data, isMap);
- }
-
- void validate404(xhr) {
- expect(xhr.status, equals(404));
- // We cannot say much about xhr.responseText, most HTTP servers will
- // include an HTML page explaining the error to a human.
- String responseText = xhr.responseText;
- expect(responseText, isNotNull);
- }
-
- group('xhr', () {
- test('XHR.request No file', () async {
- var log = await runMocked("404", () {
- var completer = new Completer();
- HttpRequest.request('NonExistingFile').then((_) {
- fail('Request should not have succeeded.');
- }, onError: expectAsync((error) {
- var xhr = error.target;
- expect(xhr.readyState, equals(HttpRequest.DONE));
- validate404(xhr);
- completer.complete('done');
- }));
- return completer.future;
- });
- expect(
- log,
- equals([
- [
- 'request NonExistingFile',
- ' method: null withCredentials: null responseType: null '
- 'mimeType: null data: null',
- ],
- ['success NonExistingFile with progress-event']
- ]));
- });
-
- test('XHR.request file', () async {
- var log = await runMocked('{"feed": {"entry": 499}}', () {
- var completer = new Completer();
- HttpRequest.request(url).then(expectAsync((xhr) {
- expect(xhr.readyState, equals(HttpRequest.DONE));
- validate200Response(xhr);
- completer.complete('done');
- }));
- return completer.future;
- });
- expect(
- log,
- equals([
- [
- 'request $url',
- ' method: null withCredentials: null responseType: null '
- 'mimeType: null data: null'
- ],
- ['success $url with http-request']
- ]));
- });
-
- test('XHR.getString file', () async {
- var log = await runMocked("foo", () {
- return HttpRequest.getString(url).then(expectAsync((str) {}));
- });
- expect(
- log,
- equals([
- [
- 'request $url',
- ' method: null withCredentials: null responseType: null '
- 'mimeType: null data: null'
- ],
- ['success $url with http-request']
- ]));
- });
-
- test('XHR.request responseType arraybuffer', () async {
- if (Platform.supportsTypedData) {
- var data = new Uint8List(128);
- var log = await runMocked(data.buffer, () {
- return HttpRequest.request(url,
- responseType: 'arraybuffer',
- requestHeaders: {
- 'Content-Type': 'text/xml'
- }).then(expectAsync((xhr) {
- expect(xhr.status, equals(200));
- var byteBuffer = xhr.response;
- expect(byteBuffer, new isInstanceOf<ByteBuffer>());
- expect(byteBuffer, isNotNull);
- }));
- });
- expect(
- log,
- equals([
- [
- 'request $url',
- ' method: null withCredentials: null responseType: arraybuffer'
- ' mimeType: null data: null'
- ],
- ['success $url with http-request']
- ]));
- }
- ;
- });
- });
-}
diff --git a/tests/html/xhr_task_test.dart b/tests/html/xhr_task_test.dart
deleted file mode 100644
index c315ae6..0000000
--- a/tests/html/xhr_task_test.dart
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright (c) 2016, 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.
-
-library XHRTaskTest;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:html';
-import 'dart:typed_data';
-import 'package:unittest/html_individual_config.dart';
-import 'package:unittest/unittest.dart';
-
-main() {
- useHtmlIndividualConfiguration();
-
- // Cache blocker is a workaround for:
- // https://code.google.com/p/dart/issues/detail?id=11834
- var cacheBlocker = new DateTime.now().millisecondsSinceEpoch;
- var url = '/root_dart/tests/html/xhr_cross_origin_data.txt?'
- 'cacheBlock=$cacheBlocker';
-
- var urlExpando = new Expando();
-
- Function buildCreateTaskHandler(List log, List tasks) {
- Object createTaskHandler(Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate create, TaskSpecification spec) {
- if (spec is HttpRequestTaskSpecification) {
- var url = spec.url;
- var method = spec.method;
- var withCredentials = spec.withCredentials;
- var responseType = spec.responseType;
- var mimeType = spec.mimeType;
- var data = spec.sendData;
-
- log.add("request $url");
- var dataLog = data is List<int> ? "binary ${data.length}" : "$data";
- log.add(" method: $method withCredentials: $withCredentials "
- "responseType: $responseType mimeType: $mimeType data: $dataLog");
- var task = parent.createTask(zone, create, spec);
- urlExpando[task] = url;
- tasks.add(task);
- return task;
- }
- if (spec is HttpRequestSendTaskSpecification) {
- var data = spec.sendData;
- var dataLog = data is List<int> ? "binary ${data.length}" : "$data";
- log.add("http-request (no info), data: $dataLog");
- var task = parent.createTask(zone, create, spec);
- tasks.add(task);
- urlExpando[task] = "unknown";
- return task;
- }
- if (spec is EventSubscriptionSpecification) {
- EventSubscriptionSpecification eventSpec = spec;
- if (eventSpec.target is HttpRequest) {
- HttpRequest target = eventSpec.target;
- log.add("event listener on http-request ${eventSpec.eventType}");
- if (eventSpec.eventType == "readystatechange") {
- var oldOnData = eventSpec.onData;
- spec = eventSpec.replace(onData: (event) {
- oldOnData(event);
- if (target.readyState == HttpRequest.DONE) {
- log.add("unknown request done");
- }
- });
- }
- }
- }
- return parent.createTask(zone, create, spec);
- }
-
- return createTaskHandler;
- }
-
- Function buildRunTaskHandler(List log, List tasks) {
- void runTaskHandler(Zone self, ZoneDelegate parent, Zone zone,
- TaskRun run, Object task, Object arg) {
- if (tasks.contains(task)) {
- var url = urlExpando[task];
- if (arg is Error || arg is Exception) {
- log.add("failed $url");
- } else {
- if (arg is ProgressEvent) {
- log.add("success $url with progress-event");
- } else if (arg is HttpRequest){
- log.add("success $url with http-request");
- } else {
- log.add("success $url (unknown arg)");
- }
- }
- }
- parent.runTask(zone, run, task, arg);
- }
-
- return runTaskHandler;
- }
-
- Future<List> runWithLogging(fun) async {
- var log = [];
- var tasks = [];
- await runZoned(fun, zoneSpecification: new ZoneSpecification(
- createTask: buildCreateTaskHandler(log, tasks),
- runTask: buildRunTaskHandler(log, tasks)));
- return log;
- }
-
- void validate200Response(xhr) {
- expect(xhr.status, equals(200));
- var data = JSON.decode(xhr.responseText);
- expect(data, contains('feed'));
- expect(data['feed'], contains('entry'));
- expect(data, isMap);
- }
-
- void validate404(xhr) {
- expect(xhr.status, equals(404));
- // We cannot say much about xhr.responseText, most HTTP servers will
- // include an HTML page explaining the error to a human.
- String responseText = xhr.responseText;
- expect(responseText, isNotNull);
- }
-
- group('xhr', () {
- test('XHR No file', () async {
- var log = await runWithLogging(() {
- var completer = new Completer();
- HttpRequest xhr = new HttpRequest();
- xhr.open("GET", "NonExistingFile", async: true);
- xhr.onReadyStateChange.listen(expectAsyncUntil((event) {
- if (xhr.readyState == HttpRequest.DONE) {
- validate404(xhr);
- completer.complete("done");
- }
- }, () => xhr.readyState == HttpRequest.DONE));
- xhr.send();
- return completer.future;
- });
- expect(log, equals([
- 'event listener on http-request readystatechange',
- 'http-request (no info), data: null',
- 'unknown request done'
- ]));
- });
-
- test('XHR_file', () async {
- var log = await runWithLogging(() {
- var completer = new Completer();
- var loadEndCalled = false;
-
- var xhr = new HttpRequest();
- xhr.open('GET', url, async: true);
- xhr.onReadyStateChange.listen(expectAsyncUntil((e) {
- if (xhr.readyState == HttpRequest.DONE) {
- validate200Response(xhr);
-
- Timer.run(expectAsync(() {
- expect(loadEndCalled, HttpRequest.supportsLoadEndEvent);
- completer.complete("done");
- }));
- }
- }, () => xhr.readyState == HttpRequest.DONE));
-
- xhr.onLoadEnd.listen((ProgressEvent e) {
- loadEndCalled = true;
- });
- xhr.send();
- return completer.future;
- });
- expect(log, equals([
- 'event listener on http-request readystatechange',
- 'event listener on http-request loadend',
- 'http-request (no info), data: null',
- 'unknown request done'
- ]));
- });
-
- test('XHR.request No file', () async {
- var log = await runWithLogging(() {
- var completer = new Completer();
- HttpRequest.request('NonExistingFile').then(
- (_) { fail('Request should not have succeeded.'); },
- onError: expectAsync((error) {
- var xhr = error.target;
- expect(xhr.readyState, equals(HttpRequest.DONE));
- validate404(xhr);
- completer.complete('done');
- }));
- return completer.future;
- });
- expect(log, equals([
- 'request NonExistingFile',
- ' method: null withCredentials: null responseType: null '
- 'mimeType: null data: null',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success NonExistingFile with progress-event'
- ]));
- });
-
- test('XHR.request file', () async {
- var log = await runWithLogging(() {
- var completer = new Completer();
- HttpRequest.request(url).then(expectAsync((xhr) {
- expect(xhr.readyState, equals(HttpRequest.DONE));
- validate200Response(xhr);
- completer.complete('done');
- }));
- return completer.future;
- });
- expect(log, equals([
- 'request $url',
- ' method: null withCredentials: null responseType: null '
- 'mimeType: null data: null',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success $url with http-request'
- ]));
- });
-
- test('XHR.request onProgress', () async {
- var log = await runWithLogging(() {
- var completer = new Completer();
- var progressCalled = false;
- HttpRequest.request(url,
- onProgress: (_) {
- progressCalled = true;
- }).then(expectAsync(
- (xhr) {
- expect(xhr.readyState, equals(HttpRequest.DONE));
- expect(progressCalled, HttpRequest.supportsProgressEvent);
- validate200Response(xhr);
- completer.complete("done");
- }));
- return completer.future;
- });
- expect(log, equals([
- 'request $url',
- ' method: null withCredentials: null responseType: null '
- 'mimeType: null data: null',
- 'event listener on http-request progress',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success $url with http-request'
- ]));
- });
-
- test('XHR.request withCredentials No file', () async {
- var log = await runWithLogging(() {
- var completer = new Completer();
- HttpRequest.request('NonExistingFile', withCredentials: true).then(
- (_) { fail('Request should not have succeeded.'); },
- onError: expectAsync((error) {
- var xhr = error.target;
- expect(xhr.readyState, equals(HttpRequest.DONE));
- validate404(xhr);
- completer.complete("done");
- }));
- return completer.future;
- });
- expect(log, equals([
- 'request NonExistingFile',
- ' method: null withCredentials: true responseType: null '
- 'mimeType: null data: null',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success NonExistingFile with progress-event'
- ]));
- });
-
-
- test('XHR.request withCredentials file', () async {
- var log = await runWithLogging(() {
- var completer = new Completer();
- HttpRequest.request(url, withCredentials: true).then(expectAsync((xhr) {
- expect(xhr.readyState, equals(HttpRequest.DONE));
- validate200Response(xhr);
- completer.complete("done");
- }));
- return completer.future;
- });
- expect(log, equals([
- 'request $url',
- ' method: null withCredentials: true responseType: null '
- 'mimeType: null data: null',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success $url with http-request'
- ]));
- });
-
- test('XHR.getString file', () async {
- var log = await runWithLogging(() {
- return HttpRequest.getString(url).then(expectAsync((str) {}));
- });
- expect(log, equals([
- 'request $url',
- ' method: null withCredentials: null responseType: null '
- 'mimeType: null data: null',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success $url with http-request'
- ]));
- });
-
- test('XHR.getString No file', () async {
- var log = await runWithLogging(() {
- return HttpRequest.getString('NonExistingFile').then(
- (_) { fail('Succeeded for non-existing file.'); },
- onError: expectAsync((error) {
- validate404(error.target);
- }));
- });
- expect(log, equals([
- 'request NonExistingFile',
- ' method: null withCredentials: null responseType: null '
- 'mimeType: null data: null',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success NonExistingFile with progress-event'
- ]));
- });
-
- test('XHR.request responseType arraybuffer', () async {
- if (Platform.supportsTypedData) {
- var log = await runWithLogging(() {
- return HttpRequest.request(url, responseType: 'arraybuffer',
- requestHeaders: {'Content-Type': 'text/xml'}).then(
- expectAsync((xhr) {
- expect(xhr.status, equals(200));
- var byteBuffer = xhr.response;
- expect(byteBuffer, new isInstanceOf<ByteBuffer>());
- expect(byteBuffer, isNotNull);
- }));
- });
- expect(log, equals([
- 'request $url',
- ' method: null withCredentials: null responseType: arraybuffer '
- 'mimeType: null data: null',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success $url with http-request'
- ]));
- };
- });
-
- test('overrideMimeType', () async {
- var expectation =
- HttpRequest.supportsOverrideMimeType ? returnsNormally : throws;
-
- var log = await runWithLogging(() {
- var completer = new Completer();
- expect(() {
- HttpRequest.request(url, mimeType: 'application/binary')
- .whenComplete(completer.complete);
- }, expectation);
- return completer.future;
- });
- expect(log, equals([
- 'request $url',
- ' method: null withCredentials: null responseType: null '
- 'mimeType: application/binary data: null',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success $url with http-request'
- ]));
- });
-
- if (Platform.supportsTypedData) {
- test('xhr upload', () async {
- var log = await runWithLogging(() {
- var xhr = new HttpRequest();
- var progressCalled = false;
- xhr.upload.onProgress.listen((e) {
- progressCalled = true;
- });
-
- xhr.open('POST',
- '${window.location.protocol}//${window.location.host}/echo');
-
- // 10MB of payload data w/ a bit of data to make sure it
- // doesn't get compressed to nil.
- var data = new Uint8List(1 * 1024 * 1024);
- for (var i = 0; i < data.length; ++i) {
- data[i] = i & 0xFF;
- }
- xhr.send(new Uint8List.view(data.buffer));
-
- return xhr.onLoad.first.then((_) {
- expect(
- progressCalled, isTrue, reason: 'onProgress should be fired');
- });
- });
- expect(log, equals([
- 'http-request (no info), data: binary 1048576',
- 'event listener on http-request load',
- ]));
- });
- }
-
- test('xhr postFormData', () async {
- var url = '${window.location.protocol}//${window.location.host}/echo';
- var log = await runWithLogging(() {
- var data = { 'name': 'John', 'time': '2 pm'};
-
- var parts = [];
- for (var key in data.keys) {
- parts.add('${Uri.encodeQueryComponent(key)}='
- '${Uri.encodeQueryComponent(data[key])}');
- }
- var encodedData = parts.join('&');
-
- return HttpRequest.postFormData(url, data).then((xhr) {
- expect(xhr.responseText, encodedData);
- });
- });
- expect(log, equals([
- 'request $url',
- ' method: POST withCredentials: null responseType: null '
- 'mimeType: null data: name=John&time=2+pm',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success $url with http-request'
- ]));
- });
- });
-
- group('xhr_requestBlob', () {
- test('XHR.request responseType blob', () async {
- if (Platform.supportsTypedData) {
- var log = await runWithLogging(() {
- return HttpRequest.request(url, responseType: 'blob').then(
- (xhr) {
- expect(xhr.status, equals(200));
- var blob = xhr.response;
- expect(blob is Blob, isTrue);
- expect(blob, isNotNull);
- });
- });
- expect(log, equals([
- 'request $url',
- ' method: null withCredentials: null responseType: blob '
- 'mimeType: null data: null',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success $url with http-request'
- ]));
- }
- });
- });
-
- group('json', () {
- test('xhr responseType json', () async {
- var url = '${window.location.protocol}//${window.location.host}/echo';
- var log = await runWithLogging(() {
- var completer = new Completer();
- var data = {
- 'key': 'value',
- 'a': 'b',
- 'one': 2,
- };
-
- HttpRequest.request(url,
- method: 'POST',
- sendData: JSON.encode(data),
- responseType: 'json').then(
- expectAsync((xhr) {
- expect(xhr.status, equals(200));
- var json = xhr.response;
- expect(json, equals(data));
- completer.complete("done");
- }));
- return completer.future;
- });
- expect(log, equals([
- 'request $url',
- ' method: POST withCredentials: null responseType: json mimeType: null'
- ' data: {"key":"value","a":"b","one":2}',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success $url with http-request'
- ]));
- });
- });
-
- group('headers', () {
- test('xhr responseHeaders', () async {
- var log = await runWithLogging(() {
- return HttpRequest.request(url).then(
- (xhr) {
- var contentTypeHeader = xhr.responseHeaders['content-type'];
- expect(contentTypeHeader, isNotNull);
- // Should be like: 'text/plain; charset=utf-8'
- expect(contentTypeHeader.contains('text/plain'), isTrue);
- expect(contentTypeHeader.contains('charset=utf-8'), isTrue);
- });
- });
- expect(log, equals([
- 'request $url',
- ' method: null withCredentials: null responseType: null'
- ' mimeType: null data: null',
- 'event listener on http-request load',
- 'event listener on http-request error',
- 'success $url with http-request'
- ]));
- });
- });
-}
diff --git a/tests/lib/async/zone_task_test.dart b/tests/lib/async/zone_task_test.dart
deleted file mode 100644
index aa9b008..0000000
--- a/tests/lib/async/zone_task_test.dart
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright (c) 2016, 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.
-
-// Tests basic functionality of tasks in zones.
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'dart:async';
-
-List log = [];
-
-class MySpecification extends TaskSpecification {
- final Function callback;
- final bool isOneShot;
- final int value;
-
- MySpecification(void this.callback(), this.isOneShot, this.value);
-
- String get name => "test.specification-name";
-}
-
-class MyTask {
- final Zone zone;
- final Function callback;
- final int id;
- int invocationCount = 0;
- bool shouldStop = false;
-
- MyTask(this.zone, void this.callback(), this.id);
-}
-
-void runMyTask(MyTask task, int value) {
- log.add("running "
- "zone: ${Zone.current['name']} "
- "task-id: ${task.id} "
- "invocation-count: ${task.invocationCount} "
- "value: $value");
- task.callback();
- task.invocationCount++;
-}
-
-MyTask createMyTask(MySpecification spec, Zone zone) {
- var task = new MyTask(zone, spec.callback, spec.value);
- log.add("creating task: ${spec.value} oneshot?: ${spec.isOneShot}");
- if (spec.isOneShot) {
- Timer.run(() {
- zone.runTask(runMyTask, task, task.id);
- });
- } else {
- new Timer.periodic(const Duration(milliseconds: 10), (Timer timer) {
- zone.runTask(runMyTask, task, task.id);
- if (task.shouldStop) {
- timer.cancel();
- }
- });
- }
- return task;
-}
-
-MyTask startTask(f, bool oneShot, int value) {
- var spec = new MySpecification(f, oneShot, value);
- return Zone.current.createTask(createMyTask, spec);
-}
-
-/// Makes sure things are working in a simple setting.
-/// No interceptions, changes, ...
-Future testCustomTask() {
- var testCompleter = new Completer();
- asyncStart();
-
- Object createTaskHandler(Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate create, TaskSpecification specification) {
- if (specification is MySpecification) {
- log.add("create enter "
- "zone: ${self['name']} "
- "spec-value: ${specification.value} "
- "spec-oneshot?: ${specification.isOneShot}");
- MyTask result = parent.createTask(zone, create, specification);
- log.add("create leave");
- return result;
- }
- return parent.createTask(zone, create, specification);
- }
-
- void runTaskHandler(Zone self, ZoneDelegate parent, Zone zone, TaskRun run,
- Object task, Object arg) {
- if (task is MyTask) {
- log.add("run enter "
- "zone: ${self['name']} "
- "task-id: ${task.id} "
- "invocation-count: ${task.invocationCount} "
- "arg: $arg");
- parent.runTask(zone, run, task, arg);
- log.add("run leave invocation-count: ${task.invocationCount}");
- return;
- }
- parent.runTask(zone, run, task, arg);
- }
-
- runZoned(() async {
- var completer0 = new Completer();
- startTask(() {
- completer0.complete("done");
- }, true, 0);
- await completer0.future;
-
- Expect.listEquals([
- 'create enter zone: custom zone spec-value: 0 spec-oneshot?: true',
- 'creating task: 0 oneshot?: true',
- 'create leave',
- 'run enter zone: custom zone task-id: 0 invocation-count: 0 arg: 0',
- 'running zone: custom zone task-id: 0 invocation-count: 0 value: 0',
- 'run leave invocation-count: 1'
- ], log);
- log.clear();
-
- var completer1 = new Completer();
- MyTask task1;
- task1 = startTask(() {
- if (task1.invocationCount == 1) {
- task1.shouldStop = true;
- completer1.complete("done");
- }
- }, false, 1);
- await completer1.future;
-
- Expect.listEquals([
- 'create enter zone: custom zone spec-value: 1 spec-oneshot?: false',
- 'creating task: 1 oneshot?: false',
- 'create leave',
- 'run enter zone: custom zone task-id: 1 invocation-count: 0 arg: 1',
- 'running zone: custom zone task-id: 1 invocation-count: 0 value: 1',
- 'run leave invocation-count: 1',
- 'run enter zone: custom zone task-id: 1 invocation-count: 1 arg: 1',
- 'running zone: custom zone task-id: 1 invocation-count: 1 value: 1',
- 'run leave invocation-count: 2',
- ], log);
- log.clear();
-
- testCompleter.complete("done");
- asyncEnd();
- },
- zoneValues: {'name': 'custom zone'},
- zoneSpecification: new ZoneSpecification(
- createTask: createTaskHandler,
- runTask: runTaskHandler));
-
- return testCompleter.future;
-}
-
-/// More complicated zone, that intercepts...
-Future testCustomTask2() {
- var testCompleter = new Completer();
- asyncStart();
-
- Object createTaskHandler(Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate create, TaskSpecification specification) {
- if (specification is MySpecification) {
- log.add("create enter "
- "zone: ${self['name']} "
- "spec-value: ${specification.value} "
- "spec-oneshot?: ${specification.isOneShot}");
- var replacement = new MySpecification(specification.callback,
- specification.isOneShot, specification.value + 1);
- MyTask result = parent.createTask(zone, create, replacement);
- log.add("create leave");
- return result;
- }
- return parent.createTask(zone, create, specification);
- }
-
- void runTaskHandler(Zone self, ZoneDelegate parent, Zone zone, TaskRun run,
- Object task, Object arg) {
- if (task is MyTask) {
- log.add("run enter "
- "zone: ${self['name']} "
- "task-id: ${task.id} "
- "invocation-count: ${task.invocationCount} "
- "arg: $arg");
- int value = arg;
- parent.runTask(zone, run, task, value + 101);
- log.add("run leave invocation-count: ${task.invocationCount}");
- return;
- }
- parent.runTask(zone, run, task, arg);
- }
-
- runZoned(() async {
- var completer0 = new Completer();
- startTask(() {
- completer0.complete("done");
- }, true, 0);
- await completer0.future;
-
- Expect.listEquals([
- 'create enter zone: outer-zone spec-value: 0 spec-oneshot?: true',
- 'creating task: 1 oneshot?: true',
- 'create leave',
- 'run enter zone: outer-zone task-id: 1 invocation-count: 0 arg: 1',
- 'running zone: outer-zone task-id: 1 invocation-count: 0 value: 102',
- 'run leave invocation-count: 1'
- ], log);
- log.clear();
-
- var completer1 = new Completer();
- MyTask task1;
- task1 = startTask(() {
- if (task1.invocationCount == 1) {
- task1.shouldStop = true;
- completer1.complete("done");
- }
- }, false, 1);
- await completer1.future;
-
- Expect.listEquals([
- 'create enter zone: outer-zone spec-value: 1 spec-oneshot?: false',
- 'creating task: 2 oneshot?: false',
- 'create leave',
- 'run enter zone: outer-zone task-id: 2 invocation-count: 0 arg: 2',
- 'running zone: outer-zone task-id: 2 invocation-count: 0 value: 103',
- 'run leave invocation-count: 1',
- 'run enter zone: outer-zone task-id: 2 invocation-count: 1 arg: 2',
- 'running zone: outer-zone task-id: 2 invocation-count: 1 value: 103',
- 'run leave invocation-count: 2',
- ], log);
- log.clear();
-
- var nestedCompleter = new Completer();
-
- runZoned(() async {
- var completer0 = new Completer();
- startTask(() {
- completer0.complete("done");
- }, true, 0);
- await completer0.future;
-
- Expect.listEquals([
- 'create enter zone: inner-zone spec-value: 0 spec-oneshot?: true',
- 'create enter zone: outer-zone spec-value: 1 spec-oneshot?: true',
- 'creating task: 2 oneshot?: true',
- 'create leave',
- 'create leave',
- 'run enter zone: inner-zone task-id: 2 invocation-count: 0 arg: 2',
- 'run enter zone: outer-zone task-id: 2 invocation-count: 0 arg: 103',
- 'running zone: inner-zone task-id: 2 invocation-count: 0 value: 204',
- 'run leave invocation-count: 1',
- 'run leave invocation-count: 1'
- ], log);
- log.clear();
-
- var completer1 = new Completer();
- MyTask task1;
- task1 = startTask(() {
- if (task1.invocationCount == 1) {
- task1.shouldStop = true;
- completer1.complete("done");
- }
- }, false, 1);
- await completer1.future;
-
- Expect.listEquals([
- 'create enter zone: inner-zone spec-value: 1 spec-oneshot?: false',
- 'create enter zone: outer-zone spec-value: 2 spec-oneshot?: false',
- 'creating task: 3 oneshot?: false',
- 'create leave',
- 'create leave',
- 'run enter zone: inner-zone task-id: 3 invocation-count: 0 arg: 3',
- 'run enter zone: outer-zone task-id: 3 invocation-count: 0 arg: 104',
- 'running zone: inner-zone task-id: 3 invocation-count: 0 value: 205',
- 'run leave invocation-count: 1',
- 'run leave invocation-count: 1',
- 'run enter zone: inner-zone task-id: 3 invocation-count: 1 arg: 3',
- 'run enter zone: outer-zone task-id: 3 invocation-count: 1 arg: 104',
- 'running zone: inner-zone task-id: 3 invocation-count: 1 value: 205',
- 'run leave invocation-count: 2',
- 'run leave invocation-count: 2',
- ], log);
- log.clear();
-
- nestedCompleter.complete("done");
- },
- zoneValues: {'name': 'inner-zone'},
- zoneSpecification: new ZoneSpecification(
- createTask: createTaskHandler,
- runTask: runTaskHandler));
-
- await nestedCompleter.future;
- testCompleter.complete("done");
- asyncEnd();
- },
- zoneValues: {'name': 'outer-zone'},
- zoneSpecification: new ZoneSpecification(
- createTask: createTaskHandler,
- runTask: runTaskHandler));
-
- return testCompleter.future;
-}
-
-runTests() async {
- await testCustomTask();
- await testCustomTask2();
-}
-
-main() {
- asyncStart();
- runTests().then((_) {
- asyncEnd();
- });
-}
diff --git a/tests/lib/async/zone_timer_task_test.dart b/tests/lib/async/zone_timer_task_test.dart
deleted file mode 100644
index 310f7ca..0000000
--- a/tests/lib/async/zone_timer_task_test.dart
+++ /dev/null
@@ -1,515 +0,0 @@
-// Copyright (c) 2016, 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.
-
-// Tests timer tasks.
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'dart:async';
-import 'dart:collection';
-
-class MyTimerSpecification implements SingleShotTimerTaskSpecification {
- final Function callback;
- final Duration duration;
-
- MyTimerSpecification(this.callback, this.duration);
-
- bool get isOneShot => true;
- String get name => "test.timer-override";
-}
-
-class MyPeriodicTimerSpecification implements PeriodicTimerTaskSpecification {
- final Function callback;
- final Duration duration;
-
- MyPeriodicTimerSpecification(this.callback, this.duration);
-
- bool get isOneShot => true;
- String get name => "test.periodic-timer-override";
-}
-
-/// Makes sure things are working in a simple setting.
-/// No interceptions, changes, ...
-Future testTimerTask() {
- List log = [];
-
- var testCompleter = new Completer();
- asyncStart();
-
- int taskIdCounter = 0;
-
- Object createTaskHandler(Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate create, TaskSpecification specification) {
- var taskMap = self['taskMap'];
- var taskIdMap = self['taskIdMap'];
- if (specification is SingleShotTimerTaskSpecification) {
- log.add("create enter "
- "zone: ${self['name']} "
- "spec-duration: ${specification.duration} "
- "spec-oneshot?: ${specification.isOneShot}");
- var result = parent.createTask(zone, create, specification);
- taskMap[result] = specification;
- taskIdMap[specification] = taskIdCounter++;
- log.add("create leave");
- return result;
- } else if (specification is PeriodicTimerTaskSpecification) {
- log.add("create enter "
- "zone: ${self['name']} "
- "spec-duration: ${specification.duration} "
- "spec-oneshot?: ${specification.isOneShot}");
- var result = parent.createTask(zone, create, specification);
- taskMap[result] = specification;
- taskIdMap[specification] = taskIdCounter++;
- log.add("create leave");
- return result;
- }
- return parent.createTask(zone, create, specification);
- }
-
- void runTaskHandler(Zone self, ZoneDelegate parent, Zone zone, TaskRun run,
- Object task, Object arg) {
- var taskMap = self['taskMap'];
- var taskIdMap = self['taskIdMap'];
- if (taskMap.containsKey(task)) {
- var spec = taskMap[task];
- log.add("run enter "
- "zone: ${self['name']} "
- "task-id: ${taskIdMap[spec]} "
- "arg: $arg");
- parent.runTask(zone, run, task, arg);
- log.add("run leave");
- return;
- }
- parent.runTask(zone, run, task, arg);
- }
-
- runZoned(() async {
- var completer0 = new Completer();
- Timer.run(() {
- completer0.complete("done");
- });
- await completer0.future;
-
- Expect.listEquals([
- 'create enter zone: custom zone spec-duration: 0:00:00.000000 '
- 'spec-oneshot?: true',
- 'create leave',
- 'run enter zone: custom zone task-id: 0 arg: null',
- 'run leave'
- ], log);
- log.clear();
-
- var completer1 = new Completer();
- var counter1 = 0;
- new Timer.periodic(const Duration(milliseconds: 5), (Timer timer) {
- if (counter1++ > 1) {
- timer.cancel();
- completer1.complete("done");
- }
- });
- await completer1.future;
-
- Expect.listEquals([
- 'create enter zone: custom zone spec-duration: 0:00:00.005000 '
- 'spec-oneshot?: false',
- 'create leave',
- 'run enter zone: custom zone task-id: 1 arg: null',
- 'run leave',
- 'run enter zone: custom zone task-id: 1 arg: null',
- 'run leave',
- 'run enter zone: custom zone task-id: 1 arg: null',
- 'run leave'
- ], log);
- log.clear();
-
- testCompleter.complete("done");
- asyncEnd();
- },
- zoneValues: {'name': 'custom zone', 'taskMap': {}, 'taskIdMap': {}},
- zoneSpecification: new ZoneSpecification(
- createTask: createTaskHandler,
- runTask: runTaskHandler));
-
- return testCompleter.future;
-}
-
-/// More complicated zone, that intercepts...
-Future testTimerTask2() {
- List log = [];
-
- var testCompleter = new Completer();
- asyncStart();
-
- int taskIdCounter = 0;
-
- Object createTaskHandler(Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate create, TaskSpecification specification) {
- var taskMap = self['taskMap'];
- var taskIdMap = self['taskIdMap'];
- if (specification is SingleShotTimerTaskSpecification) {
- log.add("create enter "
- "zone: ${self['name']} "
- "spec-duration: ${specification.duration} "
- "spec-oneshot?: ${specification.isOneShot}");
- var mySpec = new MyTimerSpecification(specification.callback,
- specification.duration + const Duration(milliseconds: 2));
- var result = parent.createTask(zone, create, mySpec);
- taskMap[result] = specification;
- taskIdMap[specification] = taskIdCounter++;
- log.add("create leave");
- return result;
- } else if (specification is PeriodicTimerTaskSpecification) {
- log.add("create enter "
- "zone: ${self['name']} "
- "spec-duration: ${specification.duration} "
- "spec-oneshot?: ${specification.isOneShot}");
- var mySpec = new MyPeriodicTimerSpecification(specification.callback,
- specification.duration + const Duration(milliseconds: 2));
- var result = parent.createTask(zone, create, specification);
- taskMap[result] = specification;
- taskIdMap[specification] = taskIdCounter++;
- log.add("create leave");
- return result;
- }
- return parent.createTask(zone, create, specification);
- }
-
- void runTaskHandler(Zone self, ZoneDelegate parent, Zone zone, TaskRun run,
- Object task, Object arg) {
- var taskMap = self['taskMap'];
- var taskIdMap = self['taskIdMap'];
- if (taskMap.containsKey(task)) {
- var spec = taskMap[task];
- log.add("run enter "
- "zone: ${self['name']} "
- "task-id: ${taskIdMap[spec]} "
- "arg: $arg");
- parent.runTask(zone, run, task, arg);
- log.add("run leave");
- return;
- }
- parent.runTask(zone, run, task, arg);
- }
-
- runZoned(() async {
- var completer0 = new Completer();
- Timer.run(() {
- completer0.complete("done");
- });
- await completer0.future;
-
- // No visible change (except for the zone name) in the log, compared to the
- // simple invocations.
- Expect.listEquals([
- 'create enter zone: outer-zone spec-duration: 0:00:00.000000 '
- 'spec-oneshot?: true',
- 'create leave',
- 'run enter zone: outer-zone task-id: 0 arg: null',
- 'run leave'
- ], log);
- log.clear();
-
- var completer1 = new Completer();
- var counter1 = 0;
- new Timer.periodic(const Duration(milliseconds: 5), (Timer timer) {
- if (counter1++ > 1) {
- timer.cancel();
- completer1.complete("done");
- }
- });
- await completer1.future;
-
- // No visible change (except for the zone nome) in the log, compared to the
- // simple invocations.
- Expect.listEquals([
- 'create enter zone: outer-zone spec-duration: 0:00:00.005000 '
- 'spec-oneshot?: false',
- 'create leave',
- 'run enter zone: outer-zone task-id: 1 arg: null',
- 'run leave',
- 'run enter zone: outer-zone task-id: 1 arg: null',
- 'run leave',
- 'run enter zone: outer-zone task-id: 1 arg: null',
- 'run leave'
- ], log);
- log.clear();
-
- var nestedCompleter = new Completer();
-
- runZoned(() async {
- var completer0 = new Completer();
- Timer.run(() {
- completer0.complete("done");
- });
- await completer0.future;
-
- // The outer zone sees the duration change of the inner zone.
- Expect.listEquals([
- 'create enter zone: inner-zone spec-duration: 0:00:00.000000 '
- 'spec-oneshot?: true',
- 'create enter zone: outer-zone spec-duration: 0:00:00.002000 '
- 'spec-oneshot?: true',
- 'create leave',
- 'create leave',
- 'run enter zone: inner-zone task-id: 3 arg: null',
- 'run enter zone: outer-zone task-id: 2 arg: null',
- 'run leave',
- 'run leave'
- ], log);
- log.clear();
-
- var completer1 = new Completer();
- var counter1 = 0;
- new Timer.periodic(const Duration(milliseconds: 5), (Timer timer) {
- if (counter1++ > 1) {
- timer.cancel();
- completer1.complete("done");
- }
- });
- await completer1.future;
-
- // The outer zone sees the duration change of the inner zone.
- Expect.listEquals([
- 'create enter zone: inner-zone spec-duration: 0:00:00.005000 '
- 'spec-oneshot?: false',
- 'create enter zone: outer-zone spec-duration: 0:00:00.005000 '
- 'spec-oneshot?: false',
- 'create leave',
- 'create leave',
- 'run enter zone: inner-zone task-id: 5 arg: null',
- 'run enter zone: outer-zone task-id: 4 arg: null',
- 'run leave',
- 'run leave',
- 'run enter zone: inner-zone task-id: 5 arg: null',
- 'run enter zone: outer-zone task-id: 4 arg: null',
- 'run leave',
- 'run leave',
- 'run enter zone: inner-zone task-id: 5 arg: null',
- 'run enter zone: outer-zone task-id: 4 arg: null',
- 'run leave',
- 'run leave'
- ], log);
- log.clear();
-
- nestedCompleter.complete("done");
- },
- zoneValues: {'name': 'inner-zone', 'taskMap': {}, 'taskIdMap': {}},
- zoneSpecification: new ZoneSpecification(
- createTask: createTaskHandler,
- runTask: runTaskHandler));
-
- await nestedCompleter.future;
- testCompleter.complete("done");
- asyncEnd();
- },
- zoneValues: {'name': 'outer-zone', 'taskMap': {}, 'taskIdMap': {}},
- zoneSpecification: new ZoneSpecification(
- createTask: createTaskHandler,
- runTask: runTaskHandler));
-
- return testCompleter.future;
-}
-
-class TimerEntry {
- final int time;
- final SimulatedTimer timer;
-
- TimerEntry(this.time, this.timer);
-}
-
-class SimulatedTimer implements Timer {
- static int _idCounter = 0;
-
- Zone _zone;
- final int _id = _idCounter++;
- final Duration _duration;
- final Function _callback;
- final bool _isPeriodic;
- bool _isActive = true;
-
- SimulatedTimer(this._zone, this._duration, this._callback, this._isPeriodic);
-
- bool get isActive => _isActive;
-
- void cancel() {
- _isActive = false;
- }
-
- void _run() {
- if (!isActive) return;
- _zone.runTask(_runTimer, this, null);
- }
-
- static void _runTimer(SimulatedTimer timer, _) {
- if (timer._isPeriodic) {
- timer._callback(timer);
- } else {
- timer._callback();
- }
- }
-}
-
-testSimulatedTimer() {
- List log = [];
-
- var currentTime = 0;
- // Using a simple list as queue. Not very efficient, but the test has only
- // very few timers running at the same time.
- var queue = new DoubleLinkedQueue<TimerEntry>();
-
- // Schedules the given callback at now + duration.
- void schedule(int scheduledTime, SimulatedTimer timer) {
- log.add("scheduling timer ${timer._id} for $scheduledTime");
- if (queue.isEmpty) {
- queue.add(new TimerEntry(scheduledTime, timer));
- } else {
- DoubleLinkedQueueEntry current = queue.firstEntry();
- while (current != null) {
- if (current.element.time <= scheduledTime) {
- current = current.nextEntry();
- } else {
- current.prepend(new TimerEntry(scheduledTime, timer));
- break;
- }
- }
- if (current == null) {
- queue.add(new TimerEntry(scheduledTime, timer));
- }
- }
- }
-
- void runQueue() {
- while (queue.isNotEmpty) {
- var item = queue.removeFirst();
- // If multiple callbacks were scheduled at the same time, increment the
- // current time instead of staying at the same time.
- currentTime = item.time > currentTime ? item.time : currentTime + 1;
- SimulatedTimer timer = item.timer;
- log.add("running timer ${timer._id} at $currentTime "
- "(active?: ${timer.isActive})");
- if (!timer.isActive) continue;
- if (timer._isPeriodic) {
- schedule(currentTime + timer._duration.inMilliseconds, timer);
- }
- item.timer._run();
- }
- }
-
- SimulatedTimer createSimulatedOneShotTimer(
- SingleShotTimerTaskSpecification spec, Zone zone) {
- var timer = new SimulatedTimer(zone, spec.duration, spec.callback, false);
- schedule(currentTime + spec.duration.inMilliseconds, timer);
- return timer;
- }
-
- SimulatedTimer createSimulatedPeriodicTimer(
- PeriodicTimerTaskSpecification spec, Zone zone) {
- var timer = new SimulatedTimer(zone, spec.duration, spec.callback, true);
- schedule(currentTime + spec.duration.inMilliseconds, timer);
- return timer;
- }
-
- Object createSimulatedTaskHandler(Zone self, ZoneDelegate parent, Zone zone,
- TaskCreate create, TaskSpecification specification) {
- var taskMap = self['taskMap'];
- var taskIdMap = self['taskIdMap'];
- if (specification is SingleShotTimerTaskSpecification) {
- log.add("create enter "
- "zone: ${self['name']} "
- "spec-duration: ${specification.duration} "
- "spec-oneshot?: ${specification.isOneShot}");
- var result =
- parent.createTask(zone, createSimulatedOneShotTimer, specification);
- log.add("create leave");
- return result;
- }
- if (specification is PeriodicTimerTaskSpecification) {
- log.add("create enter "
- "zone: ${self['name']} "
- "spec-duration: ${specification.duration} "
- "spec-oneshot?: ${specification.isOneShot}");
- var result =
- parent.createTask(zone, createSimulatedPeriodicTimer, specification);
- log.add("create leave");
- return result;
- }
- return parent.createTask(zone, create, specification);
- }
-
- runZoned(() {
- Timer.run(() {
- log.add("running Timer.run");
- });
-
- var timer0;
-
- new Timer(const Duration(milliseconds: 10), () {
- log.add("running Timer(10)");
- timer0.cancel();
- log.add("canceled timer0");
- });
-
- timer0 = new Timer(const Duration(milliseconds: 15), () {
- log.add("running Timer(15)");
- });
-
- var counter1 = 0;
- new Timer.periodic(const Duration(milliseconds: 5), (Timer timer) {
- log.add("running periodic timer $counter1");
- if (counter1++ > 1) {
- timer.cancel();
- }
- });
- },
- zoneSpecification:
- new ZoneSpecification(createTask: createSimulatedTaskHandler));
-
- runQueue();
-
- Expect.listEquals([
- 'create enter zone: null spec-duration: 0:00:00.000000 spec-oneshot?: true',
- 'scheduling timer 0 for 0',
- 'create leave',
- 'create enter zone: null spec-duration: 0:00:00.010000 spec-oneshot?: true',
- 'scheduling timer 1 for 10',
- 'create leave',
- 'create enter zone: null spec-duration: 0:00:00.015000 spec-oneshot?: true',
- 'scheduling timer 2 for 15',
- 'create leave',
- 'create enter zone: null spec-duration: 0:00:00.005000 '
- 'spec-oneshot?: false',
- 'scheduling timer 3 for 5',
- 'create leave',
- 'running timer 0 at 1 (active?: true)',
- 'running Timer.run',
- 'running timer 3 at 5 (active?: true)',
- 'scheduling timer 3 for 10',
- 'running periodic timer 0',
- 'running timer 1 at 10 (active?: true)',
- 'running Timer(10)',
- 'canceled timer0',
- 'running timer 3 at 11 (active?: true)',
- 'scheduling timer 3 for 16',
- 'running periodic timer 1',
- 'running timer 2 at 15 (active?: false)',
- 'running timer 3 at 16 (active?: true)',
- 'scheduling timer 3 for 21',
- 'running periodic timer 2',
- 'running timer 3 at 21 (active?: false)'
- ], log);
- log.clear();
-}
-
-runTests() async {
- await testTimerTask();
- await testTimerTask2();
- testSimulatedTimer();
-}
-
-main() {
- asyncStart();
- runTests().then((_) {
- asyncEnd();
- });
-}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index ecfc10d..8d3dcee 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -167,8 +167,6 @@
async/stream_transformation_broadcast_test: RuntimeError # Timer interface not supported: Issue 7728.
async/stream_controller_test: Fail # Timer interface not supported: Issue 7728.
async/future_constructor2_test: Fail # Timer interface not supported: Issue 7728.
-async/zone_timer_task_test: Fail # Timer interface not supported: Issue 7728.
-async/zone_task_test: Fail # Timer interface not supported: Issue 7728.
mirrors/mirrors_reader_test: Skip # Running in v8 suffices. Issue 16589 - RuntimeError. Issue 22130 - Crash (out of memory).
[ $compiler == dart2js && $checked ]
diff --git a/tools/VERSION b/tools/VERSION
index e275633..261629f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 18
PATCH 0
PRERELEASE 4
-PRERELEASE_PATCH 2
+PRERELEASE_PATCH 3
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index 98455fd..123447d 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -4201,7 +4201,7 @@
" *",
" * Note: Most simple HTTP requests can be accomplished using the [getString],",
" * [request], [requestCrossOrigin], or [postFormData] methods. Use of this",
- " * `open` method is intended only for more complex HTTP requests where",
+ " * `open` method is intended only for more complext HTTP requests where",
" * finer-grained control is needed.",
" */"
],
@@ -4298,7 +4298,7 @@
" *",
" * Note: Most simple HTTP requests can be accomplished using the [getString],",
" * [request], [requestCrossOrigin], or [postFormData] methods. Use of this",
- " * `send` method is intended only for more complex HTTP requests where",
+ " * `send` method is intended only for more complext HTTP requests where",
" * finer-grained control is needed.",
" *",
" * ## Other resources",
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 3d3c410..856da50 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -402,11 +402,8 @@
'WindowTimers.setTimeout',
'Window.moveTo',
'Window.requestAnimationFrame',
- 'Window.cancelAnimationFrame',
'Window.setInterval',
'Window.setTimeout',
-
- 'XMLHttpRequest.send',
])
# Members from the standard dom that exist in the dart:html library with
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index b6c32fc..474a143 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -118,41 +118,6 @@
StreamSubscription<T> capture(void onData(T event));
}
-/// Task specification for DOM Events.
-///
-/// *Experimental*. May disappear without notice.
-class EventSubscriptionSpecification<T extends Event>
- implements TaskSpecification {
- @override
- final String name;
- @override
- final bool isOneShot;
-
- final EventTarget target;
- /// The event-type of the event. For example 'click' for click events.
- final String eventType;
- // TODO(floitsch): the first generic argument should be 'void'.
- final ZoneUnaryCallback<dynamic, T> onData;
- final bool useCapture;
-
- EventSubscriptionSpecification({this.name, this.isOneShot, this.target,
- this.eventType, void this.onData(T event), this.useCapture});
-
- /// Returns a copy of this instance, with every non-null argument replaced
- /// by the given value.
- EventSubscriptionSpecification<T> replace(
- {String name, bool isOneShot, EventTarget target,
- String eventType, void onData(T event), bool useCapture}) {
- return new EventSubscriptionSpecification<T>(
- name: name ?? this.name,
- isOneShot: isOneShot ?? this.isOneShot,
- target: target ?? this.target,
- eventType: eventType ?? this.eventType,
- onData: onData ?? this.onData,
- useCapture: useCapture ?? this.useCapture);
- }
-}
-
/**
* Adapter for exposing DOM events as Dart streams.
*/
@@ -160,16 +125,8 @@
final EventTarget _target;
final String _eventType;
final bool _useCapture;
- /// The name that is used in the task specification.
- final String _name;
- /// Whether the stream can trigger multiple times.
- final bool _isOneShot;
- _EventStream(this._target, String eventType, this._useCapture,
- {String name, bool isOneShot: false})
- : _eventType = eventType,
- _isOneShot = isOneShot,
- _name = name ?? "dart.html.event.$eventType";
+ _EventStream(this._target, this._eventType, this._useCapture);
// DOM events are inherently multi-subscribers.
Stream<T> asBroadcastStream({void onListen(StreamSubscription<T> subscription),
@@ -177,31 +134,13 @@
=> this;
bool get isBroadcast => true;
- StreamSubscription<T> _listen(
- void onData(T event), {bool useCapture}) {
-
- if (identical(Zone.current, Zone.ROOT)) {
- return new _EventStreamSubscription<T>(
- this._target, this._eventType, onData, this._useCapture,
- Zone.current);
- }
-
- var specification = new EventSubscriptionSpecification<T>(
- name: this._name, isOneShot: this._isOneShot,
- target: this._target, eventType: this._eventType,
- onData: onData, useCapture: useCapture);
- // We need to wrap the _createStreamSubscription call, since a tear-off
- // would not bind the generic type 'T'.
- return Zone.current.createTask((spec, Zone zone) {
- return _createStreamSubscription/*<T>*/(spec, zone);
- }, specification);
- }
-
StreamSubscription<T> listen(void onData(T event),
{ Function onError,
void onDone(),
bool cancelOnError}) {
- return _listen(onData, useCapture: this._useCapture);
+
+ return new _EventStreamSubscription<T>(
+ this._target, this._eventType, onData, this._useCapture);
}
}
@@ -216,9 +155,8 @@
*/
class _ElementEventStreamImpl<T extends Event> extends _EventStream<T>
implements ElementStream<T> {
- _ElementEventStreamImpl(target, eventType, useCapture,
- {String name, bool isOneShot: false}) :
- super(target, eventType, useCapture, name: name, isOneShot: isOneShot);
+ _ElementEventStreamImpl(target, eventType, useCapture) :
+ super(target, eventType, useCapture);
Stream<T> matches(String selector) => this.where(
(event) => _matchesWithAncestors(event, selector)).map((e) {
@@ -226,9 +164,9 @@
return e;
});
- StreamSubscription<T> capture(void onData(T event)) {
- return _listen(onData, useCapture: true);
- }
+ StreamSubscription<T> capture(void onData(T event)) =>
+ new _EventStreamSubscription<T>(
+ this._target, this._eventType, onData, true);
}
/**
@@ -277,13 +215,7 @@
bool get isBroadcast => true;
}
-StreamSubscription/*<T>*/ _createStreamSubscription/*<T>*/(
- EventSubscriptionSpecification/*<T>*/ spec, Zone zone) {
- return new _EventStreamSubscription/*<T>*/(spec.target, spec.eventType,
- spec.onData, spec.useCapture, zone);
-}
-
-// We would like this to just be EventListener<T> but that typedef cannot
+// We would like this to just be EventListener<T> but that typdef cannot
// use generics until dartbug/26276 is fixed.
typedef _EventListener<T extends Event>(T event);
@@ -292,19 +224,15 @@
EventTarget _target;
final String _eventType;
EventListener _onData;
- EventListener _domCallback;
final bool _useCapture;
- final Zone _zone;
// TODO(jacobr): for full strong mode correctness we should write
- // _onData = onData == null ? null : _wrapZone/*<dynamic, Event>*/((e) => onData(e as T))
+ // _onData = onData == null ? null : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
// but that breaks 114 co19 tests as well as multiple html tests as it is reasonable
// to pass the wrong type of event object to an event listener as part of a
// test.
_EventStreamSubscription(this._target, this._eventType, void onData(T event),
- this._useCapture, Zone zone)
- : _zone = zone,
- _onData = _registerZone/*<dynamic, Event>*/(zone, onData) {
+ this._useCapture) : _onData = _wrapZone/*<Event, dynamic>*/(onData) {
_tryResume();
}
@@ -326,7 +254,7 @@
}
// Remove current event listener.
_unlisten();
- _onData = _registerZone/*<dynamic, Event>*/(_zone, handleData);
+ _onData = _wrapZone/*<Event, dynamic>*/(handleData);
_tryResume();
}
@@ -355,25 +283,14 @@
}
void _tryResume() {
- if (_onData == null || isPaused) return;
- if (identical(_zone, Zone.ROOT)) {
- _domCallback = _onData;
- } else {
- _domCallback = (event) {
- _zone.runTask(_runEventNotification, this, event);
- };
+ if (_onData != null && !isPaused) {
+ _target.addEventListener(_eventType, _onData, _useCapture);
}
- _target.addEventListener(_eventType, _domCallback, _useCapture);
- }
-
- static void _runEventNotification/*<T>*/(
- _EventStreamSubscription/*<T>*/ subscription, /*=T*/ event) {
- subscription._onData(event);
}
void _unlisten() {
if (_onData != null) {
- _target.removeEventListener(_eventType, _domCallback, _useCapture);
+ _target.removeEventListener(_eventType, _onData, _useCapture);
}
}
diff --git a/tools/dom/src/shared_html.dart b/tools/dom/src/shared_html.dart
index f2c32f3..7342cdf 100644
--- a/tools/dom/src/shared_html.dart
+++ b/tools/dom/src/shared_html.dart
@@ -4,26 +4,31 @@
part of dart.dom.html;
-ZoneUnaryCallback/*<R, T>*/ _registerZone/*<R, T>*/(Zone zone,
- ZoneUnaryCallback/*<R, T>*/ callback) {
- // For performance reasons avoid registering if we are in the root zone.
- if (identical(zone, Zone.ROOT)) return callback;
- if (callback == null) return null;
- return zone.registerUnaryCallback(callback);
-}
+// TODO(jacobr): remove these typedefs when dart:async supports generic types.
+typedef R _wrapZoneCallback<A, R>(A a);
+typedef R _wrapZoneBinaryCallback<A, B, R>(A a, B b);
-ZoneUnaryCallback/*<R, T>*/ _wrapZone/*<R, T>*/(ZoneUnaryCallback/*<R, T>*/ callback) {
+_wrapZoneCallback/*<A, R>*/ _wrapZone/*<A, R>*/(_wrapZoneCallback/*<A, R>*/ callback) {
// For performance reasons avoid wrapping if we are in the root zone.
- if (identical(Zone.current, Zone.ROOT)) return callback;
+ if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
- return Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ // TODO(jacobr): we cast to _wrapZoneCallback/*<A, R>*/ to hack around missing
+ // generic method support in zones.
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneCallback/*<A, R>*/ wrapped =
+ Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ return wrapped;
}
-ZoneBinaryCallback/*<R, A, B>*/ _wrapBinaryZone/*<R, A, B>*/(
- ZoneBinaryCallback/*<R, A, B>*/ callback) {
- if (identical(Zone.current, Zone.ROOT)) return callback;
+_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
+ if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
- return Zone.current.bindBinaryCallback(callback, runGuarded: true);
+ // We cast to _wrapZoneBinaryCallback/*<A, B, R>*/ to hack around missing
+ // generic method support in zones.
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneBinaryCallback/*<A, B, R>*/ wrapped =
+ Zone.current.bindBinaryCallback(callback, runGuarded: true);
+ return wrapped;
}
/**
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index e2cdaee..8abac37 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -4,99 +4,6 @@
part of $LIBRARYNAME;
-typedef void RemoveFrameRequestMapping(int id);
-
-/**
- * The task object representing animation-frame requests.
- *
- * For historical reasons, [Window.requestAnimationFrame] returns an integer
- * to users. However, zone tasks must be unique objects, and an integer can
- * therefore not be used as task object. The [Window] class thus keeps a mapping
- * from the integer ID to the corresponding task object. All zone related
- * operations work on this task object, whereas users of
- * [Window.requestAnimationFrame] only see the integer ID.
- *
- * Since this mapping takes up space, it must be removed when the
- * animation-frame task has triggered. The default implementation does this
- * automatically, but intercepting implementations of `requestAnimationFrame`
- * must make sure to call the [AnimationFrameTask.removeMapping]
- * function that is provided in the task specification.
- *
- * *Experimental*. This class may disappear without notice.
- */
-abstract class AnimationFrameTask {
- /** The ID that is returned to users. */
- int get id;
-
- /** The zone in which the task will run. */
- Zone get zone;
-
- /**
- * Cancels the animation-frame request.
- *
- * A call to [Window.cancelAnimationFrame] with an `id` argument equal to [id]
- * forwards the request to this function.
- *
- * Zones that intercept animation-frame requests implement this method so
- * that they can react to cancelation requests.
- */
- void cancel(Window window);
-
- /**
- * Maps animation-frame request IDs to their task objects.
- */
- static final Map<int, _AnimationFrameTask> _tasks = {};
-
- /**
- * Removes the mapping from [id] to [AnimationFrameTask].
- *
- * This function must be invoked by user-implemented animation-frame
- * tasks, before running [callback].
- *
- * See [AnimationFrameTask].
- */
- static void removeMapping(int id) {
- _tasks.remove(id);
- }
-}
-
-class _AnimationFrameTask implements AnimationFrameTask {
- final int id;
- final Zone zone;
- final FrameRequestCallback _callback;
-
- _AnimationFrameTask(this.id, this.zone, this._callback);
-
- void cancel(Window window) {
- window._cancelAnimationFrame(this.id);
- }
-}
-
-/**
- * The task specification for an animation-frame request.
- *
- * *Experimental*. This class may disappear without notice.
- */
-class AnimationFrameRequestSpecification implements TaskSpecification {
- /**
- * The window on which [Window.requestAnimationFrame] was invoked.
- */
- final Window window;
-
- /**
- * The callback that is executed when the animation-frame is ready.
- *
- * Note that the callback hasn't been registered in any zone when the `create`
- * function (passed to [Zone.createTask]) is invoked.
- */
- final FrameRequestCallback callback;
-
- AnimationFrameRequestSpecification(this.window, this.callback);
-
- String get name => "dart.html.request-animation-frame";
- bool get isOneShot => true;
-}
-
@DocsEditable()
$if DART2JS
$(ANNOTATIONS)@Native("Window,DOMWindow")
@@ -122,7 +29,9 @@
*/
Future<num> get animationFrame {
var completer = new Completer<num>.sync();
- requestAnimationFrame(completer.complete);
+ requestAnimationFrame((time) {
+ completer.complete(time);
+ });
return completer.future;
}
@@ -187,8 +96,6 @@
JS('void', '#.location = #', this, value);
}
-$endif
-
/**
* Called to draw an animation frame and then request the window to repaint
* after [callback] has finished (creating the animation).
@@ -207,33 +114,8 @@
*/
@DomName('Window.requestAnimationFrame')
int requestAnimationFrame(FrameRequestCallback callback) {
-$if DART2JS
_ensureRequestAnimationFrame();
-$endif
- if (identical(Zone.current, Zone.ROOT)) {
- return _requestAnimationFrame(callback);
- }
- var spec = new AnimationFrameRequestSpecification(this, callback);
- var task = Zone.current.createTask/*<AnimationFrameTask>*/(
- _createAnimationFrameTask, spec);
- AnimationFrameTask._tasks[task.id] = task;
- return task.id;
- }
-
- static _AnimationFrameTask _createAnimationFrameTask(
- AnimationFrameRequestSpecification spec, Zone zone) {
- var task;
- var id = spec.window._requestAnimationFrame((num time) {
- AnimationFrameTask.removeMapping(task.id);
- zone.runTask(_runAnimationFrame, task, time);
- });
- var callback = zone.registerUnaryCallback(spec.callback);
- task = new _AnimationFrameTask(id, zone, callback);
- return task;
- }
-
- static void _runAnimationFrame(_AnimationFrameTask task, num time) {
- task._callback(time);
+ return _requestAnimationFrame(_wrapZone/*<num, dynamic>*/(callback));
}
/**
@@ -244,21 +126,11 @@
* * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame)
* from MDN.
*/
- @DomName('Window.cancelAnimationFrame')
void cancelAnimationFrame(int id) {
-$if DART2JS
_ensureRequestAnimationFrame();
-$endif
- var task = AnimationFrameTask._tasks.remove(id);
- if (task == null) {
- // Assume that the animation frame request wasn't intercepted by a zone.
- _cancelAnimationFrame(id);
- return;
- }
- task.cancel(this);
+ _cancelAnimationFrame(id);
}
-$if DART2JS
@JSName('requestAnimationFrame')
int _requestAnimationFrame(FrameRequestCallback callback) native;
@@ -309,6 +181,28 @@
/// The debugging console for this window.
@DomName('Window.console')
Console get console => Console._safeConsole;
+
+$else
+ /**
+ * Called to draw an animation frame and then request the window to repaint
+ * after [callback] has finished (creating the animation).
+ *
+ * Use this method only if you need to later call [cancelAnimationFrame]. If
+ * not, the preferred Dart idiom is to set animation frames by calling
+ * [animationFrame], which returns a Future.
+ *
+ * Returns a non-zero valued integer to represent the request id for this
+ * request. This value only needs to be saved if you intend to call
+ * [cancelAnimationFrame] so you can specify the particular animation to
+ * cancel.
+ *
+ * Note: The supplied [callback] needs to call [requestAnimationFrame] again
+ * for the animation to continue.
+ */
+ @DomName('Window.requestAnimationFrame')
+ int requestAnimationFrame(FrameRequestCallback callback) {
+ return _requestAnimationFrame(_wrapZone(callback));
+ }
$endif
/**
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index 35683fc..9ad00f6 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -4,109 +4,6 @@
part of $LIBRARYNAME;
-/**
- * A task specification for HTTP requests.
- *
- * This specification is not available when an HTTP request is sent through
- * direct use of [HttpRequest.send]. See [HttpRequestSendTaskSpecification].
- *
- * A task created from this specification is a `Future<HttpRequest>`.
- *
- * *Experimental*. This class may disappear without notice.
- */
-class HttpRequestTaskSpecification extends TaskSpecification {
- /// The URL of the request.
- final String url;
-
- /// The HTTP request method.
- ///
- /// By default (when `null`) this is a `"GET"` request. Alternatively, the
- /// method can be `"POST"`, `"PUT"`, `"DELETE"`, etc.
- final String method;
-
- /// Whether the request should send credentials. Credentials are only useful
- /// for cross-origin requests.
- ///
- /// See [HttpRequest.request] for more information.
- final bool withCredentials;
-
- /// The desired response format.
- ///
- /// Supported types are:
- /// - `""`: (same as `"text"`),
- /// - `"arraybuffer"`,
- /// - `"blob"`,
- /// - `"document"`,
- /// - `"json"`,
- /// - `"text"`
- ///
- /// When no value is provided (when equal to `null`) defaults to `""`.
- final String responseType;
-
- /// The desired MIME type.
- ///
- /// This overrides the default MIME type which is set up to transfer textual
- /// data.
- final String mimeType;
-
- /// The request headers that should be sent with the request.
- final Map<String, String> requestHeaders;
-
- /// The data that is sent with the request.
- ///
- /// When data is provided (the value is not `null`), it must be a
- /// [ByteBuffer], [Blob], [Document], [String], or [FormData].
- final dynamic sendData;
-
- /// The function that is invoked on progress updates. This function is
- /// registered as an event listener on the created [HttpRequest] object, and
- /// thus has its own task. Further invocations of the progress function do
- /// *not* use the HTTP request task as task object.
- ///
- /// Creating an HTTP request automatically registers the on-progress listener.
- final ZoneUnaryCallback<dynamic, ProgressEvent> onProgress;
-
- HttpRequestTaskSpecification(this.url,
- {String this.method, bool this.withCredentials, String this.responseType,
- String this.mimeType, Map<String, String> this.requestHeaders,
- this.sendData,
- void this.onProgress(ProgressEvent e)});
-
- String get name => "dart.html.http-request";
- bool get isOneShot => true;
-}
-
-/**
- * A task specification for HTTP requests that are initiated through a direct
- * invocation of [HttpRequest.send].
- *
- * This specification serves as signal to zones that an HTTP request has been
- * initiated. The created task is the [request] object itself, and
- * no callback is ever executed in this task.
- *
- * Note that event listeners on the HTTP request are also registered in the
- * zone (although with their own task creations), and that a zone can thus
- * detect when the HTTP request returns.
- *
- * HTTP requests that are initiated through `request` methods don't use
- * this class but use [HttpRequestTaskSpecification].
- *
- * *Experimental*. This class may disappear without notice.
- */
-class HttpRequestSendTaskSpecification extends TaskSpecification {
- final HttpRequest request;
- final dynamic sendData;
-
- HttpRequestSendTaskSpecification(this.request, this.sendData);
-
- String get name => "dart.html.http-request-send";
-
- /**
- * No callback is ever executed in an HTTP request send task.
- */
- bool get isOneShot => false;
-}
-
/**
* A client-side XHR request for getting data from a URL,
* formally known as XMLHttpRequest.
@@ -293,34 +190,7 @@
{String method, bool withCredentials, String responseType,
String mimeType, Map<String, String> requestHeaders, sendData,
void onProgress(ProgressEvent e)}) {
- var spec = new HttpRequestTaskSpecification(
- url, method: method,
- withCredentials: withCredentials,
- responseType: responseType,
- mimeType: mimeType,
- requestHeaders: requestHeaders,
- sendData: sendData,
- onProgress: onProgress);
-
- if (identical(Zone.current, Zone.ROOT)) {
- return _createHttpRequestTask(spec, null);
- }
- return Zone.current.createTask(_createHttpRequestTask, spec);
- }
-
- static Future<HttpRequest> _createHttpRequestTask(
- HttpRequestTaskSpecification spec, Zone zone) {
- String url = spec.url;
- String method = spec.method;
- bool withCredentials = spec.withCredentials;
- String responseType = spec.responseType;
- String mimeType = spec.mimeType;
- Map<String, String> requestHeaders = spec.requestHeaders;
- var sendData = spec.sendData;
- var onProgress = spec.onProgress;
-
var completer = new Completer<HttpRequest>();
- var task = completer.future;
var xhr = new HttpRequest();
if (method == null) {
@@ -360,42 +230,23 @@
// redirect case will be handled by the browser before it gets to us,
// so if we see it we should pass it through to the user.
var unknownRedirect = xhr.status > 307 && xhr.status < 400;
-
- var isSuccessful = accepted || fileUri || notModified || unknownRedirect;
-
- if (zone == null && isSuccessful) {
+
+ if (accepted || fileUri || notModified || unknownRedirect) {
completer.complete(xhr);
- } else if (zone == null) {
- completer.completeError(e);
- } else if (isSuccessful) {
- zone.runTask((task, value) {
- completer.complete(value);
- }, task, xhr);
} else {
- zone.runTask((task, error) {
- completer.completeError(error);
- }, task, e);
+ completer.completeError(e);
}
});
- if (zone == null) {
- xhr.onError.listen(completer.completeError);
- } else {
- xhr.onError.listen((error) {
- zone.runTask((task, error) {
- completer.completeError(error);
- }, task, error);
- });
- }
+ xhr.onError.listen(completer.completeError);
if (sendData != null) {
- // TODO(floitsch): should we go through 'send()' and have nested tasks?
- xhr._send(sendData);
+ xhr.send(sendData);
} else {
- xhr._send();
+ xhr.send();
}
- return task;
+ return completer.future;
}
/**
@@ -465,9 +316,6 @@
return xhr.responseText;
});
}
- // TODO(floitsch): the following code doesn't go through task zones.
- // Since 'XDomainRequest' is an IE9 feature we should probably just remove
- // it.
$if DART2JS
var completer = new Completer<String>();
if (method == null) {
@@ -548,7 +396,7 @@
*
* Note: Most simple HTTP requests can be accomplished using the [getString],
* [request], [requestCrossOrigin], or [postFormData] methods. Use of this
- * `open` method is intended only for more complex HTTP requests where
+ * `open` method is intended only for more complext HTTP requests where
* finer-grained control is needed.
*/
@DomName('XMLHttpRequest.open')
@@ -565,35 +413,5 @@
void open(String method, String url, {bool async, String user, String password}) native;
$endif
- /**
- * Sends the request with any given `data`.
- *
- * Note: Most simple HTTP requests can be accomplished using the [getString],
- * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
- * `send` method is intended only for more complex HTTP requests where
- * finer-grained control is needed.
- *
- * ## Other resources
- *
- * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
- * from MDN.
- */
- @DomName('XMLHttpRequest.send')
- @DocsEditable()
- void send([body_OR_data]) {
- if (identical(Zone.current, Zone.ROOT)) {
- _send(body_OR_data);
- } else {
- Zone.current.createTask(_createHttpRequestSendTask,
- new HttpRequestSendTaskSpecification(this, body_OR_data));
- }
- }
-
- static HttpRequest _createHttpRequestSendTask(
- HttpRequestSendTaskSpecification spec, Zone zone) {
- spec.request._send(spec.sendData);
- return spec.request;
- }
-
$!MEMBERS
}