mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
feat: improved css-shadow parser
This commit is contained in:
committed by
Nathan Walker
parent
945656fe3e
commit
527c70b465
@@ -1,9 +1,65 @@
|
||||
import { Color } from '../../color';
|
||||
import { Length } from './style-properties';
|
||||
|
||||
export class CSSShadow {
|
||||
public offsetX: number;
|
||||
public offsetY: number;
|
||||
public blurRadius: number;
|
||||
public spreadRadius: number;
|
||||
public color: Color;
|
||||
export interface CSSShadow {
|
||||
inset: boolean;
|
||||
offsetX: Length;
|
||||
offsetY: Length;
|
||||
blurRadius?: Length;
|
||||
spreadRadius?: Length;
|
||||
color: Color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches whitespace except if the whitespace is contained in parenthesis - ex. rgb(a), hsl color.
|
||||
*/
|
||||
const PARTS_RE = /\s(?![^(]*\))/;
|
||||
|
||||
/**
|
||||
* Matches a Length value with or without a unit
|
||||
*/
|
||||
const LENGTH_RE = /^-?[0-9]+[a-zA-Z%]*?$/;
|
||||
|
||||
/**
|
||||
* Checks if the value is a Length or 0
|
||||
*/
|
||||
const isLength = (v) => v === '0' || LENGTH_RE.test(v);
|
||||
|
||||
/**
|
||||
* Parse a string into a CSSShadow
|
||||
* Supports any valid css box/text shadow combination.
|
||||
*
|
||||
* inspired by https://github.com/jxnblk/css-box-shadow/blob/master/index.js (MIT License)
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
export function parseCSSShadow(value: string): CSSShadow {
|
||||
const parts = value.split(PARTS_RE);
|
||||
const inset = parts.includes('inset');
|
||||
const first = parts[0];
|
||||
const last = parts[parts.length - 1];
|
||||
|
||||
let colorRaw = 'black';
|
||||
if (!isLength(first) && first !== 'inset') {
|
||||
colorRaw = first;
|
||||
} else if (!isLength(last)) {
|
||||
colorRaw = last;
|
||||
}
|
||||
const nums = parts
|
||||
.filter((n) => n !== 'inset')
|
||||
.filter((n) => n !== colorRaw)
|
||||
.map((val) => {
|
||||
console.log(val);
|
||||
return Length.parse(val);
|
||||
});
|
||||
const [offsetX, offsetY, blurRadius, spreadRadius] = nums;
|
||||
|
||||
return {
|
||||
inset,
|
||||
offsetX: offsetX,
|
||||
offsetY: offsetY,
|
||||
blurRadius: blurRadius,
|
||||
spreadRadius: spreadRadius,
|
||||
color: new Color(colorRaw),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import { Trace } from '../../trace';
|
||||
|
||||
import * as parser from '../../css/parser';
|
||||
import { LinearGradient } from './linear-gradient';
|
||||
import { CSSShadow } from './css-shadow';
|
||||
import { CSSShadow, parseCSSShadow } from './css-shadow';
|
||||
|
||||
export type LengthDipUnit = { readonly unit: 'dip'; readonly value: dip };
|
||||
export type LengthPxUnit = { readonly unit: 'px'; readonly value: px };
|
||||
@@ -452,53 +452,6 @@ export const verticalAlignmentProperty = new CssProperty<Style, VerticalAlignmen
|
||||
});
|
||||
verticalAlignmentProperty.register(Style);
|
||||
|
||||
export function parseShadowProperites(value: string): CSSShadow {
|
||||
if (typeof value === 'string') {
|
||||
let arr;
|
||||
let colorRaw = 'black';
|
||||
if (value.indexOf('rgb') > -1) {
|
||||
arr = value.split(' ');
|
||||
colorRaw = arr.pop();
|
||||
} else {
|
||||
arr = value.split(/[ ,]+/);
|
||||
colorRaw = arr.pop();
|
||||
}
|
||||
|
||||
let offsetX = 0;
|
||||
let offsetY = 0;
|
||||
let blurRadius = 0; // not currently in use
|
||||
let spreadRadius = 0; // maybe rename this to just radius
|
||||
let color: Color = new Color(colorRaw);
|
||||
|
||||
if (arr.length === 1) {
|
||||
Trace.write('Expected 3, 4 or 5 parameters. Actual: ' + value, Trace.categories.Error, Trace.messageType.error);
|
||||
}
|
||||
|
||||
if (arr.length > 1) {
|
||||
offsetX = parseFloat(arr[0]);
|
||||
offsetY = parseFloat(arr[1]);
|
||||
}
|
||||
|
||||
if (arr.length > 2) {
|
||||
blurRadius = parseFloat(arr[2]);
|
||||
}
|
||||
|
||||
if (arr.length > 3) {
|
||||
spreadRadius = parseFloat(arr[3]);
|
||||
}
|
||||
|
||||
return {
|
||||
offsetX: offsetX,
|
||||
offsetY: offsetY,
|
||||
blurRadius: blurRadius,
|
||||
spreadRadius: spreadRadius,
|
||||
color: color,
|
||||
};
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
interface Thickness {
|
||||
top: string;
|
||||
right: string;
|
||||
@@ -1330,7 +1283,7 @@ const boxShadowProperty = new CssProperty<Style, CSSShadow>({
|
||||
target.boxShadow = newValue;
|
||||
},
|
||||
valueConverter: (value) => {
|
||||
return parseShadowProperites(value);
|
||||
return parseCSSShadow(value);
|
||||
},
|
||||
});
|
||||
boxShadowProperty.register(Style);
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Observable } from '../../../data/observable';
|
||||
|
||||
import { FlexDirection, FlexWrap, JustifyContent, AlignItems, AlignContent, Order, FlexGrow, FlexShrink, FlexWrapBefore, AlignSelf } from '../../layouts/flexbox-layout';
|
||||
import { Trace } from '../../../trace';
|
||||
import { TextAlignment, TextDecoration, TextTransform, WhiteSpace, TextShadow } from '../../text-base';
|
||||
import { TextAlignment, TextDecoration, TextTransform, WhiteSpace } from '../../text-base';
|
||||
import { AccessibilityLiveRegion, AccessibilityRole, AccessibilityState } from '../../../accessibility/accessibility-types';
|
||||
import { CSSShadow } from '../css-shadow';
|
||||
|
||||
@@ -159,7 +159,7 @@ export class Style extends Observable implements StyleDefinition {
|
||||
public textAlignment: TextAlignment;
|
||||
public textDecoration: TextDecoration;
|
||||
public textTransform: TextTransform;
|
||||
public textShadow: TextShadow;
|
||||
public textShadow: CSSShadow;
|
||||
public whiteSpace: WhiteSpace;
|
||||
|
||||
public minWidth: Length;
|
||||
|
||||
Reference in New Issue
Block a user