Reverting setTimeout removal.

BUG=

Review URL: https://codereview.chromium.org//12258020

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@18478 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
efortuna@google.com 2013-02-13 21:06:31 +00:00
parent 5051029f26
commit 3b0c52f47f
16 changed files with 182 additions and 230 deletions

View file

@ -25702,56 +25702,6 @@ 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<num> get animationFrame {
var completer = new Completer<int>();
requestAnimationFrame(completer.complete);
return completer.future;
}
Document get document => JS('Document', '#.document', this);
WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name);
@ -25817,21 +25767,15 @@ class Window extends EventTarget implements WindowBase native "@*DOMWindow" {
}
/**
* Called to draw an animation frame and then request the window to repaint
* after [callback] has finished (creating the animation).
* Executes a [callback] after the immediate execution stack has completed.
*
* 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.
* 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);
}
@DomName('DOMWindow.requestAnimationFrame')
int requestAnimationFrame(RequestAnimationFrameCallback callback) {
_ensureRequestAnimationFrame();
@ -25890,6 +25834,25 @@ 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;
@ -26208,6 +26171,14 @@ class Window extends EventTarget implements WindowBase native "@*DOMWindow" {
@DocsEditable
void captureEvents() native;
@DomName('DOMWindow.clearInterval')
@DocsEditable
void clearInterval(int handle) native;
@DomName('DOMWindow.clearTimeout')
@DocsEditable
void clearTimeout(int handle) native;
@DomName('DOMWindow.close')
@DocsEditable
void close() native;
@ -26318,6 +26289,14 @@ class Window extends EventTarget implements WindowBase native "@*DOMWindow" {
@DocsEditable
void scrollTo(int x, int y) native;
@DomName('DOMWindow.setInterval')
@DocsEditable
int setInterval(TimeoutHandler handler, int timeout) native;
@DomName('DOMWindow.setTimeout')
@DocsEditable
int setTimeout(TimeoutHandler handler, int timeout) native;
@DomName('DOMWindow.showModalDialog')
@DocsEditable
Object showModalDialog(String url, [Object dialogArgs, String featureArgs]) native;

View file

@ -28093,23 +28093,19 @@ class Window extends EventTarget implements WindowBase {
/**
* 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
* 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) {
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']);
lookupPort(String name) {
var port = json.parse(document.documentElement.attributes['dart-port:$name']);
return _deserialize(port);
}
@ -28118,26 +28114,9 @@ class Window extends EventTarget implements WindowBase {
* port may be retrieved by any isolate (or JavaScript script)
* running in this window.
*/
void registerPort(String name, var port) {
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<num> get animationFrame {
var completer = new Completer<int>();
requestAnimationFrame(completer.complete);
return completer.future;
document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized);
}
/// Checks if _setImmediate is supported.
@ -28476,6 +28455,14 @@ class Window extends EventTarget implements WindowBase {
@DocsEditable
void captureEvents() native "DOMWindow_captureEvents_Callback";
@DomName('DOMWindow.clearInterval')
@DocsEditable
void clearInterval(int handle) native "DOMWindow_clearInterval_Callback";
@DomName('DOMWindow.clearTimeout')
@DocsEditable
void clearTimeout(int handle) native "DOMWindow_clearTimeout_Callback";
@DomName('DOMWindow.close')
@DocsEditable
void close() native "DOMWindow_close_Callback";
@ -28567,6 +28554,14 @@ class Window extends EventTarget implements WindowBase {
@DocsEditable
void scrollTo(int x, int y) native "DOMWindow_scrollTo_Callback";
@DomName('DOMWindow.setInterval')
@DocsEditable
int setInterval(TimeoutHandler handler, int timeout) native "DOMWindow_setInterval_Callback";
@DomName('DOMWindow.setTimeout')
@DocsEditable
int setTimeout(TimeoutHandler handler, int timeout) native "DOMWindow_setTimeout_Callback";
@DomName('DOMWindow.showModalDialog')
@DocsEditable
Object showModalDialog(String url, [Object dialogArgs, String featureArgs]) native "DOMWindow_showModalDialog_Callback";

View file

@ -94,7 +94,7 @@ class BenchmarkBase {
class BenchmarkSuite {
/** The set of benchmarks that have yet to run. */
List<Function> 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<Function> remainingBenchmarks) {
@ -128,11 +128,10 @@ 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. */
new Timer(const Duration(milliseconds: 25),
() => runBenchmarksHelper(remainingBenchmarks));
window.setTimeout(() => runBenchmarksHelper(remainingBenchmarks), 25);
} else if (remainingBenchmarks.length == 0) {
// We've run all of the benchmarks. Update the page with the score.
BENCHMARK_VIEW.setScore(geometricMean(scores));
@ -141,7 +140,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);
}
@ -173,9 +172,9 @@ class BenchmarkView {
body.nodes.add(
new Element.html("<p id='testResultScore'>Score: $newScore</p>"));
}
/**
* 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) {
@ -185,8 +184,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.
*/

View file

@ -4,9 +4,7 @@
library benchmark_lib;
import 'dart:async';
import 'dart:html';
import 'dart:async';
import 'dart:math' as Math;
import 'smoketest_lib.dart';

View file

@ -6,7 +6,6 @@ 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';
@ -14,9 +13,9 @@ import '../../pkg/unittest/lib/html_config.dart';
void main() {
useHtmlConfiguration();
test('performanceTesting', () {
Timer.run(BENCHMARK_SUITE.runBenchmarks);
Timer.run(expectAsync0(testForCompletion));
test('performanceTesting', () {
window.setTimeout(BENCHMARK_SUITE.runBenchmarks, 0);
window.setTimeout(expectAsync0(testForCompletion), 0);
});
}

View file

@ -2,32 +2,29 @@ library AsyncWindowTest;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
import 'dart:html';
import 'dart:async';
main() {
useHtmlConfiguration();
test('Timer', () {
new Timer(const Duration(milliseconds: 10), expectAsync0((){}));
test('Window.setTimeout', () {
window.setTimeout(expectAsync0((){}), 10);
});
test('Timer.repeating', () {
test('Window.setInterval', () {
int counter = 0;
int id = null;
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));
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);
});
}

View file

@ -6,7 +6,6 @@ library CssStyleDeclarationTest;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
import 'dart:html';
import 'dart:async';
main() {
useHtmlConfiguration();
@ -85,10 +84,10 @@ main() {
document.body.children.add(element);
// Need to wait one tick after the element has been added to the page.
new Timer(const Duration(milliseconds: 10), expectAsync0(() {
window.setTimeout(expectAsync0(() {
element.style.textDecoration = 'underline';
var style = element.getComputedStyle();
expect(style.textDecoration, equals('underline'));
}));
}), 10);
});
}

View file

@ -2,7 +2,6 @@ library HistoryTest;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_individual_config.dart';
import 'dart:html';
import 'dart:async';
main() {
useHtmlIndividualConfiguration();
@ -43,14 +42,14 @@ main() {
expect(window.location.href.endsWith('dummy2'), isTrue);
// Need to wait a frame or two to let the pushState events occur.
new Timer(const Duration(milliseconds: 100), expectAsync0(() {
window.setTimeout(expectAsync0(() {
window.onPopState.first.then(expectAsync1((_){
expect(window.history.length, length);
expect(window.location.href.endsWith('dummy1'), isTrue);
}));
window.history.back();
}));
}), 100);
}, expectation);
});

View file

@ -5,7 +5,6 @@
library JsInterop3Test;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
import 'dart:async';
import 'dart:html';
import 'dart:isolate';
@ -44,7 +43,7 @@ main() {
var done = expectAsync0(() {});
var fun2 = (message) {
expect(message, 42);
Timer.run(done);
window.setTimeout(done, 0);
};
var port2 = new ReceivePortSync();

View file

@ -5,7 +5,6 @@
library JsInterop4Test;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
import 'dart:async';
import 'dart:html';
import 'dart:isolate';
@ -53,7 +52,7 @@ main() {
var done = expectAsync0(() {});
var fun2 = (message) {
expect(message, 3);
Timer.run(done);
window.setTimeout(done, 0);
};
var port2 = new ReceivePortSync();

View file

@ -5,7 +5,6 @@
library microtask_;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
import 'dart:async';
import 'dart:html';
main() {
@ -16,10 +15,10 @@ main() {
var rafCalled = false;
var immediateCalled = false;
Timer.run(expectAsync0(() {
window.setTimeout(expectAsync0(() {
timeoutCalled = true;
expect(immediateCalled, true);
}));
}), 0);
window.requestAnimationFrame((_) {

View file

@ -6,7 +6,6 @@ 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();
@ -29,14 +28,14 @@ main() {
element.style.background = 'red';
element.style.transition = 'opacity .1s';
new Timer(const Duration(milliseconds: 100), expectAsync0(() {
window.setTimeout(expectAsync0(() {
element.onTransitionEnd.first.then(expectAsync1((e) {
expect(e is TransitionEvent, isTrue);
expect(e.propertyName, 'opacity');
}));
element.style.opacity = '1';
}));
}), 100);
}
});
});

View file

@ -2,7 +2,6 @@ library WindowOpenTest;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
import 'dart:html';
import 'dart:async';
main() {
useHtmlConfiguration();
@ -27,8 +26,8 @@ closeWindow(win) {
win.close();
doneHandler() {
if (!win.closed) {
new Timer(const Duration(milliseconds: 1), expectAsync0(doneHandler));
window.setTimeout(expectAsync0(doneHandler), 1);
}
}
new Timer(const Duration(milliseconds: 1), expectAsync0(doneHandler));
window.setTimeout(expectAsync0(doneHandler), 1);
}

View file

@ -242,13 +242,9 @@ _removed_html_members = monitored.Set('htmlrenamer._removed_html_members', [
'DOMWindow.call:blur',
'DOMWindow.clientInformation',
'DOMWindow.call:focus',
'DOMWindow.clearTimeout',
'DOMWindow.clearInterval',
'DOMWindow.get:frames',
'DOMWindow.get:length',
'DOMWindow.prompt',
'DOMWindow.setTimeout',
'DOMWindow.setInterval',
'DOMWindow.webkitCancelAnimationFrame',
'DOMWindow.webkitCancelRequestAnimationFrame',
'DOMWindow.webkitIndexedDB',

View file

@ -4,63 +4,8 @@
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<num> get animationFrame {
var completer = new Completer<int>();
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);
@ -126,21 +71,15 @@ $if DART2JS
}
/**
* Called to draw an animation frame and then request the window to repaint
* after [callback] has finished (creating the animation).
* Executes a [callback] after the immediate execution stack has completed.
*
* 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.
* 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);
}
@DomName('DOMWindow.requestAnimationFrame')
int requestAnimationFrame(RequestAnimationFrameCallback callback) {
_ensureRequestAnimationFrame();
@ -199,6 +138,25 @@ $if DART2JS
'#.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;
@ -210,15 +168,6 @@ $if DART2JS
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
}

View file

@ -0,0 +1,47 @@
// 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
}