Index: sdk/lib/html/dartium/html_dartium.dart |
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart |
index bc92d6dc423011f9620a4c0f04c23a2adbd7ef9e..21ea0327aaf6b0fa19d09f61326da95028af7a74 100644 |
--- a/sdk/lib/html/dartium/html_dartium.dart |
+++ b/sdk/lib/html/dartium/html_dartium.dart |
@@ -37662,10 +37662,10 @@ class Url extends DartHtmlDomObject implements UrlUtils { |
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 MediaStream)) { |
+ if ((blob_OR_source_OR_stream is MediaSource)) { |
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); |
} |
throw new ArgumentError("Incorrect number or type of arguments"); |
@@ -44492,6 +44492,41 @@ abstract class ElementStream<T extends Event> implements Stream<T> { |
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. |
*/ |
@@ -44499,8 +44534,16 @@ class _EventStream<T extends Event> extends Stream<T> { |
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, this._eventType, this._useCapture); |
+ _EventStream(this._target, String eventType, this._useCapture, |
+ {String name, bool isOneShot: false}) |
+ : _eventType = eventType, |
+ _isOneShot = isOneShot, |
+ _name = name ?? "dart.html.event.$eventType"; |
// DOM events are inherently multi-subscribers. |
Stream<T> asBroadcastStream({void onListen(StreamSubscription<T> subscription), |
@@ -44508,13 +44551,31 @@ class _EventStream<T extends Event> extends Stream<T> { |
=> 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 new _EventStreamSubscription<T>( |
- this._target, this._eventType, onData, this._useCapture); |
+ return _listen(onData, useCapture: this._useCapture); |
} |
} |
@@ -44529,8 +44590,9 @@ bool _matchesWithAncestors(Event event, String selector) { |
*/ |
class _ElementEventStreamImpl<T extends Event> extends _EventStream<T> |
implements ElementStream<T> { |
- _ElementEventStreamImpl(target, eventType, useCapture) : |
- super(target, eventType, useCapture); |
+ _ElementEventStreamImpl(target, eventType, useCapture, |
+ {String name, bool isOneShot: false}) : |
+ super(target, eventType, useCapture, name: name, isOneShot: isOneShot); |
Stream<T> matches(String selector) => this.where( |
(event) => _matchesWithAncestors(event, selector)).map((e) { |
@@ -44538,9 +44600,9 @@ class _ElementEventStreamImpl<T extends Event> extends _EventStream<T> |
return e; |
}); |
- StreamSubscription<T> capture(void onData(T event)) => |
- new _EventStreamSubscription<T>( |
- this._target, this._eventType, onData, true); |
+ StreamSubscription<T> capture(void onData(T event)) { |
+ return _listen(onData, useCapture: true); |
+ } |
} |
/** |
@@ -44589,7 +44651,13 @@ class _ElementListEventStreamImpl<T extends Event> extends Stream<T> |
bool get isBroadcast => true; |
} |
-// We would like this to just be EventListener<T> but that typdef cannot |
+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 |
// use generics until dartbug/26276 is fixed. |
typedef _EventListener<T extends Event>(T event); |
@@ -44598,15 +44666,19 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> { |
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/*<Event, dynamic>*/((e) => onData(e as T)) |
+ // _onData = onData == null ? null : _wrapZone/*<dynamic, Event>*/((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) : _onData = _wrapZone/*<Event, dynamic>*/(onData) { |
+ this._useCapture, Zone zone) |
+ : _zone = zone, |
+ _onData = _registerZone/*<dynamic, Event>*/(zone, onData) { |
_tryResume(); |
} |
@@ -44628,7 +44700,7 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> { |
} |
// Remove current event listener. |
_unlisten(); |
- _onData = _wrapZone/*<Event, dynamic>*/(handleData); |
+ _onData = _registerZone/*<dynamic, Event>*/(_zone, handleData); |
_tryResume(); |
} |
@@ -44657,14 +44729,25 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> { |
} |
void _tryResume() { |
- if (_onData != null && !isPaused) { |
- _target.addEventListener(_eventType, _onData, _useCapture); |
+ if (_onData == null || isPaused) return; |
+ if (identical(_zone, Zone.ROOT)) { |
+ _domCallback = _onData; |
+ } else { |
+ _domCallback = (event) { |
+ _zone.runTask(_runEventNotification, this, event); |
+ }; |
} |
+ _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, _onData, _useCapture); |
+ _target.removeEventListener(_eventType, _domCallback, _useCapture); |
} |
} |
@@ -47856,31 +47939,26 @@ class _WrappedEvent implements Event { |
// BSD-style license that can be found in the LICENSE file. |
-// 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>*/ _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); |
+} |
-_wrapZoneCallback/*<A, R>*/ _wrapZone/*<A, R>*/(_wrapZoneCallback/*<A, R>*/ callback) { |
+ZoneUnaryCallback/*<R, T>*/ _wrapZone/*<R, T>*/(ZoneUnaryCallback/*<R, T>*/ callback) { |
// For performance reasons avoid wrapping if we are in the root zone. |
- if (Zone.current == Zone.ROOT) return callback; |
+ if (identical(Zone.current, Zone.ROOT)) return callback; |
if (callback == null) return null; |
- // 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; |
+ return Zone.current.bindUnaryCallback(callback, runGuarded: true); |
} |
-_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) { |
- if (Zone.current == Zone.ROOT) return callback; |
+ZoneBinaryCallback/*<R, A, B>*/ _wrapBinaryZone/*<R, A, B>*/( |
+ ZoneBinaryCallback/*<R, A, B>*/ callback) { |
+ if (identical(Zone.current, Zone.ROOT)) return callback; |
if (callback == null) return null; |
- // 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; |
+ return Zone.current.bindBinaryCallback(callback, runGuarded: true); |
} |
/** |