tsx.ts
114 lines
| 3.8 KiB
| video/mp2t
|
TypeScriptLexer
|
|
r96 | import { Constructor } from "@implab/core-amd/interfaces"; | ||
|
|
r65 | import { HtmlRendition } from "./tsx/HtmlRendition"; | ||
| import { WidgetRendition } from "./tsx/WidgetRendition"; | ||||
|
|
r96 | import { isWidgetConstructor, Rendition } from "./tsx/traits"; | ||
|
|
r65 | import { FunctionRendition } from "./tsx/FunctionRendition"; | ||
|
|
r89 | import Stateful = require("dojo/Stateful"); | ||
| import _WidgetBase = require("dijit/_WidgetBase"); | ||||
| import { DjxWidgetBase } from "./tsx/DjxWidgetBase"; | ||||
|
|
r96 | import { WatchRendition } from "./tsx/WatchRendition"; | ||
| import { observe } from "./observable"; | ||||
|
|
r65 | |||
| export function createElement<T extends Constructor | string | ((props: any) => Element)>(elementType: T, ...args: any[]): Rendition { | ||||
| if (typeof elementType === "string") { | ||||
| const ctx = new HtmlRendition(elementType); | ||||
| if (args) | ||||
| args.forEach(x => ctx.visitNext(x)); | ||||
| return ctx; | ||||
| } else if (isWidgetConstructor(elementType)) { | ||||
| const ctx = new WidgetRendition(elementType); | ||||
| if (args) | ||||
| args.forEach(x => ctx.visitNext(x)); | ||||
| return ctx; | ||||
| } else if (typeof elementType === "function") { | ||||
| const ctx = new FunctionRendition(elementType as (props: any) => Element); | ||||
| if (args) | ||||
| args.forEach(x => ctx.visitNext(x)); | ||||
| return ctx; | ||||
| } else { | ||||
| throw new Error(`The element type '${elementType}' is unsupported`); | ||||
| } | ||||
| } | ||||
| export interface EventDetails<T = any> { | ||||
| detail: T; | ||||
| } | ||||
| export interface EventSelector { | ||||
| selectorTarget: HTMLElement; | ||||
| target: HTMLElement; | ||||
| } | ||||
| export type DojoMouseEvent<T = any> = MouseEvent & EventSelector & EventDetails<T>; | ||||
|
|
r89 | |||
| type StatefulProps<T> = T extends Stateful<infer A> ? A : never; | ||||
| /** | ||||
| * 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 | ||||
| * @returns Rendition which is created instantly | ||||
| */ | ||||
| export function watch<W extends _WidgetBase, K extends keyof W>( | ||||
| target: W, | ||||
| prop: K, | ||||
|
|
r96 | render: (model: W[K]) => any | ||
|
|
r89 | ): 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 | ||||
| * @returns Rendition which is created instantly | ||||
| */ | ||||
| export function watch<T extends Stateful, K extends keyof StatefulProps<T>>( | ||||
| target: T, | ||||
| prop: K, | ||||
|
|
r96 | render: (model: StatefulProps<T>[K]) => any | ||
|
|
r89 | ): Rendition; | ||
| export function watch<T extends Stateful, K extends keyof StatefulProps<T> & string>( | ||||
| target: T, | ||||
| prop: K, | ||||
|
|
r96 | render: (model: StatefulProps<T>[K]) => any | ||
|
|
r89 | ) { | ||
|
|
r96 | return new WatchRendition( | ||
| render, | ||||
| observe(({next}) => { | ||||
| const h = target.watch( | ||||
| prop, | ||||
| (_prop, oldValue, newValue) => oldValue !== newValue && next(newValue) | ||||
| ); | ||||
| return () => h.remove(); | ||||
| }) | ||||
| ) | ||||
|
|
r89 | } | ||
| /** 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) { | ||||
| * // ... | ||||
| * } | ||||
| * ``` | ||||
| */ | ||||
| export const on = <E extends string>(...eventNames: E[]) => | ||||
| <K extends string, | ||||
| T extends DjxWidgetBase<any, { [p in E]: EV }>, | ||||
| EV extends Event | ||||
| >( | ||||
| target: T, | ||||
| key: K, | ||||
| _descriptor: TypedPropertyDescriptor<(eventObj: EV) => void> | TypedPropertyDescriptor<() => void> | ||||
| ): any => { | ||||
|
|
r93 | const handlers = eventNames.map(eventName => ({ eventName, handlerMethod: key })); | ||
|
|
r89 | target._eventHandlers = target._eventHandlers ? target._eventHandlers.concat(handlers) : handlers; | ||
| }; | ||||
