mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-26 11:17:04 +08:00
file-name-resolver module
This commit is contained in:
@ -109,6 +109,7 @@
|
||||
<TypeScriptCompile Include="apps\tests\gestures-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\layouts\dock-layout-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\pages\app.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\pages\file-load-test.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\pages\page12.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\layouts\absolute-layout-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\layouts\layout-helper.ts" />
|
||||
@ -167,6 +168,10 @@
|
||||
<TypeScriptCompile Include="apps\ui-tests-app\pages\i61.ts" />
|
||||
<TypeScriptCompile Include="apps\ui-tests-app\pages\i73.ts" />
|
||||
<TypeScriptCompile Include="apps\ui-tests-app\pages\gestures.ts" />
|
||||
<TypeScriptCompile Include="file-system\file-name-resolver.d.ts" />
|
||||
<TypeScriptCompile Include="file-system\file-name-resolver.ts">
|
||||
<DependentUpon>file-name-resolver.d.ts</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="image-source\image-source-common.ts">
|
||||
<DependentUpon>image-source.d.ts</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
@ -540,6 +545,12 @@
|
||||
<Content Include="apps\template-settings\app.css" />
|
||||
<Content Include="apps\tests\app\binding_tests.xml" />
|
||||
<Content Include="apps\tests\ui\label\label-tests-wrong.css" />
|
||||
<Content Include="apps\tests\pages\files\other.xml" />
|
||||
<Content Include="apps\tests\pages\files\test.android.phone.xml" />
|
||||
<Content Include="apps\tests\pages\files\test.android.xml" />
|
||||
<Content Include="apps\tests\pages\files\test.minWH300.xml" />
|
||||
<Content Include="apps\tests\pages\files\test.minWH450.xml" />
|
||||
<Content Include="apps\tests\pages\files\test.xml" />
|
||||
<Content Include="apps\ui-tests-app\pages\i86.xml" />
|
||||
<Content Include="apps\template-blank\app.css" />
|
||||
<Content Include="apps\template-hello-world\app.css" />
|
||||
@ -1500,7 +1511,7 @@
|
||||
<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_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_2layouts_2linear-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>
|
||||
</Project>
|
29
apps/tests/pages/file-load-test.ts
Normal file
29
apps/tests/pages/file-load-test.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import label = require("ui/label");
|
||||
import pages = require("ui/page");
|
||||
import fs = require("file-system");
|
||||
import fileResolverModule = require("file-system/file-name-resolver");
|
||||
|
||||
export function createPage() {
|
||||
var page = new pages.Page();
|
||||
var lbl = new label.Label();
|
||||
|
||||
var moduleName = "app/tests/pages/files/test";
|
||||
|
||||
var resolver = new fileResolverModule.FileNameResolver({
|
||||
width: 400,
|
||||
height: 600,
|
||||
os: "android",
|
||||
deviceType: "phone"
|
||||
});
|
||||
|
||||
// Current app full path.
|
||||
var currentAppPath = fs.knownFolders.currentApp().path;
|
||||
var moduleNamePath = fs.path.join(currentAppPath, moduleName);
|
||||
|
||||
var fileName = resolver.resolveFileName(moduleNamePath, "xml");
|
||||
lbl.text = fileName;
|
||||
lbl.textWrap = true;;
|
||||
|
||||
page.content = lbl;
|
||||
return page;
|
||||
}
|
1
apps/tests/pages/files/other.xml
Normal file
1
apps/tests/pages/files/other.xml
Normal file
@ -0,0 +1 @@
|
||||
other.xml
|
1
apps/tests/pages/files/test.android.phone.xml
Normal file
1
apps/tests/pages/files/test.android.phone.xml
Normal file
@ -0,0 +1 @@
|
||||
test.android.phone.xml
|
1
apps/tests/pages/files/test.android.xml
Normal file
1
apps/tests/pages/files/test.android.xml
Normal file
@ -0,0 +1 @@
|
||||
test.android.xml
|
1
apps/tests/pages/files/test.minWH300.xml
Normal file
1
apps/tests/pages/files/test.minWH300.xml
Normal file
@ -0,0 +1 @@
|
||||
test.minWH300.xml
|
1
apps/tests/pages/files/test.minWH450.xml
Normal file
1
apps/tests/pages/files/test.minWH450.xml
Normal file
@ -0,0 +1 @@
|
||||
test.monWH450.xml
|
1
apps/tests/pages/files/test.xml
Normal file
1
apps/tests/pages/files/test.xml
Normal file
@ -0,0 +1 @@
|
||||
test.xml
|
16
file-system/file-name-resolver.d.ts
vendored
Normal file
16
file-system/file-name-resolver.d.ts
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Provides FileNameResolver class used for loading files based on device capabilities.
|
||||
*/
|
||||
declare module "file-system/file-name-resolver" {
|
||||
interface PlatformContext {
|
||||
width: number;
|
||||
height: number;
|
||||
os: string;
|
||||
deviceType: string;
|
||||
}
|
||||
|
||||
class FileNameResolver {
|
||||
constructor(context: PlatformContext);
|
||||
resolveFileName(path: string, ext: string): string;
|
||||
}
|
||||
}
|
206
file-system/file-name-resolver.ts
Normal file
206
file-system/file-name-resolver.ts
Normal file
@ -0,0 +1,206 @@
|
||||
import definition = require("file-system/file-name-resolver");
|
||||
import fs = require("file-system");
|
||||
import types = require("utils/types");
|
||||
|
||||
var MIN_WH: string = "minWH";
|
||||
var MIN_W: string = "minW";
|
||||
var MIN_H: string = "minH";
|
||||
var PRIORITY_STEP = 10000;
|
||||
|
||||
interface QualifierSpec {
|
||||
isMatch(value: string): boolean;
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number;
|
||||
}
|
||||
|
||||
var minWidthHeightQualifier: QualifierSpec = {
|
||||
isMatch: function (value: string): boolean {
|
||||
return value.indexOf(MIN_WH) === 0;
|
||||
|
||||
},
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number {
|
||||
var numVal = parseInt(value.substr(MIN_WH.length));
|
||||
if (isNaN(numVal)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actualLength = Math.min(context.width, context.height);
|
||||
if (actualLength < numVal) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return PRIORITY_STEP - (actualLength - numVal);
|
||||
}
|
||||
}
|
||||
|
||||
var minWidthQualifier: QualifierSpec = {
|
||||
isMatch: function (value: string): boolean {
|
||||
return value.indexOf(MIN_W) === 0 && value.indexOf(MIN_WH) < 0;
|
||||
|
||||
},
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number {
|
||||
var numVal = parseInt(value.substr(MIN_W.length));
|
||||
if (isNaN(numVal)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actualWidth = context.width;
|
||||
if (actualWidth < numVal) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return PRIORITY_STEP - (actualWidth - numVal);
|
||||
}
|
||||
}
|
||||
|
||||
var minHeightQualifier: QualifierSpec = {
|
||||
isMatch: function (value: string): boolean {
|
||||
return value.indexOf(MIN_H) === 0 && value.indexOf(MIN_WH) < 0;
|
||||
|
||||
},
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number {
|
||||
var numVal = parseInt(value.substr(MIN_H.length));
|
||||
if (isNaN(numVal)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actualHeight = context.height;
|
||||
if (actualHeight < numVal) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return PRIORITY_STEP - (actualHeight - numVal)
|
||||
}
|
||||
}
|
||||
|
||||
var fromQualifier: QualifierSpec = {
|
||||
isMatch: function (value: string): boolean {
|
||||
return value === "tablet" || value === "phone";
|
||||
|
||||
},
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number{
|
||||
if (value !== context.deviceType.toLocaleLowerCase()) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
var paltformQualifier: QualifierSpec = {
|
||||
isMatch: function (value: string): boolean {
|
||||
return value === "android" ||
|
||||
value === "ios";
|
||||
|
||||
},
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number{
|
||||
return value === context.os.toLowerCase() ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
// List of supported qualifiers ordered by priority
|
||||
var supportedQualifiers: Array<QualifierSpec> = [
|
||||
minWidthHeightQualifier,
|
||||
minWidthQualifier,
|
||||
minHeightQualifier,
|
||||
paltformQualifier,
|
||||
fromQualifier];
|
||||
|
||||
export class FileNameResolver implements definition.FileNameResolver {
|
||||
private _context: definition.PlatformContext;
|
||||
private _cache = {};
|
||||
|
||||
constructor(context: definition.PlatformContext) {
|
||||
this._context = context;
|
||||
}
|
||||
|
||||
public resolveFileName(path: string, ext: string): string {
|
||||
var key = path + ext;
|
||||
var result: string = this._cache[key];
|
||||
if(types.isUndefined(result)) {
|
||||
result = this.resolveFileNameImpl(path, ext);
|
||||
this._cache[key] = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private resolveFileNameImpl(path: string, ext: string): string {
|
||||
path = fs.path.normalize(path);
|
||||
ext = "." + ext;
|
||||
var folderPath = path.substring(0, path.lastIndexOf(fs.path.separator) + 1);
|
||||
console.log("search folderPath: " + folderPath);
|
||||
|
||||
if (fs.Folder.exists(folderPath)) {
|
||||
var folder = fs.Folder.fromPath(folderPath);
|
||||
|
||||
var candidates = new Array<fs.File>();
|
||||
folder.eachEntity((e) => {
|
||||
|
||||
if (e instanceof fs.File) {
|
||||
var file = <fs.File>e;
|
||||
console.log("File path: " + e.path);
|
||||
if (file.path.indexOf(path) === 0 && file.extension === ext) {
|
||||
candidates.push(file);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
var bestValue = Number.MIN_VALUE;
|
||||
var bestCandidate: fs.File = null;
|
||||
|
||||
console.log("Candidates:");
|
||||
for (var i = 0; i < candidates.length; i++) {
|
||||
console.log("---------- candiate[" + i + "]: " + candidates[i].name);
|
||||
var filePath = candidates[i].path;
|
||||
var qualifiersStr: string = filePath.substr(path.length, filePath.length - path.length - ext.length);
|
||||
|
||||
var qualifiers = qualifiersStr.split(".");
|
||||
|
||||
var value = this.checkQualifiers(qualifiers);
|
||||
console.log("qualifiers: " + qualifiersStr + " result: " + value);
|
||||
|
||||
if (value >= 0 && value > bestValue) {
|
||||
bestValue = value;
|
||||
bestCandidate = candidates[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bestCandidate ? bestCandidate.path : null;
|
||||
}
|
||||
|
||||
private checkQualifiers(qualifiers: Array<string>): number {
|
||||
var result = 0;
|
||||
for (var i = 0; i < qualifiers.length; i++) {
|
||||
if (qualifiers[i]) {
|
||||
var value = this.checkQualifier(qualifiers[i]);
|
||||
|
||||
console.log("checking qualifier: " + qualifiers[i] + " result: " + value);
|
||||
if (value < 0) {
|
||||
// Non of the supported qualifiers matched this or the match was not satisified
|
||||
return -1;
|
||||
}
|
||||
|
||||
result += value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private checkQualifier(value: string) {
|
||||
for (var i = 0; i < supportedQualifiers.length; i++) {
|
||||
if (supportedQualifiers[i].isMatch(value)) {
|
||||
var result = supportedQualifiers[i].getMatchValue(value, this._context);
|
||||
if (result > 0) {
|
||||
result += (supportedQualifiers.length - i) * PRIORITY_STEP;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
@ -73,7 +73,9 @@ export class screen implements definition.screen {
|
||||
mainScreenInfo = {
|
||||
widthPixels: metrics.widthPixels,
|
||||
heightPixels: metrics.heightPixels,
|
||||
scale: metrics.density
|
||||
scale: metrics.density,
|
||||
widthDIPs: metrics.widthPixels / metrics.density,
|
||||
heightDIPs: metrics.heightPixels / metrics.density
|
||||
}
|
||||
}
|
||||
return mainScreenInfo;
|
||||
|
10
platform/platform.d.ts
vendored
10
platform/platform.d.ts
vendored
@ -61,6 +61,16 @@ declare module "platform" {
|
||||
*/
|
||||
heightPixels: number;
|
||||
|
||||
/**
|
||||
* Gets the absolute width of the screen in density independent pixels.
|
||||
*/
|
||||
widthDIPs: number;
|
||||
|
||||
/**
|
||||
* Gets the absolute height of the screen in density independent pixels.
|
||||
*/
|
||||
heightDIPs: number;
|
||||
|
||||
/**
|
||||
* The logical density of the display. This is a scaling factor for the Density Independent Pixel unit.
|
||||
*/
|
||||
|
@ -71,7 +71,9 @@ export class screen implements definition.screen {
|
||||
mainScreenInfo = {
|
||||
widthPixels: size.width * scale,
|
||||
heightPixels: size.height * scale,
|
||||
scale: scale
|
||||
scale: scale,
|
||||
widthDIPs: size.width,
|
||||
heightDIPs: size.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import builder = require("ui/builder");
|
||||
import fs = require("file-system");
|
||||
import utils = require("utils/utils");
|
||||
import platform = require("platform");
|
||||
import fileResolverModule = require("file-system/file-name-resolver");
|
||||
|
||||
var frameStack: Array<Frame> = [];
|
||||
|
||||
@ -68,14 +69,17 @@ function resolvePageFromEntry(entry: definition.NavigationEntry): pages.Page {
|
||||
return page;
|
||||
}
|
||||
|
||||
function resolvePlatformPath(path, ext) {
|
||||
var platformName = platform.device.os.toLowerCase();
|
||||
var platformPath = [path, platformName, ext].join(".");
|
||||
if (fs.File.exists(platformPath)) {
|
||||
return platformPath;
|
||||
var fileNameResolver: fileResolverModule.FileNameResolver;
|
||||
function resolveFilePath(path, ext) {
|
||||
if (!fileNameResolver) {
|
||||
fileNameResolver = new fileResolverModule.FileNameResolver({
|
||||
width: platform.screen.mainScreen.widthDIPs,
|
||||
height: platform.screen.mainScreen.heightDIPs,
|
||||
os: platform.device.os,
|
||||
deviceType: platform.device.deviceType
|
||||
});
|
||||
}
|
||||
|
||||
return [path, ext].join(".");
|
||||
return fileNameResolver.resolveFileName(path, ext);
|
||||
}
|
||||
|
||||
function pageFromBuilder(moduleNamePath: string, moduleName: string, moduleExports: any): pages.Page {
|
||||
@ -83,7 +87,7 @@ function pageFromBuilder(moduleNamePath: string, moduleName: string, moduleExpor
|
||||
var element: view.View;
|
||||
|
||||
// Possible XML file path.
|
||||
var fileName = resolvePlatformPath(moduleNamePath, "xml");
|
||||
var fileName = resolveFilePath(moduleNamePath, "xml");
|
||||
|
||||
if (fs.File.exists(fileName)) {
|
||||
trace.write("Loading XML file: " + fileName, trace.categories.Navigation);
|
||||
@ -94,7 +98,7 @@ function pageFromBuilder(moduleNamePath: string, moduleName: string, moduleExpor
|
||||
page = <pages.Page>element;
|
||||
|
||||
// Possible CSS file path.
|
||||
var cssFileName = resolvePlatformPath(moduleName, "css");
|
||||
var cssFileName = resolveFilePath(moduleName, "css");
|
||||
page.addCssFile(cssFileName);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user