Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Unified Diff: tools/dom/src/EventStreamProvider.dart

Issue 11824072: Adding streams to dart:html. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Review feedback Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/dom/scripts/systemhtml.py ('k') | tools/dom/templates/html/dart2js/html_dart2js.darttemplate » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/dom/src/EventStreamProvider.dart
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
new file mode 100644
index 0000000000000000000000000000000000000000..9c52a5dd7241f2f03d9b9c863e89c67b7fb64186
--- /dev/null
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2013, 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.
+
+part of html;
+
+/**
+ * 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;
+
+ _EventStream(this._target, this._eventType, this._useCapture);
+
+ // DOM events are inherently multi-subscribers.
+ Stream<T> asMultiSubscriberStream() => this;
+
+ StreamSubscription<T> listen(void onData(T event),
+ { void onError(AsyncError error),
+ void onDone(),
+ bool unsubscribeOnError}) {
+
+ return new _EventStreamSubscription<T>(
+ this._target, this._eventType, onData, this._useCapture);
+ }
+}
+
+class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
+ int _pauseCount = 0;
+ EventTarget _target;
+ final String _eventType;
+ var _onData;
+ final bool _useCapture;
+
+ _EventStreamSubscription(this._target, this._eventType, this._onData,
+ this._useCapture) {
+ _tryResume();
+ }
+
+ void cancel() {
+ if (_canceled) {
+ throw new StateError("Subscription has been canceled.");
+ }
+
+ _unlisten();
+ // Clear out the target to indicate this is complete.
+ _target = null;
+ _onData = null;
+ }
+
+ bool get _canceled => _target == null;
+
+ void onData(void handleData(T event)) {
+ if (_canceled) {
+ throw new StateError("Subscription has been canceled.");
+ }
+ // Remove current event listener.
+ _unlisten();
+
+ _onData = handleData;
+ _tryResume();
+ }
+
+ /// Has no effect.
+ void onError(void handleError(AsyncError error)) {}
+
+ /// Has no effect.
+ void onDone(void handleDone()) {}
+
+ void pause([Future resumeSignal]) {
+ if (_canceled) {
+ throw new StateError("Subscription has been canceled.");
+ }
+ ++_pauseCount;
+ _unlisten();
+
+ if (resumeSignal != null) {
+ resumeSignal.whenComplete(resume);
+ }
+ }
+
+ bool get _paused => _pauseCount > 0;
+
+ void resume() {
+ if (_canceled) {
+ throw new StateError("Subscription has been canceled.");
+ }
+ if (!_paused) {
+ throw new StateError("Subscription is not paused.");
+ }
+ --_pauseCount;
+ _tryResume();
+ }
+
+ void _tryResume() {
+ if (_onData != null && !_paused) {
+ _target.$dom_addEventListener(_eventType, _onData, _useCapture);
+ }
+ }
+
+ void _unlisten() {
+ if (_onData != null) {
+ _target.$dom_removeEventListener(_eventType, _onData, _useCapture);
+ }
+ }
+}
+
+
+/**
+ * A factory to expose DOM events as Streams.
+ */
+class EventStreamProvider<T extends Event> {
+ final String _eventType;
+
+ const EventStreamProvider(this._eventType);
+
+ /**
+ * Gets a [Stream] for this event type, on the specified target.
+ *
+ * This may be used to capture DOM events:
+ *
+ * Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
+ *
+ * Or for listening to an event which will bubble through the DOM tree:
+ *
+ * MediaElement.pauseEvent.forTarget(document.body).listen(...);
+ *
+ * See also:
+ *
+ * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
+ */
+ Stream<T> forTarget(EventTarget e, {bool useCapture: false}) {
+ return new _EventStream(e, _eventType, useCapture);
+ }
+}
« no previous file with comments | « tools/dom/scripts/systemhtml.py ('k') | tools/dom/templates/html/dart2js/html_dart2js.darttemplate » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698