Skip to content

Commit 4da75c2

Browse files
committed
feat: expose timers under the standard global names
Register setTimeout/setInterval/clearTimeout/clearInterval directly on every global (workers included), keeping the __ns__-prefixed variants for backwards compatibility. The test app's Handler-based setTimeout polyfill is retired: the suite now runs on the native timers.
1 parent 7c9c3db commit 4da75c2

5 files changed

Lines changed: 41 additions & 59 deletions

File tree

Lines changed: 3 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,3 @@
1-
var timeoutHandler;
2-
var timeoutCallbacks = {};
3-
function createHadlerAndGetId() {
4-
if (!timeoutHandler) {
5-
timeoutHandler = new android.os.Handler(android.os.Looper.getMainLooper());
6-
}
7-
return new Date().getUTCMilliseconds();
8-
}
9-
function setTimeout(callback, milliseconds) {
10-
if (milliseconds === void 0) { milliseconds = 0; }
11-
var id = createHadlerAndGetId();
12-
var runnable = new java.lang.Runnable({
13-
run: function () {
14-
callback();
15-
if (timeoutCallbacks && timeoutCallbacks[id]) {
16-
timeoutCallbacks[id] = null;
17-
}
18-
}
19-
});
20-
if (!timeoutCallbacks[id]) {
21-
timeoutCallbacks[id] = runnable;
22-
}
23-
timeoutHandler.postDelayed(runnable, long(milliseconds));
24-
return id;
25-
}
26-
global.setTimeout = setTimeout;
27-
function clearTimeout(id) {
28-
if (timeoutCallbacks[id]) {
29-
timeoutHandler.removeCallbacks(timeoutCallbacks[id]);
30-
timeoutCallbacks[id] = null;
31-
}
32-
}
33-
global.clearTimeout = clearTimeout;
34-
function setInterval(callback, milliseconds) {
35-
if (milliseconds === void 0) { milliseconds = 0; }
36-
var id = createHadlerAndGetId();
37-
var handler = timeoutHandler;
38-
var runnable = new java.lang.Runnable({
39-
run: function () {
40-
callback();
41-
handler.postDelayed(runnable, long(milliseconds));
42-
}
43-
});
44-
if (!timeoutCallbacks[id]) {
45-
timeoutCallbacks[id] = runnable;
46-
}
47-
timeoutHandler.postDelayed(runnable, long(milliseconds));
48-
return id;
49-
}
50-
global.setInterval = setInterval;
51-
global.clearInterval = clearTimeout;
1+
// Kept only because scripts in the shared tests submodule still require this
2+
// path; setTimeout/setInterval/clearTimeout/clearInterval are provided
3+
// natively by the runtime on every global (including workers).

test-app/app/src/main/assets/app/boot.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ global.__onUncaughtError = function(error){
1313
return true;
1414
}
1515

16-
require('./Infrastructure/timers');
1716
global.__JUnitSaveResults = function (unitTestResults) {
1817
var pathToApp = '/data/data/com.tns.testapplication';
1918
var unitTestFileName = 'android_unit_test_results.xml';

test-app/app/src/main/assets/app/tests/testEventLoop.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ describe("event loop ordered macrotasks", function () {
9191
Promise.resolve().then(() => order.push("microtask"));
9292
});
9393

94-
// native timers (__ns__*): the app-level `setTimeout` global in this test
95-
// app is an old Handler-based polyfill, not the runtime timers
9694
it("stays FIFO-ordered with native setTimeout(0)", function (done) {
9795
const order = [];
9896
__ns__queueMacrotask(() => order.push("macro1"));

test-app/app/src/main/assets/app/tests/testNativeTimers.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,33 @@ describe('native timer', () => {
1616
expect(clearInterval).toBeDefined();
1717
});
1818

19+
it('is exposed under the standard global names', () => {
20+
expect(typeof global.setTimeout).toBe('function');
21+
expect(typeof global.setInterval).toBe('function');
22+
expect(typeof global.clearTimeout).toBe('function');
23+
expect(typeof global.clearInterval).toBe('function');
24+
});
25+
26+
it('triggers and cancels via the standard global names', (done) => {
27+
let cancelledFired = false;
28+
const cancelled = global.setTimeout(() => {
29+
cancelledFired = true;
30+
}, 50);
31+
global.clearTimeout(cancelled);
32+
let intervalCalls = 0;
33+
const itv = global.setInterval(() => {
34+
intervalCalls++;
35+
if (intervalCalls >= 2) {
36+
global.clearInterval(itv);
37+
}
38+
}, 20);
39+
global.setTimeout(() => {
40+
expect(cancelledFired).toBe(false);
41+
expect(intervalCalls).toBe(2);
42+
done();
43+
}, 200);
44+
});
45+
1946
it('triggers timeout', (done) => {
2047
const now = Date.now();
2148
setTimeout(() => {

test-app/runtime/src/main/cpp/Timers.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,17 @@ namespace tns {
6060

6161
void Timers::Init(v8::Isolate *isolate, v8::Local<v8::ObjectTemplate> &globalObjectTemplate) {
6262
isolate_ = isolate;
63-
// TODO: remove the __ns__ prefix once this is validated
64-
SetMethod(isolate, globalObjectTemplate, "__ns__setTimeout", SetTimeoutCallback, External::New(isolate, this, v8::kExternalPointerTypeTagDefault));
65-
SetMethod(isolate, globalObjectTemplate, "__ns__setInterval", SetIntervalCallback, External::New(isolate, this, v8::kExternalPointerTypeTagDefault));
66-
SetMethod(isolate, globalObjectTemplate, "__ns__clearTimeout", ClearTimer, External::New(isolate, this, v8::kExternalPointerTypeTagDefault));
67-
SetMethod(isolate, globalObjectTemplate, "__ns__clearInterval", ClearTimer, External::New(isolate, this, v8::kExternalPointerTypeTagDefault));
63+
Local<External> data = External::New(isolate, this, v8::kExternalPointerTypeTagDefault);
64+
// the __ns__-prefixed variants are kept for backwards compatibility with
65+
// callers that predate the timers being exposed under their standard names
66+
SetMethod(isolate, globalObjectTemplate, "setTimeout", SetTimeoutCallback, data);
67+
SetMethod(isolate, globalObjectTemplate, "setInterval", SetIntervalCallback, data);
68+
SetMethod(isolate, globalObjectTemplate, "clearTimeout", ClearTimer, data);
69+
SetMethod(isolate, globalObjectTemplate, "clearInterval", ClearTimer, data);
70+
SetMethod(isolate, globalObjectTemplate, "__ns__setTimeout", SetTimeoutCallback, data);
71+
SetMethod(isolate, globalObjectTemplate, "__ns__setInterval", SetIntervalCallback, data);
72+
SetMethod(isolate, globalObjectTemplate, "__ns__clearTimeout", ClearTimer, data);
73+
SetMethod(isolate, globalObjectTemplate, "__ns__clearInterval", ClearTimer, data);
6874

6975
// PrepareV8Runtime bound the loop to this thread's looper before any
7076
// builtin initialization runs

0 commit comments

Comments
 (0)