mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-18 05:18:39 +08:00
Merge pull request #706 from NativeScript/CSS-and-code-files-from-XML
CSS and XML code files now can be specified in XML
This commit is contained in:
@ -79,6 +79,7 @@
|
||||
<TypeScriptCompile Include="apps\action-bar-demo\pages\data-binding.ts">
|
||||
<DependentUpon>data-binding.xml</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="apps\tests\xml-declaration\custom-code-file.ts" />
|
||||
<TypeScriptCompile Include="apps\transforms\app.ts" />
|
||||
<TypeScriptCompile Include="apps\transforms\main-page.ts" />
|
||||
<TypeScriptCompile Include="apps\transforms\model.ts" />
|
||||
@ -110,6 +111,7 @@
|
||||
<Content Include="apps\action-bar-demo\pages\center-view-segmented.xml" />
|
||||
<Content Include="apps\action-bar-demo\pages\center-view.xml" />
|
||||
<Content Include="apps\action-bar-demo\pages\data-binding.xml" />
|
||||
<Content Include="apps\tests\xml-declaration\custom-css-file.css" />
|
||||
<Content Include="apps\transforms\main-page.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
@ -1982,8 +1984,6 @@
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
<UserProperties ui_2scroll-view_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2editable-text-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2absolute-layout-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2gallery-app_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2content-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2web-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2absolute-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2dock-layout_2package_1json__JSONSchema="" ui_2layouts_2grid-layout_2package_1json__JSONSchema="" ui_2layouts_2wrap-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" />
|
||||
<UserProperties ui_2scroll-view_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2editable-text-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2absolute-layout-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2gallery-app_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2content-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2web-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2linear-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2absolute-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2dock-layout_2package_1json__JSONSchema="" ui_2layouts_2grid-layout_2package_1json__JSONSchema="" ui_2layouts_2wrap-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" />
|
||||
<UserProperties ui_2layouts_2wrap-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2grid-layout_2package_1json__JSONSchema="" ui_2layouts_2dock-layout_2package_1json__JSONSchema="" ui_2layouts_2absolute-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2web-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2content-view_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2gallery-app_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2absolute-layout-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2editable-text-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2scroll-view_2package_1json__JSONSchema="http://json.schemastore.org/package" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
|
3
apps/tests/xml-declaration/custom-code-file.ts
Normal file
3
apps/tests/xml-declaration/custom-code-file.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function loaded(args) {
|
||||
args.object.customCodeLoaded = true;
|
||||
}
|
3
apps/tests/xml-declaration/custom-css-file.css
Normal file
3
apps/tests/xml-declaration/custom-css-file.css
Normal file
@ -0,0 +1,3 @@
|
||||
.MyClass {
|
||||
background-color: green;
|
||||
}
|
@ -148,10 +148,91 @@ export function test_parse_ShouldNotCrashWithoutExports() {
|
||||
var file = fs.File.fromPath(fs.path.join(__dirname, "mainPage.xml"));
|
||||
var text = file.readTextSync();
|
||||
|
||||
var v: view.View = builder.parse(text);
|
||||
var v: view.View = builder.parse(text);
|
||||
TKUnit.assert(v instanceof view.View, "Expected result: View; Actual result: " + v + ";");
|
||||
};
|
||||
|
||||
export function test_parse_ShouldResolveExportsFromCodeFile() {
|
||||
var page = builder.parse("<Page codeFile='~/xml-declaration/custom-code-file' loaded='loaded'></Page>");
|
||||
page._emit("loaded");
|
||||
|
||||
TKUnit.assert((<any>page).customCodeLoaded, "Parse should resolve exports from custom code file.");
|
||||
}
|
||||
|
||||
export function test_parse_ShouldThrowErrorWhenInvalidCodeFileIsSpecified() {
|
||||
var e: Error;
|
||||
try {
|
||||
builder.parse("<Page codeFile='~/xml-declaration/some-code-file' loaded='pageLoaded'></Page>");
|
||||
} catch (ex) {
|
||||
e = ex;
|
||||
}
|
||||
|
||||
TKUnit.assert(e, "Expected result: Error; Actual result: " + e);
|
||||
};
|
||||
|
||||
export function test_parse_ShouldResolveExportsFromCodeFileForTemplates() {
|
||||
var p = <Page>builder.parse('<Page codeFile="~/xml-declaration/custom-code-file" xmlns:customControls="xml-declaration/mymodulewithxml"><ListView items="{{ items }}" itemLoading="{{ itemLoading }}"><ListView.itemTemplate><customControls:MyControl loaded="loaded" /></ListView.itemTemplate></ListView></Page>');
|
||||
|
||||
function testAction(views: Array<viewModule.View>) {
|
||||
var ctrl;
|
||||
|
||||
var obj = new observable.Observable();
|
||||
obj.set("items", [1]);
|
||||
obj.set("itemLoading", function (args: listViewModule.ItemEventData) {
|
||||
ctrl = args.view
|
||||
});
|
||||
p.bindingContext = obj;
|
||||
|
||||
TKUnit.wait(0.2);
|
||||
|
||||
TKUnit.assert((<any>ctrl).customCodeLoaded, "Parse should resolve exports for templates from custom code file.");
|
||||
};
|
||||
|
||||
helper.navigate(function () { return p; });
|
||||
|
||||
try {
|
||||
testAction([p.content, p]);
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
}
|
||||
|
||||
export function test_parse_ShouldApplyCssFromCssFile() {
|
||||
var newPage: Page;
|
||||
var pageFactory = function (): Page {
|
||||
newPage = <Page>builder.parse("<Page cssFile='~/xml-declaration/custom-css-file.css'><Label cssClass='MyClass' /></Page>");
|
||||
return newPage;
|
||||
};
|
||||
|
||||
helper.navigate(pageFactory);
|
||||
TKUnit.assert(newPage.isLoaded, "The page should be loaded here.");
|
||||
try {
|
||||
helper.assertViewBackgroundColor(newPage.content, "#008000");
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
};
|
||||
|
||||
export function test_parse_ShouldResolveExportsFromCodeFileAndApplyCssFile() {
|
||||
var newPage: Page;
|
||||
var pageFactory = function (): Page {
|
||||
newPage = <Page>builder.parse("<Page codeFile='~/xml-declaration/custom-code-file' cssFile='~/xml-declaration/custom-css-file.css' loaded='loaded'><Label cssClass='MyClass' /></Page>");
|
||||
return newPage;
|
||||
};
|
||||
|
||||
helper.navigate(pageFactory);
|
||||
TKUnit.assert(newPage.isLoaded, "The page should be loaded here.");
|
||||
TKUnit.assert((<any>newPage).customCodeLoaded, "Parse should resolve exports from custom code file.");
|
||||
try {
|
||||
helper.assertViewBackgroundColor(newPage.content, "#008000");
|
||||
}
|
||||
finally {
|
||||
helper.goBack();
|
||||
}
|
||||
};
|
||||
|
||||
export function test_parse_ShouldFindEventHandlersInExports() {
|
||||
var loaded;
|
||||
var page = builder.parse("<Page loaded='myLoaded'></Page>", {
|
||||
|
@ -10,6 +10,7 @@ import fs = require("file-system");
|
||||
import gestures = require("ui/gestures");
|
||||
import bindingBuilder = require("ui/builder/binding-builder");
|
||||
import platform = require("platform");
|
||||
import pages = require("ui/page");
|
||||
|
||||
var UI_PATH = "ui/";
|
||||
var MODULES = {
|
||||
@ -28,6 +29,8 @@ var ROW_SPAN = "rowSpan";
|
||||
var DOCK = "dock";
|
||||
var LEFT = "left";
|
||||
var TOP = "top";
|
||||
var CODEFILE = "codeFile";
|
||||
var CSSFILE = "cssFile";
|
||||
|
||||
export var specialProperties: Array<string> = [
|
||||
ROW,
|
||||
@ -37,6 +40,8 @@ export var specialProperties: Array<string> = [
|
||||
DOCK,
|
||||
LEFT,
|
||||
TOP,
|
||||
CODEFILE,
|
||||
CSSFILE
|
||||
]
|
||||
|
||||
var eventHandlers = {};
|
||||
@ -78,6 +83,42 @@ export function getComponentModule(elementName: string, namespace: string, attri
|
||||
throw new Error("Cannot create module " + moduleId + ". " + ex + ". StackTrace: " + ex.stack);
|
||||
}
|
||||
|
||||
if (attributes) {
|
||||
if (attributes[CODEFILE]) {
|
||||
if (instance instanceof pages.Page) {
|
||||
var codeFilePath = attributes[CODEFILE].trim();
|
||||
if (codeFilePath.indexOf("~/") === 0) {
|
||||
codeFilePath = fs.path.join(fs.knownFolders.currentApp().path, codeFilePath.replace("~/", ""));
|
||||
}
|
||||
try {
|
||||
exports = require(codeFilePath);
|
||||
(<any>instance).exports = exports;
|
||||
} catch (ex) {
|
||||
throw new Error(`Code file with path "${codeFilePath}" cannot be found!`);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Code file atribute is valid only for pages!");
|
||||
}
|
||||
}
|
||||
|
||||
if (attributes[CSSFILE]) {
|
||||
if (instance instanceof pages.Page) {
|
||||
var cssFilePath = attributes[CSSFILE].trim();
|
||||
if (cssFilePath.indexOf("~/") === 0) {
|
||||
cssFilePath = fs.path.join(fs.knownFolders.currentApp().path, cssFilePath.replace("~/", ""));
|
||||
}
|
||||
if (fs.File.exists(cssFilePath)) {
|
||||
(<pages.Page>instance).addCssFile(cssFilePath);
|
||||
instance[CSSFILE] = true;
|
||||
} else {
|
||||
throw new Error(`Css file with path "${cssFilePath}" cannot be found!`);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Css file atribute is valid only for pages!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (instance && instanceModule) {
|
||||
var bindings = new Array<bindable.BindingOptions>();
|
||||
|
||||
|
@ -66,9 +66,9 @@ export function resolvePageFromEntry(entry: definition.NavigationEntry): pages.P
|
||||
throw new Error("Failed to load Page from entry.moduleName: " + entry.moduleName);
|
||||
}
|
||||
|
||||
// Possible CSS file path.
|
||||
// Possible CSS file path. Add it only if CSS not already specified and loaded from cssFile Page attribute in XML.
|
||||
var cssFileName = fileResolverModule.resolveFileName(moduleNamePath, "css");
|
||||
if (cssFileName) {
|
||||
if (cssFileName && !page["cssFile"]) {
|
||||
page.addCssFile(cssFileName);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user