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

Side by Side Diff: tools/dom/src/Microtask.dart

Issue 27441002: Removing setImmediate and hiding WindowTimers interface (take 2) (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: The fix Created 7 years, 2 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of html;
6
7 typedef void _MicrotaskCallback();
8
9 /**
10 * This class attempts to invoke a callback as soon as the current event stack
11 * unwinds, but before the browser repaints.
12 */
13 abstract class _MicrotaskScheduler {
14 bool _nextMicrotaskFrameScheduled = false;
15 final _MicrotaskCallback _callback;
16
17 _MicrotaskScheduler(this._callback);
18
19 /**
20 * Creates the best possible microtask scheduler for the current platform.
21 */
22 factory _MicrotaskScheduler.best(_MicrotaskCallback callback) {
23 if (Window._supportsSetImmediate) {
24 return new _SetImmediateScheduler(callback);
25 } else if (MutationObserver.supported) {
26 return new _MutationObserverScheduler(callback);
27 }
28 return new _PostMessageScheduler(callback);
29 }
30
31 /**
32 * Schedules a microtask callback if one has not been scheduled already.
33 */
34 void maybeSchedule() {
35 if (this._nextMicrotaskFrameScheduled) {
36 return;
37 }
38 this._nextMicrotaskFrameScheduled = true;
39 this._schedule();
40 }
41
42 /**
43 * Does the actual scheduling of the callback.
44 */
45 void _schedule();
46
47 /**
48 * Handles the microtask callback and forwards it if necessary.
49 */
50 void _onCallback() {
51 // Ignore spurious messages.
52 if (!_nextMicrotaskFrameScheduled) {
53 return;
54 }
55 _nextMicrotaskFrameScheduled = false;
56 this._callback();
57 }
58 }
59
60 /**
61 * Scheduler which uses window.postMessage to schedule events.
62 */
63 class _PostMessageScheduler extends _MicrotaskScheduler {
64 final _MICROTASK_MESSAGE = "DART-MICROTASK";
65
66 _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
67 // Messages from other windows do not cause a security risk as
68 // all we care about is that _handleMessage is called
69 // after the current event loop is unwound and calling the function is
70 // a noop when zero requests are pending.
71 window.onMessage.listen(this._handleMessage);
72 }
73
74 void _schedule() {
75 window.postMessage(_MICROTASK_MESSAGE, "*");
76 }
77
78 void _handleMessage(e) {
79 this._onCallback();
80 }
81 }
82
83 /**
84 * Scheduler which uses a MutationObserver to schedule events.
85 */
86 class _MutationObserverScheduler extends _MicrotaskScheduler {
87 MutationObserver _observer;
88 Element _dummy;
89
90 _MutationObserverScheduler(_MicrotaskCallback callback): super(callback) {
91 // Mutation events get fired as soon as the current event stack is unwound
92 // so we just make a dummy event and listen for that.
93 _observer = new MutationObserver(this._handleMutation);
94 _dummy = new DivElement();
95 _observer.observe(_dummy, attributes: true);
96 }
97
98 void _schedule() {
99 // Toggle it to trigger the mutation event.
100 _dummy.hidden = !_dummy.hidden;
101 }
102
103 _handleMutation(List<MutationRecord> mutations, MutationObserver observer) {
104 this._onCallback();
105 }
106 }
107
108 /**
109 * Scheduler which uses window.setImmediate to schedule events.
110 */
111 class _SetImmediateScheduler extends _MicrotaskScheduler {
112 _SetImmediateScheduler(_MicrotaskCallback callback): super(callback);
113
114 void _schedule() {
115 window._setImmediate(_handleImmediate);
116 }
117
118 void _handleImmediate() {
119 this._onCallback();
120 }
121 }
122
123 List<TimeoutHandler> _pendingMicrotasks;
124 _MicrotaskScheduler _microtaskScheduler = null;
125
126 void _maybeScheduleMicrotaskFrame() {
127 if (_microtaskScheduler == null) {
128 _microtaskScheduler =
129 new _MicrotaskScheduler.best(_completeMicrotasks);
130 }
131 _microtaskScheduler.maybeSchedule();
132 }
133
134 /**
135 * Registers a [callback] which is called after the current execution stack
136 * unwinds.
137 */
138 void _addMicrotaskCallback(TimeoutHandler callback) {
139 if (_pendingMicrotasks == null) {
140 _pendingMicrotasks = <TimeoutHandler>[];
141 _maybeScheduleMicrotaskFrame();
142 }
143 _pendingMicrotasks.add(callback);
144 }
145
146
147 /**
148 * Complete all pending microtasks.
149 */
150 void _completeMicrotasks() {
151 var callbacks = _pendingMicrotasks;
152 _pendingMicrotasks = null;
153 for (var callback in callbacks) {
154 callback();
155 }
156 }
OLDNEW
« no previous file with comments | « tools/dom/scripts/htmlrenamer.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