mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
chore: cleanup
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
//@private
|
||||
export module bindingConstants {
|
||||
export const sourceProperty: string;
|
||||
export const targetProperty: string;
|
||||
export const expression: string;
|
||||
export const twoWay: string;
|
||||
export const source: string;
|
||||
export const bindingValueKey: string;
|
||||
export const parentValueKey: string;
|
||||
export const parentsValueKey: string;
|
||||
export const newPropertyValueKey: string;
|
||||
export const sourceProperty: string;
|
||||
export const targetProperty: string;
|
||||
export const expression: string;
|
||||
export const twoWay: string;
|
||||
export const source: string;
|
||||
export const bindingValueKey: string;
|
||||
export const parentValueKey: string;
|
||||
export const parentsValueKey: string;
|
||||
export const newPropertyValueKey: string;
|
||||
}
|
||||
|
||||
export function getBindingOptions(name: string, value: string): any;
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
const expressionSymbolsRegex = /[\+\-\*\/%\?:<>=!\|&\(\)^~]/;
|
||||
|
||||
export module bindingConstants {
|
||||
export const sourceProperty = "sourceProperty";
|
||||
export const targetProperty = "targetProperty";
|
||||
export const expression = "expression";
|
||||
export const twoWay = "twoWay";
|
||||
export const source = "source";
|
||||
export const bindingValueKey = "$value";
|
||||
export const parentValueKey = "$parent";
|
||||
export const parentsValueKey = "$parents";
|
||||
export const newPropertyValueKey = "$newPropertyValue";
|
||||
export const sourceProperty = 'sourceProperty';
|
||||
export const targetProperty = 'targetProperty';
|
||||
export const expression = 'expression';
|
||||
export const twoWay = 'twoWay';
|
||||
export const source = 'source';
|
||||
export const bindingValueKey = '$value';
|
||||
export const parentValueKey = '$parent';
|
||||
export const parentsValueKey = '$parents';
|
||||
export const newPropertyValueKey = '$newPropertyValue';
|
||||
}
|
||||
|
||||
const hasEqualSignRegex = /=+/;
|
||||
@@ -20,218 +20,188 @@ const equalSignComparisionOperatorsRegex = /(==|===|>=|<=|!=|!==)/;
|
||||
export const parentsRegex = /\$parents\s*\[\s*(['"]*)\w*\1\s*\]/g;
|
||||
|
||||
function isNamedParam(value) {
|
||||
const equalSignIndex = value.search(hasEqualSignRegex);
|
||||
if (equalSignIndex > -1) {
|
||||
const equalSignSurround = value.substr(
|
||||
equalSignIndex > 0 ? equalSignIndex - 1 : 0,
|
||||
3
|
||||
);
|
||||
if (
|
||||
equalSignSurround.search(equalSignComparisionOperatorsRegex) === -1
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
const equalSignIndex = value.search(hasEqualSignRegex);
|
||||
if (equalSignIndex > -1) {
|
||||
const equalSignSurround = value.substr(equalSignIndex > 0 ? equalSignIndex - 1 : 0, 3);
|
||||
if (equalSignSurround.search(equalSignComparisionOperatorsRegex) === -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
function areNamedParams(params: Array<any>) {
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
if (isNamedParam(params[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
if (isNamedParam(params[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
const namedParamConstants = {
|
||||
propName: "propName",
|
||||
propValue: "propValue",
|
||||
propName: 'propName',
|
||||
propValue: 'propValue',
|
||||
};
|
||||
|
||||
function getPropertyNameValuePair(param, knownOptions, callback) {
|
||||
let nameValuePair = {};
|
||||
let propertyName = param.substr(0, param.indexOf("=")).trim();
|
||||
const propertyValue = param.substr(param.indexOf("=") + 1).trim();
|
||||
if (knownOptions) {
|
||||
if (!propertyName) {
|
||||
propertyName = knownOptions.defaultProperty;
|
||||
} else {
|
||||
propertyName = propertyName in knownOptions ? propertyName : null;
|
||||
}
|
||||
}
|
||||
let nameValuePair = {};
|
||||
let propertyName = param.substr(0, param.indexOf('=')).trim();
|
||||
const propertyValue = param.substr(param.indexOf('=') + 1).trim();
|
||||
if (knownOptions) {
|
||||
if (!propertyName) {
|
||||
propertyName = knownOptions.defaultProperty;
|
||||
} else {
|
||||
propertyName = propertyName in knownOptions ? propertyName : null;
|
||||
}
|
||||
}
|
||||
|
||||
if (propertyName) {
|
||||
if (callback) {
|
||||
nameValuePair = callback(propertyName, propertyValue);
|
||||
} else {
|
||||
nameValuePair[namedParamConstants.propName] = propertyName;
|
||||
nameValuePair[namedParamConstants.propValue] = propertyValue;
|
||||
}
|
||||
if (propertyName) {
|
||||
if (callback) {
|
||||
nameValuePair = callback(propertyName, propertyValue);
|
||||
} else {
|
||||
nameValuePair[namedParamConstants.propName] = propertyName;
|
||||
nameValuePair[namedParamConstants.propValue] = propertyValue;
|
||||
}
|
||||
|
||||
return nameValuePair;
|
||||
}
|
||||
return nameValuePair;
|
||||
}
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
function parseNamedProperties(parameterList, knownOptions, callback) {
|
||||
const result = {};
|
||||
let nameValuePair;
|
||||
for (let i = 0; i < parameterList.length; i++) {
|
||||
nameValuePair = getPropertyNameValuePair(
|
||||
parameterList[i],
|
||||
knownOptions,
|
||||
callback
|
||||
);
|
||||
if (nameValuePair) {
|
||||
result[nameValuePair[namedParamConstants.propName]] =
|
||||
nameValuePair[namedParamConstants.propValue];
|
||||
}
|
||||
}
|
||||
const result = {};
|
||||
let nameValuePair;
|
||||
for (let i = 0; i < parameterList.length; i++) {
|
||||
nameValuePair = getPropertyNameValuePair(parameterList[i], knownOptions, callback);
|
||||
if (nameValuePair) {
|
||||
result[nameValuePair[namedParamConstants.propName]] = nameValuePair[namedParamConstants.propValue];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getParamsArray(value: string) {
|
||||
const result = [];
|
||||
let skipComma = 0;
|
||||
let indexReached = 0;
|
||||
let singleQuoteBlock = false;
|
||||
let doubleQuoteBlock = false;
|
||||
const result = [];
|
||||
let skipComma = 0;
|
||||
let indexReached = 0;
|
||||
let singleQuoteBlock = false;
|
||||
let doubleQuoteBlock = false;
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (value[i] === '"') {
|
||||
doubleQuoteBlock = !doubleQuoteBlock;
|
||||
}
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (value[i] === '"') {
|
||||
doubleQuoteBlock = !doubleQuoteBlock;
|
||||
}
|
||||
|
||||
if (value[i] === "'") {
|
||||
singleQuoteBlock = !singleQuoteBlock;
|
||||
}
|
||||
if (value[i] === "'") {
|
||||
singleQuoteBlock = !singleQuoteBlock;
|
||||
}
|
||||
|
||||
if (value[i] === "(" || value[i] === "[") {
|
||||
skipComma++;
|
||||
}
|
||||
if (value[i] === '(' || value[i] === '[') {
|
||||
skipComma++;
|
||||
}
|
||||
|
||||
if (value[i] === ")" || value[i] === "]") {
|
||||
skipComma--;
|
||||
}
|
||||
if (value[i] === ')' || value[i] === ']') {
|
||||
skipComma--;
|
||||
}
|
||||
|
||||
if (
|
||||
value[i] === "," &&
|
||||
skipComma === 0 &&
|
||||
!(singleQuoteBlock || doubleQuoteBlock)
|
||||
) {
|
||||
result.push(value.substr(indexReached, i - indexReached));
|
||||
indexReached = i + 1;
|
||||
}
|
||||
}
|
||||
if (value[i] === ',' && skipComma === 0 && !(singleQuoteBlock || doubleQuoteBlock)) {
|
||||
result.push(value.substr(indexReached, i - indexReached));
|
||||
indexReached = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
result.push(value.substr(indexReached));
|
||||
result.push(value.substr(indexReached));
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function isExpression(expression: string): boolean {
|
||||
if (expression.search(expressionSymbolsRegex) > -1) {
|
||||
const parentsMatches = expression.match(parentsRegex);
|
||||
if (parentsMatches) {
|
||||
const restOfExpression = expression.substr(
|
||||
expression.indexOf(parentsMatches[0]) + parentsMatches[0].length
|
||||
);
|
||||
// no more expression regognition symbols so it is safe for sourceProperty
|
||||
if (!(restOfExpression.search(expressionSymbolsRegex) > -1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (expression.search(expressionSymbolsRegex) > -1) {
|
||||
const parentsMatches = expression.match(parentsRegex);
|
||||
if (parentsMatches) {
|
||||
const restOfExpression = expression.substr(expression.indexOf(parentsMatches[0]) + parentsMatches[0].length);
|
||||
// no more expression regognition symbols so it is safe for sourceProperty
|
||||
if (!(restOfExpression.search(expressionSymbolsRegex) > -1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getBindingOptions(name: string, value: string): any {
|
||||
let namedParams = [];
|
||||
const params = getParamsArray(value);
|
||||
if (!areNamedParams(params)) {
|
||||
if (params.length === 1) {
|
||||
const trimmedValue = params[0].trim();
|
||||
let sourceProp;
|
||||
if (isExpression(trimmedValue)) {
|
||||
sourceProp = bindingConstants.bindingValueKey;
|
||||
namedParams.push(
|
||||
bindingConstants.expression + " = " + trimmedValue
|
||||
);
|
||||
} else {
|
||||
sourceProp = trimmedValue;
|
||||
}
|
||||
namedParams.push(
|
||||
bindingConstants.sourceProperty + " = " + sourceProp
|
||||
);
|
||||
let namedParams = [];
|
||||
const params = getParamsArray(value);
|
||||
if (!areNamedParams(params)) {
|
||||
if (params.length === 1) {
|
||||
const trimmedValue = params[0].trim();
|
||||
let sourceProp;
|
||||
if (isExpression(trimmedValue)) {
|
||||
sourceProp = bindingConstants.bindingValueKey;
|
||||
namedParams.push(bindingConstants.expression + ' = ' + trimmedValue);
|
||||
} else {
|
||||
sourceProp = trimmedValue;
|
||||
}
|
||||
namedParams.push(bindingConstants.sourceProperty + ' = ' + sourceProp);
|
||||
|
||||
namedParams.push(bindingConstants.twoWay + " = true");
|
||||
} else {
|
||||
namedParams.push(
|
||||
bindingConstants.sourceProperty + " = " + params[0].trim()
|
||||
);
|
||||
namedParams.push(
|
||||
bindingConstants.expression + " = " + params[1].trim()
|
||||
);
|
||||
const twoWay = params[2]
|
||||
? params[2].toLowerCase().trim() === "true"
|
||||
: true;
|
||||
namedParams.push(bindingConstants.twoWay + " = " + twoWay);
|
||||
}
|
||||
} else {
|
||||
namedParams = params;
|
||||
}
|
||||
namedParams.push(bindingConstants.twoWay + ' = true');
|
||||
} else {
|
||||
namedParams.push(bindingConstants.sourceProperty + ' = ' + params[0].trim());
|
||||
namedParams.push(bindingConstants.expression + ' = ' + params[1].trim());
|
||||
const twoWay = params[2] ? params[2].toLowerCase().trim() === 'true' : true;
|
||||
namedParams.push(bindingConstants.twoWay + ' = ' + twoWay);
|
||||
}
|
||||
} else {
|
||||
namedParams = params;
|
||||
}
|
||||
|
||||
const bindingPropertyHandler = function (prop, value) {
|
||||
const result = {};
|
||||
result[namedParamConstants.propName] = prop;
|
||||
if (prop === bindingConstants.twoWay) {
|
||||
// create a real boolean value
|
||||
if (value === "true") {
|
||||
result[namedParamConstants.propValue] = true;
|
||||
} else {
|
||||
result[namedParamConstants.propValue] = false;
|
||||
}
|
||||
} else {
|
||||
result[namedParamConstants.propValue] = value;
|
||||
}
|
||||
const bindingPropertyHandler = function (prop, value) {
|
||||
const result = {};
|
||||
result[namedParamConstants.propName] = prop;
|
||||
if (prop === bindingConstants.twoWay) {
|
||||
// create a real boolean value
|
||||
if (value === 'true') {
|
||||
result[namedParamConstants.propValue] = true;
|
||||
} else {
|
||||
result[namedParamConstants.propValue] = false;
|
||||
}
|
||||
} else {
|
||||
result[namedParamConstants.propValue] = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
return result;
|
||||
};
|
||||
|
||||
const bindingOptionsParameters = parseNamedProperties(
|
||||
namedParams,
|
||||
xmlBindingProperties,
|
||||
bindingPropertyHandler
|
||||
);
|
||||
const bindOptions = {
|
||||
targetProperty: name,
|
||||
};
|
||||
const bindingOptionsParameters = parseNamedProperties(namedParams, xmlBindingProperties, bindingPropertyHandler);
|
||||
const bindOptions = {
|
||||
targetProperty: name,
|
||||
};
|
||||
|
||||
for (let prop in bindingOptionsParameters) {
|
||||
if (bindingOptionsParameters.hasOwnProperty(prop)) {
|
||||
bindOptions[prop] = bindingOptionsParameters[prop];
|
||||
}
|
||||
}
|
||||
for (let prop in bindingOptionsParameters) {
|
||||
if (bindingOptionsParameters.hasOwnProperty(prop)) {
|
||||
bindOptions[prop] = bindingOptionsParameters[prop];
|
||||
}
|
||||
}
|
||||
|
||||
if (bindOptions[bindingConstants.twoWay] === undefined) {
|
||||
bindOptions[bindingConstants.twoWay] = true;
|
||||
}
|
||||
if (bindOptions[bindingConstants.twoWay] === undefined) {
|
||||
bindOptions[bindingConstants.twoWay] = true;
|
||||
}
|
||||
|
||||
return bindOptions;
|
||||
return bindOptions;
|
||||
}
|
||||
|
||||
const xmlBindingProperties = {
|
||||
sourceProperty: true,
|
||||
expression: true,
|
||||
twoWay: true,
|
||||
source: true,
|
||||
defaultProperty: bindingConstants.sourceProperty,
|
||||
sourceProperty: true,
|
||||
expression: true,
|
||||
twoWay: true,
|
||||
source: true,
|
||||
defaultProperty: bindingConstants.sourceProperty,
|
||||
};
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
import { View } from "../../core/view";
|
||||
import { View } from '../../core/view';
|
||||
|
||||
export interface ComponentModule {
|
||||
component: View;
|
||||
exports: any;
|
||||
component: View;
|
||||
exports: any;
|
||||
}
|
||||
|
||||
export function getComponentModule(
|
||||
elementName: string,
|
||||
namespace: string,
|
||||
attributes: Object,
|
||||
exports: Object,
|
||||
moduleNamePath?: string,
|
||||
isRootComponent?: boolean
|
||||
): ComponentModule;
|
||||
export function setPropertyValue(
|
||||
instance: View,
|
||||
instanceModuleExports: Object,
|
||||
pageExports: Object,
|
||||
propertyName: string,
|
||||
propertyValue: any
|
||||
): void;
|
||||
export function getComponentModule(elementName: string, namespace: string, attributes: Object, exports: Object, moduleNamePath?: string, isRootComponent?: boolean): ComponentModule;
|
||||
export function setPropertyValue(instance: View, instanceModuleExports: Object, pageExports: Object, propertyName: string, propertyValue: any): void;
|
||||
|
||||
@@ -1,305 +1,216 @@
|
||||
// Definitions.
|
||||
import { ComponentModule } from ".";
|
||||
import { View } from "../../core/view";
|
||||
import { ComponentModule } from '.';
|
||||
import { View } from '../../core/view';
|
||||
|
||||
// Types.
|
||||
import { isEventOrGesture } from "../../core/bindable";
|
||||
import { getBindingOptions, bindingConstants } from "../binding-builder";
|
||||
import { profile } from "../../../profiling";
|
||||
import * as debugModule from "../../../utils/debug";
|
||||
import * as platform from "../../../platform";
|
||||
import { sanitizeModuleName } from "../module-name-sanitizer";
|
||||
import { resolveModuleName } from "../../../module-name-resolver";
|
||||
import { isEventOrGesture } from '../../core/bindable';
|
||||
import { getBindingOptions, bindingConstants } from '../binding-builder';
|
||||
import { profile } from '../../../profiling';
|
||||
import * as debugModule from '../../../utils/debug';
|
||||
import * as platform from '../../../platform';
|
||||
import { sanitizeModuleName } from '../module-name-sanitizer';
|
||||
import { resolveModuleName } from '../../../module-name-resolver';
|
||||
|
||||
const UI_PATH = "ui/";
|
||||
const UI_PATH = 'ui/';
|
||||
const MODULES = {
|
||||
TabViewItem: "ui/tab-view",
|
||||
TabStrip: "ui/tab-navigation-base/tab-strip",
|
||||
TabStripItem: "ui/tab-navigation-base/tab-strip-item",
|
||||
TabContentItem: "ui/tab-navigation-base/tab-content-item",
|
||||
FormattedString: "ui/text-base/formatted-string",
|
||||
Span: "ui/text-base/span",
|
||||
ActionItem: "ui/action-bar",
|
||||
NavigationButton: "ui/action-bar",
|
||||
SegmentedBarItem: "ui/segmented-bar",
|
||||
TabViewItem: 'ui/tab-view',
|
||||
TabStrip: 'ui/tab-navigation-base/tab-strip',
|
||||
TabStripItem: 'ui/tab-navigation-base/tab-strip-item',
|
||||
TabContentItem: 'ui/tab-navigation-base/tab-content-item',
|
||||
FormattedString: 'ui/text-base/formatted-string',
|
||||
Span: 'ui/text-base/span',
|
||||
ActionItem: 'ui/action-bar',
|
||||
NavigationButton: 'ui/action-bar',
|
||||
SegmentedBarItem: 'ui/segmented-bar',
|
||||
};
|
||||
|
||||
const CODE_FILE = "codeFile";
|
||||
const CSS_FILE = "cssFile";
|
||||
const IMPORT = "import";
|
||||
const CODE_FILE = 'codeFile';
|
||||
const CSS_FILE = 'cssFile';
|
||||
const IMPORT = 'import';
|
||||
|
||||
const createComponentInstance = profile(
|
||||
"createComponentInstance",
|
||||
(
|
||||
elementName: string,
|
||||
namespace: string
|
||||
): { instance: View; instanceModule: Object } => {
|
||||
let instance: View;
|
||||
let instanceModule: Object;
|
||||
// Get module id.
|
||||
let resolvedModuleName;
|
||||
try {
|
||||
if (typeof namespace === "string") {
|
||||
resolvedModuleName = resolveModuleName(namespace, "");
|
||||
instanceModule = global.loadModule(resolvedModuleName, true);
|
||||
} else {
|
||||
// load module from @nativescript/core/ui or mapped paths
|
||||
resolvedModuleName =
|
||||
MODULES[elementName] ||
|
||||
UI_PATH +
|
||||
(elementName.toLowerCase().indexOf("layout") !== -1
|
||||
? "layouts/"
|
||||
: "") +
|
||||
elementName
|
||||
.split(/(?=[A-Z])/)
|
||||
.join("-")
|
||||
.toLowerCase();
|
||||
const createComponentInstance = profile('createComponentInstance', (elementName: string, namespace: string): { instance: View; instanceModule: Object } => {
|
||||
let instance: View;
|
||||
let instanceModule: Object;
|
||||
// Get module id.
|
||||
let resolvedModuleName;
|
||||
try {
|
||||
if (typeof namespace === 'string') {
|
||||
resolvedModuleName = resolveModuleName(namespace, '');
|
||||
instanceModule = global.loadModule(resolvedModuleName, true);
|
||||
} else {
|
||||
// load module from @nativescript/core/ui or mapped paths
|
||||
resolvedModuleName =
|
||||
MODULES[elementName] ||
|
||||
UI_PATH +
|
||||
(elementName.toLowerCase().indexOf('layout') !== -1 ? 'layouts/' : '') +
|
||||
elementName
|
||||
.split(/(?=[A-Z])/)
|
||||
.join('-')
|
||||
.toLowerCase();
|
||||
|
||||
// don't register core modules for HMR self-accept
|
||||
instanceModule = global.loadModule(resolvedModuleName, false);
|
||||
}
|
||||
// don't register core modules for HMR self-accept
|
||||
instanceModule = global.loadModule(resolvedModuleName, false);
|
||||
}
|
||||
|
||||
// Get the component type from module.
|
||||
const instanceType = instanceModule[elementName] || Object;
|
||||
// Get the component type from module.
|
||||
const instanceType = instanceModule[elementName] || Object;
|
||||
|
||||
// Create instance of the component.
|
||||
instance = new instanceType();
|
||||
} catch (ex) {
|
||||
const debug: typeof debugModule = require("../../../utils/debug");
|
||||
throw new debug.ScopeError(
|
||||
ex,
|
||||
"Module '" +
|
||||
resolvedModuleName +
|
||||
"' not found for element '" +
|
||||
(namespace ? namespace + ":" : "") +
|
||||
elementName +
|
||||
"'."
|
||||
);
|
||||
}
|
||||
// Create instance of the component.
|
||||
instance = new instanceType();
|
||||
} catch (ex) {
|
||||
const debug: typeof debugModule = require('../../../utils/debug');
|
||||
throw new debug.ScopeError(ex, "Module '" + resolvedModuleName + "' not found for element '" + (namespace ? namespace + ':' : '') + elementName + "'.");
|
||||
}
|
||||
|
||||
return { instance, instanceModule };
|
||||
}
|
||||
);
|
||||
return { instance, instanceModule };
|
||||
});
|
||||
|
||||
const getComponentModuleExports = profile(
|
||||
"getComponentModuleExports",
|
||||
(instance: View, moduleExports: Object, attributes: Object): Object => {
|
||||
if (attributes) {
|
||||
const codeFileAttribute =
|
||||
attributes[CODE_FILE] || attributes[IMPORT];
|
||||
if (codeFileAttribute) {
|
||||
const resolvedCodeFileModule = resolveModuleName(
|
||||
sanitizeModuleName(codeFileAttribute),
|
||||
""
|
||||
);
|
||||
if (resolvedCodeFileModule) {
|
||||
moduleExports = global.loadModule(
|
||||
resolvedCodeFileModule,
|
||||
true
|
||||
);
|
||||
(<any>instance).exports = moduleExports;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Code file with path "${codeFileAttribute}" cannot be found! Looking for webpack module with name "${resolvedCodeFileModule}"`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
'getComponentModuleExports',
|
||||
(instance: View, moduleExports: Object, attributes: Object): Object => {
|
||||
if (attributes) {
|
||||
const codeFileAttribute = attributes[CODE_FILE] || attributes[IMPORT];
|
||||
if (codeFileAttribute) {
|
||||
const resolvedCodeFileModule = resolveModuleName(sanitizeModuleName(codeFileAttribute), '');
|
||||
if (resolvedCodeFileModule) {
|
||||
moduleExports = global.loadModule(resolvedCodeFileModule, true);
|
||||
(<any>instance).exports = moduleExports;
|
||||
} else {
|
||||
throw new Error(`Code file with path "${codeFileAttribute}" cannot be found! Looking for webpack module with name "${resolvedCodeFileModule}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return moduleExports;
|
||||
}
|
||||
return moduleExports;
|
||||
}
|
||||
);
|
||||
|
||||
const applyComponentCss = profile(
|
||||
"applyComponentCss",
|
||||
(instance: View, moduleName: string, attributes: Object) => {
|
||||
let cssApplied = false;
|
||||
const applyComponentCss = profile('applyComponentCss', (instance: View, moduleName: string, attributes: Object) => {
|
||||
let cssApplied = false;
|
||||
|
||||
if (attributes && attributes[CSS_FILE]) {
|
||||
let resolvedCssModuleName = resolveModuleName(
|
||||
sanitizeModuleName(attributes[CSS_FILE]),
|
||||
"css"
|
||||
);
|
||||
if (attributes && attributes[CSS_FILE]) {
|
||||
let resolvedCssModuleName = resolveModuleName(sanitizeModuleName(attributes[CSS_FILE]), 'css');
|
||||
|
||||
if (resolvedCssModuleName) {
|
||||
instance.addCssFile(resolvedCssModuleName);
|
||||
cssApplied = true;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Css file with path "${attributes[CSS_FILE]}" cannot be found! Looking for webpack module with name "${resolvedCssModuleName}"`
|
||||
);
|
||||
}
|
||||
}
|
||||
if (resolvedCssModuleName) {
|
||||
instance.addCssFile(resolvedCssModuleName);
|
||||
cssApplied = true;
|
||||
} else {
|
||||
throw new Error(`Css file with path "${attributes[CSS_FILE]}" cannot be found! Looking for webpack module with name "${resolvedCssModuleName}"`);
|
||||
}
|
||||
}
|
||||
|
||||
if (moduleName && !cssApplied) {
|
||||
let resolvedCssModuleName = resolveModuleName(moduleName, "css");
|
||||
if (resolvedCssModuleName) {
|
||||
instance.addCssFile(resolvedCssModuleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
if (moduleName && !cssApplied) {
|
||||
let resolvedCssModuleName = resolveModuleName(moduleName, 'css');
|
||||
if (resolvedCssModuleName) {
|
||||
instance.addCssFile(resolvedCssModuleName);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const applyComponentAttributes = profile(
|
||||
"applyComponentAttributes",
|
||||
(
|
||||
instance: View,
|
||||
instanceModule: Object,
|
||||
moduleExports: Object,
|
||||
attributes: Object
|
||||
) => {
|
||||
if (instance && instanceModule) {
|
||||
for (let attr in attributes) {
|
||||
const attrValue = <string>attributes[attr];
|
||||
const applyComponentAttributes = profile('applyComponentAttributes', (instance: View, instanceModule: Object, moduleExports: Object, attributes: Object) => {
|
||||
if (instance && instanceModule) {
|
||||
for (let attr in attributes) {
|
||||
const attrValue = <string>attributes[attr];
|
||||
|
||||
if (attr.indexOf(":") !== -1) {
|
||||
const platformName = attr.split(":")[0].trim();
|
||||
if (attr.indexOf(':') !== -1) {
|
||||
const platformName = attr.split(':')[0].trim();
|
||||
|
||||
if (
|
||||
platformName.toLowerCase() ===
|
||||
platform.device.os.toLowerCase()
|
||||
) {
|
||||
attr = attr.split(":")[1].trim();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (platformName.toLowerCase() === platform.device.os.toLowerCase()) {
|
||||
attr = attr.split(':')[1].trim();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (attr.indexOf(".") !== -1) {
|
||||
let subObj = instance;
|
||||
const properties = attr.split(".");
|
||||
const subPropName = properties[properties.length - 1];
|
||||
if (attr.indexOf('.') !== -1) {
|
||||
let subObj = instance;
|
||||
const properties = attr.split('.');
|
||||
const subPropName = properties[properties.length - 1];
|
||||
|
||||
for (let i = 0; i < properties.length - 1; i++) {
|
||||
if (subObj !== undefined && subObj !== null) {
|
||||
subObj = subObj[properties[i]];
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < properties.length - 1; i++) {
|
||||
if (subObj !== undefined && subObj !== null) {
|
||||
subObj = subObj[properties[i]];
|
||||
}
|
||||
}
|
||||
|
||||
if (subObj !== undefined && subObj !== null) {
|
||||
setPropertyValue(
|
||||
subObj,
|
||||
instanceModule,
|
||||
moduleExports,
|
||||
subPropName,
|
||||
attrValue
|
||||
);
|
||||
}
|
||||
} else {
|
||||
setPropertyValue(
|
||||
instance,
|
||||
instanceModule,
|
||||
moduleExports,
|
||||
attr,
|
||||
attrValue
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
if (subObj !== undefined && subObj !== null) {
|
||||
setPropertyValue(subObj, instanceModule, moduleExports, subPropName, attrValue);
|
||||
}
|
||||
} else {
|
||||
setPropertyValue(instance, instanceModule, moduleExports, attr, attrValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export function getComponentModule(
|
||||
elementName: string,
|
||||
namespace: string,
|
||||
attributes: Object,
|
||||
moduleExports: Object,
|
||||
moduleNamePath?: string,
|
||||
isRootComponent?: boolean
|
||||
): ComponentModule {
|
||||
// Support lower-case-dashed component declaration in the XML (https://github.com/NativeScript/NativeScript/issues/309).
|
||||
elementName = elementName
|
||||
.split("-")
|
||||
.map((s) => s[0].toUpperCase() + s.substring(1))
|
||||
.join("");
|
||||
export function getComponentModule(elementName: string, namespace: string, attributes: Object, moduleExports: Object, moduleNamePath?: string, isRootComponent?: boolean): ComponentModule {
|
||||
// Support lower-case-dashed component declaration in the XML (https://github.com/NativeScript/NativeScript/issues/309).
|
||||
elementName = elementName
|
||||
.split('-')
|
||||
.map((s) => s[0].toUpperCase() + s.substring(1))
|
||||
.join('');
|
||||
|
||||
const { instance, instanceModule } = createComponentInstance(
|
||||
elementName,
|
||||
namespace,
|
||||
null
|
||||
);
|
||||
moduleExports = getComponentModuleExports(
|
||||
instance,
|
||||
<any>moduleExports,
|
||||
attributes
|
||||
);
|
||||
if (isRootComponent) {
|
||||
applyComponentCss(instance, moduleNamePath, attributes);
|
||||
}
|
||||
const { instance, instanceModule } = createComponentInstance(elementName, namespace, null);
|
||||
moduleExports = getComponentModuleExports(instance, <any>moduleExports, attributes);
|
||||
if (isRootComponent) {
|
||||
applyComponentCss(instance, moduleNamePath, attributes);
|
||||
}
|
||||
|
||||
applyComponentAttributes(instance, instanceModule, moduleExports);
|
||||
applyComponentAttributes(instance, instanceModule, moduleExports);
|
||||
|
||||
let componentModule;
|
||||
if (instance && instanceModule) {
|
||||
componentModule = { component: instance, exports: instanceModule };
|
||||
}
|
||||
let componentModule;
|
||||
if (instance && instanceModule) {
|
||||
componentModule = { component: instance, exports: instanceModule };
|
||||
}
|
||||
|
||||
return componentModule;
|
||||
return componentModule;
|
||||
}
|
||||
|
||||
export function setPropertyValue(
|
||||
instance: View,
|
||||
instanceModule: Object,
|
||||
exports: Object,
|
||||
propertyName: string,
|
||||
propertyValue: any
|
||||
) {
|
||||
// Note: instanceModule can be null if we are loading custom component with no code-behind.
|
||||
if (isBinding(propertyValue) && instance.bind) {
|
||||
const bindOptions = getBindingOptions(
|
||||
propertyName,
|
||||
getBindingExpressionFromAttribute(propertyValue)
|
||||
);
|
||||
instance.bind(
|
||||
{
|
||||
sourceProperty: bindOptions[bindingConstants.sourceProperty],
|
||||
targetProperty: bindOptions[bindingConstants.targetProperty],
|
||||
expression: bindOptions[bindingConstants.expression],
|
||||
twoWay: bindOptions[bindingConstants.twoWay],
|
||||
},
|
||||
bindOptions[bindingConstants.source]
|
||||
);
|
||||
} else if (isEventOrGesture(propertyName, instance)) {
|
||||
// Get the event handler from page module exports.
|
||||
const handler = exports && exports[propertyValue];
|
||||
export function setPropertyValue(instance: View, instanceModule: Object, exports: Object, propertyName: string, propertyValue: any) {
|
||||
// Note: instanceModule can be null if we are loading custom component with no code-behind.
|
||||
if (isBinding(propertyValue) && instance.bind) {
|
||||
const bindOptions = getBindingOptions(propertyName, getBindingExpressionFromAttribute(propertyValue));
|
||||
instance.bind(
|
||||
{
|
||||
sourceProperty: bindOptions[bindingConstants.sourceProperty],
|
||||
targetProperty: bindOptions[bindingConstants.targetProperty],
|
||||
expression: bindOptions[bindingConstants.expression],
|
||||
twoWay: bindOptions[bindingConstants.twoWay],
|
||||
},
|
||||
bindOptions[bindingConstants.source]
|
||||
);
|
||||
} else if (isEventOrGesture(propertyName, instance)) {
|
||||
// Get the event handler from page module exports.
|
||||
const handler = exports && exports[propertyValue];
|
||||
|
||||
// Check if the handler is function and add it to the instance for specified event name.
|
||||
if (typeof handler === "function") {
|
||||
instance.on(propertyName, handler);
|
||||
}
|
||||
} else if (
|
||||
isKnownFunction(propertyName, instance) &&
|
||||
exports &&
|
||||
typeof exports[propertyValue] === "function"
|
||||
) {
|
||||
instance[propertyName] = exports[propertyValue];
|
||||
} else {
|
||||
instance[propertyName] = propertyValue;
|
||||
}
|
||||
// Check if the handler is function and add it to the instance for specified event name.
|
||||
if (typeof handler === 'function') {
|
||||
instance.on(propertyName, handler);
|
||||
}
|
||||
} else if (isKnownFunction(propertyName, instance) && exports && typeof exports[propertyValue] === 'function') {
|
||||
instance[propertyName] = exports[propertyValue];
|
||||
} else {
|
||||
instance[propertyName] = propertyValue;
|
||||
}
|
||||
}
|
||||
|
||||
function getBindingExpressionFromAttribute(value: string): string {
|
||||
return value.replace("{{", "").replace("}}", "").trim();
|
||||
return value.replace('{{', '').replace('}}', '').trim();
|
||||
}
|
||||
|
||||
function isBinding(value: any): boolean {
|
||||
let isBinding;
|
||||
let isBinding;
|
||||
|
||||
if (typeof value === "string") {
|
||||
const str = value.trim();
|
||||
isBinding =
|
||||
str.indexOf("{{") === 0 && str.lastIndexOf("}}") === str.length - 2;
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
const str = value.trim();
|
||||
isBinding = str.indexOf('{{') === 0 && str.lastIndexOf('}}') === str.length - 2;
|
||||
}
|
||||
|
||||
return isBinding;
|
||||
return isBinding;
|
||||
}
|
||||
|
||||
// For example, ListView.itemTemplateSelector
|
||||
let KNOWN_FUNCTIONS = "knownFunctions";
|
||||
let KNOWN_FUNCTIONS = 'knownFunctions';
|
||||
function isKnownFunction(name: string, instance: View): boolean {
|
||||
return (
|
||||
instance.constructor &&
|
||||
KNOWN_FUNCTIONS in instance.constructor &&
|
||||
instance.constructor[KNOWN_FUNCTIONS].indexOf(name) !== -1
|
||||
);
|
||||
return instance.constructor && KNOWN_FUNCTIONS in instance.constructor && instance.constructor[KNOWN_FUNCTIONS].indexOf(name) !== -1;
|
||||
}
|
||||
|
||||
70
nativescript-core/ui/builder/index.d.ts
vendored
70
nativescript-core/ui/builder/index.d.ts
vendored
@@ -1,13 +1,13 @@
|
||||
import { View, Template, KeyedTemplate } from "../core/view";
|
||||
import { Page } from "../page";
|
||||
import { NavigationEntry } from "../frame";
|
||||
import { View, Template, KeyedTemplate } from '../core/view';
|
||||
import { Page } from '../page';
|
||||
import { NavigationEntry } from '../frame';
|
||||
|
||||
export interface LoadOptions {
|
||||
path: string;
|
||||
name: string;
|
||||
attributes?: any;
|
||||
exports?: any;
|
||||
page?: Page;
|
||||
path: string;
|
||||
name: string;
|
||||
attributes?: any;
|
||||
exports?: any;
|
||||
page?: Page;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,10 +23,7 @@ export function parse(value: string | Template, exports?: any): View;
|
||||
/**
|
||||
* @deprecated Use Builder.parseMultipleTemplates() instead.
|
||||
*/
|
||||
export function parseMultipleTemplates(
|
||||
value: string,
|
||||
exports?: any
|
||||
): Array<KeyedTemplate>;
|
||||
export function parseMultipleTemplates(value: string, exports?: any): Array<KeyedTemplate>;
|
||||
|
||||
/**
|
||||
* @deprecated Use Builder.load() instead.
|
||||
@@ -39,34 +36,31 @@ export function load(fileName: string, exports?: any): View;
|
||||
export function load(options: LoadOptions): View;
|
||||
|
||||
export class Builder {
|
||||
/**
|
||||
* Creates view from navigation entry
|
||||
* @param entry NavigationEntry
|
||||
*/
|
||||
static createViewFromEntry(entry: NavigationEntry): View;
|
||||
/**
|
||||
* Creates view from navigation entry
|
||||
* @param entry NavigationEntry
|
||||
*/
|
||||
static createViewFromEntry(entry: NavigationEntry): View;
|
||||
|
||||
static parse(value: string | Template, exports?: any): View;
|
||||
static parse(value: string | Template, exports?: any): View;
|
||||
|
||||
/**
|
||||
* Creates an array of KeyedTemplates from string
|
||||
* @param value The xml of the template to be parsed
|
||||
* @param exports Current context of the template
|
||||
*/
|
||||
static parseMultipleTemplates(
|
||||
value: string,
|
||||
exports?: any
|
||||
): Array<KeyedTemplate>;
|
||||
/**
|
||||
* Creates an array of KeyedTemplates from string
|
||||
* @param value The xml of the template to be parsed
|
||||
* @param exports Current context of the template
|
||||
*/
|
||||
static parseMultipleTemplates(value: string, exports?: any): Array<KeyedTemplate>;
|
||||
|
||||
/**
|
||||
* Loads component from module with context
|
||||
* @param moduleName the module name
|
||||
* @param exports the context of the component to be loaded
|
||||
*/
|
||||
static load(moduleName: string, exports?: any): View;
|
||||
/**
|
||||
* Loads component from module with context
|
||||
* @param moduleName the module name
|
||||
* @param exports the context of the component to be loaded
|
||||
*/
|
||||
static load(moduleName: string, exports?: any): View;
|
||||
|
||||
/**
|
||||
* Loads component from options
|
||||
* @param options Load options
|
||||
*/
|
||||
static load(options: LoadOptions): View;
|
||||
/**
|
||||
* Loads component from options
|
||||
* @param options Load options
|
||||
*/
|
||||
static load(options: LoadOptions): View;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1 @@
|
||||
export function sanitizeModuleName(
|
||||
moduleName: string,
|
||||
removeExtension?: boolean
|
||||
): string;
|
||||
export function sanitizeModuleName(moduleName: string, removeExtension?: boolean): string;
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
export function sanitizeModuleName(
|
||||
moduleName: string,
|
||||
removeExtension: boolean = true
|
||||
): string {
|
||||
moduleName = moduleName.trim();
|
||||
export function sanitizeModuleName(moduleName: string, removeExtension: boolean = true): string {
|
||||
moduleName = moduleName.trim();
|
||||
|
||||
if (moduleName.startsWith("~/")) {
|
||||
moduleName = moduleName.substring(2);
|
||||
} else if (moduleName.startsWith("~")) {
|
||||
moduleName = moduleName.substring(1);
|
||||
} else if (moduleName.startsWith("/")) {
|
||||
moduleName = moduleName.substring(1);
|
||||
}
|
||||
if (moduleName.startsWith('~/')) {
|
||||
moduleName = moduleName.substring(2);
|
||||
} else if (moduleName.startsWith('~')) {
|
||||
moduleName = moduleName.substring(1);
|
||||
} else if (moduleName.startsWith('/')) {
|
||||
moduleName = moduleName.substring(1);
|
||||
}
|
||||
|
||||
if (removeExtension) {
|
||||
const extToRemove = ["js", "ts", "xml", "html", "css", "scss"];
|
||||
const extensionRegEx = new RegExp(
|
||||
`(.*)\\.(?:${extToRemove.join("|")})`,
|
||||
"i"
|
||||
);
|
||||
moduleName = moduleName.replace(extensionRegEx, "$1");
|
||||
}
|
||||
if (removeExtension) {
|
||||
const extToRemove = ['js', 'ts', 'xml', 'html', 'css', 'scss'];
|
||||
const extensionRegEx = new RegExp(`(.*)\\.(?:${extToRemove.join('|')})`, 'i');
|
||||
moduleName = moduleName.replace(extensionRegEx, '$1');
|
||||
}
|
||||
|
||||
return moduleName;
|
||||
return moduleName;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user