From d7057b2d8c75938e8b76536c3605b66471b9f8d8 Mon Sep 17 00:00:00 2001 From: "efortuna@google.com" Date: Fri, 15 Feb 2013 07:40:51 +0000 Subject: [PATCH] Reapply setTimeout change. This CL is identical to 18555. The reason it will work now is the corresponding dartium change has been checked in. TBR-blois BUG= Review URL: https://codereview.chromium.org//12254046 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@18562 260f80e4-7a28-3924-810f-c04153c831b5 --- sdk/lib/html/dart2js/html_dart2js.dart | 109 ++++++++++++------ sdk/lib/html/dartium/html_dartium.dart | 51 +++++--- tests/benchmark_smoke/benchmark_base.dart | 23 ++-- tests/benchmark_smoke/benchmark_lib.dart | 1 + .../benchmark_smoke/benchmark_smoke_test.dart | 7 +- tests/html/async_window_test.dart | 39 ++++--- tests/html/cssstyledeclaration_test.dart | 5 +- tests/html/dromaeo_noop/dromaeo_smoke.dart | 1 + tests/html/history_test.dart | 5 +- tests/html/js_interop_3_test.dart | 3 +- tests/html/js_interop_4_test.dart | 3 +- tests/html/microtask_test.dart | 5 +- tests/html/transition_event_test.dart | 5 +- tests/html/window_open_test.dart | 5 +- tools/dom/scripts/htmlrenamer.py | 4 + tools/dom/src/Timer.dart | 8 +- .../html/dartium/impl_Window.darttemplate | 47 -------- .../impl_Window.darttemplate | 103 ++++++++++++----- 18 files changed, 254 insertions(+), 170 deletions(-) delete mode 100644 tools/dom/templates/html/dartium/impl_Window.darttemplate rename tools/dom/templates/html/{dart2js => impl}/impl_Window.darttemplate (71%) diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart index 257d672c0d0..8688fea5cc4 100644 --- a/sdk/lib/html/dart2js/html_dart2js.dart +++ b/sdk/lib/html/dart2js/html_dart2js.dart @@ -25826,6 +25826,56 @@ class WheelEvent extends MouseEvent native "*WheelEvent" { @DomName('Window') class Window extends EventTarget implements WindowBase native "@*DOMWindow" { + /** + * Executes a [callback] after the immediate execution stack has completed. + * + * This differs from using Timer.run(callback) + * because Timer will run in about 4-15 milliseconds, depending on browser, + * depending on load. [setImmediate], in contrast, makes browser-specific + * changes in behavior to attempt to run immediately after the current + * frame unwinds, causing the future to complete after all processing has + * completed for the current event, but before any subsequent events. + */ + void setImmediate(TimeoutHandler callback) { + _addMicrotaskCallback(callback); + } + /** + * Lookup a port by its [name]. Return null if no port is + * registered under [name]. + */ + SendPortSync lookupPort(String name) { + var port = + json.parse(document.documentElement.attributes['dart-port:$name']); + return _deserialize(port); + } + + /** + * Register a [port] on this window under the given [name]. This + * port may be retrieved by any isolate (or JavaScript script) + * running in this window. + */ + void registerPort(String name, var port) { + var serialized = _serialize(port); + document.documentElement.attributes['dart-port:$name'] = + json.stringify(serialized); + } + + /** + * Returns a Future that completes just before the window is about to repaint + * so the user can draw an animation frame + * + * If you need to later cancel this animation, use [requestAnimationFrame] + * instead. + * + * Note: The code that runs when the future completes should call + * [animationFrame] again for the animation to continue. + */ + Future get animationFrame { + var completer = new Completer(); + requestAnimationFrame(completer.complete); + return completer.future; + } + Document get document => JS('Document', '#.document', this); WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name); @@ -25891,15 +25941,21 @@ class Window extends EventTarget implements WindowBase native "@*DOMWindow" { } /** - * Executes a [callback] after the immediate execution stack has completed. + * Called to draw an animation frame and then request the window to repaint + * after [callback] has finished (creating the animation). * - * This will cause the callback to be executed after all processing has - * completed for the current event, but before any subsequent events. + * 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. */ - void setImmediate(TimeoutHandler callback) { - _addMicrotaskCallback(callback); - } - @DomName('DOMWindow.requestAnimationFrame') int requestAnimationFrame(RequestAnimationFrameCallback callback) { _ensureRequestAnimationFrame(); @@ -25958,25 +26014,6 @@ class Window extends EventTarget implements WindowBase native "@*DOMWindow" { '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB', this, this, this); - /** - * Lookup a port by its [name]. Return null if no port is - * registered under [name]. - */ - SendPortSync lookupPort(String name) { - var port = json.parse(document.documentElement.attributes['dart-port:$name']); - return _deserialize(port); - } - - /** - * Register a [port] on this window under the given [name]. This - * port may be retrieved by any isolate (or JavaScript script) - * running in this window. - */ - void registerPort(String name, var port) { - var serialized = _serialize(port); - document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized); - } - @DomName('Window.console') Console get console => Console.safeConsole; @@ -26295,13 +26332,15 @@ class Window extends EventTarget implements WindowBase native "@*DOMWindow" { @DocsEditable void captureEvents() native; + @JSName('clearInterval') @DomName('DOMWindow.clearInterval') @DocsEditable - void clearInterval(int handle) native; + void _clearInterval(int handle) native; + @JSName('clearTimeout') @DomName('DOMWindow.clearTimeout') @DocsEditable - void clearTimeout(int handle) native; + void _clearTimeout(int handle) native; @DomName('DOMWindow.close') @DocsEditable @@ -26413,13 +26452,15 @@ class Window extends EventTarget implements WindowBase native "@*DOMWindow" { @DocsEditable void scrollTo(int x, int y) native; + @JSName('setInterval') @DomName('DOMWindow.setInterval') @DocsEditable - int setInterval(TimeoutHandler handler, int timeout) native; + int _setInterval(TimeoutHandler handler, int timeout) native; + @JSName('setTimeout') @DomName('DOMWindow.setTimeout') @DocsEditable - int setTimeout(TimeoutHandler handler, int timeout) native; + int _setTimeout(TimeoutHandler handler, int timeout) native; @DomName('DOMWindow.showModalDialog') @DocsEditable @@ -31416,11 +31457,11 @@ get _timerFactoryClosure => (int milliSeconds, void callback(Timer timer), bool var maker; var canceller; if (repeating) { - maker = window.setInterval; - canceller = window.clearInterval; + maker = window._setInterval; + canceller = window._clearInterval; } else { - maker = window.setTimeout; - canceller = window.clearTimeout; + maker = window._setTimeout; + canceller = window._clearTimeout; } Timer timer; final int id = maker(() { callback(timer); }, milliSeconds); diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart index 3aefe46a5cf..ff4665549c5 100644 --- a/sdk/lib/html/dartium/html_dartium.dart +++ b/sdk/lib/html/dartium/html_dartium.dart @@ -28225,19 +28225,23 @@ class Window extends EventTarget implements WindowBase { /** * Executes a [callback] after the immediate execution stack has completed. * - * This will cause the callback to be executed after all processing has + * This differs from using Timer.run(callback) + * because Timer will run in about 4-15 milliseconds, depending on browser, + * depending on load. [setImmediate], in contrast, makes browser-specific + * changes in behavior to attempt to run immediately after the current + * frame unwinds, causing the future to complete after all processing has * completed for the current event, but before any subsequent events. */ - void setImmediate(TimeoutHandler callback) { + void setImmediate(TimeoutHandler callback) { _addMicrotaskCallback(callback); } - /** * Lookup a port by its [name]. Return null if no port is * registered under [name]. */ - lookupPort(String name) { - var port = json.parse(document.documentElement.attributes['dart-port:$name']); + SendPortSync lookupPort(String name) { + var port = + json.parse(document.documentElement.attributes['dart-port:$name']); return _deserialize(port); } @@ -28246,9 +28250,26 @@ class Window extends EventTarget implements WindowBase { * port may be retrieved by any isolate (or JavaScript script) * running in this window. */ - registerPort(String name, var port) { + void registerPort(String name, var port) { var serialized = _serialize(port); - document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized); + document.documentElement.attributes['dart-port:$name'] = + json.stringify(serialized); + } + + /** + * Returns a Future that completes just before the window is about to repaint + * so the user can draw an animation frame + * + * If you need to later cancel this animation, use [requestAnimationFrame] + * instead. + * + * Note: The code that runs when the future completes should call + * [animationFrame] again for the animation to continue. + */ + Future get animationFrame { + var completer = new Completer(); + requestAnimationFrame(completer.complete); + return completer.future; } /// Checks if _setImmediate is supported. @@ -28589,11 +28610,11 @@ class Window extends EventTarget implements WindowBase { @DomName('DOMWindow.clearInterval') @DocsEditable - void clearInterval(int handle) native "DOMWindow_clearInterval_Callback"; + void _clearInterval(int handle) native "DOMWindow_clearInterval_Callback"; @DomName('DOMWindow.clearTimeout') @DocsEditable - void clearTimeout(int handle) native "DOMWindow_clearTimeout_Callback"; + void _clearTimeout(int handle) native "DOMWindow_clearTimeout_Callback"; @DomName('DOMWindow.close') @DocsEditable @@ -28688,11 +28709,11 @@ class Window extends EventTarget implements WindowBase { @DomName('DOMWindow.setInterval') @DocsEditable - int setInterval(TimeoutHandler handler, int timeout) native "DOMWindow_setInterval_Callback"; + int _setInterval(TimeoutHandler handler, int timeout) native "DOMWindow_setInterval_Callback"; @DomName('DOMWindow.setTimeout') @DocsEditable - int setTimeout(TimeoutHandler handler, int timeout) native "DOMWindow_setTimeout_Callback"; + int _setTimeout(TimeoutHandler handler, int timeout) native "DOMWindow_setTimeout_Callback"; @DomName('DOMWindow.showModalDialog') @DocsEditable @@ -33885,11 +33906,11 @@ get _timerFactoryClosure => (int milliSeconds, void callback(Timer timer), bool var maker; var canceller; if (repeating) { - maker = window.setInterval; - canceller = window.clearInterval; + maker = window._setInterval; + canceller = window._clearInterval; } else { - maker = window.setTimeout; - canceller = window.clearTimeout; + maker = window._setTimeout; + canceller = window._clearTimeout; } Timer timer; final int id = maker(() { callback(timer); }, milliSeconds); diff --git a/tests/benchmark_smoke/benchmark_base.dart b/tests/benchmark_smoke/benchmark_base.dart index e2699cd9030..6b724c11d7d 100644 --- a/tests/benchmark_smoke/benchmark_base.dart +++ b/tests/benchmark_smoke/benchmark_base.dart @@ -94,7 +94,7 @@ class BenchmarkBase { class BenchmarkSuite { /** The set of benchmarks that have yet to run. */ List benchmarks; - + /** * The set of scores from the benchmarks that have already run. (Used for * calculating the Geometric mean). @@ -112,15 +112,15 @@ class BenchmarkSuite { benchmarks = [() => Smoketest.main()]; totalBenchmarks = benchmarks.length; } - + /** Run all of the benchmarks that we have in our benchmarks list. */ runBenchmarks() { runBenchmarksHelper(benchmarks); } - + /** * Run the remaining benchmarks in our list. We chain the calls providing - * little breaks for the main page to gain control, so we don't force the + * little breaks for the main page to gain control, so we don't force the * entire page to hang the whole time. */ runBenchmarksHelper(List remainingBenchmarks) { @@ -128,10 +128,11 @@ class BenchmarkSuite { var benchmark = remainingBenchmarks.removeLast(); benchmark(); if (remainingBenchmarks.length > 0) { - /* Provide small breaks between each benchmark, so that the browser + /* Provide small breaks between each benchmark, so that the browser doesn't get unhappy about long running scripts, and so the user can regain control of the UI to kill the page as needed. */ - window.setTimeout(() => runBenchmarksHelper(remainingBenchmarks), 25); + new Timer(const Duration(milliseconds: 25), + () => runBenchmarksHelper(remainingBenchmarks)); } else if (remainingBenchmarks.length == 0) { // We've run all of the benchmarks. Update the page with the score. BENCHMARK_VIEW.setScore(geometricMean(scores)); @@ -140,7 +141,7 @@ class BenchmarkSuite { /** Store the results of a single benchmark run. */ updateIndividualScore(String name, num score) { - scores.add(score); + scores.add(score); BENCHMARK_VIEW.incrementProgress(name, score, totalBenchmarks); } @@ -172,9 +173,9 @@ class BenchmarkView { body.nodes.add( new Element.html("

Score: $newScore

")); } - + /** - * Update the page HTML to show how much progress we've made through the + * Update the page HTML to show how much progress we've made through the * benchmarks. */ incrementProgress(String name, num score, num totalBenchmarks) { @@ -184,8 +185,8 @@ class BenchmarkView { // the user we're making progress. num percentage = 100 * numCompleted ~/ totalBenchmarks; } - - /** + + /** * Rounds the score to have at least three significant digits (hopefully) * helping readability of the scores. */ diff --git a/tests/benchmark_smoke/benchmark_lib.dart b/tests/benchmark_smoke/benchmark_lib.dart index 33233adc8ad..4171b28e442 100644 --- a/tests/benchmark_smoke/benchmark_lib.dart +++ b/tests/benchmark_smoke/benchmark_lib.dart @@ -4,6 +4,7 @@ library benchmark_lib; +import 'dart:async'; import 'dart:html'; import 'dart:math' as Math; diff --git a/tests/benchmark_smoke/benchmark_smoke_test.dart b/tests/benchmark_smoke/benchmark_smoke_test.dart index 2c46a48544c..2e458276737 100644 --- a/tests/benchmark_smoke/benchmark_smoke_test.dart +++ b/tests/benchmark_smoke/benchmark_smoke_test.dart @@ -6,6 +6,7 @@ library benchmarksmoketest; // Tests that benchmark classes used in perf testing are not broken. import 'benchmark_lib.dart'; +import 'dart:async'; import 'dart:html'; import '../../pkg/unittest/lib/unittest.dart'; import '../../pkg/unittest/lib/html_config.dart'; @@ -13,9 +14,9 @@ import '../../pkg/unittest/lib/html_config.dart'; void main() { useHtmlConfiguration(); - test('performanceTesting', () { - window.setTimeout(BENCHMARK_SUITE.runBenchmarks, 0); - window.setTimeout(expectAsync0(testForCompletion), 0); + test('performanceTesting', () { + Timer.run(BENCHMARK_SUITE.runBenchmarks); + Timer.run(expectAsync0(testForCompletion)); }); } diff --git a/tests/html/async_window_test.dart b/tests/html/async_window_test.dart index 1e554485771..7410e4976eb 100644 --- a/tests/html/async_window_test.dart +++ b/tests/html/async_window_test.dart @@ -2,29 +2,32 @@ library AsyncWindowTest; import '../../pkg/unittest/lib/unittest.dart'; import '../../pkg/unittest/lib/html_config.dart'; import 'dart:html'; +import 'dart:async'; main() { useHtmlConfiguration(); - test('Window.setTimeout', () { - window.setTimeout(expectAsync0((){}), 10); + test('Timer', () { + new Timer(const Duration(milliseconds: 10), expectAsync0((){})); }); - test('Window.setInterval', () { + test('Timer.repeating', () { int counter = 0; int id = null; - id = window.setInterval(expectAsyncUntil0( - () { - if (counter == 3) { - counter = 1024; - window.clearInterval(id); - // Wait some more time to be sure callback won't be invoked any more. - window.setTimeout(expectAsync0((){}), 50); - return; - } - // As callback should have been cleared on 4th invocation, counter - // should never be greater than 3. - assert(counter < 3); - counter++; - }, - () => counter == 3), 10); + new Timer.repeating(const Duration(milliseconds: 10), + expectAsyncUntil1( + (timer) { + if (counter == 3) { + counter = 1024; + timer.cancel(); + // Wait some more time to be sure callback won't be invoked any + // more. + new Timer(const Duration(milliseconds: 50), expectAsync0((){})); + return; + } + // As callback should have been cleared on 4th invocation, counter + // should never be greater than 3. + assert(counter < 3); + counter++; + }, + () => counter == 3)); }); } diff --git a/tests/html/cssstyledeclaration_test.dart b/tests/html/cssstyledeclaration_test.dart index a0ef366835b..1f8660532d9 100644 --- a/tests/html/cssstyledeclaration_test.dart +++ b/tests/html/cssstyledeclaration_test.dart @@ -6,6 +6,7 @@ library CssStyleDeclarationTest; import '../../pkg/unittest/lib/unittest.dart'; import '../../pkg/unittest/lib/html_config.dart'; import 'dart:html'; +import 'dart:async'; main() { useHtmlConfiguration(); @@ -84,10 +85,10 @@ main() { document.body.children.add(element); // Need to wait one tick after the element has been added to the page. - window.setTimeout(expectAsync0(() { + new Timer(const Duration(milliseconds: 10), expectAsync0(() { element.style.textDecoration = 'underline'; var style = element.getComputedStyle(); expect(style.textDecoration, equals('underline')); - }), 10); + })); }); } diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart b/tests/html/dromaeo_noop/dromaeo_smoke.dart index fbae236d81e..4dd24f2b30e 100644 --- a/tests/html/dromaeo_noop/dromaeo_smoke.dart +++ b/tests/html/dromaeo_noop/dromaeo_smoke.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. library dromaeo; +import 'dart:async'; import 'dart:html'; import 'dart:json' as json; import '../../../samples/third_party/dromaeo/common/common.dart'; diff --git a/tests/html/history_test.dart b/tests/html/history_test.dart index f2c7c1286cf..7ee08cec4b5 100644 --- a/tests/html/history_test.dart +++ b/tests/html/history_test.dart @@ -2,6 +2,7 @@ library HistoryTest; import '../../pkg/unittest/lib/unittest.dart'; import '../../pkg/unittest/lib/html_individual_config.dart'; import 'dart:html'; +import 'dart:async'; main() { useHtmlIndividualConfiguration(); @@ -42,14 +43,14 @@ main() { expect(window.location.href.endsWith('dummy2'), isTrue); // Need to wait a frame or two to let the pushState events occur. - window.setTimeout(expectAsync0(() { + new Timer(const Duration(milliseconds: 100), expectAsync0(() { window.onPopState.first.then(expectAsync1((_){ expect(window.history.length, length); expect(window.location.href.endsWith('dummy1'), isTrue); })); window.history.back(); - }), 100); + })); }, expectation); }); diff --git a/tests/html/js_interop_3_test.dart b/tests/html/js_interop_3_test.dart index 142c4d9311f..390c687a9b5 100644 --- a/tests/html/js_interop_3_test.dart +++ b/tests/html/js_interop_3_test.dart @@ -5,6 +5,7 @@ library JsInterop3Test; import '../../pkg/unittest/lib/unittest.dart'; import '../../pkg/unittest/lib/html_config.dart'; +import 'dart:async'; import 'dart:html'; import 'dart:isolate'; @@ -43,7 +44,7 @@ main() { var done = expectAsync0(() {}); var fun2 = (message) { expect(message, 42); - window.setTimeout(done, 0); + Timer.run(done); }; var port2 = new ReceivePortSync(); diff --git a/tests/html/js_interop_4_test.dart b/tests/html/js_interop_4_test.dart index 935c790a166..944506b73c0 100644 --- a/tests/html/js_interop_4_test.dart +++ b/tests/html/js_interop_4_test.dart @@ -5,6 +5,7 @@ library JsInterop4Test; import '../../pkg/unittest/lib/unittest.dart'; import '../../pkg/unittest/lib/html_config.dart'; +import 'dart:async'; import 'dart:html'; import 'dart:isolate'; @@ -52,7 +53,7 @@ main() { var done = expectAsync0(() {}); var fun2 = (message) { expect(message, 3); - window.setTimeout(done, 0); + Timer.run(done); }; var port2 = new ReceivePortSync(); diff --git a/tests/html/microtask_test.dart b/tests/html/microtask_test.dart index 0dfcc53402b..79adb284c72 100644 --- a/tests/html/microtask_test.dart +++ b/tests/html/microtask_test.dart @@ -5,6 +5,7 @@ library microtask_; import '../../pkg/unittest/lib/unittest.dart'; import '../../pkg/unittest/lib/html_config.dart'; +import 'dart:async'; import 'dart:html'; main() { @@ -15,10 +16,10 @@ main() { var rafCalled = false; var immediateCalled = false; - window.setTimeout(expectAsync0(() { + Timer.run(expectAsync0(() { timeoutCalled = true; expect(immediateCalled, true); - }), 0); + })); window.requestAnimationFrame((_) { diff --git a/tests/html/transition_event_test.dart b/tests/html/transition_event_test.dart index c96b46b4dd0..8e041105354 100644 --- a/tests/html/transition_event_test.dart +++ b/tests/html/transition_event_test.dart @@ -6,6 +6,7 @@ library transition_event_test; import '../../pkg/unittest/lib/unittest.dart'; import '../../pkg/unittest/lib/html_individual_config.dart'; import 'dart:html'; +import 'dart:async'; main() { useHtmlIndividualConfiguration(); @@ -28,14 +29,14 @@ main() { element.style.background = 'red'; element.style.transition = 'opacity .1s'; - window.setTimeout(expectAsync0(() { + new Timer(const Duration(milliseconds: 100), expectAsync0(() { element.onTransitionEnd.first.then(expectAsync1((e) { expect(e is TransitionEvent, isTrue); expect(e.propertyName, 'opacity'); })); element.style.opacity = '1'; - }), 100); + })); } }); }); diff --git a/tests/html/window_open_test.dart b/tests/html/window_open_test.dart index 8fbe664ba32..23baef4603a 100644 --- a/tests/html/window_open_test.dart +++ b/tests/html/window_open_test.dart @@ -2,6 +2,7 @@ library WindowOpenTest; import '../../pkg/unittest/lib/unittest.dart'; import '../../pkg/unittest/lib/html_config.dart'; import 'dart:html'; +import 'dart:async'; main() { useHtmlConfiguration(); @@ -26,8 +27,8 @@ closeWindow(win) { win.close(); doneHandler() { if (!win.closed) { - window.setTimeout(expectAsync0(doneHandler), 1); + new Timer(const Duration(milliseconds: 1), expectAsync0(doneHandler)); } } - window.setTimeout(expectAsync0(doneHandler), 1); + new Timer(const Duration(milliseconds: 1), expectAsync0(doneHandler)); } diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py index 0eb33acb834..32bb71245e7 100644 --- a/tools/dom/scripts/htmlrenamer.py +++ b/tools/dom/scripts/htmlrenamer.py @@ -194,6 +194,10 @@ renamed_html_members = monitored.Dict('htmlrenamer.renamed_html_members', { 'Document.defaultView': 'window', 'DOMURL.createObjectURL': 'createObjectUrl', 'DOMURL.revokeObjectURL': 'revokeObjectUrl', + 'DOMWindow.clearTimeout': '_clearTimeout', + 'DOMWindow.clearInterval': '_clearInterval', + 'DOMWindow.setTimeout': '_setTimeout', + 'DOMWindow.setInterval': '_setInterval', 'DOMWindow.webkitConvertPointFromNodeToPage': 'convertPointFromNodeToPage', 'DOMWindow.webkitConvertPointFromPageToNode': 'convertPointFromPageToNode', 'DOMWindow.webkitNotifications': 'notifications', diff --git a/tools/dom/src/Timer.dart b/tools/dom/src/Timer.dart index 91ad28118c1..01048ea8449 100644 --- a/tools/dom/src/Timer.dart +++ b/tools/dom/src/Timer.dart @@ -17,11 +17,11 @@ get _timerFactoryClosure => (int milliSeconds, void callback(Timer timer), bool var maker; var canceller; if (repeating) { - maker = window.setInterval; - canceller = window.clearInterval; + maker = window._setInterval; + canceller = window._clearInterval; } else { - maker = window.setTimeout; - canceller = window.clearTimeout; + maker = window._setTimeout; + canceller = window._clearTimeout; } Timer timer; final int id = maker(() { callback(timer); }, milliSeconds); diff --git a/tools/dom/templates/html/dartium/impl_Window.darttemplate b/tools/dom/templates/html/dartium/impl_Window.darttemplate deleted file mode 100644 index 3c4125be478..00000000000 --- a/tools/dom/templates/html/dartium/impl_Window.darttemplate +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2012, 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 $LIBRARYNAME; - -$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { - - /** - * Executes a [callback] after the immediate execution stack has completed. - * - * This will cause the callback to be executed after all processing has - * completed for the current event, but before any subsequent events. - */ - void setImmediate(TimeoutHandler callback) { - _addMicrotaskCallback(callback); - } - - /** - * Lookup a port by its [name]. Return null if no port is - * registered under [name]. - */ - lookupPort(String name) { - var port = json.parse(document.documentElement.attributes['dart-port:$name']); - return _deserialize(port); - } - - /** - * Register a [port] on this window under the given [name]. This - * port may be retrieved by any isolate (or JavaScript script) - * running in this window. - */ - registerPort(String name, var port) { - var serialized = _serialize(port); - document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized); - } - - /// Checks if _setImmediate is supported. - static bool get _supportsSetImmediate => false; - - /// Dartium stub for IE's setImmediate. - void _setImmediate(void callback()) { - throw new UnsupportedError('setImmediate is not supported'); - } - -$!MEMBERS -} diff --git a/tools/dom/templates/html/dart2js/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate similarity index 71% rename from tools/dom/templates/html/dart2js/impl_Window.darttemplate rename to tools/dom/templates/html/impl/impl_Window.darttemplate index 1f74f224a89..083aebd2d55 100644 --- a/tools/dom/templates/html/dart2js/impl_Window.darttemplate +++ b/tools/dom/templates/html/impl/impl_Window.darttemplate @@ -4,8 +4,63 @@ part of $LIBRARYNAME; +$if DART2JS $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS native "@*DOMWindow" { +$else +$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { +$endif + /** + * Executes a [callback] after the immediate execution stack has completed. + * + * This differs from using Timer.run(callback) + * because Timer will run in about 4-15 milliseconds, depending on browser, + * depending on load. [setImmediate], in contrast, makes browser-specific + * changes in behavior to attempt to run immediately after the current + * frame unwinds, causing the future to complete after all processing has + * completed for the current event, but before any subsequent events. + */ + void setImmediate(TimeoutHandler callback) { + _addMicrotaskCallback(callback); + } + /** + * Lookup a port by its [name]. Return null if no port is + * registered under [name]. + */ + SendPortSync lookupPort(String name) { + var port = + json.parse(document.documentElement.attributes['dart-port:$name']); + return _deserialize(port); + } + + /** + * Register a [port] on this window under the given [name]. This + * port may be retrieved by any isolate (or JavaScript script) + * running in this window. + */ + void registerPort(String name, var port) { + var serialized = _serialize(port); + document.documentElement.attributes['dart-port:$name'] = + json.stringify(serialized); + } + + /** + * Returns a Future that completes just before the window is about to repaint + * so the user can draw an animation frame + * + * If you need to later cancel this animation, use [requestAnimationFrame] + * instead. + * + * Note: The code that runs when the future completes should call + * [animationFrame] again for the animation to continue. + */ + Future get animationFrame { + var completer = new Completer(); + requestAnimationFrame(completer.complete); + return completer.future; + } + +$if DART2JS Document get document => JS('Document', '#.document', this); WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name); @@ -71,15 +126,21 @@ $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS native "@*DOMWindow" { } /** - * Executes a [callback] after the immediate execution stack has completed. + * Called to draw an animation frame and then request the window to repaint + * after [callback] has finished (creating the animation). * - * This will cause the callback to be executed after all processing has - * completed for the current event, but before any subsequent events. + * 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. */ - void setImmediate(TimeoutHandler callback) { - _addMicrotaskCallback(callback); - } - @DomName('DOMWindow.requestAnimationFrame') int requestAnimationFrame(RequestAnimationFrameCallback callback) { _ensureRequestAnimationFrame(); @@ -138,25 +199,6 @@ $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS native "@*DOMWindow" { '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB', this, this, this); - /** - * Lookup a port by its [name]. Return null if no port is - * registered under [name]. - */ - SendPortSync lookupPort(String name) { - var port = json.parse(document.documentElement.attributes['dart-port:$name']); - return _deserialize(port); - } - - /** - * Register a [port] on this window under the given [name]. This - * port may be retrieved by any isolate (or JavaScript script) - * running in this window. - */ - void registerPort(String name, var port) { - var serialized = _serialize(port); - document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized); - } - @DomName('Window.console') Console get console => Console.safeConsole; @@ -168,6 +210,15 @@ $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS native "@*DOMWindow" { void _setImmediate(void callback()) { JS('void', '#.setImmediate(#)', this, convertDartClosureToJS(callback, 0)); } +$else + /// Checks if _setImmediate is supported. + static bool get _supportsSetImmediate => false; + + /// Dartium stub for IE's setImmediate. + void _setImmediate(void callback()) { + throw new UnsupportedError('setImmediate is not supported'); + } +$endif $!MEMBERS }