mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-18 22:01:42 +08:00
chore: cleanup
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
import { EventData, TextBase } from '@nativescript/core';
|
import { EventData, TextBase } from '@nativescript/core';
|
||||||
|
|
||||||
const possibleValues = ['2 10 4 rgb(255, 100, 100)', '2 10 2 rgba(10, 10, 10, 0.5)', '1 1 1 #55a', '2 2 2 #aaa', ''];
|
const possibleValues = ['2 10 4 rgb(255, 100, 100)', '2 10 2 rgba(10, 10, 10, 0.5)', '1 1 1 #55a', '2 2 2 #aaa', '0 0 1 yellow', '-1 -1 1 #aaa', ''];
|
||||||
let currentIndex = 0;
|
let currentIndex = 0;
|
||||||
|
|
||||||
export function butonTap(args: EventData) {
|
export function butonTap(args: EventData) {
|
||||||
|
@ -25,7 +25,7 @@ import * as am from '../../animation';
|
|||||||
import { AccessibilityLiveRegion, AccessibilityRole, AccessibilityState, AccessibilityTrait, AndroidAccessibilityEvent, IOSPostAccessibilityNotificationType } from '../../../accessibility/accessibility-types';
|
import { AccessibilityLiveRegion, AccessibilityRole, AccessibilityState, AccessibilityTrait, AndroidAccessibilityEvent, IOSPostAccessibilityNotificationType } from '../../../accessibility/accessibility-types';
|
||||||
import { accessibilityHintProperty, accessibilityIdentifierProperty, accessibilityLabelProperty, accessibilityTraitsProperty, accessibilityValueProperty } from '../../../accessibility/accessibility-properties';
|
import { accessibilityHintProperty, accessibilityIdentifierProperty, accessibilityLabelProperty, accessibilityTraitsProperty, accessibilityValueProperty } from '../../../accessibility/accessibility-properties';
|
||||||
import { accessibilityBlurEvent, accessibilityFocusChangedEvent, accessibilityFocusEvent, getCurrentFontScale } from '../../../accessibility';
|
import { accessibilityBlurEvent, accessibilityFocusChangedEvent, accessibilityFocusEvent, getCurrentFontScale } from '../../../accessibility';
|
||||||
import { BoxShadow } from '../../styling/box-shadow';
|
import { CSSShadow } from '../../styling/css-shadow';
|
||||||
|
|
||||||
// helpers (these are okay re-exported here)
|
// helpers (these are okay re-exported here)
|
||||||
export * from './view-helper';
|
export * from './view-helper';
|
||||||
@ -591,10 +591,10 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
|||||||
this.style.backgroundRepeat = value;
|
this.style.backgroundRepeat = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
get boxShadow(): BoxShadow {
|
get boxShadow(): CSSShadow {
|
||||||
return this.style.boxShadow;
|
return this.style.boxShadow;
|
||||||
}
|
}
|
||||||
set boxShadow(value: BoxShadow) {
|
set boxShadow(value: CSSShadow) {
|
||||||
this.style.boxShadow = value;
|
this.style.boxShadow = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import { Color } from '../../color';
|
|||||||
import { isDataURI, isFileOrResourcePath, layout } from '../../utils';
|
import { isDataURI, isFileOrResourcePath, layout } from '../../utils';
|
||||||
import { ImageSource } from '../../image-source';
|
import { ImageSource } from '../../image-source';
|
||||||
import { CSSValue, parse as cssParse } from '../../css-value';
|
import { CSSValue, parse as cssParse } from '../../css-value';
|
||||||
import { BoxShadow } from './box-shadow';
|
import { CSSShadow } from './css-shadow';
|
||||||
|
|
||||||
export * from './background-common';
|
export * from './background-common';
|
||||||
|
|
||||||
@ -717,7 +717,7 @@ function drawNoRadiusNonUniformBorders(nativeView: NativeView, background: Backg
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use sublayer if its applied to a layout
|
// TODO: use sublayer if its applied to a layout
|
||||||
function drawBoxShadow(nativeView: NativeView, view: View, boxShadow: BoxShadow, background: BackgroundDefinition, useSubLayer: boolean = false) {
|
function drawBoxShadow(nativeView: NativeView, view: View, boxShadow: CSSShadow, background: BackgroundDefinition, useSubLayer: boolean = false) {
|
||||||
const layer: CALayer = nativeView.layer;
|
const layer: CALayer = nativeView.layer;
|
||||||
|
|
||||||
layer.masksToBounds = false;
|
layer.masksToBounds = false;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Color } from '../../color';
|
import { Color } from '../../color';
|
||||||
|
|
||||||
export class BoxShadow {
|
export class CSSShadow {
|
||||||
public offsetX: number;
|
public offsetX: number;
|
||||||
public offsetY: number;
|
public offsetY: number;
|
||||||
public blurRadius: number;
|
public blurRadius: number;
|
@ -17,7 +17,7 @@ import { Trace } from '../../trace';
|
|||||||
|
|
||||||
import * as parser from '../../css/parser';
|
import * as parser from '../../css/parser';
|
||||||
import { LinearGradient } from './linear-gradient';
|
import { LinearGradient } from './linear-gradient';
|
||||||
import { BoxShadow } from './box-shadow';
|
import { CSSShadow } from './css-shadow';
|
||||||
|
|
||||||
export type LengthDipUnit = { readonly unit: 'dip'; readonly value: dip };
|
export type LengthDipUnit = { readonly unit: 'dip'; readonly value: dip };
|
||||||
export type LengthPxUnit = { readonly unit: 'px'; readonly value: px };
|
export type LengthPxUnit = { readonly unit: 'px'; readonly value: px };
|
||||||
@ -452,10 +452,10 @@ export const verticalAlignmentProperty = new CssProperty<Style, VerticalAlignmen
|
|||||||
});
|
});
|
||||||
verticalAlignmentProperty.register(Style);
|
verticalAlignmentProperty.register(Style);
|
||||||
|
|
||||||
function parseBoxShadowProperites(value: string): BoxShadow {
|
export function parseShadowProperites(value: string): CSSShadow {
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
let arr;
|
let arr;
|
||||||
let colorRaw;
|
let colorRaw = 'black';
|
||||||
if (value.indexOf('rgb') > -1) {
|
if (value.indexOf('rgb') > -1) {
|
||||||
arr = value.split(' ');
|
arr = value.split(' ');
|
||||||
colorRaw = arr.pop();
|
colorRaw = arr.pop();
|
||||||
@ -464,27 +464,29 @@ function parseBoxShadowProperites(value: string): BoxShadow {
|
|||||||
colorRaw = arr.pop();
|
colorRaw = arr.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
let offsetX: number;
|
let offsetX = 0;
|
||||||
let offsetY: number;
|
let offsetY = 0;
|
||||||
let blurRadius: number; // not currently in use
|
let blurRadius = 0; // not currently in use
|
||||||
let spreadRadius: number; // maybe rename this to just radius
|
let spreadRadius = 0; // maybe rename this to just radius
|
||||||
let color: Color = new Color(colorRaw);
|
let color: Color = new Color(colorRaw);
|
||||||
|
|
||||||
if (arr.length === 2) {
|
if (arr.length === 1) {
|
||||||
offsetX = parseFloat(arr[0]);
|
Trace.write('Expected 3, 4 or 5 parameters. Actual: ' + value, Trace.categories.Error, Trace.messageType.error);
|
||||||
offsetY = parseFloat(arr[1]);
|
|
||||||
} else if (arr.length === 3) {
|
|
||||||
offsetX = parseFloat(arr[0]);
|
|
||||||
offsetY = parseFloat(arr[1]);
|
|
||||||
blurRadius = parseFloat(arr[2]);
|
|
||||||
} else if (arr.length === 4) {
|
|
||||||
offsetX = parseFloat(arr[0]);
|
|
||||||
offsetY = parseFloat(arr[1]);
|
|
||||||
blurRadius = parseFloat(arr[2]);
|
|
||||||
spreadRadius = parseFloat(arr[3]);
|
|
||||||
} else {
|
|
||||||
throw new Error('Expected 3, 4 or 5 parameters. Actual: ' + value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
return {
|
||||||
offsetX: offsetX,
|
offsetX: offsetX,
|
||||||
offsetY: offsetY,
|
offsetY: offsetY,
|
||||||
@ -1321,14 +1323,14 @@ export const borderBottomLeftRadiusProperty = new CssProperty<Style, Length>({
|
|||||||
});
|
});
|
||||||
borderBottomLeftRadiusProperty.register(Style);
|
borderBottomLeftRadiusProperty.register(Style);
|
||||||
|
|
||||||
const boxShadowProperty = new CssProperty<Style, BoxShadow>({
|
const boxShadowProperty = new CssProperty<Style, CSSShadow>({
|
||||||
name: 'boxShadow',
|
name: 'boxShadow',
|
||||||
cssName: 'box-shadow',
|
cssName: 'box-shadow',
|
||||||
valueChanged: (target, oldValue, newValue) => {
|
valueChanged: (target, oldValue, newValue) => {
|
||||||
target.boxShadow = newValue;
|
target.boxShadow = newValue;
|
||||||
},
|
},
|
||||||
valueConverter: (value) => {
|
valueConverter: (value) => {
|
||||||
return parseBoxShadowProperites(value);
|
return parseShadowProperites(value);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
boxShadowProperty.register(Style);
|
boxShadowProperty.register(Style);
|
||||||
|
@ -12,7 +12,7 @@ import { FlexDirection, FlexWrap, JustifyContent, AlignItems, AlignContent, Orde
|
|||||||
import { Trace } from '../../../trace';
|
import { Trace } from '../../../trace';
|
||||||
import { TextAlignment, TextDecoration, TextTransform, WhiteSpace, TextShadow } from '../../text-base';
|
import { TextAlignment, TextDecoration, TextTransform, WhiteSpace, TextShadow } from '../../text-base';
|
||||||
import { AccessibilityLiveRegion, AccessibilityRole, AccessibilityState } from '../../../accessibility/accessibility-types';
|
import { AccessibilityLiveRegion, AccessibilityRole, AccessibilityState } from '../../../accessibility/accessibility-types';
|
||||||
import { BoxShadow } from '../box-shadow';
|
import { CSSShadow } from '../css-shadow';
|
||||||
|
|
||||||
export interface CommonLayoutParams {
|
export interface CommonLayoutParams {
|
||||||
width: number;
|
width: number;
|
||||||
@ -140,7 +140,7 @@ export class Style extends Observable implements StyleDefinition {
|
|||||||
public borderBottomRightRadius: Length;
|
public borderBottomRightRadius: Length;
|
||||||
public borderBottomLeftRadius: Length;
|
public borderBottomLeftRadius: Length;
|
||||||
|
|
||||||
public boxShadow: BoxShadow;
|
public boxShadow: CSSShadow;
|
||||||
|
|
||||||
public fontSize: number;
|
public fontSize: number;
|
||||||
public fontFamily: string;
|
public fontFamily: string;
|
||||||
|
@ -7,9 +7,10 @@ import { TextBaseCommon, textProperty, formattedTextProperty, textAlignmentPrope
|
|||||||
import { Color } from '../../color';
|
import { Color } from '../../color';
|
||||||
import { FormattedString } from './formatted-string';
|
import { FormattedString } from './formatted-string';
|
||||||
import { Span } from './span';
|
import { Span } from './span';
|
||||||
import { colorProperty, fontInternalProperty, VerticalAlignment } from '../styling/style-properties';
|
import { colorProperty, fontInternalProperty, Length, VerticalAlignment } from '../styling/style-properties';
|
||||||
import { isString, isDefined, isNullOrUndefined } from '../../utils/types';
|
import { isString, isDefined, isNullOrUndefined } from '../../utils/types';
|
||||||
import { iOSNativeHelper } from '../../utils';
|
import { iOSNativeHelper } from '../../utils';
|
||||||
|
import { Trace } from '../../trace';
|
||||||
|
|
||||||
export * from './text-base-common';
|
export * from './text-base-common';
|
||||||
|
|
||||||
@ -348,12 +349,10 @@ export class TextBase extends TextBaseCommon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_setShadow(value: TextShadow): void {
|
_setShadow(value: TextShadow): void {
|
||||||
let layer;
|
const layer = getShadowLayer(this);
|
||||||
|
if (!layer) {
|
||||||
if (this.nativeTextViewProtected instanceof UITextView) {
|
Trace.write('text-shadow not applied, no layer.', Trace.categories.Style, Trace.messageType.info);
|
||||||
layer = this.nativeTextViewProtected.layer.sublayers.objectAtIndex(1);
|
return;
|
||||||
} else {
|
|
||||||
layer = this.nativeTextViewProtected.layer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNullOrUndefined(value)) {
|
if (isNullOrUndefined(value)) {
|
||||||
@ -365,12 +364,24 @@ export class TextBase extends TextBaseCommon {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
layer.shadowOpacity = 1;
|
if (value.color) {
|
||||||
layer.shadowRadius = value.blurRadius;
|
layer.shadowOpacity = value.color.a / 255;
|
||||||
layer.shadowColor = value.color.ios.CGColor;
|
layer.shadowColor = value.color.ios.CGColor;
|
||||||
layer.shadowOffset = CGSizeMake(value.offsetX, value.offsetY);
|
}
|
||||||
layer.shouldRasterize = true;
|
|
||||||
|
if (value.blurRadius) {
|
||||||
|
layer.shadowRadius = Length.toDevicePixels(value.blurRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.shadowOffset = CGSizeMake(Length.toDevicePixels(value.offsetX), Length.toDevicePixels(value.offsetY));
|
||||||
|
// layer.shadowOffset = CGSizeMake(Length.toDevicePixels(value.offsetX), Length.toDevicePixels(value.offsetY));
|
||||||
layer.masksToBounds = false;
|
layer.masksToBounds = false;
|
||||||
|
|
||||||
|
// NOTE: generally should not need shouldRaterize
|
||||||
|
// however for various detailed animation work which involves text-shadow applicable layers, we may want to give users the control of enabling this with text-shadow
|
||||||
|
// if (!(this.nativeTextViewProtected instanceof UITextView)) {
|
||||||
|
// layer.shouldRasterize = true;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
createNSMutableAttributedString(formattedString: FormattedString): NSMutableAttributedString {
|
createNSMutableAttributedString(formattedString: FormattedString): NSMutableAttributedString {
|
||||||
@ -493,6 +504,41 @@ export function getTransformedText(text: string, textTransform: TextTransform):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getShadowLayer(view: TextBase): CALayer {
|
||||||
|
let layer: CALayer;
|
||||||
|
const name = 'shadow-layer';
|
||||||
|
const nativeView = view && view.nativeTextViewProtected;
|
||||||
|
if (nativeView) {
|
||||||
|
if (nativeView.layer) {
|
||||||
|
if (nativeView.layer.name === name) {
|
||||||
|
return nativeView.layer;
|
||||||
|
} else {
|
||||||
|
if (nativeView.layer.sublayers && nativeView.layer.sublayers.count) {
|
||||||
|
console.log('this.nativeTextViewProtected.layer.sublayers.count:', nativeView.layer.sublayers.count);
|
||||||
|
for (let i = 0; i < nativeView.layer.sublayers.count; i++) {
|
||||||
|
console.log(`layer ${i}:`, nativeView.layer.sublayers.objectAtIndex(i));
|
||||||
|
if (nativeView.layer.sublayers.objectAtIndex(i).name === name) {
|
||||||
|
return nativeView.layer.sublayers.objectAtIndex(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nativeView instanceof UITextView) {
|
||||||
|
layer = nativeView.layer.sublayers.objectAtIndex(1);
|
||||||
|
} else {
|
||||||
|
layer = nativeView.layer.sublayers.objectAtIndex(nativeView.layer.sublayers.count - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
layer = nativeView.layer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// could this occur?
|
||||||
|
console.log('no layer!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layer.name = name;
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
function NSStringFromNSAttributedString(source: NSAttributedString | string): NSString {
|
function NSStringFromNSAttributedString(source: NSAttributedString | string): NSString {
|
||||||
return NSString.stringWithString((source instanceof NSAttributedString && source.string) || <string>source);
|
return NSString.stringWithString((source instanceof NSAttributedString && source.string) || <string>source);
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,13 @@ import { Span } from './span';
|
|||||||
import { View } from '../core/view';
|
import { View } from '../core/view';
|
||||||
import { Property, CssProperty, InheritedCssProperty, makeValidator, makeParser } from '../core/properties';
|
import { Property, CssProperty, InheritedCssProperty, makeValidator, makeParser } from '../core/properties';
|
||||||
import { Style } from '../styling/style';
|
import { Style } from '../styling/style';
|
||||||
import { Length } from '../styling/style-properties';
|
import { Length, parseShadowProperites } from '../styling/style-properties';
|
||||||
import { Observable } from '../../data/observable';
|
import { Observable } from '../../data/observable';
|
||||||
|
|
||||||
import { TextAlignment, TextDecoration, TextTransform, WhiteSpace, TextShadow } from './text-base-interfaces';
|
import { TextAlignment, TextDecoration, TextTransform, WhiteSpace } from './text-base-interfaces';
|
||||||
import { TextBase as TextBaseDefinition } from '.';
|
import { TextBase as TextBaseDefinition } from '.';
|
||||||
import { Color } from '../../color';
|
import { Color } from '../../color';
|
||||||
|
import { CSSShadow } from '../styling/css-shadow';
|
||||||
|
|
||||||
export * from './text-base-interfaces';
|
export * from './text-base-interfaces';
|
||||||
|
|
||||||
@ -27,6 +28,26 @@ export abstract class TextBaseCommon extends View implements TextBaseDefinition
|
|||||||
public text: string;
|
public text: string;
|
||||||
public formattedText: FormattedString;
|
public formattedText: FormattedString;
|
||||||
|
|
||||||
|
/***
|
||||||
|
* In the NativeScript Core; by default the nativeTextViewProtected points to the same value as nativeViewProtected.
|
||||||
|
* At this point no internal NS components need this indirection functionality.
|
||||||
|
* This indirection is used to allow support usage by third party components so they don't have to duplicate functionality.
|
||||||
|
*
|
||||||
|
* A third party component can just override the `nativeTextViewProtected` getter and return a different internal view and that view would be
|
||||||
|
* what all TextView/TextInput class features would be applied to.
|
||||||
|
*
|
||||||
|
* A example is the Android MaterialDesign TextInput class, it has a wrapper view of a TextInputLayout
|
||||||
|
* https://developer.android.com/reference/com/google/android/material/textfield/TextInputLayout
|
||||||
|
* which wraps the actual TextInput. This wrapper layout (TextInputLayout) must be assigned to the nativeViewProtected as the entire
|
||||||
|
* NS Core uses nativeViewProtected for everything related to layout, so that it can be measured, added to the parent view as a child, ect.
|
||||||
|
*
|
||||||
|
* However, its internal view would be the actual TextView/TextInput and to allow that sub-view to have the normal TextView/TextInput
|
||||||
|
* class features, which we expose and to allow them to work on it, the internal TextView/TextInput is what the needs to have the class values applied to it.
|
||||||
|
*
|
||||||
|
* So all code that works on what is expected to be a TextView/TextInput should use `nativeTextViewProtected` so that any third party
|
||||||
|
* components that need to have two separate components can work properly without them having to duplicate all the TextBase (and decendants) functionality
|
||||||
|
* by just overriding the nativeTextViewProtected getter.
|
||||||
|
**/
|
||||||
get nativeTextViewProtected() {
|
get nativeTextViewProtected() {
|
||||||
return this.nativeViewProtected;
|
return this.nativeViewProtected;
|
||||||
}
|
}
|
||||||
@ -247,18 +268,12 @@ export const textTransformProperty = new CssProperty<Style, TextTransform>({
|
|||||||
});
|
});
|
||||||
textTransformProperty.register(Style);
|
textTransformProperty.register(Style);
|
||||||
|
|
||||||
export const textShadowProperty = new CssProperty<Style, string | TextShadow>({
|
export const textShadowProperty = new CssProperty<Style, string | CSSShadow>({
|
||||||
name: 'textShadow',
|
name: 'textShadow',
|
||||||
cssName: 'text-shadow',
|
cssName: 'text-shadow',
|
||||||
affectsLayout: global.isIOS,
|
affectsLayout: global.isIOS,
|
||||||
valueConverter: (value) => {
|
valueConverter: (value) => {
|
||||||
const params = value.split(' ');
|
return parseShadowProperites(value);
|
||||||
return {
|
|
||||||
offsetX: Length.parse(params[0]),
|
|
||||||
offsetY: Length.parse(params[1]),
|
|
||||||
blurRadius: Length.parse(params[2]),
|
|
||||||
color: new Color(params.slice(3).join('')),
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
textShadowProperty.register(Style);
|
textShadowProperty.register(Style);
|
||||||
|
@ -5,9 +5,3 @@ export type WhiteSpace = 'initial' | 'normal' | 'nowrap';
|
|||||||
export type TextAlignment = 'initial' | 'left' | 'center' | 'right';
|
export type TextAlignment = 'initial' | 'left' | 'center' | 'right';
|
||||||
export type TextTransform = 'initial' | 'none' | 'capitalize' | 'uppercase' | 'lowercase';
|
export type TextTransform = 'initial' | 'none' | 'capitalize' | 'uppercase' | 'lowercase';
|
||||||
export type TextDecoration = 'none' | 'underline' | 'line-through' | 'underline line-through';
|
export type TextDecoration = 'none' | 'underline' | 'line-through' | 'underline line-through';
|
||||||
export type TextShadow = {
|
|
||||||
offsetX: Length;
|
|
||||||
offsetY: Length;
|
|
||||||
blurRadius: Length;
|
|
||||||
color: Color;
|
|
||||||
};
|
|
||||||
|
Reference in New Issue
Block a user