##// END OF EJS Templates
@on decorator registers handlers directry on domNode, added support to multiple events in one decorator...
@on decorator registers handlers directry on domNode, added support to multiple events in one decorator fixed isRendition failing on null objects

File last commit:

r85:35a7b6319ebe v1.2.6 default
r85:35a7b6319ebe v1.2.6 default
Show More
traits.ts
228 lines | 7.3 KiB | video/mp2t | TypeScriptLexer
cin
Switched to @implab/dojo-typings
r71 import { IDestroyable, IRemovable } from "@implab/core-amd/interfaces";
cin
Converted to subproject djx, removed dojo-typings
r65 import { isDestroyable } from "@implab/core-amd/safe";
import _WidgetBase = require("dijit/_WidgetBase");
import registry = require("dijit/registry");
import dom = require("dojo/dom-construct");
cin
Switched to @implab/dojo-typings
r71 import Stateful = require("dojo/Stateful");
import { FunctionRendition } from "./FunctionRendition";
cin
temp commit, working on @on() decorator
r72 import { DjxWidgetBase } from "./DjxWidgetBase";
cin
Converted to subproject djx, removed dojo-typings
r65
type _WidgetBaseConstructor = typeof _WidgetBase;
export type DojoNodePosition = "first" | "after" | "before" | "last" | "replace" | "only" | number;
export interface Rendition<TNode extends Node = Node> {
getDomNode(): TNode;
placeAt(refNode: string | Node, position?: DojoNodePosition): void;
}
cin
temp commit, working on @on() decorator
r72 /**
cin
Converted to subproject djx, removed dojo-typings
r65 * @deprecated use Rendition
*/
export type BuildContext<TNode extends Node = Node> = Rendition<TNode>;
export interface IRecursivelyDestroyable {
destroyRecursive(): void;
}
export function isNode(el: any): el is Node {
return el && el.nodeName && el.nodeType;
}
export function isElementNode(el: any): el is Element {
return isNode(el) && el.nodeType === 1;
}
export function isTextNode(el: any): el is Text {
return isNode(el) && el.nodeType === 3;
}
export function isProcessingInstructionNode(el: any): el is ProcessingInstruction {
return isNode(el) && el.nodeType === 7;
}
export function isCommentNode(el: any): el is Comment {
return isNode(el) && el.nodeType === 8;
}
export function isDocumentNode(el: any): el is Document {
return isNode(el) && el.nodeType === 9;
}
export function isDocumentTypeNode(el: any): el is DocumentType {
return isNode(el) && el.nodeType === 10;
}
export function isDocumentFragmentNode(el: any): el is DocumentFragment {
return isNode(el) && el.nodeType === 11;
}
export function isWidget(v: any): v is _WidgetBase {
return v && "domNode" in v;
}
export function isRendition(v: any): v is Rendition {
cin
@on decorator registers handlers directry on domNode, added support to multiple events in one decorator...
r85 return typeof v && typeof v.getDomElement === "function";
cin
Converted to subproject djx, removed dojo-typings
r65 }
/**
* @deprecated use isRendition
*/
export const isBuildContext = isRendition;
export function isPlainObject(v: object) {
if (typeof v !== "object")
return false;
const vp = Object.getPrototypeOf(v);
return !vp || vp === Object.prototype;
}
export function isWidgetConstructor(v: any): v is _WidgetBaseConstructor {
return typeof v === "function" && v.prototype && (
"domNode" in v.prototype ||
"buildRendering" in v.prototype
);
}
/** Tests whether the specified node is placed in visible dom.
* @param {Node} node The node to test
*/
export function isInPage(node: Node) {
return (node === document.body) ? false : document.body.contains(node);
}
export function isRecursivelyDestroyable(target: any): target is IRecursivelyDestroyable {
return target && typeof target.destroyRecursive === "function";
}
/** Destroys DOM Node with all contained widgets.
* If the specified node is the root node of a widget, then the
* widget will be destroyed.
*
* @param target DOM Node or widget to destroy
*/
export function destroy(target: Node | IDestroyable | IRecursivelyDestroyable) {
if (isRecursivelyDestroyable(target)) {
target.destroyRecursive();
} else if (isDestroyable(target)) {
target.destroy();
} else if (isNode(target)) {
cin
fixed tsx/traits.destroy to handle non-element dom nodes
r75 const w = isElementNode(target) ? registry.byNode(target) : undefined;
if (w) {
w.destroyRecursive();
cin
Converted to subproject djx, removed dojo-typings
r65 } else {
registry.findWidgets(target).forEach(destroy);
dom.destroy(target);
}
}
}
/** Empties a content of the specified node and destroys all contained widgets.
*
* @param target DOM node to .
*/
export function emptyNode(target: Node) {
registry.findWidgets(target).forEach(destroy);
dom.empty(target);
}
/** This function starts all widgets inside the DOM node if the target is a node
* or starts widget itself if the target is the widget. If the specified node
* associated with the widget that widget will be started.
cin
temp commit, working on @on() decorator
r72 *
cin
Converted to subproject djx, removed dojo-typings
r65 * @param target DOM node to find and start widgets or the widget itself.
*/
export function startupWidgets(target: Node | _WidgetBase, skipNode?: Node) {
if (isNode(target)) {
cin
Fixed startupWidgets for nodes are not of the Element type.
r69 const w = isElementNode(target) ? registry.byNode(target) : undefined;
cin
Converted to subproject djx, removed dojo-typings
r65 if (w) {
cin
Fixed startupWidgets for nodes are not of the Element type.
r69 if (w.startup)
w.startup();
cin
Converted to subproject djx, removed dojo-typings
r65 } else {
cin
Fixed startupWidgets for nodes are not of the Element type.
r69 registry.findWidgets(target, skipNode).forEach(x => x.startup());
cin
Converted to subproject djx, removed dojo-typings
r65 }
} else {
cin
temp commit, working on @on() decorator
r72 if (target.startup)
cin
Fixed startupWidgets for nodes are not of the Element type.
r69 target.startup();
cin
Converted to subproject djx, removed dojo-typings
r65 }
cin
Switched to @implab/dojo-typings
r71 }
type StatefulProps<T> = T extends Stateful<infer A> ? A : never;
type CleanFn = (instance: IRemovable | IDestroyable) => void;
/**
* Observers the property and calls render callback each change.
*
* @param target The target object which property will be observed.
* @param prop The name of the property.
* @param render The callback which will be called every time the value is changed
* @param cleanupOrOwner The object with method `own` or an callback to register lifecycle for the observer.
* @returns Rendition which is created instantly
*/
cin
temp commit, working on @on() decorator
r72 export function watch<W extends _WidgetBase, K extends keyof W>(
cin
Switched to @implab/dojo-typings
r71 target: W,
prop: K,
render: (model: W[K]) => any,
cin
temp commit, working on @on() decorator
r72 cleanupOrOwner?: { own: CleanFn } | CleanFn
cin
Switched to @implab/dojo-typings
r71 ): Rendition;
/**
* Observers the property and calls render callback each change.
*
* @param target The target object which property will be observed.
* @param prop The name of the property.
* @param render The callback which will be called every time the value is changed
* @param cleanupOrOwner The object with method `own` or an callback to register lifecycle for the observer.
* @returns Rendition which is created instantly
*/
export function watch<T extends Stateful, K extends keyof StatefulProps<T>>(
target: T,
prop: K,
render: (model: StatefulProps<T>[K]) => any,
cin
temp commit, working on @on() decorator
r72 cleanupOrOwner?: { own: CleanFn } | CleanFn
cin
Switched to @implab/dojo-typings
r71 ): Rendition;
export function watch<T extends Stateful, K extends keyof StatefulProps<T> & string>(
target: T,
prop: K,
cin
temp commit, working on @on() decorator
r72 render: (model: StatefulProps<T>[K]) => any,
cleanupOrOwner: { own: CleanFn } | CleanFn = () => { }
cin
Switched to @implab/dojo-typings
r71 ) {
let rendition = new FunctionRendition(() => render(target.get(prop)));
cin
fixed tslint errors, added support for private methods to @on() decorator
r79 const _own = cleanupOrOwner instanceof Function ? cleanupOrOwner : (x: IRemovable) => cleanupOrOwner.own(x);
cin
Switched to @implab/dojo-typings
r71 _own(target.watch(prop, (_name, oldValue, newValue) => {
if (oldValue !== newValue) {
const newRendition = new FunctionRendition(() => render(newValue));
newRendition.placeAt(rendition.getDomNode(), "replace");
destroy(rendition.getDomNode());
rendition = newRendition;
}
}));
return rendition;
}
cin
temp commit, working on @on() decorator
r72
cin
implemented @on("event-name") decorator for event handlers
r73 /** Decorates the method which will be registered as the handle for the specified event.
* This decorator can be applied to DjxWidgetBase subclass methods.
*
* ```
* @on("click")
* _onClick(eventObj: MouseEvent) {
* // ...
* }
* ```
*/
cin
@on decorator registers handlers directry on domNode, added support to multiple events in one decorator...
r85 export const on = <E extends string>(...eventNames: E[]) =>
cin
fixed tslint errors, added support for private methods to @on() decorator
r79 <K extends string,
cin
implemented @on("event-name") decorator for event handlers
r73 T extends DjxWidgetBase<any, { [p in E]: EV }>,
EV extends Event
cin
temp commit, working on @on() decorator
r72 >(
target: T,
key: K,
cin
fixed tslint errors, added support for private methods to @on() decorator
r79 _descriptor: TypedPropertyDescriptor<(eventObj: EV) => void> | TypedPropertyDescriptor<() => void>
cin
temp commit, working on @on() decorator
r72 ): any => {
cin
@on decorator registers handlers directry on domNode, added support to multiple events in one decorator...
r85 const handlers = eventNames.map(eventName => ({ eventName, handlerMethod: key }))
target._eventHandlers = target._eventHandlers ? target._eventHandlers.concat(handlers) : handlers;
cin
temp commit, working on @on() decorator
r72 };