mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
feat: implement css-variables and css-calc (#7553)
* feat: implement basic support for css-variables * fix(test): test-watch-android and test-watch-ios was broken * fix: processing css-variables belong in CssProperty-classes Not in the StyleScope. * fix(css-variables): set style attribute override value from css-classes * feat: add css calc-support using 'reduce-css-calc' * fix(tslint): missing semicolon and incorrect quotemark * feat: move css-variable handling to Style-class * chor: add comments explaining css-variable implmentation * chor: set css-variables before other style properties * chor(css-variables): cleaning up * chor: code style fixes * test(CSS-CALC): Add tests for nested css-calc statements * fix(CSS-CALC): dip-unit not supported by reduce-css-calc * fix(tslint): use double quotemarks * test(css-calc): test _cssCalcConverter directly * chor(css-variables): rename and clean up _cssVariableConverter to _evaluateCssVariable * chor: rename varname to varName for consistency * chor: support css-calc and variables for normal properties * chor: use string.replace to evaluate css-variables * fix: Missing blank line before return * chor: rename css-calc functions * fix: undefined css-variables treated as 'unset' * fix(tslint): use double quotemarks * feat(css-variable): handle fallback values * chor(css-variables): handle unsetValue * chor: process css-calc and css-variables in style-scope * chore: clean-up css-calc/variable expressions * fix(css-calc): handle invalid expressions * chore(CSSState): update comments * chore(Style): rename css-variable functions * chore(css-variables): describe fallback logic * chore: move reset scoped css-variables to Style-class * chore(CssState): simplify check for css expressions * chore: add reduce-css-calc to /package.json
This commit is contained in:
committed by
Svetoslav
parent
0adcb64cc3
commit
673c8087e0
@@ -144,6 +144,10 @@ export function makeParser<T>(isValid: (value: any) => boolean): (value: any) =>
|
||||
export function getSetProperties(view: ViewBase): [string, any][];
|
||||
export function getComputedCssValues(view: ViewBase): [string, any][];
|
||||
|
||||
export function isCssVariable(property: string): boolean;
|
||||
export function isCssCalcExpression(value: string): boolean;
|
||||
export function isCssVariableExpression(value: string): boolean;
|
||||
|
||||
//@private
|
||||
/**
|
||||
* @private get all properties defined on ViewBase
|
||||
@@ -154,4 +158,8 @@ export function _getProperties(): Property<any, any>[];
|
||||
* @private get all properties defined on Style
|
||||
*/
|
||||
export function _getStyleProperties(): CssProperty<any, any>[];
|
||||
|
||||
export function _evaluateCssVariableExpression(view: ViewBase, cssName: string, value: string): string;
|
||||
|
||||
export function _evaluateCssCalcExpression(value: string): string;
|
||||
//@endprivate
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import reduceCSSCalc from "reduce-css-calc";
|
||||
|
||||
// Definitions.
|
||||
import * as definitions from "../view-base";
|
||||
import { ViewBase } from "../view-base";
|
||||
@@ -56,6 +58,76 @@ export function _getStyleProperties(): CssProperty<any, any>[] {
|
||||
return getPropertiesFromMap(cssSymbolPropertyMap) as CssProperty<any, any>[];
|
||||
}
|
||||
|
||||
const cssVariableExpressionRegexp = /\bvar\(\s*(--[^,\s]+?)(?:\s*,\s*(.+))?\s*\)/;
|
||||
const cssVariableAllExpressionsRegexp = /\bvar\(\s*(--[^,\s]+?)(?:\s*,\s*(.+))?\s*\)/g;
|
||||
|
||||
export function isCssVariable(property: string) {
|
||||
return /^--[^,\s]+?$/.test(property);
|
||||
}
|
||||
|
||||
export function isCssCalcExpression(value: string) {
|
||||
return /\bcalc\(/.test(value);
|
||||
}
|
||||
|
||||
export function isCssVariableExpression(value: string) {
|
||||
return cssVariableExpressionRegexp.test(value);
|
||||
}
|
||||
|
||||
export function _evaluateCssVariableExpression(view: ViewBase, cssName: string, value: string): string {
|
||||
if (typeof value !== "string") {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (!isCssVariableExpression(value)) {
|
||||
// Value is not using css-variable(s)
|
||||
return value;
|
||||
}
|
||||
|
||||
let output = value.trim();
|
||||
|
||||
// Evaluate every (and nested) css-variables in the value.
|
||||
let lastValue: string;
|
||||
while (lastValue !== output) {
|
||||
lastValue = output;
|
||||
|
||||
output = output.replace(cssVariableAllExpressionsRegexp, (matchStr, cssVariableName: string, fallbackStr: string) => {
|
||||
const cssVariableValue = view.style.getCssVariable(cssVariableName);
|
||||
if (cssVariableValue !== null) {
|
||||
return cssVariableValue;
|
||||
}
|
||||
|
||||
if (fallbackStr) {
|
||||
// css-variable not found, using fallback-string.
|
||||
const fallbackOutput = _evaluateCssVariableExpression(view, cssName, fallbackStr);
|
||||
if (fallbackOutput) {
|
||||
// If the fallback have multiple values, return the first of them.
|
||||
return fallbackOutput.split(",")[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find a value for the css-variable or the fallback, return "unset"
|
||||
traceWrite(`Failed to get value for css-variable "${cssVariableName}" used in "${cssName}"=[${value}] to ${view}`, traceCategories.Style, traceMessageType.error);
|
||||
|
||||
return "unset";
|
||||
});
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
export function _evaluateCssCalcExpression(value: string) {
|
||||
if (typeof value !== "string") {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (isCssCalcExpression(value)) {
|
||||
// WORKAROUND: reduce-css-calc can't handle the dip-unit.
|
||||
return reduceCSSCalc(value.replace(/([0-9]+(\.[0-9]+)?)dip\b/g, "$1"));
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
function getPropertiesFromMap(map): Property<any, any>[] | CssProperty<any, any>[] {
|
||||
const props = [];
|
||||
Object.getOwnPropertySymbols(map).forEach(symbol => props.push(map[symbol]));
|
||||
|
||||
Reference in New Issue
Block a user