Skip to content

Commit b94a61f

Browse files
Globals in snapshot are overriden by the V8 on start, so they have to be installed later (NativeScript#4387)
1 parent ab5da0a commit b94a61f

File tree

4 files changed

+64
-43
lines changed

4 files changed

+64
-43
lines changed

tns-core-modules/globals/globals.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/**
2+
* Register globals such as setTimeout, setInterval, console etc.
3+
*/
4+
export function install();

tns-core-modules/globals/globals.ts

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -86,49 +86,62 @@ function registerOnGlobalContext(name: string, module: string): void {
8686
});
8787
}
8888

89-
if ((<any>global).__snapshot) {
90-
// when we have a snapshot, it is better to pre-populate these on the global context to get them saved within the blob
91-
var timer: typeof timerModule = require("timer");
92-
(<any>global).setTimeout = timer.setTimeout;
93-
(<any>global).clearTimeout = timer.clearTimeout;
94-
(<any>global).setInterval = timer.setInterval;
95-
(<any>global).clearInterval = timer.clearInterval;
96-
97-
var dialogs: typeof dialogsModule = require("ui/dialogs");
98-
(<any>global).alert = dialogs.alert;
99-
(<any>global).confirm = dialogs.confirm;
100-
(<any>global).prompt = dialogs.prompt;
101-
102-
var xhr = require("xhr");
103-
(<any>global).XMLHttpRequest = xhr.XMLHttpRequest;
104-
(<any>global).FormData = xhr.FormData;
105-
106-
var fetch = require("fetch");
107-
(<any>global).fetch = fetch.fetch;
108-
(<any>global).Headers = fetch.Headers;
109-
(<any>global).Request = fetch.Request;
110-
(<any>global).Response = fetch.Response;
111-
} else {
112-
registerOnGlobalContext("setTimeout", "timer");
113-
registerOnGlobalContext("clearTimeout", "timer");
114-
registerOnGlobalContext("setInterval", "timer");
115-
registerOnGlobalContext("clearInterval", "timer");
116-
registerOnGlobalContext("alert", "ui/dialogs");
117-
registerOnGlobalContext("confirm", "ui/dialogs");
118-
registerOnGlobalContext("prompt", "ui/dialogs");
119-
registerOnGlobalContext("XMLHttpRequest", "xhr");
120-
registerOnGlobalContext("FormData", "xhr");
121-
registerOnGlobalContext("fetch", "fetch");
122-
}
123-
124-
// check whether the 'android' namespace is exposed
125-
// if positive - the current device is an Android
126-
// so a custom implementation of the global 'console' object is attached.
127-
// otherwise do nothing on iOS - the NS runtime provides a native 'console' functionality.
128-
if ((<any>global).android || (<any>global).__snapshot) {
129-
const consoleModule = require("console");
130-
(<any>global).console = new consoleModule.Console();
89+
let snapshotGlobals;
90+
export function install() {
91+
if ((<any>global).__snapshot) {
92+
if (!snapshotGlobals) {
93+
// require in snapshot mode is cheap
94+
var timer: typeof timerModule = require("timer");
95+
var dialogs: typeof dialogsModule = require("ui/dialogs");
96+
var xhr = require("xhr");
97+
var fetch = require("fetch");
98+
var consoleModule = require("console");
99+
100+
snapshotGlobals = snapshotGlobals || {
101+
setTimeout: timer.setTimeout,
102+
clearTimeout: timer.clearTimeout,
103+
setInterval: timer.setInterval,
104+
clearInterval: timer.clearInterval,
105+
106+
alert: dialogs.alert,
107+
confirm: dialogs.confirm,
108+
prompt: dialogs.prompt,
109+
110+
XMLHttpRequest: xhr.XMLHttpRequest,
111+
FormData: xhr.FormData,
112+
113+
fetch: fetch.fetch,
114+
Headers: fetch.Headers,
115+
Request: fetch.Request,
116+
Response: fetch.Response,
117+
118+
console: new consoleModule.Console()
119+
}
120+
}
121+
Object.assign(global, snapshotGlobals);
122+
} else {
123+
registerOnGlobalContext("setTimeout", "timer");
124+
registerOnGlobalContext("clearTimeout", "timer");
125+
registerOnGlobalContext("setInterval", "timer");
126+
registerOnGlobalContext("clearInterval", "timer");
127+
registerOnGlobalContext("alert", "ui/dialogs");
128+
registerOnGlobalContext("confirm", "ui/dialogs");
129+
registerOnGlobalContext("prompt", "ui/dialogs");
130+
registerOnGlobalContext("XMLHttpRequest", "xhr");
131+
registerOnGlobalContext("FormData", "xhr");
132+
registerOnGlobalContext("fetch", "fetch");
133+
134+
// check whether the 'android' namespace is exposed
135+
// if positive - the current device is an Android
136+
// so a custom implementation of the global 'console' object is attached.
137+
// otherwise do nothing on iOS - the NS runtime provides a native 'console' functionality.
138+
if ((<any>global).android) {
139+
const consoleModule = require("console");
140+
(<any>global).console = new consoleModule.Console();
141+
}
142+
}
131143
}
144+
install();
132145

133146
export function Deprecated(target: Object, key?: string | symbol, descriptor?: any) {
134147
if (descriptor) {

tns-core-modules/globals/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,3 @@
44
"types": "globals.d.ts",
55
"nativescript": {}
66
}
7-

tns-core-modules/ui/frame/activity.android.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { setActivityCallbacks, AndroidActivityCallbacks } from "./frame";
2+
import * as globals from "../../globals";
23
import * as appModule from "../../application";
34

5+
if ((<any>global).__snapshot) {
6+
globals.install();
7+
}
8+
49
@JavaProxy("com.tns.NativeScriptActivity")
510
class NativeScriptActivity extends android.app.Activity {
611
private _callbacks: AndroidActivityCallbacks;

0 commit comments

Comments
 (0)