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';
|
||||
|
||||
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;
|
||||
|
||||
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 { accessibilityHintProperty, accessibilityIdentifierProperty, accessibilityLabelProperty, accessibilityTraitsProperty, accessibilityValueProperty } from '../../../accessibility/accessibility-properties';
|
||||
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)
|
||||
export * from './view-helper';
|
||||
@ -591,10 +591,10 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
this.style.backgroundRepeat = value;
|
||||
}
|
||||
|
||||
get boxShadow(): BoxShadow {
|
||||
get boxShadow(): CSSShadow {
|
||||
return this.style.boxShadow;
|
||||
}
|
||||
set boxShadow(value: BoxShadow) {
|
||||
set boxShadow(value: CSSShadow) {
|
||||
this.style.boxShadow = value;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import { Color } from '../../color';
|
||||
import { isDataURI, isFileOrResourcePath, layout } from '../../utils';
|
||||
import { ImageSource } from '../../image-source';
|
||||
import { CSSValue, parse as cssParse } from '../../css-value';
|
||||
import { BoxShadow } from './box-shadow';
|
||||
import { CSSShadow } from './css-shadow';
|
||||
|
||||
export * from './background-common';
|
||||
|
||||
@ -717,7 +717,7 @@ function drawNoRadiusNonUniformBorders(nativeView: NativeView, background: Backg
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
layer.masksToBounds = false;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Color } from '../../color';
|
||||
|
||||
export class BoxShadow {
|
||||
export class CSSShadow {
|
||||
public offsetX: number;
|
||||
public offsetY: number;
|
||||
public blurRadius: number;
|
@ -17,7 +17,7 @@ import { Trace } from '../../trace';
|
||||
|
||||
import * as parser from '../../css/parser';
|
||||
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 LengthPxUnit = { readonly unit: 'px'; readonly value: px };
|
||||
@ -452,10 +452,10 @@ export const verticalAlignmentProperty = new CssProperty<Style, VerticalAlignmen
|
||||
});
|
||||
verticalAlignmentProperty.register(Style);
|
||||
|
||||
function parseBoxShadowProperites(value: string): BoxShadow {
|
||||
export function parseShadowProperites(value: string): CSSShadow {
|
||||
if (typeof value === 'string') {
|
||||
let arr;
|
||||
let colorRaw;
|
||||
let colorRaw = 'black';
|
||||
if (value.indexOf('rgb') > -1) {
|
||||
arr = value.split(' ');
|
||||
colorRaw = arr.pop();
|
||||
@ -464,27 +464,29 @@ function parseBoxShadowProperites(value: string): BoxShadow {
|
||||
colorRaw = arr.pop();
|
||||
}
|
||||
|
||||
let offsetX: number;
|
||||
let offsetY: number;
|
||||
let blurRadius: number; // not currently in use
|
||||
let spreadRadius: number; // maybe rename this to just radius
|
||||
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 === 2) {
|
||||
offsetX = parseFloat(arr[0]);
|
||||
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) {
|
||||
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,
|
||||
@ -1321,14 +1323,14 @@ export const borderBottomLeftRadiusProperty = new CssProperty<Style, Length>({
|
||||
});
|
||||
borderBottomLeftRadiusProperty.register(Style);
|
||||
|
||||
const boxShadowProperty = new CssProperty<Style, BoxShadow>({
|
||||
const boxShadowProperty = new CssProperty<Style, CSSShadow>({
|
||||
name: 'boxShadow',
|
||||
cssName: 'box-shadow',
|
||||
valueChanged: (target, oldValue, newValue) => {
|
||||
target.boxShadow = newValue;
|
||||
},
|
||||
valueConverter: (value) => {
|
||||
return parseBoxShadowProperites(value);
|
||||
return parseShadowProperites(value);
|
||||
},
|
||||
});
|
||||
boxShadowProperty.register(Style);
|
||||
|
@ -12,7 +12,7 @@ import { FlexDirection, FlexWrap, JustifyContent, AlignItems, AlignContent, Orde
|
||||
import { Trace } from '../../../trace';
|
||||
import { TextAlignment, TextDecoration, TextTransform, WhiteSpace, TextShadow } from '../../text-base';
|
||||
import { AccessibilityLiveRegion, AccessibilityRole, AccessibilityState } from '../../../accessibility/accessibility-types';
|
||||
import { BoxShadow } from '../box-shadow';
|
||||
import { CSSShadow } from '../css-shadow';
|
||||
|
||||
export interface CommonLayoutParams {
|
||||
width: number;
|
||||
@ -140,7 +140,7 @@ export class Style extends Observable implements StyleDefinition {
|
||||
public borderBottomRightRadius: Length;
|
||||
public borderBottomLeftRadius: Length;
|
||||
|
||||
public boxShadow: BoxShadow;
|
||||
public boxShadow: CSSShadow;
|
||||
|
||||
public fontSize: number;
|
||||
public fontFamily: string;
|
||||
|
@ -7,9 +7,10 @@ import { TextBaseCommon, textProperty, formattedTextProperty, textAlignmentPrope
|
||||
import { Color } from '../../color';
|
||||
import { FormattedString } from './formatted-string';
|
||||
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 { iOSNativeHelper } from '../../utils';
|
||||
import { Trace } from '../../trace';
|
||||
|
||||
export * from './text-base-common';
|
||||
|
||||
@ -348,12 +349,10 @@ export class TextBase extends TextBaseCommon {
|
||||
}
|
||||
|
||||
_setShadow(value: TextShadow): void {
|
||||
let layer;
|
||||
|
||||
if (this.nativeTextViewProtected instanceof UITextView) {
|
||||
layer = this.nativeTextViewProtected.layer.sublayers.objectAtIndex(1);
|
||||
} else {
|
||||
layer = this.nativeTextViewProtected.layer;
|
||||
const layer = getShadowLayer(this);
|
||||
if (!layer) {
|
||||
Trace.write('text-shadow not applied, no layer.', Trace.categories.Style, Trace.messageType.info);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNullOrUndefined(value)) {
|
||||
@ -365,12 +364,24 @@ export class TextBase extends TextBaseCommon {
|
||||
return;
|
||||
}
|
||||
|
||||
layer.shadowOpacity = 1;
|
||||
layer.shadowRadius = value.blurRadius;
|
||||
layer.shadowColor = value.color.ios.CGColor;
|
||||
layer.shadowOffset = CGSizeMake(value.offsetX, value.offsetY);
|
||||
layer.shouldRasterize = true;
|
||||
if (value.color) {
|
||||
layer.shadowOpacity = value.color.a / 255;
|
||||
layer.shadowColor = value.color.ios.CGColor;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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 {
|
||||
@ -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 {
|
||||
return NSString.stringWithString((source instanceof NSAttributedString && source.string) || <string>source);
|
||||
}
|
||||
|
@ -9,12 +9,13 @@ import { Span } from './span';
|
||||
import { View } from '../core/view';
|
||||
import { Property, CssProperty, InheritedCssProperty, makeValidator, makeParser } from '../core/properties';
|
||||
import { Style } from '../styling/style';
|
||||
import { Length } from '../styling/style-properties';
|
||||
import { Length, parseShadowProperites } from '../styling/style-properties';
|
||||
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 { Color } from '../../color';
|
||||
import { CSSShadow } from '../styling/css-shadow';
|
||||
|
||||
export * from './text-base-interfaces';
|
||||
|
||||
@ -27,6 +28,26 @@ export abstract class TextBaseCommon extends View implements TextBaseDefinition
|
||||
public text: string;
|
||||
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() {
|
||||
return this.nativeViewProtected;
|
||||
}
|
||||
@ -247,18 +268,12 @@ export const textTransformProperty = new CssProperty<Style, TextTransform>({
|
||||
});
|
||||
textTransformProperty.register(Style);
|
||||
|
||||
export const textShadowProperty = new CssProperty<Style, string | TextShadow>({
|
||||
export const textShadowProperty = new CssProperty<Style, string | CSSShadow>({
|
||||
name: 'textShadow',
|
||||
cssName: 'text-shadow',
|
||||
affectsLayout: global.isIOS,
|
||||
valueConverter: (value) => {
|
||||
const params = value.split(' ');
|
||||
return {
|
||||
offsetX: Length.parse(params[0]),
|
||||
offsetY: Length.parse(params[1]),
|
||||
blurRadius: Length.parse(params[2]),
|
||||
color: new Color(params.slice(3).join('')),
|
||||
};
|
||||
return parseShadowProperites(value);
|
||||
},
|
||||
});
|
||||
textShadowProperty.register(Style);
|
||||
|
@ -5,9 +5,3 @@ export type WhiteSpace = 'initial' | 'normal' | 'nowrap';
|
||||
export type TextAlignment = 'initial' | 'left' | 'center' | 'right';
|
||||
export type TextTransform = 'initial' | 'none' | 'capitalize' | 'uppercase' | 'lowercase';
|
||||
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