web-atoms-core
Version:
187 lines (164 loc) • 5.58 kB
text/typescript
import Bind from "./Bind";
import { IClassOf } from "./types";
export interface IAttributes {
[key: string]: string | number | null | any;
}
export class RootObject {
public get vsProps(): {
[k in keyof this]?: this[k] | Bind
} | { [k: string]: any } | {} {
return undefined;
}
}
// tslint:disable-next-line: no-namespace
declare global {
namespace JSX {
// tslint:disable-next-line: interface-name
interface ElementAttributesProperty {
vsProps;
}
type HtmlPartial<T> = {
[k in keyof T]?: {
[tx in keyof T[k]]?: T[k][tx] | any;
} | {
eventClick?: any;
eventBlur?: any;
eventFocus?: any;
text?: string | any;
[key: string]: any
}
};
type IAllHtmlElements = HtmlPartial<HTMLElementTagNameMap>;
// tslint:disable-next-line
interface IntrinsicElements extends IAllHtmlElements {
}
}
}
export type IMergedControl<T, T1> =
{
[P in keyof (T & T1)]?: (T & T1)[P];
} & {
vsProps: {
[P in keyof (T & T1)]?: (T & T1)[P];
}
};
export type NodeFactory = (a?: any, ... nodes: XNode[]) => XNode;
export type AttachedNode = (n: any) => { [key: string]: any};
export default class XNode {
public static attach<T, T1 extends HTMLElementTagNameMap, K extends keyof T1>(
n: IClassOf<T>,
tag: K): new (... a: any[]) => IMergedControl<T, T1[K]> ;
public static attach<T, T1>(
n: IClassOf<T>,
tag: (a?: Partial<T1>, ... nodes: XNode[]) => XNode): new (... a: any[]) => IMergedControl<T, T1> ;
public static attach(
n: any,
tag: any): any {
return {
factory: (attributes: any, ... nodes: XNode[] ) => new XNode(n, attributes
? { ... attributes, for: tag }
: { for: tag}, nodes)
};
}
public static prepare<T>(
n: any,
isProperty?: boolean,
isTemplate?: boolean): ((attributes: Partial<T>, ... nodes: XNode[]) => XNode) {
return {
factory(a: any, ... nodes: any[]) {
return new XNode(n, a, nodes, isProperty , isTemplate);
},
toString() {
return n;
}
} as any;
}
public static template(): NodeFactory {
return {
factory: true,
isTemplate: true,
} as any;
}
/**
* This is only for intellisense...
*/
public static attached(): AttachedNode {
return {
attached: true
} as any;
}
public static property(): NodeFactory {
return {
factory: true
} as any;
}
/**
* Declares Root Namespace and Assembly. You can use return function to
* to declare the type
* @param ns Root Namespace
*/
public static namespace(ns: string, assemblyName: string) {
return (type: string, isTemplate?: boolean) => {
return (c) => {
for (const key in c) {
if (c.hasOwnProperty(key)) {
const element = c[key];
if (element) {
const n = ns + "." + type + ":" + key + ";" + assemblyName;
const af: any = (a) => {
const r = {
[n]: a
};
Object.defineProperty(r, "toString", {
value: () => n,
enumerable: false,
configurable: false
});
return r;
};
af.factory = (a?: any, ... nodes: any[]) =>
new XNode(n, a, nodes, true, element.isTemplate );
af.toString = () => n;
c[key] = af;
}
}
}
const tn = ns + "." + type + ";" + assemblyName;
c.factory = (a?: any, ... nodes: XNode[]) => {
return new XNode(tn, a, nodes, false, isTemplate);
};
c.toString = () => tn;
};
};
}
public static create(
// tslint:disable-next-line: ban-types
name: string | Function,
attributes: IAttributes,
... children: Array<XNode | XNode[] | any>): XNode {
if ((name as any).factory) {
return ((name as any).factory)(attributes, ... children);
}
if ((name as any).isControl) {
return new XNode(name as any, attributes, children);
}
if (typeof name === "object") {
name = (name as any).toString();
}
return new XNode(name as any, attributes, children);
}
constructor(
// tslint:disable-next-line: ban-types
public name: string | Function,
public attributes: IAttributes,
public children: XNode[] | XNode[][] | any[],
public isProperty?: boolean,
public isTemplate?: boolean) {
}
public toString(): string {
if (typeof this.name === "string") {
return `name is of type string and value is ${this.name}`;
}
return `name is of type ${typeof this.name}`;
}
}