feat(core): CSS wide keywords (#10709)

This commit is contained in:
Dimitris-Rafail Katsampas
2025-02-26 05:15:47 +02:00
committed by GitHub
parent 5024156f0d
commit 2d71ada46d
12 changed files with 247 additions and 94 deletions

View File

@ -176,6 +176,9 @@ allTests['STYLE'] = styleTests;
import * as visualStateTests from './ui/styling/visual-state-tests';
allTests['VISUAL-STATE'] = visualStateTests;
import * as cssKeywordsTests from './ui/styling/css-keywords-tests';
allTests['CSS-KEYWORDS'] = cssKeywordsTests;
import * as valueSourceTests from './ui/styling/value-source-tests';
allTests['VALUE-SOURCE'] = valueSourceTests;

View File

@ -0,0 +1,132 @@
import * as helper from '../../ui-helper';
import * as TKUnit from '../../tk-unit';
import { Color, Button, StackLayout } from '@nativescript/core';
export var test_value_after_initial = function () {
let page = helper.getCurrentPage();
let btn = new Button();
let testStack = new StackLayout();
page.css = 'StackLayout { background-color: #FF0000; }';
page.content = testStack;
testStack.addChild(btn);
btn.backgroundColor = new Color('#0000FF');
TKUnit.assertEqual(btn.backgroundColor.hex, '#0000FF', 'backgroundColor property');
btn.backgroundColor = 'initial';
TKUnit.assertEqual(btn.backgroundColor, undefined, 'backgroundColor property');
};
export var test_value_Inherited_after_initial = function () {
let page = helper.getCurrentPage();
let btn = new Button();
let testStack = new StackLayout();
page.css = 'StackLayout { color: #FF0000; }';
page.content = testStack;
testStack.addChild(btn);
btn.color = new Color('#0000FF');
TKUnit.assertEqual(btn.color.hex, '#0000FF', 'color property');
(btn as any).color = 'initial';
TKUnit.assertEqual(btn.color, undefined, 'color property');
};
export var test_value_after_unset = function () {
let page = helper.getCurrentPage();
let btn = new Button();
let testStack = new StackLayout();
page.css = 'StackLayout { background-color: #FF0000; }';
page.content = testStack;
testStack.addChild(btn);
btn.backgroundColor = new Color('#0000FF');
TKUnit.assertEqual(btn.backgroundColor.hex, '#0000FF', 'backgroundColor property');
btn.backgroundColor = 'unset';
TKUnit.assertEqual(btn.backgroundColor, undefined, 'backgroundColor property');
};
export var test_value_Inherited_after_unset = function () {
let page = helper.getCurrentPage();
let btn = new Button();
let testStack = new StackLayout();
page.css = 'StackLayout { color: #FF0000; }';
page.content = testStack;
testStack.addChild(btn);
btn.color = new Color('#0000FF');
TKUnit.assertEqual(btn.color.hex, '#0000FF', 'color property');
(btn as any).color = 'unset';
TKUnit.assertEqual(btn.color.hex, '#FF0000', 'color property');
};
export var test_value_after_revert = function () {
let page = helper.getCurrentPage();
let btn = new Button();
let testStack = new StackLayout();
page.css = 'StackLayout { background-color: #FF0000; }';
page.content = testStack;
testStack.addChild(btn);
btn.backgroundColor = new Color('#0000FF');
TKUnit.assertEqual(btn.backgroundColor.hex, '#0000FF', 'backgroundColor property');
btn.backgroundColor = 'revert';
TKUnit.assertEqual(btn.backgroundColor, undefined, 'backgroundColor property');
};
export var test_value_Inherited_after_revert = function () {
let page = helper.getCurrentPage();
let btn = new Button();
let testStack = new StackLayout();
page.css = 'StackLayout { color: #FF0000; }';
page.content = testStack;
testStack.addChild(btn);
btn.color = new Color('#0000FF');
TKUnit.assertEqual(btn.color.hex, '#0000FF', 'color property');
(btn as any).color = 'revert';
TKUnit.assertEqual(btn.color.hex, '#FF0000', 'color property');
};
// TODO: Add missing inherit support for non-inherited properties
export var test_value_after_inherit = function () {
let page = helper.getCurrentPage();
let btn = new Button();
let testStack = new StackLayout();
page.css = 'StackLayout { background-color: #FF0000; }';
page.content = testStack;
testStack.addChild(btn);
btn.backgroundColor = new Color('#0000FF');
TKUnit.assertEqual(btn.backgroundColor.hex, '#0000FF', 'backgroundColor property');
btn.backgroundColor = 'inherit';
TKUnit.assertEqual(btn.backgroundColor, undefined, 'backgroundColor property');
};
export var test_value_Inherited_after_inherit = function () {
let page = helper.getCurrentPage();
let btn = new Button();
let testStack = new StackLayout();
page.css = 'StackLayout { color: #FF0000; }';
page.content = testStack;
testStack.addChild(btn);
btn.color = new Color('#0000FF');
TKUnit.assertEqual(btn.color.hex, '#0000FF', 'color property');
(btn as any).color = 'inherit';
TKUnit.assertEqual(btn.color.hex, '#FF0000', 'color property');
};

View File

@ -7,6 +7,8 @@ import { makeValidator, makeParser } from '../ui/core/properties';
import { CubicBezierAnimationCurve } from '../ui/animation/animation-interfaces';
export namespace CoreTypes {
export type CSSWideKeywords = 'initial' | 'inherit' | 'unset' | 'revert';
/**
* Denotes a length number that is in device independent pixel units.
*/
@ -29,7 +31,7 @@ export namespace CoreTypes {
export type LengthPxUnit = { readonly unit: 'px'; readonly value: px };
export type LengthPercentUnit = { readonly unit: '%'; readonly value: percent };
export type FixedLengthType = dip | LengthDipUnit | LengthPxUnit;
export type FixedLengthType = dip | LengthDipUnit | LengthPxUnit | CSSWideKeywords;
export type LengthType = 'auto' | FixedLengthType;
export type PercentLengthType = 'auto' | FixedLengthType | LengthPercentUnit;
@ -66,7 +68,7 @@ export namespace CoreTypes {
export const send = 'send';
}
export type TextAlignmentType = 'initial' | 'left' | 'center' | 'right' | 'justify';
export type TextAlignmentType = 'left' | 'center' | 'right' | 'justify' | CSSWideKeywords;
export namespace TextAlignment {
export const left = 'left';
export const center = 'center';
@ -74,14 +76,14 @@ export namespace CoreTypes {
export const justify = 'justify';
}
export type TextDecorationType = 'none' | 'underline' | 'line-through' | 'underline line-through';
export type TextDecorationType = 'none' | 'underline' | 'line-through' | 'underline line-through' | CSSWideKeywords;
export namespace TextDecoration {
export const none = 'none';
export const underline = 'underline';
export const lineThrough = 'line-through';
}
export type TextTransformType = 'initial' | 'none' | 'capitalize' | 'uppercase' | 'lowercase';
export type TextTransformType = 'none' | 'capitalize' | 'uppercase' | 'lowercase' | CSSWideKeywords;
export namespace TextTransform {
export const none = 'none';
export const capitalize = 'capitalize';
@ -89,18 +91,16 @@ export namespace CoreTypes {
export const lowercase = 'lowercase';
}
export type WhiteSpaceType = 'initial' | 'normal' | 'nowrap';
export type WhiteSpaceType = 'normal' | 'nowrap' | CSSWideKeywords;
export namespace WhiteSpace {
export const normal = 'normal';
export const nowrap = 'nowrap';
}
export type TextOverflowType = 'clip' | 'ellipsis' | 'initial' | 'unset';
export type TextOverflowType = 'clip' | 'ellipsis' | CSSWideKeywords;
export namespace TextOverflow {
export const clip = 'clip';
export const ellipsis = 'ellipsis';
export const initial = 'initial';
export const unset = 'unset';
}
export type MaxLinesType = number;
@ -118,7 +118,7 @@ export namespace CoreTypes {
export const unknown = 'unknown';
}
export type HorizontalAlignmentType = 'left' | 'center' | 'right' | 'stretch';
export type HorizontalAlignmentType = 'left' | 'center' | 'right' | 'stretch' | CSSWideKeywords;
export namespace HorizontalAlignment {
export const left = 'left';
export const center = 'center';
@ -128,7 +128,7 @@ export namespace CoreTypes {
export const parse = makeParser<HorizontalAlignmentType>(isValid);
}
export type VerticalAlignmentType = 'top' | 'middle' | 'bottom' | 'stretch';
export type VerticalAlignmentType = 'top' | 'middle' | 'bottom' | 'stretch' | CSSWideKeywords;
export namespace VerticalAlignment {
export const top = 'top';
export const middle = 'middle';
@ -159,7 +159,7 @@ export namespace CoreTypes {
export const fill: ImageStretchType = 'fill';
}
export type VisibilityType = 'visible' | 'hidden' | 'collapse' | 'collapsed';
export type VisibilityType = 'visible' | 'hidden' | 'collapse' | 'collapsed' | CSSWideKeywords;
export namespace Visibility {
export const visible: VisibilityType = 'visible';
export const collapse: VisibilityType = 'collapse';
@ -254,7 +254,7 @@ export namespace CoreTypes {
export const black: string = '900';
}
export type BackgroundRepeatType = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat';
export type BackgroundRepeatType = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat' | CSSWideKeywords;
export namespace BackgroundRepeat {
export const repeat: BackgroundRepeatType = 'repeat';
export const repeatX: BackgroundRepeatType = 'repeat-x';

View File

@ -7,6 +7,7 @@ import { Trace } from '../../../trace';
import { Style } from '../../styling/style';
import { profile } from '../../../profiling';
import { CoreTypes } from '../../enums';
/**
* Value specifying that Property should be set to its initial value.
@ -53,6 +54,14 @@ const cssSymbolPropertyMap = {};
const inheritableProperties = new Array<InheritedProperty<any, any>>();
const inheritableCssProperties = new Array<InheritedCssProperty<any, any>>();
const enum ValueSource {
Default = 0,
Inherited = 1,
Css = 2,
Local = 3,
Keyframe = 4,
}
function print(map) {
const symbols = Object.getOwnPropertySymbols(map);
for (const symbol of symbols) {
@ -63,19 +72,19 @@ function print(map) {
}
}
function isCssUnsetValue(value: any): boolean {
return value === 'unset' || value === 'revert';
}
function isResetValue(value: any): boolean {
return value === unsetValue || value === 'initial' || value === 'inherit' || isCssUnsetValue(value);
}
export function _printUnregisteredProperties(): void {
print(symbolPropertyMap);
print(cssSymbolPropertyMap);
}
const enum ValueSource {
Default = 0,
Inherited = 1,
Css = 2,
Local = 3,
Keyframe = 4,
}
export function _getProperties(): Property<any, any>[] {
return getPropertiesFromMap(symbolPropertyMap) as Property<any, any>[];
}
@ -96,6 +105,10 @@ export function isCssVariableExpression(value: string) {
return value.includes('var(--');
}
export function isCssWideKeyword(value: any): value is CoreTypes.CSSWideKeywords {
return value === 'initial' || value === 'inherit' || isCssUnsetValue(value);
}
export function _evaluateCssVariableExpression(view: ViewBase, cssName: string, value: string): string {
if (typeof value !== 'string') {
return value;
@ -236,7 +249,7 @@ export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<
const property = this;
this.set = function (this: T, boxedValue: U): void {
const reset = boxedValue === unsetValue;
const reset = isResetValue(boxedValue);
let value: U;
let wrapped: boolean;
if (reset) {
@ -419,7 +432,7 @@ export class CoercibleProperty<T extends ViewBase, U> extends Property<T, U> imp
};
this.set = function (this: T, boxedValue: U): void {
const reset = boxedValue === unsetValue;
const reset = isResetValue(boxedValue);
let value: U;
let wrapped: boolean;
if (reset) {
@ -528,11 +541,11 @@ export class InheritedProperty<T extends ViewBase, U> extends Property<T, U> imp
let unboxedValue: U;
let newValueSource: number;
if (value === unsetValue) {
// If unsetValue - we want to reset the property.
if (isResetValue(value)) {
const parent: ViewBase = that.parent;
// If we have parent and it has non-default value we use as our inherited value.
if (parent && parent[sourceKey] !== ValueSource.Default) {
// If value is not initial or unset and view has a parent that has non-default value, use it as the reset value.
if (value !== 'initial' && parent && parent[sourceKey] !== ValueSource.Default) {
unboxedValue = parent[name];
newValueSource = ValueSource.Inherited;
} else {
@ -659,8 +672,9 @@ export class CssProperty<T extends Style, U> implements CssProperty<T, U> {
return;
}
const reset = newValue === unsetValue || newValue === '';
const reset = isResetValue(newValue) || newValue === '';
let value: U;
if (reset) {
value = defaultValue;
delete this[sourceKey];
@ -744,8 +758,9 @@ export class CssProperty<T extends Style, U> implements CssProperty<T, U> {
return;
}
const reset = newValue === unsetValue || newValue === '';
const reset = isResetValue(newValue) || newValue === '';
let value: U;
if (reset) {
value = defaultValue;
delete this[sourceKey];
@ -942,16 +957,16 @@ export class CssAnimationProperty<T extends Style, U> implements CssAnimationPro
const oldValue = this[computedValue];
const oldSource = this[computedSource];
const wasSet = oldSource !== ValueSource.Default;
const reset = boxedValue === unsetValue || boxedValue === '';
const reset = isResetValue(boxedValue) || boxedValue === '';
if (reset) {
this[symbol] = unsetValue;
this[symbol] = boxedValue;
if (this[computedSource] === propertySource) {
// Fallback to lower value source.
if (this[styleValue] !== unsetValue) {
if (!isResetValue(this[styleValue])) {
this[computedSource] = ValueSource.Local;
this[computedValue] = this[styleValue];
} else if (this[cssValue] !== unsetValue) {
} else if (!isResetValue(this[cssValue])) {
this[computedSource] = ValueSource.Css;
this[computedValue] = this[cssValue];
} else {
@ -1082,9 +1097,9 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
const getDefault = this.getDefault;
const setNative = this.setNative;
const defaultValueKey = this.defaultValueKey;
const eventName = propertyName + 'Change';
let defaultValue: U = options.defaultValue;
const defaultValue: U = options.defaultValue;
let affectsLayout: boolean = options.affectsLayout;
let equalityComparer = options.equalityComparer;
let valueChanged = options.valueChanged;
@ -1112,12 +1127,12 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
const view = this.viewRef.get();
if (!view) {
Trace.write(`${boxedValue} not set to view's property because ".viewRef" is cleared`, Trace.categories.Style, Trace.messageType.warn);
return;
}
const reset = boxedValue === unsetValue || boxedValue === '';
const reset = isResetValue(boxedValue) || boxedValue === '';
const currentValueSource: number = this[sourceKey] || ValueSource.Default;
if (reset) {
// If we want to reset cssValue and we have localValue - return;
if (valueSource === ValueSource.Css && currentValueSource === ValueSource.Local) {
@ -1132,13 +1147,13 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
const oldValue: U = key in this ? this[key] : defaultValue;
let value: U;
let unsetNativeValue = false;
if (reset) {
// If unsetValue - we want to reset this property.
const parent = view.parent;
const style = parent ? parent.style : null;
// If we have parent and it has non-default value we use as our inherited value.
if (style && style[sourceKey] > ValueSource.Default) {
value = style[propertyName];
const parentStyle = view.parent ? view.parent.style : null;
// If value is not initial or unset and view has a parent that has non-default value, use it as the reset value.
if (boxedValue !== 'initial' && parentStyle && parentStyle[sourceKey] > ValueSource.Default) {
value = parentStyle[propertyName];
this[sourceKey] = ValueSource.Inherited;
this[key] = value;
} else {

View File

@ -2,12 +2,12 @@
import type { Point, CustomLayoutView as CustomLayoutViewDefinition, Position } from '.';
import type { GestureTypes, GestureEventData } from '../../gestures';
// Types.
import { ViewCommon, isEnabledProperty, originXProperty, originYProperty, isUserInteractionEnabledProperty, testIDProperty, AndroidHelper } from './view-common';
import { paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, Length } from '../../styling/style-properties';
import { layout } from '../../../utils';
import { Trace } from '../../../trace';
import { ShowModalOptions, hiddenProperty } from '../view-base';
import { isCssWideKeyword } from '../properties';
import { EventData } from '../../../data/observable';
import { perspectiveProperty, visibilityProperty, opacityProperty, horizontalAlignmentProperty, verticalAlignmentProperty, minWidthProperty, minHeightProperty, widthProperty, heightProperty, marginLeftProperty, marginTopProperty, marginRightProperty, marginBottomProperty, rotateProperty, rotateXProperty, rotateYProperty, scaleXProperty, scaleYProperty, translateXProperty, translateYProperty, zIndexProperty, backgroundInternalProperty, androidElevationProperty, androidDynamicElevationOffsetProperty } from '../../styling/style-properties';
@ -16,14 +16,13 @@ import { CoreTypes } from '../../../core-types';
import { Background, BackgroundClearFlags, refreshBorderDrawable } from '../../styling/background';
import { profile } from '../../../profiling';
import { topmost } from '../../frame/frame-stack';
import { Device, Screen } from '../../../platform';
import { Screen } from '../../../platform';
import { AndroidActivityBackPressedEventData, Application } from '../../../application';
import { accessibilityEnabledProperty, accessibilityHiddenProperty, accessibilityHintProperty, accessibilityIdentifierProperty, accessibilityLabelProperty, accessibilityLanguageProperty, accessibilityLiveRegionProperty, accessibilityMediaSessionProperty, accessibilityRoleProperty, accessibilityStateProperty, accessibilityValueProperty } from '../../../accessibility/accessibility-properties';
import { AccessibilityLiveRegion, AccessibilityRole, AndroidAccessibilityEvent, isAccessibilityServiceEnabled, sendAccessibilityEvent, updateAccessibilityProperties, updateContentDescription, AccessibilityState } from '../../../accessibility';
import { accessibilityEnabledProperty, accessibilityHiddenProperty, accessibilityHintProperty, accessibilityIdentifierProperty, accessibilityLabelProperty, accessibilityLiveRegionProperty, accessibilityMediaSessionProperty, accessibilityRoleProperty, accessibilityStateProperty, accessibilityValueProperty } from '../../../accessibility/accessibility-properties';
import { AccessibilityLiveRegion, AccessibilityRole, AndroidAccessibilityEvent, updateAccessibilityProperties, updateContentDescription, AccessibilityState } from '../../../accessibility';
import * as Utils from '../../../utils';
import { SDK_VERSION } from '../../../utils/constants';
import { BoxShadow } from '../../styling/box-shadow';
import { _setAndroidFragmentTransitions, _getAnimatedEntries, _updateTransitions, _reverseTransitions, _clearEntry, _clearFragment, addNativeTransitionListener } from '../../frame/fragment.transitions';
import { NativeScriptAndroidView } from '../../utils';
export * from './view-common';
@ -1366,7 +1365,7 @@ function createNativePercentLengthProperty(options: NativePercentLengthPropertyO
setPercent = options.setPercent || percentNotSupported;
options = null;
}
if (length == 'auto' || length == null) {
if (length == 'auto' || length == null || isCssWideKeyword(length)) {
// tslint:disable-line
setPixels(this.nativeViewProtected, auto);
} else if (typeof length === 'number') {

View File

@ -2,6 +2,7 @@ import { LayoutBase } from '../layout-base';
import { Style } from '../../styling/style';
import { CssProperty } from '../../core/properties';
import { View } from '../../core/view';
import { CoreTypes } from '../../enums';
export type FlexDirection = 'row' | 'row-reverse' | 'column' | 'column-reverse';
export type FlexWrap = 'nowrap' | 'wrap' | 'wrap-reverse';
@ -9,7 +10,7 @@ export type JustifyContent = 'flex-start' | 'flex-end' | 'center' | 'space-betwe
export type AlignItems = 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch';
export type AlignContent = 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'stretch';
export type FlexFlow = `${FlexDirection} ${FlexWrap}`;
export type Flex = number | 'initial' | 'auto' | 'none' | `${FlexGrow} ${FlexShrink}`;
export type Flex = number | 'auto' | 'none' | `${FlexGrow} ${FlexShrink}` | CoreTypes.CSSWideKeywords;
/**
* A flex order integer.

View File

@ -42,31 +42,32 @@ export function parseCSSShorthand(value: string): {
if (['', 'none', 'unset'].includes(first)) {
return null;
} else {
const invalidColors = ['inset', 'unset'];
const inset = parts.includes('inset');
const last = parts[parts.length - 1];
let color = 'black';
if (first && !isLength(first) && !invalidColors.includes(first)) {
color = first;
} else if (last && !isLength(last) && !invalidColors.includes(last)) {
color = last;
}
const values = parts
.filter((n) => !invalidColors.includes(n))
.filter((n) => n !== color)
.map((val) => {
try {
return Length.parse(val);
} catch (err) {
return CoreTypes.zeroLength;
}
});
return {
inset,
color,
values,
};
}
const invalidColors = ['inset', 'unset'];
const inset = parts.includes('inset');
const last = parts[parts.length - 1];
let color = 'black';
if (first && !isLength(first) && !invalidColors.includes(first)) {
color = first;
} else if (last && !isLength(last) && !invalidColors.includes(last)) {
color = last;
}
const values = parts
.filter((n) => !invalidColors.includes(n))
.filter((n) => n !== color)
.map((val) => {
try {
return Length.parse(val);
} catch (err) {
return CoreTypes.zeroLength;
}
});
return {
inset,
color,
values,
};
}

View File

@ -83,7 +83,7 @@ export namespace FontVariationSettings {
return null;
}
const excluded = ['normal', 'inherit', 'initial', 'revert', 'revert-layer', 'unset'];
const excluded = ['normal', 'revert-layer'];
const variationSettingsValue: string = fontVariationSettings.trim();
if (excluded.indexOf(variationSettingsValue.toLowerCase()) !== -1) {

View File

@ -1,5 +1,7 @@
export type FontStyleType = 'normal' | 'italic';
export type FontWeightType = '100' | '200' | '300' | 'normal' | '400' | '500' | '600' | 'bold' | '700' | '800' | '900' | number;
import { CoreTypes } from '../enums';
export type FontStyleType = 'normal' | 'italic' | CoreTypes.CSSWideKeywords;
export type FontWeightType = '100' | '200' | '300' | 'normal' | '400' | '500' | '600' | 'bold' | '700' | '800' | '900' | number | CoreTypes.CSSWideKeywords;
export interface ParsedFont {
fontStyle?: FontStyleType;

View File

@ -1,4 +1,4 @@
import { unsetValue, CssProperty, CssAnimationProperty, ShorthandProperty, InheritedCssProperty } from '../core/properties';
import { unsetValue, CssProperty, CssAnimationProperty, ShorthandProperty, InheritedCssProperty, isCssWideKeyword } from '../core/properties';
import { Style } from './style';
import { Color } from '../../color';
@ -25,11 +25,11 @@ interface ShorthandPositioning {
function equalsCommon(a: CoreTypes.LengthType, b: CoreTypes.LengthType): boolean;
function equalsCommon(a: CoreTypes.PercentLengthType, b: CoreTypes.PercentLengthType): boolean;
function equalsCommon(a: CoreTypes.PercentLengthType, b: CoreTypes.PercentLengthType): boolean {
if (a == 'auto') {
return b == 'auto';
if (a == 'auto' || isCssWideKeyword(a)) {
return b == 'auto' || isCssWideKeyword(b);
}
if (b == 'auto') {
if (b == 'auto' || isCssWideKeyword(b)) {
return false;
}
@ -53,7 +53,7 @@ function equalsCommon(a: CoreTypes.PercentLengthType, b: CoreTypes.PercentLength
}
function convertToStringCommon(length: CoreTypes.LengthType | CoreTypes.PercentLengthType): string {
if (length == 'auto') {
if (length == 'auto' || isCssWideKeyword(length)) {
return 'auto';
}
@ -70,7 +70,7 @@ function convertToStringCommon(length: CoreTypes.LengthType | CoreTypes.PercentL
}
function toDevicePixelsCommon(length: CoreTypes.PercentLengthType, auto: number = Number.NaN, parentAvailableWidth: number = Number.NaN): number {
if (length == 'auto') {
if (length == 'auto' || isCssWideKeyword(length)) {
return auto;
}
if (typeof length === 'number') {

View File

@ -16,7 +16,7 @@ import { layout } from '../../utils';
import { SDK_VERSION } from '../../utils/constants';
import { isString, isNullOrUndefined } from '../../utils/types';
import { accessibilityIdentifierProperty } from '../../accessibility/accessibility-properties';
import { testIDProperty } from '../../ui/core/view';
import { isCssWideKeyword, testIDProperty } from '../../ui/core/view';
export * from './text-base-common';
@ -289,7 +289,6 @@ export class TextBase extends TextBaseCommon {
[textTransformProperty.setNative](value: CoreTypes.TextTransformType) {
if (value === 'initial') {
this.nativeTextViewProtected.setTransformationMethod(this._defaultTransformationMethod);
return;
}
@ -411,9 +410,6 @@ export class TextBase extends TextBaseCommon {
[textDecorationProperty.setNative](value: number | CoreTypes.TextDecorationType) {
switch (value) {
case 'none':
this.nativeTextViewProtected.setPaintFlags(0);
break;
case 'underline':
this.nativeTextViewProtected.setPaintFlags(android.graphics.Paint.UNDERLINE_TEXT_FLAG);
break;
@ -424,7 +420,11 @@ export class TextBase extends TextBaseCommon {
this.nativeTextViewProtected.setPaintFlags(android.graphics.Paint.UNDERLINE_TEXT_FLAG | android.graphics.Paint.STRIKE_THRU_TEXT_FLAG);
break;
default:
this.nativeTextViewProtected.setPaintFlags(value);
if (value === 'none' || isCssWideKeyword(value)) {
this.nativeTextViewProtected.setPaintFlags(0);
} else {
this.nativeTextViewProtected.setPaintFlags(value);
}
break;
}
}

View File

@ -280,7 +280,7 @@ export function getClosestPropertyValue<T>(property: CssProperty<any, T>, span:
}
}
const textAlignmentConverter = makeParser<CoreTypes.TextAlignmentType>(makeValidator<CoreTypes.TextAlignmentType>('initial', 'left', 'center', 'right', 'justify'));
const textAlignmentConverter = makeParser<CoreTypes.TextAlignmentType>(makeValidator<CoreTypes.TextAlignmentType>('left', 'center', 'right', 'justify'));
export const textAlignmentProperty = new InheritedCssProperty<Style, CoreTypes.TextAlignmentType>({
name: 'textAlignment',
cssName: 'text-align',
@ -289,7 +289,7 @@ export const textAlignmentProperty = new InheritedCssProperty<Style, CoreTypes.T
});
textAlignmentProperty.register(Style);
const textTransformConverter = makeParser<CoreTypes.TextTransformType>(makeValidator<CoreTypes.TextTransformType>('initial', 'none', 'capitalize', 'uppercase', 'lowercase'));
const textTransformConverter = makeParser<CoreTypes.TextTransformType>(makeValidator<CoreTypes.TextTransformType>('none', 'capitalize', 'uppercase', 'lowercase'));
export const textTransformProperty = new InheritedCssProperty<Style, CoreTypes.TextTransformType>({
name: 'textTransform',
cssName: 'text-transform',
@ -318,7 +318,7 @@ export const textStrokeProperty = new InheritedCssProperty<Style, string | Strok
});
textStrokeProperty.register(Style);
const whiteSpaceConverter = makeParser<CoreTypes.WhiteSpaceType>(makeValidator<CoreTypes.WhiteSpaceType>('initial', 'normal', 'nowrap'));
const whiteSpaceConverter = makeParser<CoreTypes.WhiteSpaceType>(makeValidator<CoreTypes.WhiteSpaceType>('normal', 'nowrap'));
export const whiteSpaceProperty = new InheritedCssProperty<Style, CoreTypes.WhiteSpaceType>({
name: 'whiteSpace',
cssName: 'white-space',
@ -328,7 +328,7 @@ export const whiteSpaceProperty = new InheritedCssProperty<Style, CoreTypes.Whit
});
whiteSpaceProperty.register(Style);
const textOverflowConverter = makeParser<CoreTypes.TextOverflowType>(makeValidator<CoreTypes.TextOverflowType>('clip', 'ellipsis', 'initial', 'unset'));
const textOverflowConverter = makeParser<CoreTypes.TextOverflowType>(makeValidator<CoreTypes.TextOverflowType>('clip', 'ellipsis'));
export const textOverflowProperty = new CssProperty<Style, CoreTypes.TextOverflowType>({
name: 'textOverflow',
cssName: 'text-overflow',