Hhristov/fix (#3653)

* Fix action-bar systemIcon
Fix CSS applying

* refactoring

* fix console

* remove StyleScope import - it is private and cannot be imported in public .d.ts
This commit is contained in:
Hristo Hristov
2017-02-17 17:21:57 +02:00
committed by GitHub
parent 373bdc1814
commit a582adc561
73 changed files with 1063 additions and 2481 deletions

View File

@@ -2,6 +2,7 @@
import { View, Template, KeyedTemplate } from "ui/core/view";
import { Page } from "ui/page";
export function loadPage(moduleNamePath: string, fileName: string, moduleExports?: any): Page;
export function load(fileName: string, exports?: any): View;
export function load(options: LoadOptions): View;
export function parse(value: string | Template, exports?: any): View;

View File

@@ -44,7 +44,7 @@ export function parseMultipleTemplates(value: string, context: any): Array<Keyed
return parseInternal(dummyComponent, context).component["itemTemplates"];
}
function parseInternal(value: string, context: any, uri?: string): ComponentModule {
function parseInternal(value: string, context: any, uri?: string, moduleNamePath?: string): ComponentModule {
var start: xml2ui.XmlStringParser;
var ui: xml2ui.ComponentParser;
@@ -55,7 +55,7 @@ function parseInternal(value: string, context: any, uri?: string): ComponentModu
(start = new xml2ui.XmlStringParser(errorFormat))
.pipe(new xml2ui.PlatformFilter())
.pipe(new xml2ui.XmlStateParser(ui = new xml2ui.ComponentParser(context, errorFormat, componentSourceTracker)));
.pipe(new xml2ui.XmlStateParser(ui = new xml2ui.ComponentParser(context, errorFormat, componentSourceTracker, moduleNamePath)));
start.parse(value);
@@ -63,7 +63,7 @@ function parseInternal(value: string, context: any, uri?: string): ComponentModu
}
function loadCustomComponent(componentPath: string, componentName?: string, attributes?: Object, context?: Object, parentPage?: Page): ComponentModule {
if (!parentPage && context){
if (!parentPage && context) {
// Read the parent page that was passed down below
// https://github.com/NativeScript/NativeScript/issues/1639
parentPage = context["_parentPage"];
@@ -95,20 +95,19 @@ function loadCustomComponent(componentPath: string, componentName?: string, attr
subExports = global.loadModule(jsFilePath)
}
}
// Pass the parent page down the chain in case of custom components nested on many levels. Use the context for piggybacking.
// https://github.com/NativeScript/NativeScript/issues/1639
if (!subExports) {
subExports = {};
subExports = {};
}
subExports["_parentPage"] = parentPage;
result = loadInternal(xmlFilePath, subExports);
// Attributes will be transfered to the custom component
if (isDefined(result) && isDefined(result.component) && isDefined(attributes)) {
var attr: string;
for (attr in attributes) {
for (let attr in attributes) {
setPropertyValue(result.component, subExports, context, attr, attributes[attr]);
}
}
@@ -156,16 +155,37 @@ export function load(pathOrOptions: string | LoadOptions, context?: any): View {
return viewToReturn;
}
export function loadPage(moduleNamePath: string, fileName: string, context?: any): Page {
var componentModule: ComponentModule;
// Check if the XML file exists.
if (File.exists(fileName)) {
const file = File.fromPath(fileName);
const onError = function (error) {
throw new Error("Error loading file " + fileName + " :" + error.message);
}
const text = file.readTextSync(onError);
componentModule = parseInternal(text, context, fileName, moduleNamePath);
}
if (componentModule && componentModule.component) {
// Save exports to root component (will be used for templates).
(<any>componentModule.component).exports = context;
}
return (<Page>componentModule.component);
}
function loadInternal(fileName: string, context?: any): ComponentModule {
var componentModule: ComponentModule;
// Check if the XML file exists.
if (File.exists(fileName)) {
var file = File.fromPath(fileName);
var onError = function (error) {
const file = File.fromPath(fileName);
const onError = function (error) {
throw new Error("Error loading file " + fileName + " :" + error.message);
}
var text = file.readTextSync(onError);
const text = file.readTextSync(onError);
componentModule = parseInternal(text, context, fileName);
}
@@ -501,7 +521,7 @@ namespace xml2ui {
private error: ErrorFormatter;
private sourceTracker: SourceTracker;
constructor(context: any, errorFormat: ErrorFormatter, sourceTracker: SourceTracker) {
constructor(context: any, errorFormat: ErrorFormatter, sourceTracker: SourceTracker, private moduleNamePath?: string) {
this.context = context;
this.error = errorFormat;
this.sourceTracker = sourceTracker;
@@ -563,7 +583,7 @@ namespace xml2ui {
//Ignore the default ...tns.xsd namespace URL
namespace = undefined;
}
componentModule = getComponentModule(args.elementName, namespace, args.attributes, this.context);
componentModule = getComponentModule(args.elementName, namespace, args.attributes, this.context, this.moduleNamePath);
}
if (componentModule) {
@@ -662,4 +682,4 @@ namespace xml2ui {
items?: Array<any>;
}
}
}
}

View File

@@ -1,7 +1,7 @@
declare module "ui/builder/component-builder" {
import { View } from "ui/core/view";
export function getComponentModule(elementName: string, namespace: string, attributes: Object, exports: Object): ComponentModule;
export function getComponentModule(elementName: string, namespace: string, attributes: Object, exports: Object, moduleNamePath?: string): ComponentModule;
export function setPropertyValue(instance: View, instanceModuleExports: Object, pageExports: Object, propertyName: string, propertyValue: any): void;
export interface ComponentModule {

View File

@@ -4,18 +4,12 @@ import { View, isEventOrGesture } from "ui/core/view";
import { ComponentModule } from "ui/builder/component-builder";
import { File, path, knownFolders } from "file-system";
import { getBindingOptions, bindingConstants } from "./binding-builder";
import { resolveFileName } from "file-system/file-name-resolver";
import * as debugModule from "utils/debug";
import * as platformModule from "platform";
//the imports below are needed for special property registration
import "ui/layouts/dock-layout";
import "ui/layouts/grid-layout";
import "ui/layouts/absolute-layout";
import { getSpecialPropertySetter } from "ui/builder/special-properties";
var UI_PATH = "ui/";
var MODULES = {
const UI_PATH = "ui/";
const MODULES = {
"TabViewItem": "ui/tab-view",
"FormattedString": "text/formatted-string",
"Span": "text/span",
@@ -24,19 +18,18 @@ var MODULES = {
"SegmentedBarItem": "ui/segmented-bar",
};
var CODEFILE = "codeFile";
var CSSFILE = "cssFile";
const CODEFILE = "codeFile";
const CSSFILE = "cssFile";
const IMPORT = "import";
var IMPORT = "import";
var platform: typeof platformModule;
let platform: typeof platformModule;
function ensurePlatform() {
if (!platform) {
platform = require("platform");
}
}
export function getComponentModule(elementName: string, namespace: string, attributes: Object, exports: Object): ComponentModule {
export function getComponentModule(elementName: string, namespace: string, attributes: Object, exports: Object, moduleNamePath?: string): ComponentModule {
var instance: View;
var instanceModule: Object;
var componentModule: ComponentModule;
@@ -50,11 +43,11 @@ export function getComponentModule(elementName: string, namespace: string, attri
elementName.split(/(?=[A-Z])/).join("-").toLowerCase();
try {
if (isString(namespace)) {
if (typeof namespace === "string") {
if (global.moduleExists(namespace)) {
moduleId = namespace;
} else {
var pathInsideTNSModules = path.join(knownFolders.currentApp().path, "tns_modules", namespace);
const pathInsideTNSModules = path.join(knownFolders.currentApp().path, "tns_modules", namespace);
try {
// module inside tns_modules
@@ -73,18 +66,19 @@ export function getComponentModule(elementName: string, namespace: string, attri
}
// Get the component type from module.
var instanceType = instanceModule[elementName] || Object;
const instanceType = instanceModule[elementName] || Object;
// Create instance of the component.
instance = new instanceType();
} catch (ex) {
var debug: typeof debugModule = require("utils/debug");
const debug: typeof debugModule = require("utils/debug");
throw new debug.ScopeError(ex, "Module '" + moduleId + "' not found for element '" + (namespace ? namespace + ":" : "") + elementName + "'.");
}
let cssApplied = false;
if (attributes) {
if (attributes[IMPORT]) {
var importPath = attributes[IMPORT].trim();
let importPath = attributes[IMPORT].trim();
if (importPath.indexOf("~/") === 0) {
importPath = path.join(knownFolders.currentApp().path, importPath.replace("~/", ""));
@@ -94,45 +88,55 @@ export function getComponentModule(elementName: string, namespace: string, attri
(<any>instance).exports = exports;
}
if (attributes[CODEFILE]) {
if (instance instanceof Page) {
var codeFilePath = attributes[CODEFILE].trim();
if (instance instanceof Page) {
if (attributes[CODEFILE]) {
let codeFilePath = attributes[CODEFILE].trim();
if (codeFilePath.indexOf("~/") === 0) {
codeFilePath = path.join(knownFolders.currentApp().path, codeFilePath.replace("~/", ""));
}
let codeFilePathWithExt = codeFilePath.indexOf(".js") !== -1 ? codeFilePath : `${codeFilePath}.js`;
const codeFilePathWithExt = codeFilePath.indexOf(".js") !== -1 ? codeFilePath : `${codeFilePath}.js`;
if (File.exists(codeFilePathWithExt)) {
exports = global.loadModule(codeFilePath);
(<any>instance).exports = exports;
} else {
throw new Error(`Code file with path "${codeFilePathWithExt}" cannot be found!`);
}
} else {
throw new Error("Code file atribute is valid only for pages!");
}
}
if (attributes[CSSFILE]) {
if (instance instanceof Page) {
var cssFilePath = attributes[CSSFILE].trim();
if (attributes[CSSFILE]) {
let cssFilePath = attributes[CSSFILE].trim();
if (cssFilePath.indexOf("~/") === 0) {
cssFilePath = path.join(knownFolders.currentApp().path, cssFilePath.replace("~/", ""));
}
if (File.exists(cssFilePath)) {
(<Page>instance).addCssFile(cssFilePath);
instance[CSSFILE] = true;
instance.addCssFile(cssFilePath);
cssApplied = true;
} else {
throw new Error(`Css file with path "${cssFilePath}" cannot be found!`);
}
} else {
throw new Error("Css file attribute is valid only for pages!");
}
}
}
if (instance instanceof Page) {
if (moduleNamePath && !cssApplied) {
let cssFilePath = resolveFileName(moduleNamePath, "css");
if (cssFilePath) {
instance.addCssFile(cssFilePath);
cssApplied = true;
}
}
if (!cssApplied) {
// Called only to apply application css.
// If we have page css (through file or cssAttribute) we have appCss applied.
instance._refreshCss();
}
}
if (instance && instanceModule) {
for (var attr in attributes) {
for (let attr in attributes) {
var attrValue = <string>attributes[attr];
@@ -149,12 +153,11 @@ export function getComponentModule(elementName: string, namespace: string, attri
}
if (attr.indexOf(".") !== -1) {
var subObj = instance;
var properties = attr.split(".");
var subPropName = properties[properties.length - 1];
let subObj = instance;
const properties = attr.split(".");
const subPropName = properties[properties.length - 1];
var i: number;
for (i = 0; i < properties.length - 1; i++) {
for (let i = 0; i < properties.length - 1; i++) {
if (isDefined(subObj)) {
subObj = subObj[properties[i]];
}
@@ -199,13 +202,8 @@ export function setPropertyValue(instance: View, instanceModule: Object, exports
}
else {
let attrHandled = false;
let specialSetter = getSpecialPropertySetter(propertyName);
if (!attrHandled && specialSetter) {
specialSetter(instance, propertyValue);
attrHandled = true;
}
if (!attrHandled && (<any>instance)._applyXmlAttribute) {
attrHandled = (<any>instance)._applyXmlAttribute(propertyName, propertyValue);
if (!attrHandled && instance._applyXmlAttribute) {
attrHandled = instance._applyXmlAttribute(propertyName, propertyValue);
}
if (!attrHandled) {
instance[propertyName] = propertyValue;