Chromium Code Reviews| 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..18a63891f2d6c4b48b1736f9034561b52f5e5c13 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)) { |
|
floitsch
2016/05/31 19:27:49
This file is automatically generated.
|
| + 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"); |
| @@ -44493,14 +44493,54 @@ abstract class ElementStream<T extends Event> implements Stream<T> { |
| } |
| /** |
| + * Task specification for Dom Events. |
| + */ |
| +class EventSubscriptionSpecification<T extends Event> |
| + implements TaskSpecification { |
| + final String name; |
| + final bool isOneShot; |
| + |
| + final EventTarget target; |
| + 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. |
| */ |
| 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), |
| @@ -44513,8 +44553,21 @@ class _EventStream<T extends Event> extends Stream<T> { |
| void onDone(), |
| bool cancelOnError}) { |
| - return new _EventStreamSubscription<T>( |
| - this._target, this._eventType, onData, this._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: this._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); |
| } |
| } |
| @@ -44529,8 +44582,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 +44592,23 @@ 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)) { |
| + |
| + if (identical(Zone.current, Zone.ROOT)) { |
| + return new _EventStreamSubscription<T>( |
| + this._target, this._eventType, onData, true, Zone.current); |
| + } |
| + |
| + var specification = new EventSubscriptionSpecification<T>( |
| + name: this._name, isOneShot: this._isOneShot, |
| + target: this._target, eventType: this._eventtype, |
| + onData: onData, useCapture: true); |
| + // 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); |
| + } |
| } |
| /** |
| @@ -44589,7 +44657,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 +44672,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(); |
| } |
| @@ -44617,6 +44695,7 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> { |
| // Clear out the target to indicate this is complete. |
| _target = null; |
| _onData = null; |
| + if (!identical(_zone, Zone.ROOT)) _zone.cancelTask(this); |
| return null; |
| } |
| @@ -44628,7 +44707,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 +44736,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 +47946,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 (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 (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) { |
| +ZoneBinaryCallback/*<R, A, B>*/ _wrapBinaryZone/*<R, A, B>*/( |
| + ZoneBinaryCallback/*<R, A, B>*/ callback) { |
| if (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); |
| } |
| /** |