mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
141 lines
4.5 KiB
TypeScript
141 lines
4.5 KiB
TypeScript
import { Observable, EventData } from "data/observable";
|
|
import { propagateInheritedProperties, clearInheritedProperties, applyNativeSetters, Property, InheritedProperty, CssProperty } from "./properties";
|
|
import { Binding, BindingOptions } from "ui/core/bindable";
|
|
import { isIOS } from "platform";
|
|
import { ViewBase as ViewBaseDefinition } from "ui/core/view-base";
|
|
import { Style } from "ui/styling/style";
|
|
import { fromString as gestureFromString } from "ui/gestures";
|
|
|
|
let defaultBindingSource = {};
|
|
|
|
export function getAncestor(view: ViewBaseDefinition, criterion: string | Function): ViewBaseDefinition {
|
|
let matcher: (view: ViewBaseDefinition) => boolean = null;
|
|
if (typeof criterion === "string") {
|
|
matcher = (view: ViewBaseDefinition) => view.typeName === criterion;
|
|
} else {
|
|
matcher = (view: ViewBaseDefinition) => view instanceof criterion;
|
|
}
|
|
|
|
for (let parent = view.parent; parent != null; parent = parent.parent) {
|
|
if (matcher(parent)) {
|
|
return parent;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export function getEventOrGestureName(name: string): string {
|
|
return name.indexOf("on") === 0 ? name.substr(2, name.length - 2) : name;
|
|
}
|
|
|
|
export function isEventOrGesture(name: string, view: ViewBaseDefinition): boolean {
|
|
if (typeof name === "string") {
|
|
let eventOrGestureName = getEventOrGestureName(name);
|
|
let evt = `${eventOrGestureName}Event`;
|
|
|
|
return view.constructor && evt in view.constructor ||
|
|
gestureFromString(eventOrGestureName.toLowerCase()) !== undefined;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
export class ViewBase extends Observable implements ViewBaseDefinition {
|
|
private _updatingJSPropertiesDict = {};
|
|
private _style: Style;
|
|
|
|
public bindingContext: any;
|
|
public nativeView: any;
|
|
public parent: ViewBase;
|
|
public isCollapsed;
|
|
|
|
constructor() {
|
|
super();
|
|
this._style = new Style(this);
|
|
}
|
|
|
|
get style(): Style {
|
|
return this._style;
|
|
}
|
|
|
|
get android(): any {
|
|
return undefined;
|
|
}
|
|
|
|
get ios(): any {
|
|
return undefined;
|
|
}
|
|
|
|
private bindings = new Map<string, Binding>();
|
|
public bind(options: BindingOptions, source: Object = defaultBindingSource): void {
|
|
let binding: Binding = this.bindings.get(options.targetProperty);
|
|
if (binding) {
|
|
binding.unbind();
|
|
}
|
|
|
|
binding = new Binding(this, options);
|
|
this.bindings.set(options.targetProperty, binding);
|
|
|
|
let bindingSource = source;
|
|
if (bindingSource === defaultBindingSource) {
|
|
bindingSource = this.bindingContext;
|
|
binding.sourceIsBindingContext = true;
|
|
}
|
|
|
|
// if (!types.isNullOrUndefined(bindingSource)) {
|
|
binding.bind(bindingSource);
|
|
// }
|
|
}
|
|
|
|
public unbind(property: string): void {
|
|
let binding: Binding = this.bindings.get(property);
|
|
if (binding) {
|
|
binding.unbind();
|
|
this.bindings.delete(property);
|
|
}
|
|
}
|
|
|
|
public _updateTwoWayBinding(propertyName: string, value: any) {
|
|
let binding: Binding = this.bindings.get(propertyName);
|
|
if (binding) {
|
|
binding.updateTwoWay(value);
|
|
}
|
|
}
|
|
|
|
// public _setCore(data: PropertyChangeData) {
|
|
// super._setCore(data);
|
|
// this._updateTwoWayBinding(data.propertyName, data.value);
|
|
// }
|
|
|
|
public nativePropertyChanged(property: Property<ViewBase, any>, newValue: any): void {
|
|
if (this._updatingJSPropertiesDict[property.native]) {
|
|
return;
|
|
}
|
|
this._updatingJSPropertiesDict[property.native] = true;
|
|
property.set.call(this, newValue);
|
|
delete this._updatingJSPropertiesDict[property.native];
|
|
}
|
|
|
|
public requestLayout(): void {
|
|
//
|
|
}
|
|
|
|
public eachChild(callback: (child: ViewBase) => boolean) {
|
|
//
|
|
}
|
|
}
|
|
|
|
export const visibilityProperty = new CssProperty<Style, "visible" | "hidden" | "collapse" | "collapsed">({
|
|
name: "visibility", cssName: "visibility", defaultValue: "visible", affectsLayout: isIOS, valueChanged: (target, newValue) => {
|
|
if (newValue !== "visible" && newValue !== "collapse" && newValue !== "collapsed" && newValue !== "hidden") {
|
|
throw new Error(`Invalid visibility value: ${newValue}`);
|
|
}
|
|
|
|
target.view.isCollapsed = (newValue === "collapse" || newValue === "collapsed");
|
|
}
|
|
});
|
|
visibilityProperty.register(Style);
|
|
|
|
export let bindingContextProperty = new InheritedProperty<ViewBase, any>({ name: "bindingContext" });
|
|
bindingContextProperty.register(ViewBase); |