Files
NativeScript/tns-core-modules/globals/globals.ts
Hristo Hristov 058a216ac9 Move styleScope from Page to View
Fix image-source test for API 27
setupAsRootView now makes the component styleScope
set css, addCss & addCssFile makes view to be styleScopeHost which cannot be overriden later from parent
Android modals now call setupAsRootView
Small fixes on ios layouts
launch event fired in andriod too
Moved some requestLayout calls to ios files where they belongs
2017-12-19 16:35:15 +02:00

252 lines
8.8 KiB
TypeScript

// Required by TypeScript compiler
require("./decorators");
// Required by V8 snapshot generator
if (!global.__extends) {
global.__extends = function (d, b) {
for (var p in b) {
if (b.hasOwnProperty(p)) {
d[p] = b[p];
}
}
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
}
// This method iterates all the keys in the source exports object and copies them to the destination exports one.
// Note: the method will not check for naming collisions and will override any already existing entries in the destination exports.
global.moduleMerge = function (sourceExports: any, destExports: any) {
for (var key in sourceExports) {
destExports[key] = sourceExports[key];
}
}
import * as timerModule from "../timer";
import * as dialogsModule from "../ui/dialogs";
type ModuleLoader = (name?: string) => any;
const modules: Map<string, ModuleLoader> = new Map<string, ModuleLoader>();
(<any>global).moduleResolvers = [global.require];
global.registerModule = function (name: string, loader: ModuleLoader): void {
modules.set(name, loader);
}
interface Context {
keys(): string[];
(key: string): any;
}
interface ExtensionMap {
[originalFileExtension: string]: string;
}
const defaultExtensionMap = { ".js": ".js", ".ts": ".js", ".css": ".css", ".scss": ".css", ".xml": ".xml", ".less": ".css", ".sass": ".css" };
global.registerWebpackModules = function registerWebpackModules(context: Context, extensionMap: ExtensionMap = {}) {
context.keys().forEach(key => {
const extDotIndex = key.lastIndexOf(".");
const base = key.substr(0, extDotIndex);
const originalExt = key.substr(extDotIndex);
const registerExt = extensionMap[originalExt] || defaultExtensionMap[originalExt] || originalExt;
// We prefer source files for webpack scenarios before compilation leftovers,
// e. g. if we get a .js and .ts for the same module, the .js is probably the compiled version of the .ts file,
// so we register the .ts with higher priority, similar is the case with us preferring the .scss to .css
const isSourceFile = originalExt !== registerExt;
const registerName = base + registerExt;
if (registerName.startsWith("./") && registerName.endsWith(".js")) {
const jsNickNames = [
// This is extremely short version like "main-page" that was promoted to be used with global.registerModule("module-name", loaderFunc);
registerName.substr(2, registerName.length - 5),
// This is for supporting module names like "./main/main-page"
registerName.substr(0, registerName.length - 3),
// This is for supporting module names like "main/main-page.js"
registerName.substr(2),
];
jsNickNames.forEach(jsNickName => {
if (isSourceFile || !global.moduleExists(jsNickName)) {
global.registerModule(jsNickName, () => context(key));
}
});
}
if (isSourceFile || !global.moduleExists(registerName)) {
global.registerModule(registerName, () => context(key));
}
});
}
global.moduleExists = function (name: string): boolean {
return modules.has(name);
}
global.loadModule = function (name: string): any {
const loader = modules.get(name);
if (loader) {
return loader();
}
for (let resolver of (<any>global).moduleResolvers) {
const result = resolver(name);
if (result) {
modules.set(name, () => result);
return result;
}
}
}
global.zonedCallback = function (callback: Function): Function {
if ((<any>global).zone) {
// Zone v0.5.* style callback wrapping
return (<any>global).zone.bind(callback);
}
if ((<any>global).Zone) {
// Zone v0.6.* style callback wrapping
return (<any>global).Zone.current.wrap(callback);
} else {
return callback;
}
}
global.registerModule("timer", () => require("timer"));
global.registerModule("ui/dialogs", () => require("ui/dialogs"));
global.registerModule("xhr", () => require("xhr"));
global.registerModule("fetch", () => require("fetch"));
(<any>global).System = {
import(path) {
return new Promise((resolve, reject) => {
try {
resolve(global.require(path));
} catch (e) {
reject(e);
}
});
}
}
const __tnsGlobalMergedModules = new Map<string, boolean>();
function registerOnGlobalContext(name: string, module: string): void {
Object.defineProperty(global, name, {
get: function () {
// We do not need to cache require() call since it is already cached in the runtime.
let m = global.loadModule(module);
// Redefine the property to make sure the above code is executed only once.
let resolvedValue = m[name];
Object.defineProperty(this, name, { value: resolvedValue, configurable: true, writable: true });
return resolvedValue;
},
configurable: true
});
}
let snapshotGlobals;
export function install() {
if ((<any>global).__snapshot || (<any>global).__snapshotEnabled) {
if (!snapshotGlobals) {
// require in snapshot mode is cheap
var timer: typeof timerModule = require("timer");
var dialogs: typeof dialogsModule = require("ui/dialogs");
var xhr = require("xhr");
var fetch = require("fetch");
var consoleModule = require("console");
snapshotGlobals = snapshotGlobals || {
setTimeout: timer.setTimeout,
clearTimeout: timer.clearTimeout,
setInterval: timer.setInterval,
clearInterval: timer.clearInterval,
alert: dialogs.alert,
confirm: dialogs.confirm,
prompt: dialogs.prompt,
login: dialogs.login,
action: dialogs.action,
XMLHttpRequest: xhr.XMLHttpRequest,
FormData: xhr.FormData,
fetch: fetch.fetch,
Headers: fetch.Headers,
Request: fetch.Request,
Response: fetch.Response,
console: new consoleModule.Console()
}
}
Object.assign(global, snapshotGlobals);
} else {
registerOnGlobalContext("setTimeout", "timer");
registerOnGlobalContext("clearTimeout", "timer");
registerOnGlobalContext("setInterval", "timer");
registerOnGlobalContext("clearInterval", "timer");
registerOnGlobalContext("alert", "ui/dialogs");
registerOnGlobalContext("confirm", "ui/dialogs");
registerOnGlobalContext("prompt", "ui/dialogs");
registerOnGlobalContext("login", "ui/dialogs");
registerOnGlobalContext("action", "ui/dialogs");
registerOnGlobalContext("XMLHttpRequest", "xhr");
registerOnGlobalContext("FormData", "xhr");
registerOnGlobalContext("fetch", "fetch");
registerOnGlobalContext("Headers", "fetch");
registerOnGlobalContext("Request", "fetch");
registerOnGlobalContext("Response", "fetch");
// check whether the 'android' namespace is exposed
// if positive - the current device is an Android
// so a custom implementation of the global 'console' object is attached.
// otherwise do nothing on iOS - the NS runtime provides a native 'console' functionality.
if ((<any>global).android) {
const consoleModule = require("console");
(<any>global).console = new consoleModule.Console();
}
}
}
install();
export function Deprecated(target: Object, key?: string | symbol, descriptor?: any) {
if (descriptor) {
var originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`${key} is deprecated`);
return originalMethod.apply(this, args);
}
return descriptor;
} else {
console.log(`${(target && (<any>target).name || target)} is deprecated`);
return target;
}
}
global.Deprecated = Deprecated;
export function Experimental(target: Object, key?: string | symbol, descriptor?: any) {
if (descriptor) {
var originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`${key} is experimental`);
return originalMethod.apply(this, args);
}
return descriptor;
} else {
console.log(`${(target && (<any>target).name || target)} is experimental`);
return target;
}
}
global.Experimental = Experimental;