mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Chrome devtools elements tab support for Android (#4351)
* Enable chrome-devtools elemets tab * Trigger updates when property is chaned form native * Tslint fixes * Don't run dom-elemet tests in IOS * fix tests * Create package.json * Update package.json * domNode changed to field for performance
This commit is contained in:
committed by
GitHub
parent
b7c61cad96
commit
f2462158fb
81
tns-core-modules/debugger/css-agent.ts
Normal file
81
tns-core-modules/debugger/css-agent.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
On element select in the inspector the following are requested:
|
||||
- Inline styles -> CSSStyle
|
||||
- Attributes styles -> CSSStyle (Appears as 'Stacklayout[Attributes style]` - unsure of its purpose) irrelevant?
|
||||
- Style matches -> RuleMatch[]
|
||||
- Inherited styles -> InheritedStyleEntry[]
|
||||
- Pseudo Element matches -> PseudoElementMatches[]
|
||||
- Computed Styles for node -> CSSComputedStyleProperty[]
|
||||
- Element Fonts -> PlatformFontUsage
|
||||
*/
|
||||
|
||||
export interface CSSProperty {
|
||||
name: string
|
||||
value: string
|
||||
disabled: boolean // strikes out the disabled property
|
||||
}
|
||||
|
||||
export interface ShorthandEntry { // seems irrelevant - feel free to leave empty for now
|
||||
name: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface CSSStyle {
|
||||
cssProperties: CSSProperty[]
|
||||
shorthandEntries: ShorthandEntry[] // doesn't seem to display anywhere
|
||||
cssText?: string
|
||||
}
|
||||
|
||||
export interface Value {
|
||||
text: string
|
||||
}
|
||||
|
||||
export interface SelectorList { // e.g. [".btn", "Button", "Label"]
|
||||
selectors: Value[]
|
||||
text: string // doesn't seem to display anywhere
|
||||
}
|
||||
|
||||
export interface CSSRule {
|
||||
selectorList: SelectorList
|
||||
origin: string // a constant - "regular"
|
||||
style: CSSStyle
|
||||
styleSheetId?: string // associated stylesheet
|
||||
}
|
||||
|
||||
export interface RuleMatch {
|
||||
rule: CSSRule
|
||||
matchingSelectors: number[] // index-based - the index of the selector that the node currently inspected matches
|
||||
}
|
||||
|
||||
export interface InheritedStyleEntry {
|
||||
matchedCSSRules: RuleMatch[]
|
||||
inlineStyle?: CSSStyle
|
||||
}
|
||||
|
||||
export interface CSSComputedStyleProperty {
|
||||
name: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface PlatformFontUsage {
|
||||
familyName: string
|
||||
glyphCount: number // number of characters in text of element
|
||||
isCustomFont: boolean
|
||||
}
|
||||
|
||||
export interface CSSStyleSheetHeader {
|
||||
styleSheetId: string // a unique identifier - file name/path should do
|
||||
frameId: string // constant
|
||||
sourceUrl: string
|
||||
origin: string // constant
|
||||
title: string // the same as the id?
|
||||
disabled: boolean // false - if the css has been invalidated/disabled
|
||||
isInLine: boolean // false
|
||||
startLine: number // constant - 1
|
||||
startColumn: number // constant - 1
|
||||
}
|
||||
|
||||
export interface PseudoElementMatches {
|
||||
pseudoType: string // e.g. last-child
|
||||
matches: RuleMatch[]
|
||||
}
|
||||
97
tns-core-modules/debugger/devtools-elements.ts
Normal file
97
tns-core-modules/debugger/devtools-elements.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { unsetValue } from "../ui/core/properties";
|
||||
import { ViewBase } from "../ui/core/view-base";
|
||||
import { topmost } from "../ui/frame";
|
||||
import { getNodeById } from "./dom-node";
|
||||
|
||||
export interface Inspector {
|
||||
// DevTools -> Application communication. Methods that devtools calls when needed.
|
||||
getDocument(): string;
|
||||
removeNode(nodeId: number): void;
|
||||
getComputedStylesForNode(nodeId: number): string;
|
||||
setAttributeAsText(nodeId: number, text: string, name: string): void;
|
||||
|
||||
// Application -> DevTools communication. Methods that the app should call when needed.
|
||||
childNodeInserted(parentId: number, lastId: number, nodeStr: string): void;
|
||||
childNodeRemoved(parentId: number, nodeId: number): void;
|
||||
attributeModified(nodeId: number, attrName: string, attrValue: string): void;
|
||||
attributeRemoved(nodeId: number, attrName: string): void;
|
||||
}
|
||||
|
||||
function getViewById(nodeId: number): ViewBase {
|
||||
const node = getNodeById(nodeId);
|
||||
let view;
|
||||
if (node) {
|
||||
view = node.viewRef.get();
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
export function attachInspectorCallbacks(inspector: Inspector) {
|
||||
inspector.getDocument = function () {
|
||||
const topMostFrame = topmost();
|
||||
topMostFrame.ensureDomNode();
|
||||
|
||||
return topMostFrame.domNode.toJSON();
|
||||
}
|
||||
|
||||
inspector.getComputedStylesForNode = function (nodeId) {
|
||||
const view = getViewById(nodeId);
|
||||
if (view) {
|
||||
return JSON.stringify(view.domNode.getComputedProperties());
|
||||
}
|
||||
|
||||
return "[]";
|
||||
}
|
||||
|
||||
inspector.removeNode = function (nodeId) {
|
||||
const view = getViewById(nodeId);
|
||||
if (view) {
|
||||
// Avoid importing layout and content view
|
||||
let parent = <any>view.parent;
|
||||
if (parent.removeChild) {
|
||||
parent.removeChild(view);
|
||||
} else if (parent.content === view) {
|
||||
parent.content = null;
|
||||
}
|
||||
else {
|
||||
console.log("Can't remove child from " + parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inspector.setAttributeAsText = function (nodeId, text, name) {
|
||||
const view = getViewById(nodeId);
|
||||
if (view) {
|
||||
// attribute is registered for the view instance
|
||||
let hasOriginalAttribute = !!name.trim();
|
||||
|
||||
if (text) {
|
||||
let textParts = text.split("=");
|
||||
|
||||
if (textParts.length === 2) {
|
||||
let attrName = textParts[0];
|
||||
let attrValue = textParts[1].replace(/['"]+/g, '');
|
||||
|
||||
// if attr name is being replaced with another
|
||||
if (name !== attrName && hasOriginalAttribute) {
|
||||
view[name] = unsetValue;
|
||||
view[attrName] = attrValue;
|
||||
} else {
|
||||
view[hasOriginalAttribute ? name : attrName] = attrValue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// delete attribute
|
||||
view[name] = unsetValue;
|
||||
}
|
||||
|
||||
view.domNode.loadAttributes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically attach callbacks if there is __inspector
|
||||
if (global && global.__inspector) {
|
||||
attachInspectorCallbacks(global.__inspector)
|
||||
}
|
||||
197
tns-core-modules/debugger/dom-node.ts
Normal file
197
tns-core-modules/debugger/dom-node.ts
Normal file
@@ -0,0 +1,197 @@
|
||||
import { getSetProperties, getComputedCssValues } from "../ui/core/properties";
|
||||
import { PercentLength } from "../ui/styling/style-properties";
|
||||
import { ViewBase } from "../ui/core/view";
|
||||
import { Color } from "../color";
|
||||
import { CSSComputedStyleProperty } from "./css-agent";
|
||||
import { Inspector } from "./devtools-elements";
|
||||
|
||||
const registeredDomNodes = {};
|
||||
const ELEMENT_NODE_TYPE = 1;
|
||||
const ROOT_NODE_TYPE = 9;
|
||||
const propertyBlacklist = [
|
||||
"effectivePaddingLeft",
|
||||
"effectivePaddingBottom",
|
||||
"effectivePaddingRight",
|
||||
"effectivePaddingTop",
|
||||
"effectiveBorderTopWidth",
|
||||
"effectiveBorderRightWidth",
|
||||
"effectiveBorderBottomWidth",
|
||||
"effectiveBorderLeftWidth",
|
||||
"effectiveMinWidth",
|
||||
"nodeName",
|
||||
"nodeType",
|
||||
"decodeWidth",
|
||||
"decodeHeight"
|
||||
]
|
||||
|
||||
function notifyInspector(callback: (inspector: Inspector) => void) {
|
||||
const ins = (<any>global).__inspector
|
||||
if (ins) {
|
||||
callback(ins);
|
||||
}
|
||||
}
|
||||
|
||||
function valueToString(value: any): string {
|
||||
if (typeof value === "undefined" || value === null) {
|
||||
return "";
|
||||
} else if (value instanceof Color) {
|
||||
return value.toString()
|
||||
} else if (typeof value === "object") {
|
||||
return PercentLength.convertToString(value)
|
||||
} else {
|
||||
return value + "";
|
||||
}
|
||||
}
|
||||
|
||||
function propertyFilter([name, value]: [string, any]): boolean {
|
||||
if (name[0] === "_") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value !== null && typeof value === "object") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (propertyBlacklist.indexOf(name) >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function registerNode(domNode: DOMNode) {
|
||||
registeredDomNodes[domNode.nodeId] = domNode;
|
||||
}
|
||||
|
||||
function unregisterNode(domNode: DOMNode) {
|
||||
delete registeredDomNodes[domNode.nodeId];
|
||||
}
|
||||
|
||||
export function getNodeById(id: number): DOMNode {
|
||||
return registeredDomNodes[id];
|
||||
}
|
||||
|
||||
export class DOMNode {
|
||||
nodeId;
|
||||
nodeType;
|
||||
nodeName;
|
||||
localName;
|
||||
nodeValue = '';
|
||||
attributes: string[] = [];
|
||||
viewRef: WeakRef<ViewBase>;
|
||||
|
||||
constructor(view: ViewBase) {
|
||||
this.viewRef = new WeakRef(view);
|
||||
this.nodeType = view.typeName === "Frame" ? ROOT_NODE_TYPE : ELEMENT_NODE_TYPE;
|
||||
this.nodeId = view._domId;
|
||||
this.nodeName = view.typeName;
|
||||
this.localName = this.nodeName;
|
||||
|
||||
// Load all attributes
|
||||
this.loadAttributes();
|
||||
|
||||
registerNode(this);
|
||||
}
|
||||
|
||||
public loadAttributes() {
|
||||
this.attributes = [];
|
||||
getSetProperties(this.viewRef.get())
|
||||
.filter(propertyFilter)
|
||||
.forEach(pair => this.attributes.push(pair[0], pair[1] + ""));
|
||||
|
||||
}
|
||||
|
||||
get children(): DOMNode[] {
|
||||
const view = this.viewRef.get();
|
||||
if (!view) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const res = [];
|
||||
|
||||
view.eachChild((child) => {
|
||||
child.ensureDomNode();
|
||||
res.push(child.domNode);
|
||||
return true;
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
onChildAdded(childView: ViewBase): void {
|
||||
notifyInspector((ins) => {
|
||||
const view = this.viewRef.get();
|
||||
childView.ensureDomNode();
|
||||
|
||||
let previousChild: ViewBase;
|
||||
view.eachChild((child) => {
|
||||
if (child === childView) {
|
||||
return false;
|
||||
}
|
||||
|
||||
previousChild = child;
|
||||
|
||||
return true;
|
||||
});
|
||||
const index = !!previousChild ? previousChild._domId : 0;
|
||||
|
||||
ins.childNodeInserted(this.nodeId, index, childView.domNode.toJSON());
|
||||
});
|
||||
}
|
||||
|
||||
onChildRemoved(view: ViewBase): void {
|
||||
notifyInspector((ins) => {
|
||||
ins.childNodeRemoved(this.nodeId, view.domNode.nodeId);
|
||||
});
|
||||
}
|
||||
|
||||
attributeModified(name: string, value: any) {
|
||||
notifyInspector((ins) => {
|
||||
ins.attributeModified(this.nodeId, name, valueToString(value));
|
||||
});
|
||||
}
|
||||
|
||||
attributeRemoved(name: string) {
|
||||
notifyInspector((ins) => {
|
||||
ins.attributeRemoved(this.nodeId, name);
|
||||
});
|
||||
}
|
||||
|
||||
getComputedProperties(): CSSComputedStyleProperty[] {
|
||||
const view = this.viewRef.get();
|
||||
if (!view) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const result = getComputedCssValues(view)
|
||||
.filter(pair => pair[0][0] !== "_")
|
||||
.map((pair) => {
|
||||
return {
|
||||
name: pair[0],
|
||||
value: valueToString(pair[1])
|
||||
};
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
unregisterNode(this);
|
||||
this.viewRef.clear();
|
||||
}
|
||||
|
||||
public toJSON() {
|
||||
return JSON.stringify(this.toObject());
|
||||
}
|
||||
|
||||
private toObject() {
|
||||
return {
|
||||
nodeId: this.nodeId,
|
||||
nodeType: this.nodeType,
|
||||
nodeName: this.nodeName,
|
||||
localName: this.localName,
|
||||
nodeValue: this.nodeValue,
|
||||
children: this.children.map(c => c.toObject()),
|
||||
attributes: this.attributes
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -108,7 +108,7 @@ export class CssAnimationProperty<T extends Style, U> {
|
||||
|
||||
public register(cls: { prototype: T }): void;
|
||||
public isSet(instance: T): boolean;
|
||||
|
||||
|
||||
public _valueConverter?: (value: string) => any;
|
||||
public static _getByCssName(name: string): CssAnimationProperty<any, any>;
|
||||
}
|
||||
@@ -121,4 +121,7 @@ export function propagateInheritableCssProperties(parentStyle: Style, childStyle
|
||||
export function clearInheritedProperties(view: ViewBase): void;
|
||||
|
||||
export function makeValidator<T>(...values: T[]): (value: any) => value is T;
|
||||
export function makeParser<T>(isValid: (value: any) => boolean): (value: any) => T;
|
||||
export function makeParser<T>(isValid: (value: any) => boolean): (value: any) => T;
|
||||
|
||||
export function getSetProperties(view: ViewBase): [string, any][];
|
||||
export function getComputedCssValues(view: ViewBase): [string, any][];
|
||||
@@ -12,6 +12,7 @@ export { Style };
|
||||
|
||||
export const unsetValue: any = new Object();
|
||||
|
||||
let cssPropertyNames: string[] = [];
|
||||
let symbolPropertyMap = {};
|
||||
let cssSymbolPropertyMap = {};
|
||||
|
||||
@@ -152,6 +153,14 @@ export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<
|
||||
if (affectsLayout) {
|
||||
this.requestLayout();
|
||||
}
|
||||
|
||||
if (this.domNode) {
|
||||
if (reset) {
|
||||
this.domNode.attributeRemoved(propertyName);
|
||||
} else {
|
||||
this.domNode.attributeModified(propertyName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -179,6 +188,10 @@ export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<
|
||||
if (affectsLayout) {
|
||||
owner.requestLayout();
|
||||
}
|
||||
|
||||
if (owner.domNode) {
|
||||
owner.domNode.attributeModified(propertyName, value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -299,6 +312,14 @@ export class CoercibleProperty<T extends ViewBase, U> extends Property<T, U> imp
|
||||
if (affectsLayout) {
|
||||
this.requestLayout();
|
||||
}
|
||||
|
||||
if (this.domNode) {
|
||||
if (reset) {
|
||||
this.domNode.attributeRemoved(propertyName);
|
||||
} else {
|
||||
this.domNode.attributeModified(propertyName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,6 +420,8 @@ export class CssProperty<T extends Style, U> implements definitions.CssProperty<
|
||||
const propertyName = options.name;
|
||||
this.name = propertyName;
|
||||
|
||||
cssPropertyNames.push(options.cssName);
|
||||
|
||||
this.cssName = `css:${options.cssName}`;
|
||||
this.cssLocalName = options.cssName;
|
||||
|
||||
@@ -635,6 +658,8 @@ export class CssAnimationProperty<T extends Style, U> {
|
||||
const propertyName = options.name;
|
||||
this.name = propertyName;
|
||||
|
||||
cssPropertyNames.push(options.cssName);
|
||||
|
||||
CssAnimationProperty.properties[propertyName] = this;
|
||||
if (options.cssName && options.cssName !== propertyName) {
|
||||
CssAnimationProperty.properties[options.cssName] = this;
|
||||
@@ -1206,4 +1231,34 @@ export function makeParser<T>(isValid: (value: any) => boolean): (value: any) =>
|
||||
throw new Error("Invalid value: " + value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getSetProperties(view: ViewBase): [string, any][] {
|
||||
const result = [];
|
||||
|
||||
Object.getOwnPropertyNames(view).forEach(prop => {
|
||||
result.push([prop, view[prop]]);
|
||||
});
|
||||
|
||||
let symbols = Object.getOwnPropertySymbols(view);
|
||||
for (let symbol of symbols) {
|
||||
const property = symbolPropertyMap[symbol];
|
||||
if (!property) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const value = view[property.key];
|
||||
result.push([property.name, value]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getComputedCssValues(view: ViewBase): [string, any][] {
|
||||
const result = [];
|
||||
const style = view.style;
|
||||
for (var prop of cssPropertyNames) {
|
||||
result.push([prop, style[prop]]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import { layout } from "../../../utils/utils";
|
||||
import { Color } from "../../../color";
|
||||
import { Order, FlexGrow, FlexShrink, FlexWrapBefore, AlignSelf } from "../../layouts/flexbox-layout";
|
||||
import { Length } from "../../styling/style-properties";
|
||||
import { DOMNode } from "../../../debugger/dom-node";
|
||||
|
||||
export { isIOS, isAndroid, layout, Color };
|
||||
|
||||
@@ -57,6 +58,7 @@ export abstract class ViewBase extends Observable {
|
||||
col: number;
|
||||
rowSpan: number;
|
||||
colSpan: number;
|
||||
domNode: DOMNode;
|
||||
|
||||
order: Order;
|
||||
flexGrow: FlexGrow;
|
||||
@@ -277,7 +279,7 @@ export abstract class ViewBase extends Observable {
|
||||
|
||||
/**
|
||||
* Performs the core logic of adding a child view to the native visual tree. Returns true if the view's native representation has been successfully added, false otherwise.
|
||||
*/
|
||||
*/
|
||||
_addViewToNativeVisualTree(view: ViewBase, atIndex?: number): boolean;
|
||||
_removeViewFromNativeVisualTree(view: ViewBase): void;
|
||||
_childIndexToNativeChildIndex(index?: number): number;
|
||||
@@ -296,6 +298,12 @@ export abstract class ViewBase extends Observable {
|
||||
*/
|
||||
public deletePseudoClass(name: string): void;
|
||||
|
||||
/**
|
||||
* @unstable
|
||||
* Ensures a dom-node for this view.
|
||||
*/
|
||||
public ensureDomNode();
|
||||
|
||||
//@private
|
||||
public _styleScope: any;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import { Binding, BindingOptions, Observable, WrappedValue, PropertyChangeData,
|
||||
import { isIOS, isAndroid } from "../../../platform";
|
||||
import { layout } from "../../../utils/utils";
|
||||
import { Length, paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty } from "../../styling/style-properties";
|
||||
import { DOMNode } from "../../../debugger/dom-node";
|
||||
|
||||
// TODO: Remove this import!
|
||||
import * as types from "../../../utils/types";
|
||||
@@ -142,6 +143,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
private _visualState: string;
|
||||
private _inlineStyleSelector: SelectorCore;
|
||||
private __nativeView: any;
|
||||
public domNode: DOMNode;
|
||||
|
||||
public bindingContext: any;
|
||||
public nativeView: any;
|
||||
@@ -259,7 +261,13 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
return null;
|
||||
}
|
||||
|
||||
// Overriden so we don't raise `poropertyChange`
|
||||
public ensureDomNode() {
|
||||
if (!this.domNode) {
|
||||
this.domNode = new DOMNode(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Overridden so we don't raise `poropertyChange`
|
||||
// The property will raise its own event.
|
||||
public set(name: string, value: any) {
|
||||
this[name] = WrappedValue.unwrap(value);
|
||||
@@ -558,6 +566,10 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
view.parent = this;
|
||||
this._addViewCore(view, atIndex);
|
||||
view._parentChanged(null);
|
||||
|
||||
if (this.domNode) {
|
||||
this.domNode.onChildAdded(view);
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
@@ -590,7 +602,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
}
|
||||
|
||||
/**
|
||||
* Core logic for removing a child view from this instance. Used by the framework to handle lifecycle events more centralized. Do not outside the UI Stack implementation.
|
||||
* Core logic for removing a child view from this instance. Used by the framework to handle lifecycle events more centralized. Do not use outside the UI Stack implementation.
|
||||
*/
|
||||
public _removeView(view: ViewBase) {
|
||||
if (traceEnabled()) {
|
||||
@@ -601,6 +613,10 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
throw new Error("View not added to this instance. View: " + view + " CurrentParent: " + view.parent + " ExpectedParent: " + this);
|
||||
}
|
||||
|
||||
if (this.domNode) {
|
||||
this.domNode.onChildRemoved(view);
|
||||
}
|
||||
|
||||
this._removeViewCore(view);
|
||||
view.parent = undefined;
|
||||
view._parentChanged(this);
|
||||
@@ -785,6 +801,12 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
// this._iosView = null;
|
||||
|
||||
this._context = null;
|
||||
|
||||
if (this.domNode) {
|
||||
this.domNode.dispose();
|
||||
this.domNode = undefined;
|
||||
}
|
||||
|
||||
traceNotifyEvent(this, "_onContextChanged");
|
||||
traceNotifyEvent(this, "_tearDownUI");
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ function onLivesync(args: EventData): void {
|
||||
}
|
||||
application.on("livesync", onLivesync);
|
||||
|
||||
if (global && global.__inspector) {
|
||||
require("tns-core-modules/debugger/devtools-elements");
|
||||
}
|
||||
|
||||
let frameStack: Array<FrameBase> = [];
|
||||
|
||||
function buildEntryFromArgs(arg: any): NavigationEntry {
|
||||
|
||||
4
tns-core-modules/ui/slider/slider.d.ts
vendored
4
tns-core-modules/ui/slider/slider.d.ts
vendored
@@ -38,12 +38,12 @@ export class Slider extends View {
|
||||
/**
|
||||
* Represents the observable property backing the value property of each Slider instance.
|
||||
*/
|
||||
export const valueProperty: Property<Slider, number>;
|
||||
export const valueProperty: CoercibleProperty<Slider, number>;
|
||||
|
||||
/**
|
||||
* Represents the observable property backing the minValue property of each Slider instance.
|
||||
*/
|
||||
export const minValueProperty: CoercibleProperty<Slider, number>;
|
||||
export const minValueProperty: Property<Slider, number>;
|
||||
|
||||
/**
|
||||
* Represents the observable property backing the maxValue property of each Slider instance.
|
||||
|
||||
@@ -129,7 +129,7 @@ export class TextBase extends TextBaseCommon {
|
||||
}
|
||||
}
|
||||
|
||||
// Overriden in TextField becasue setSingleLine(false) will remove methodTransformation.
|
||||
// Overridden in TextField because setSingleLine(false) will remove methodTransformation.
|
||||
// and we don't want to allow TextField to be multiline
|
||||
[whiteSpaceProperty.setNative](value: WhiteSpace) {
|
||||
const nativeView = this.nativeView;
|
||||
|
||||
Reference in New Issue
Block a user