feat(styling): Added 2 functions to control applicationAdditionalSelectors (#6124)

* Added getAdditionalSelectors function so that nativescript-theme can be functional again in NS 4.x

* Change to a better more extensible additional css system.

* removed redunant function on the name.

* Fix lint issues

* Adding mergeSelectors to the remove function

* Added test of new add/remove css functions.

* fix: revert testRunner.ts changes that disabled all tests except style

* refactor: fix typo

* chore: fix typo and change test to no not affect global styles
This commit is contained in:
Nathanael Anderson
2018-08-02 03:51:07 -05:00
committed by Alexander Vakrilov
parent cf034dd04d
commit 85b8c018a5
3 changed files with 67 additions and 3 deletions

View File

@@ -9,7 +9,7 @@ import * as tabViewModule from "tns-core-modules/ui/tab-view";
import * as helper from "../../ui/helper";
import * as types from "tns-core-modules/utils/types";
import * as viewModule from "tns-core-modules/ui/core/view";
import { resolveFileNameFromUrl } from "tns-core-modules/ui/styling/style-scope";
import { resolveFileNameFromUrl, removeTaggedAdditionalCSS, addTaggedAdditionalCSS } from "tns-core-modules/ui/styling/style-scope";
import { unsetValue } from "tns-core-modules/ui/core/view";
import * as color from "tns-core-modules/color";
@@ -1479,6 +1479,36 @@ export function test_resolveFileNameFromUrl_unexisting_file() {
TKUnit.assertNull(result, "Shouldn't resolve unexisting file");
}
export function test_checkAddRemoveCSS() {
const css1 = "#test_checkAddRemoveCSS_label { color: #FF0000; }";
const css2 = "#test_checkAddRemoveCSS_label { color: #00FF00; }";
const label = new labelModule.Label();
label.text = "color coming from updated rules";
label.id = "test_checkAddRemoveCSS_label";
helper.buildUIAndRunTest(label, function (views: Array<viewModule.View>) {
const page = <pageModule.Page>views[1];
// Add Red, we have to then trigger the page's CSS state change, for it to refresh the label's css with the new global rule
addTaggedAdditionalCSS(css1, "red");
page._onCssStateChange();
helper.assertViewColor(label, "#FF0000");
// Add Green (should override red)
addTaggedAdditionalCSS(css2, "green");
page._onCssStateChange();
helper.assertViewColor(label, "#00FF00");
// Remove Green (Should revert to red, since we removed the green rule)
removeTaggedAdditionalCSS("green");
page._onCssStateChange();
helper.assertViewColor(label, "#FF0000");
//Cleanup
removeTaggedAdditionalCSS("red");
});
}
// <snippet module="ui/styling" title="styling">
// For information and example how to use style properties please refer to special [**Styling**](../../../styling.md) topic.
// </snippet>

View File

@@ -43,6 +43,11 @@ export class RuleSet {
* Gets the key-value list of declarations for the ruleset.
*/
declarations: Declaration[];
/**
* Optional Tag for rules
**/
tag: string | Number;
}
export class SelectorsMap {
@@ -68,7 +73,7 @@ export class SelectorsMatch<T extends Node> {
selectors: SelectorCore[];
/**
* Gets a map of nodes to attributes and pseudo classes, that may affect the state of the dynamic
* Gets a map of nodes to attributes and pseudo classes, that may affect the state of the dynamic
*/
changeMap: ChangeMap<T>;
}

View File

@@ -262,6 +262,35 @@ class CSSSource {
}
}
export function removeTaggedAdditionalCSS(tag: String | Number): Boolean {
let changed = false;
for (let i = 0; i < applicationAdditionalSelectors.length; i++) {
if (applicationAdditionalSelectors[i].tag === tag) {
applicationAdditionalSelectors.splice(i, 1);
i--;
changed = true;
}
}
if (changed) { mergeCssSelectors(); }
return changed;
}
export function addTaggedAdditionalCSS(cssText: string, tag?: string | Number): Boolean {
const parsed: RuleSet[] = CSSSource.fromSource(cssText, applicationKeyframes, undefined).selectors;
let changed = false;
if (parsed && parsed.length) {
changed = true;
if (tag != null) {
for (let i = 0; i < parsed.length; i++) {
parsed[i].tag = tag;
}
}
applicationAdditionalSelectors.push.apply(applicationAdditionalSelectors, parsed);
mergeCssSelectors();
}
return changed;
}
const onCssChanged = profile("\"style-scope\".onCssChanged", (args: applicationCommon.CssChangedEventData) => {
if (args.cssText) {
const parsed = CSSSource.fromSource(args.cssText, applicationKeyframes, args.cssFile).selectors;
@@ -414,7 +443,7 @@ export class CssState {
* Calculate the difference between the previously applied property values,
* and the new set of property values that have to be applied for the provided selectors.
* Apply the values and ensure each property setter is called at most once to avoid excessive change notifications.
* @param matchingSelectors
* @param matchingSelectors
*/
private setPropertyValues(matchingSelectors: SelectorCore[]): void {
const newPropertyValues = new this.view.style.PropertyBag();