mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-17 04:41:36 +08:00
feat(style-scope): Resolve css sheets from tns_modules
If the css sheet is not in the app directory, try to find it in the tns_modules folder.
This commit is contained in:
@ -12,6 +12,7 @@ import types = require("utils/types");
|
|||||||
import viewModule = require("ui/core/view");
|
import viewModule = require("ui/core/view");
|
||||||
import styleModule = require("ui/styling/style");
|
import styleModule = require("ui/styling/style");
|
||||||
import dependencyObservableModule = require("ui/core/dependency-observable");
|
import dependencyObservableModule = require("ui/core/dependency-observable");
|
||||||
|
import { resolveFileNameFromUrl } from "ui/styling/style-scope";
|
||||||
|
|
||||||
export function test_css_dataURI_is_applied_to_backgroundImageSource() {
|
export function test_css_dataURI_is_applied_to_backgroundImageSource() {
|
||||||
var stack = new stackModule.StackLayout();
|
var stack = new stackModule.StackLayout();
|
||||||
@ -1382,9 +1383,9 @@ export function test_star_attr_selector_incorrect_syntax() {
|
|||||||
export function test_alone_attr_selector() {
|
export function test_alone_attr_selector() {
|
||||||
let testButton = new buttonModule.Button();
|
let testButton = new buttonModule.Button();
|
||||||
testButton["testAttr"] = "flow";
|
testButton["testAttr"] = "flow";
|
||||||
|
|
||||||
let testCss = "[testAttr*='flower'] { background-color: #FF0000; } button { background-color: #00FF00; }";
|
let testCss = "[testAttr*='flower'] { background-color: #FF0000; } button { background-color: #00FF00; }";
|
||||||
|
|
||||||
let testFunc = function (views: Array<viewModule.View>) {
|
let testFunc = function (views: Array<viewModule.View>) {
|
||||||
// style from correct type css should be applied
|
// style from correct type css should be applied
|
||||||
helper.assertViewBackgroundColor(testButton, "#00FF00");
|
helper.assertViewBackgroundColor(testButton, "#00FF00");
|
||||||
@ -1395,9 +1396,9 @@ export function test_alone_attr_selector() {
|
|||||||
export function test_UsingSameSelectors_ShouldApplyLatest() {
|
export function test_UsingSameSelectors_ShouldApplyLatest() {
|
||||||
let testButton = new buttonModule.Button();
|
let testButton = new buttonModule.Button();
|
||||||
testButton.className = 'green';
|
testButton.className = 'green';
|
||||||
|
|
||||||
let testCss = ".green { background-color: #FF0000; } .green { background-color: #00FF00; }";
|
let testCss = ".green { background-color: #FF0000; } .green { background-color: #00FF00; }";
|
||||||
|
|
||||||
let testFunc = function (views: Array<viewModule.View>) {
|
let testFunc = function (views: Array<viewModule.View>) {
|
||||||
// style from correct type css should be applied
|
// style from correct type css should be applied
|
||||||
helper.assertViewBackgroundColor(testButton, "#00FF00");
|
helper.assertViewBackgroundColor(testButton, "#00FF00");
|
||||||
@ -1408,9 +1409,9 @@ export function test_UsingSameSelectors_ShouldApplyLatest() {
|
|||||||
export function test_UsingSameSelectorsWithSpecific_ShouldApplyLatest() {
|
export function test_UsingSameSelectorsWithSpecific_ShouldApplyLatest() {
|
||||||
let testButton = new buttonModule.Button();
|
let testButton = new buttonModule.Button();
|
||||||
testButton.className = 'red green';
|
testButton.className = 'red green';
|
||||||
|
|
||||||
let testCss = ".red { background-color: #FF0000; } Button.green { background-color: #00FF00; }";
|
let testCss = ".red { background-color: #FF0000; } Button.green { background-color: #00FF00; }";
|
||||||
|
|
||||||
let testFunc = function (views: Array<viewModule.View>) {
|
let testFunc = function (views: Array<viewModule.View>) {
|
||||||
// style from correct type css should be applied
|
// style from correct type css should be applied
|
||||||
helper.assertViewBackgroundColor(testButton, "#00FF00");
|
helper.assertViewBackgroundColor(testButton, "#00FF00");
|
||||||
@ -1435,6 +1436,55 @@ export function test_CascadingClassNamesAppliesAfterPageLoad() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function test_resolveFileNameFromUrl_local_file_tilda() {
|
||||||
|
const localFileExistsMock = (fileName: string ) => true;
|
||||||
|
let url = "~/theme/core.css";
|
||||||
|
let appDirectory = "app";
|
||||||
|
let expected = `${appDirectory}/theme/core.css`;
|
||||||
|
let result = resolveFileNameFromUrl(url, appDirectory, localFileExistsMock);
|
||||||
|
|
||||||
|
TKUnit.assertEqual(result, expected, "Should resolve local file with leading tilda (~/)");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function test_resolveFileNameFromUrl_local_file_no_tilda() {
|
||||||
|
const localFileExistsMock = (fileName: string ) => true;
|
||||||
|
let url = "theme/core.css";
|
||||||
|
let appDirectory = "app";
|
||||||
|
let expected = `${appDirectory}/theme/core.css`;
|
||||||
|
let result = resolveFileNameFromUrl(url, appDirectory, localFileExistsMock);
|
||||||
|
|
||||||
|
TKUnit.assertEqual(result, expected, "Should resolve local file without leading tilda (no ~/)");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function test_resolveFileNameFromUrl_external_file_tilda() {
|
||||||
|
const externalFileExistsMock = (fileName: string) => (fileName.indexOf("tns_modules") !== -1);
|
||||||
|
let url = "~/theme/core.css";
|
||||||
|
let appDirectory = "app";
|
||||||
|
let expected = `${appDirectory}/tns_modules/theme/core.css`;
|
||||||
|
let result = resolveFileNameFromUrl(url, appDirectory, externalFileExistsMock);
|
||||||
|
|
||||||
|
TKUnit.assertEqual(result, expected, "Should resolve file from tns_modules with leading tilda (~/)");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function test_resolveFileNameFromUrl_external_file_no_tilda() {
|
||||||
|
const externalFileExistsMock = (fileName: string) => (fileName.indexOf("tns_modules") !== -1);
|
||||||
|
let url = "theme/core.css";
|
||||||
|
let appDirectory = "app";
|
||||||
|
let expected = `${appDirectory}/tns_modules/theme/core.css`;
|
||||||
|
let result = resolveFileNameFromUrl(url, appDirectory, externalFileExistsMock);
|
||||||
|
|
||||||
|
TKUnit.assertEqual(result, expected, "Should resolve file from tns_modules without leading tilda (no ~/)");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function test_resolveFileNameFromUrl_unexisting_file() {
|
||||||
|
const fileDoesNotExistMock = (fileName: string) => false;
|
||||||
|
let url = "~/theme/core.css";
|
||||||
|
let appDirectory = "app";
|
||||||
|
let result = resolveFileNameFromUrl(url, appDirectory, fileDoesNotExistMock);
|
||||||
|
|
||||||
|
TKUnit.assertNull(result, "Shouldn't resolve unexisting file");
|
||||||
|
}
|
||||||
|
|
||||||
// <snippet module="ui/styling" title="styling">
|
// <snippet module="ui/styling" title="styling">
|
||||||
// For information and example how to use style properties please refer to special [**Styling**](../../../styling.md) topic.
|
// For information and example how to use style properties please refer to special [**Styling**](../../../styling.md) topic.
|
||||||
// </snippet>
|
// </snippet>
|
||||||
|
1
tns-core-modules/ui/styling/style-scope.d.ts
vendored
1
tns-core-modules/ui/styling/style-scope.d.ts
vendored
@ -32,5 +32,6 @@ declare module "ui/styling/style-scope" {
|
|||||||
public getAnimations(ruleset: RuleSet): KeyframeAnimationInfo[];
|
public getAnimations(ruleset: RuleSet): KeyframeAnimationInfo[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolveFileNameFromUrl(url: string, appDirectory: string, fileExists: (string) => boolean): string;
|
||||||
export function applyInlineSyle(view: view.View, style: string): void;
|
export function applyInlineSyle(view: view.View, style: string): void;
|
||||||
}
|
}
|
||||||
|
@ -149,13 +149,11 @@ export class StyleScope {
|
|||||||
if (utils.isFileOrResourcePath(url)) {
|
if (utils.isFileOrResourcePath(url)) {
|
||||||
ensureFS();
|
ensureFS();
|
||||||
|
|
||||||
let fileName = types.isString(url) ? url.trim() : "";
|
let appDirectory = fs.knownFolders.currentApp().path;
|
||||||
if (fileName.indexOf("~/") === 0) {
|
let fileName = resolveFileNameFromUrl(url, appDirectory, fs.File.exists);
|
||||||
fileName = fs.path.join(fs.knownFolders.currentApp().path, fileName.replace("~/", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fs.File.exists(fileName)) {
|
if (fileName !== null) {
|
||||||
let file = fs.File.fromPath(fileName);
|
let file: fileSystemModule.File = fs.File.fromPath(fileName);
|
||||||
let text = file.readTextSync();
|
let text = file.readTextSync();
|
||||||
if (text) {
|
if (text) {
|
||||||
selectors = selectors.concat(StyleScope.createSelectorsFromCss(text, fileName, keyframes));
|
selectors = selectors.concat(StyleScope.createSelectorsFromCss(text, fileName, keyframes));
|
||||||
@ -197,7 +195,7 @@ export class StyleScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public applySelectors(view: view.View): void {
|
public applySelectors(view: view.View): void {
|
||||||
this.ensureSelectors();
|
this.ensureSelectors();
|
||||||
|
|
||||||
let state = this._selectors.query(view);
|
let state = this._selectors.query(view);
|
||||||
|
|
||||||
@ -245,6 +243,26 @@ export class StyleScope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolveFileNameFromUrl(url: string, appDirectory: string, fileExists: (string) => boolean): string {
|
||||||
|
let fileName: string = types.isString(url) ? url.trim() : "";
|
||||||
|
|
||||||
|
if (fileName.indexOf("~/") === 0) {
|
||||||
|
fileName = fileName.replace("~/", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
let local = fs.path.join(appDirectory, fileName);
|
||||||
|
if (fileExists(local)) {
|
||||||
|
return local;
|
||||||
|
}
|
||||||
|
|
||||||
|
let external = fs.path.join(appDirectory, "tns_modules", fileName);
|
||||||
|
if (fileExists(external)) {
|
||||||
|
return external;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
export function applyInlineSyle(view: view.View, style: string) {
|
export function applyInlineSyle(view: view.View, style: string) {
|
||||||
try {
|
try {
|
||||||
let syntaxTree = cssParser.parse("local { " + style + " }", undefined);
|
let syntaxTree = cssParser.parse("local { " + style + " }", undefined);
|
||||||
|
Reference in New Issue
Block a user