From fd4caf0b4a93bf0084c213c015a71afa69b7d9cc Mon Sep 17 00:00:00 2001 From: defaultkavy Date: Fri, 26 Apr 2024 18:38:32 +0800 Subject: [PATCH] add logo and icons --- $index.ts | 243 ------------------------ .gitignore | 2 - .npmignore | 2 - README.md | 90 --------- assets/icon_dark.png => icon_dark.png | Bin assets/icon_light.png => icon_light.png | Bin index.ts | 50 ----- lib/$EventManager.ts | 65 ------- lib/$NodeManager.ts | 66 ------- lib/$State.ts | 61 ------ lib/$Util.ts | 68 ------- lib/node/$Anchor.ts | 24 --- lib/node/$Async.ts | 22 --- lib/node/$Button.ts | 39 ---- lib/node/$Canvas.ts | 29 --- lib/node/$Container.ts | 64 ------- lib/node/$Dialog.ts | 19 -- lib/node/$Document.ts | 40 ---- lib/node/$Element.ts | 113 ----------- lib/node/$Form.ts | 44 ----- lib/node/$HTMLElement.ts | 65 ------- lib/node/$Image.ts | 118 ------------ lib/node/$Input.ts | 231 ---------------------- lib/node/$Label.ts | 15 -- lib/node/$Node.ts | 68 ------- lib/node/$OptGroup.ts | 17 -- lib/node/$Option.ts | 37 ---- lib/node/$SVGElement.ts | 8 - lib/node/$Select.ts | 57 ------ lib/node/$Text.ts | 14 -- lib/node/$Textarea.ts | 100 ---------- lib/node/$View.ts | 41 ---- assets/logo_dark.png => logo_dark.png | Bin assets/logo_light.png => logo_light.png | Bin package.json | 22 --- tsconfig.json | 21 -- 36 files changed, 1855 deletions(-) delete mode 100644 $index.ts delete mode 100644 .gitignore delete mode 100644 .npmignore delete mode 100644 README.md rename assets/icon_dark.png => icon_dark.png (100%) rename assets/icon_light.png => icon_light.png (100%) delete mode 100644 index.ts delete mode 100644 lib/$EventManager.ts delete mode 100644 lib/$NodeManager.ts delete mode 100644 lib/$State.ts delete mode 100644 lib/$Util.ts delete mode 100644 lib/node/$Anchor.ts delete mode 100644 lib/node/$Async.ts delete mode 100644 lib/node/$Button.ts delete mode 100644 lib/node/$Canvas.ts delete mode 100644 lib/node/$Container.ts delete mode 100644 lib/node/$Dialog.ts delete mode 100644 lib/node/$Document.ts delete mode 100644 lib/node/$Element.ts delete mode 100644 lib/node/$Form.ts delete mode 100644 lib/node/$HTMLElement.ts delete mode 100644 lib/node/$Image.ts delete mode 100644 lib/node/$Input.ts delete mode 100644 lib/node/$Label.ts delete mode 100644 lib/node/$Node.ts delete mode 100644 lib/node/$OptGroup.ts delete mode 100644 lib/node/$Option.ts delete mode 100644 lib/node/$SVGElement.ts delete mode 100644 lib/node/$Select.ts delete mode 100644 lib/node/$Text.ts delete mode 100644 lib/node/$Textarea.ts delete mode 100644 lib/node/$View.ts rename assets/logo_dark.png => logo_dark.png (100%) rename assets/logo_light.png => logo_light.png (100%) delete mode 100644 package.json delete mode 100644 tsconfig.json diff --git a/$index.ts b/$index.ts deleted file mode 100644 index 84f0ea6..0000000 --- a/$index.ts +++ /dev/null @@ -1,243 +0,0 @@ -import { $State, $StateArgument, $StateOption } from "./index"; -import { $Node } from "./lib/node/$Node" -import { $Document } from "./lib/node/$Document" -import { $Anchor } from "./lib/node/$Anchor"; -import { $Button } from "./lib/node/$Button"; -import { $Form } from "./lib/node/$Form"; -import { $Input } from "./lib/node/$Input"; -import { $Container } from "./lib/node/$Container"; -import { $Element } from "./lib/node/$Element"; -import { $Label } from "./lib/node/$Label"; -import { $Image } from "./lib/node/$Image"; -import { $Canvas } from "./lib/node/$Canvas"; -import { $Dialog } from "./lib/node/$Dialog"; -import { $View } from "./lib/node/$View"; -import { $Select } from "./lib/node/$Select"; -import { $Option } from "./lib/node/$Option"; -import { $OptGroup } from "./lib/node/$OptGroup"; -import { $Textarea } from "./lib/node/$Textarea"; -import { $Util } from "./lib/$Util"; -import { $HTMLElement } from "./lib/node/$HTMLElement"; -import { $Async } from "./lib/node/$Async"; - -export type $ = typeof $; -export function $(query: `::${string}`): E[]; -export function $(query: `:${string}`): E | null; -export function $(element: null): null; -export function $(resolver: K): $.TagNameTypeMap[K]; -export function $(resolver: K): $Container; -export function $(htmlElement: H): $.$HTMLElementMap; -export function $(element: H): $Element; -export function $(node: N): N; -export function $(element: H): $Element; -export function $(element: null | HTMLElement | EventTarget): $Element | null; -export function $(element: undefined): undefined; -export function $(resolver: any) { - if (typeof resolver === 'undefined') return resolver; - if (resolver === null) return resolver; - if (resolver instanceof $Node) return resolver; - if (typeof resolver === 'string') { - if (resolver.startsWith('::')) return Array.from(document.querySelectorAll(resolver.replace(/^::/, ''))).map(dom => $(dom)); - else if (resolver.startsWith(':')) return $(document.querySelector(resolver.replace(/^:/, ''))); - else if (resolver in $.TagNameElementMap) { - const instance = $.TagNameElementMap[resolver as keyof $.TagNameElementMap] - if (instance === $HTMLElement) return new $HTMLElement(resolver); - if (instance === $Container) return new $Container(resolver); - //@ts-expect-error - return new instance(); - } else return new $Container(resolver); - } - if (resolver instanceof Node) { - if (resolver.$) return resolver.$; - else return $Util.from(resolver); - } - throw `$: NOT SUPPORT TARGET ELEMENT TYPE ('${resolver}')` -} -export namespace $ { - export let anchorHandler: null | (($a: $Anchor, e: Event) => void) = null; - export let anchorPreventDefault: boolean = false; - export const TagNameElementMap = { - 'document': $Document, - 'body': $Container, - 'a': $Anchor, - 'p': $Container, - 'pre': $Container, - 'code': $Container, - 'blockquote': $Container, - 'strong': $Container, - 'h1': $Container, - 'h2': $Container, - 'h3': $Container, - 'h4': $Container, - 'h5': $Container, - 'h6': $Container, - 'div': $Container, - 'ol': $Container, - 'ul': $Container, - 'dl': $Container, - 'li': $Container, - 'input': $Input, - 'label': $Label, - 'button': $Button, - 'form': $Form, - 'img': $Image, - 'dialog': $Dialog, - 'canvas': $Canvas, - 'view': $View, - 'select': $Select, - 'option': $Option, - 'optgroup': $OptGroup, - 'textarea': $Textarea, - 'async': $Async, - } - export type TagNameElementMapType = typeof TagNameElementMap; - export interface TagNameElementMap extends TagNameElementMapType {} - export type TagNameTypeMap = { - [key in keyof $.TagNameElementMap]: InstanceType<$.TagNameElementMap[key]>; - }; - export type ContainerTypeTagName = Exclude; - export type SelfTypeTagName = 'input'; - - export type $HTMLElementMap = - H extends HTMLLabelElement ? $Label - : H extends HTMLInputElement ? $Input - : H extends HTMLAnchorElement ? $Anchor - : H extends HTMLButtonElement ? $Button - : H extends HTMLFormElement ? $Form - : H extends HTMLImageElement ? $Image - : H extends HTMLFormElement ? $Form - : H extends HTMLCanvasElement ? $Canvas - : H extends HTMLDialogElement ? $Dialog - : H extends HTMLSelectElement ? $Select - : H extends HTMLOptionElement ? $Option - : H extends HTMLOptGroupElement ? $OptGroup - : H extends HTMLTextAreaElement ? $Textarea - : $Container; - - /** - * A helper for fluent method design. Return the `instance` object when arguments length not equal 0. Otherwise, return the `value`. - * @param instance The object to return when arguments length not equal 0. - * @param args The method `arguments`. - * @param value The value to return when arguments length equal 0. - * @param action The action to execute when arguments length not equal 0. - * @returns - */ - export function fluent(instance: T, args: IArguments, value: () => V, action: (...args: any[]) => void) { - if (!args.length) return value(); - action(); - return instance; - } - - export function orArrayResolve(multable: OrArray) { - if (multable instanceof Array) return multable; - else return [multable]; - } - - export function mixin(target: any, constructors: OrArray) { return $Util.mixin(target, constructors) } - /** - * A helper for undefined able value and $State.set() which apply value to target. - * @param object Target object. - * @param key The key of target object. - * @param value Value of target property or parameter of method(Using Tuple to apply parameter). - * @param methodKey Variant key name when apply value on $State.set() - * @returns - */ - export function set( - object: O, - key: K, - value: O[K] extends (...args: any) => any - ? (undefined | $StateArgument>) - : (undefined | $StateArgument), - handle?: ($state: $State) => any) { - if (value === undefined) return; - if (value instanceof $State) { - value.use(object, key); - if (object[key] instanceof Function) (object[key] as Function)(value) - else object[key] = value.value; - if (handle) handle(value); - return; - } - if (object[key] instanceof Function) (object[key] as Function)(value); - else object[key] = value as any; - } - - export function state(value: T, options?: $StateOption) { - return new $State(value, options) - } - - export async function resize(object: Blob, size: number): Promise { - return new Promise(resolve => { - const reader = new FileReader(); - reader.onload = (e) => { - const $img = $('img'); - $img.once('load', e => { - const $canvas = $('canvas'); - const context = $canvas.getContext('2d'); - const ratio = $img.height() / $img.width(); - const [w, h] = [ - ratio > 1 ? size / ratio : size, - ratio > 1 ? size : size * ratio, - ] - $canvas.height(h).width(w); - context?.drawImage($img.dom, 0, 0, w, h); - resolve($canvas.toDataURL(object.type)) - }) - if (!e.target) throw "$.resize(): e.target is null"; - $img.src(e.target.result as string); - } - reader.readAsDataURL(object); - }) - } - - export function rem(amount: number = 1) { - return parseInt(getComputedStyle(document.documentElement).fontSize) * amount - } - - export function html(html: string) { - const body = new DOMParser().parseFromString(html, 'text/html').body; - return Array.from(body.children).map(child => $(child)) - } - - /**Build multiple element in once. */ - export function builder>(bulder: F, params: [...Parameters][], callback?: BuilderSelfFunction): R[] - export function builder>(bulder: [F, ...Parameters], size: number, callback?: BuilderSelfFunction): R[] - export function builder>(bulder: [F, ...Parameters], options: ($Node | string | BuilderSelfFunction)[]): R[] - export function builder(tagname: K, size: number, callback?: BuilderSelfFunction<$.TagNameTypeMap[K]>): $.TagNameTypeMap[K][] - export function builder(tagname: K, callback: BuilderSelfFunction<$.TagNameTypeMap[K]>[]): $.TagNameTypeMap[K][] - export function builder(tagname: K, size: number, callback?: BuilderSelfFunction<$.TagNameTypeMap[K]>): $.TagNameTypeMap[K][] - export function builder(tagname: K, options: ($Node | string | BuilderSelfFunction<$.TagNameTypeMap[K]>)[]): $.TagNameTypeMap[K][] - export function builder(tagname: any, resolver: any, callback?: BuilderSelfFunction) { - if (typeof resolver === 'number') { - return Array(resolver).fill('').map(v => { - const ele = isTuppleBuilder(tagname) ? tagname[0](...tagname.slice(1) as []) : $(tagname); - if (callback) callback(ele); - return ele - }); - } - else { - const eleArray = []; - for (const item of resolver) { - const ele = tagname instanceof Function ? tagname(...item) // tagname is function, item is params - : isTuppleBuilder(tagname) ? tagname[0](...tagname.slice(1) as []) - : $(tagname); - if (item instanceof Function) { item(ele) } - else if (item instanceof $Node || typeof item === 'string') { ele.content(item) } - eleArray.push(ele); - } - return eleArray; - } - - function isTuppleBuilder(target: any): target is [BuildNodeFunction, ...any] { - if (target instanceof Array && target[0] instanceof Function) return true; - else return false; - } - } - - export function registerTagName(string: string, node: {new(...args: undefined[]): $Node}) { - Object.assign($.TagNameElementMap, {[string]: node}); - return $.TagNameElementMap; - } -} -type BuildNodeFunction = (...args: any[]) => $Node; -type BuilderSelfFunction = (self: K) => void; -globalThis.$ = $; \ No newline at end of file diff --git a/.gitignore b/.gitignore deleted file mode 100644 index eb28fa7..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bun.lockb -node_modules \ No newline at end of file diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 43dbca0..0000000 --- a/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -.gitignore -assets \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index e4e3035..0000000 --- a/README.md +++ /dev/null @@ -1,90 +0,0 @@ - - - - Elexis Logo - -

Build Web in Native JavaScript Syntax

- -> ElexisJS is still in beta test now, some breaking changes might happen very often. - -## What does ElexisJS bring to developer? -1. Write website with Native JavaScript syntax and full TypeScript development experiance, no more HTML or JSX. -2. For fluent method lovers. -3. Easy to import or create extensions to extend more functional. - -## Installation -1. Install from npm - ``` - npm i elexis - ``` -2. Import to your project main entry js/ts file. - ```ts - import 'elexis'; - ``` -3. Use web packaging tools like [Vite](https://vitejs.dev/) to compile your project. - -## How to Create Element -Using the simple $ function to create any element with node name. -```ts -$('a'); -``` -> This is not jQuery selector! It looks like same but it actually create `` element, not selecting them. - -## Fluent method -Create and modify element in one line. -```ts -$('h1').class('title').css({color: 'red'}) -``` - -## Build your first "Hello, world!" ElexisJS project -Let's try this code in your entry file: - -```ts -$(document.body).content([ - $('h1').class('title').content('Hello, world!') -]) -``` - -In the first line, we create a `$Container` to using Elexis API on `document.body` element. Then we see a `content` method after the container object, this method mean the following elements will be the content of container. - -We can pass an array into `content` method. In this array, we put a new `

` element which have a class name "title" and text content "Hello, world!". - -Run the code, we will get this body structure in DOM: - -```html - -

Hello, world!

- -``` - -So far, we just simply do a hello world project that you can type less in HTML way, and these is not the point of ElexisJS. Let's figure out what ElexisJS will boost development speed in the following examples. - -## Using `$State` to sync view and data changes - -This line will create a `$State` value, usually we will put `$` sign behind variable name to mean this is a `$State` variable. - -```ts -const number$ = $.state(42); -``` - -This `$State` value has been set a number `42`, which will become a number type `$State`. We can simply put this state value into any display content! - -```ts -const value$ = $.state(42); - -$(document.body).content([ - $('input').type('number').value(value$), - $('p').content(['User input value: ', value$]) -]) -``` - -You will see the `` element is fill with number `42`, and also `

` element will display `'User input value: 42'`. Now try to change input value in browser, the value text in `

` element will be synced by your input! - -Using `set` method to set value of `$State`, all displayed content of `value$` will be synced. -```ts -value$.set(0) -``` - -## Extensions -1. [@elexis/router](https://github.com/elexisjs/router): Router for Single Page App. -2. [@elexis/layout](https://github.com/elexisjs/layout): Build waterfall/justified layout with automatic compute content size and position. \ No newline at end of file diff --git a/assets/icon_dark.png b/icon_dark.png similarity index 100% rename from assets/icon_dark.png rename to icon_dark.png diff --git a/assets/icon_light.png b/icon_light.png similarity index 100% rename from assets/icon_light.png rename to icon_light.png diff --git a/index.ts b/index.ts deleted file mode 100644 index c90f8dd..0000000 --- a/index.ts +++ /dev/null @@ -1,50 +0,0 @@ -declare global { - var $: import('./$index').$; - interface Array { - detype(...types: F[]): Array> - } - type OrMatrix = T | OrMatrix[]; - type OrArray = T | T[]; - type OrPromise = T | Promise; - type Mutable = { - -readonly [k in keyof T]: T[k]; - }; - type Types = 'string' | 'number' | 'boolean' | 'object' | 'symbol' | 'bigint' | 'function' | 'undefined' - type Autocapitalize = 'none' | 'off' | 'sentences' | 'on' | 'words' | 'characters'; - type SelectionDirection = "forward" | "backward" | "none"; - type InputType = "button" | "checkbox" | "color" | "date" | "datetime-local" | "email" | "file" | "hidden" | "image" | "month" | "number" | "password" | "radio" | "range" | "reset" | "search" | "submit" | "tel" | "text" | "time" | "url" | "week"; - type InputMode = "" | "none" | "text" | "decimal" | "numeric" | "tel" | "search" | "email" | "url"; - type ButtonType = "submit" | "reset" | "button" | "menu"; - type TextDirection = 'ltr' | 'rtl' | 'auto' | ''; - type ImageDecoding = "async" | "sync" | "auto"; - type ImageLoading = "eager" | "lazy"; - type ConstructorType = { new (...args: any[]): T } - interface Node { - $: import('./lib/node/$Node').$Node; - } -} -Array.prototype.detype = function (this: O[], ...types: T[]) { - return this.filter(item => { - if (!types.length) return item !== undefined; - else for (const type of types) if (typeof item !== typeof type) return false; else return true - }) as Exclude[]; -} -export * from "./$index"; -export * from "./lib/node/$Node"; -export * from "./lib/node/$Anchor"; -export * from "./lib/node/$Element"; -export * from "./lib/$NodeManager"; -export * from "./lib/node/$Text"; -export * from "./lib/node/$Container"; -export * from "./lib/node/$Button"; -export * from "./lib/node/$Form"; -export * from "./lib/$EventManager"; -export * from "./lib/$State"; -export * from "./lib/node/$View"; -export * from "./lib/node/$Select"; -export * from "./lib/node/$Option"; -export * from "./lib/node/$OptGroup"; -export * from "./lib/node/$Textarea"; -export * from "./lib/node/$Image"; -export * from "./lib/node/$Async"; -export * from "./lib/node/$Document"; \ No newline at end of file diff --git a/lib/$EventManager.ts b/lib/$EventManager.ts deleted file mode 100644 index 35cc005..0000000 --- a/lib/$EventManager.ts +++ /dev/null @@ -1,65 +0,0 @@ -export abstract class $EventMethod { - abstract events: $EventManager; - //@ts-expect-error - on(type: K, callback: (...args: EM[K]) => any) { this.events.on(type, callback); return this } - //@ts-expect-error - off(type: K, callback: (...args: EM[K]) => any) { this.events.off(type, callback); return this } - //@ts-expect-error - once(type: K, callback: (...args: EM[K]) => any) { this.events.once(type, callback); return this } -} -export class $EventManager { - private eventMap = new Map(); - register(...names: string[]) { - names.forEach(name => { - const event = new $Event(name); - this.eventMap.set(event.name, event); - }) - return this; - } - delete(name: string) { this.eventMap.delete(name); return this } - //@ts-expect-error - fire(type: K, ...args: EM[K]) { - const event = this.get(type) - //@ts-expect-error - if (event instanceof $Event) event.fire(...args); - return this - } - //@ts-expect-error - on(type: K, callback: (...args: EM[K]) => any) { - this.get(type).add(callback); - return this - } - //@ts-expect-error - off(type: K, callback: (...args: EM[K]) => any) { - this.get(type).delete(callback); - return this - } - //@ts-expect-error - once(type: K, callback: (...args: EM[K]) => any) { - //@ts-expect-error - const onceFn = (...args: EM[K]) => { - this.get(type).delete(onceFn); - //@ts-expect-error - callback(...args); - } - this.get(type).add(onceFn); - return this; - } - - get(type: K) { - //@ts-expect-error - const event = this.eventMap.get(type); - if (!event) throw new Error('EVENT NOT EXIST') - return event; - } -} -export class $Event { - name: string; - private callbackList = new Set() - constructor(name: string) { - this.name = name; - } - fire(...args: any[]) { this.callbackList.forEach(callback => callback(...args)) } - add(callback: Function) { this.callbackList.add(callback) } - delete(callback: Function) { this.callbackList.delete(callback) } -} \ No newline at end of file diff --git a/lib/$NodeManager.ts b/lib/$NodeManager.ts deleted file mode 100644 index 2af381e..0000000 --- a/lib/$NodeManager.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { $Container } from "./node/$Container"; -import { $Node } from "./node/$Node"; -import { $Text } from "./node/$Text"; - -export class $NodeManager { - $container: $Container; - $elementList = new Set<$Node> - constructor(container: $Container) { - this.$container = container; - } - - add(element: $Node | string) { - if (typeof element === 'string') { - const text = new $Text(element); - this.$elementList.add(text); - (text as Mutable<$Node>).parent = this.$container; - } else { - this.$elementList.add(element); - (element as Mutable<$Node>).parent = this.$container; - } - } - - remove(element: $Node) { - if (!this.$elementList.has(element)) return this; - this.$elementList.delete(element); - (element as Mutable<$Node>).parent = undefined; - return this; - } - - removeAll(render = true) { - this.$elementList.forEach(ele => this.remove(ele)); - if (render) this.render(); - } - - replace(target: $Node, replace: $Node) { - const array = this.array - array.splice(array.indexOf(target), 1, replace); - target.remove(); - this.$elementList.clear(); - array.forEach(node => this.$elementList.add(node)); - return this; - } - - render() { - const [domList, nodeList] = [this.array.map(node => node.dom), Array.from(this.dom.childNodes)]; - const appendedNodeList: Node[] = []; // appended node list - // Rearrange - while (nodeList.length || domList.length) { // while nodeList or domList has item - const [node, dom] = [nodeList.at(0), domList.at(0)]; - if (!dom) { if (node && !appendedNodeList.includes(node)) node.remove(); nodeList.shift()} - else if (!node) { if (!dom.$.__hidden) this.dom.append(dom); domList.shift();} - else if (dom !== node) { - if (!dom.$.__hidden) { this.dom.insertBefore(dom, node); appendedNodeList.push(dom) } - domList.shift(); - } - else { - if (dom.$.__hidden) this.dom.removeChild(dom); - domList.shift(); nodeList.shift(); - } - } - } - - get array() {return [...this.$elementList.values()]}; - - get dom() {return this.$container.dom} -} \ No newline at end of file diff --git a/lib/$State.ts b/lib/$State.ts deleted file mode 100644 index 49cda3e..0000000 --- a/lib/$State.ts +++ /dev/null @@ -1,61 +0,0 @@ -export interface $StateOption { - format: (value: T) => string; -} -export class $State { - readonly value: T; - readonly attributes = new Map>(); - options: Partial<$StateOption> = {} - constructor(value: T, options?: $StateOption) { - this.value = value; - if (options) this.options = options; - } - set(value: T) { - (this as Mutable<$State>).value = value; - for (const [node, attrList] of this.attributes.entries()) { - for (const attr of attrList) { - console.debug(node, attr) - //@ts-expect-error - if (node[attr] instanceof Function) { - //@ts-expect-error - if (this.options.format) node[attr](this.options.format(value)) - //@ts-expect-error - else node[attr](value) - } - else if (attr in node) { - //@ts-expect-error - node[attr] = value - } - } - } - } - - toString(): string { - if (this.options.format) return this.options.format(this.value); - if (this.value instanceof Object) return JSON.stringify(this.toJSON()); - return `${this.value}` - } - - use(object: O, attrName: K) { - const attrList = this.attributes.get(object) - if (attrList) attrList.add(attrName); - else this.attributes.set(object, new Set().add(attrName)) - } - - toJSON(): Object { - if (this.value instanceof $State) return this.value.toJSON(); - if (this.value instanceof Object) return $State.toJSON(this.value); - else return this.toString(); - } - - static toJSON(object: Object): Object { - const data = {}; - for (let [key, value] of Object.entries(object)) { - if (value instanceof $State) value = value.toJSON(); - else if (value instanceof Object) $State.toJSON(value); - Object.assign(data, {[key]: value}) - } - return data; - } -}; - -export type $StateArgument = T | $State | undefined; \ No newline at end of file diff --git a/lib/$Util.ts b/lib/$Util.ts deleted file mode 100644 index 10947b9..0000000 --- a/lib/$Util.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { $State } from "./$State"; -import { $Container } from "./node/$Container"; -import { $Document } from "./node/$Document"; -import { $Node } from "./node/$Node"; -import { $SVGElement } from "./node/$SVGElement"; -import { $Text } from "./node/$Text"; - -export namespace $Util { - export function fluent(instance: T, args: IArguments, value: () => V, action: (...args: any[]) => void) { - if (!args.length) return value(); - action(); - return instance; - } - - export function orArrayResolve(multable: OrArray) { - if (multable instanceof Array) return multable; - else return [multable]; - } - - export function mixin(target: any, constructors: OrArray) { - orArrayResolve(constructors).forEach(constructor => { - Object.getOwnPropertyNames(constructor.prototype).forEach(name => { - if (name === 'constructor') return; - Object.defineProperty( - target.prototype, - name, - Object.getOwnPropertyDescriptor(constructor.prototype, name) || Object.create(null) - ) - }) - }) - return target; - } - - export function set(object: O, key: K, value: any) { - if (value !== undefined) object[key] = value; - } - - export function state(value: T) { - return new $State(value) - } - - export function from(element: Node): $Node { - if (element.$) return element.$; - if (element.nodeName.toLowerCase() === 'body') return new $Container('body', {dom: element as HTMLBodyElement}); - if (element.nodeName.toLowerCase() === '#document') return $Document.from(element as Document); - else if (element instanceof HTMLElement) { - const instance = $.TagNameElementMap[element.tagName.toLowerCase() as keyof typeof $.TagNameElementMap]; - const $node = instance === $Container - //@ts-expect-error - ? new instance(element.tagName, {dom: element}) - //@ts-expect-error - : new instance({dom: element} as any); - if ($node instanceof $Container) for (const childnode of Array.from($node.dom.childNodes)) { - $node.children.add($(childnode as any)); - } - return $node as $Node; - } - else if (element instanceof Text) { - const node = new $Text(element.textContent ?? '') as Mutable<$Node>; - node.dom = element; - return node as $Node; - } - else if (element instanceof SVGElement) { - if (element.tagName.toLowerCase() === 'svg') {return new $SVGElement('svg', {dom: element}) }; - } - throw `$NODE.FROM: NOT SUPPORT TARGET ELEMENT TYPE (${element.nodeName})` - } -} \ No newline at end of file diff --git a/lib/node/$Anchor.ts b/lib/node/$Anchor.ts deleted file mode 100644 index 87bf5fe..0000000 --- a/lib/node/$Anchor.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { $Container, $ContainerOptions } from "./$Container"; - -export interface AnchorOptions extends $ContainerOptions {} - -export class $Anchor extends $Container { - constructor(options?: AnchorOptions) { - super('a', options); - // Link Handler event - this.dom.addEventListener('click', e => { - if ($.anchorPreventDefault) e.preventDefault(); - if ($.anchorHandler && !!this.href()) $.anchorHandler(this, e) - }) - } - /**Set URL of anchor element. */ - href(): string; - href(url: string | undefined): this; - href(url?: string | undefined) { return $.fluent(this, arguments, () => this.dom.href, () => {if (url) this.dom.href = url}) } - /**Link open with this window, new tab or other */ - target(): $AnchorTarget | undefined; - target(target: $AnchorTarget | undefined): this; - target(target?: $AnchorTarget | undefined) { return $.fluent(this, arguments, () => (this.dom.target ?? undefined) as $AnchorTarget | undefined, () => {if (target) this.dom.target = target}) } -} - -export type $AnchorTarget = '_blank' | '_self' | '_parent' | '_top'; \ No newline at end of file diff --git a/lib/node/$Async.ts b/lib/node/$Async.ts deleted file mode 100644 index 5ef5358..0000000 --- a/lib/node/$Async.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { $Container, $ContainerOptions } from "./$Container"; -import { $Node } from "./$Node"; -export interface $AsyncNodeOptions extends $ContainerOptions {} -export class $Async extends $Container { - #loaded: boolean = false; - constructor(options?: $AsyncNodeOptions) { - super('async', options) - } - - await($node: Promise) { - $node.then($node => this._loaded($node)); - return this as $Async - } - - protected _loaded($node: $Node) { - this.#loaded = true; - this.replace($node) - this.dom.dispatchEvent(new Event('load')) - } - - get loaded() { return this.#loaded } -} \ No newline at end of file diff --git a/lib/node/$Button.ts b/lib/node/$Button.ts deleted file mode 100644 index 8accab0..0000000 --- a/lib/node/$Button.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { $Container, $ContainerOptions } from "./$Container"; -import { $State, $StateArgument } from "../$State"; -export interface $ButtonOptions extends $ContainerOptions {} -export class $Button extends $Container { - constructor(options?: $ButtonOptions) { - super('button', options); - } - - disabled(): boolean; - disabled(disabled: $StateArgument): this; - disabled(disabled?: $StateArgument) { return $.fluent(this, arguments, () => this.dom.disabled, () => $.set(this.dom, 'disabled', disabled))} - - type(): ButtonType; - type(type: ButtonType): this; - type(type?: ButtonType) { return $.fluent(this, arguments, () => this.dom.type as ButtonType, () => $.set(this.dom, 'type', type as any))} - - checkValidity() { return this.dom.checkValidity() } - reportValidity() { return this.dom.reportValidity() } - - formAction(): string; - formAction(action: string | undefined): this; - formAction(action?: string) { return $.fluent(this, arguments, () => this.dom.formAction, () => $.set(this.dom, 'formAction', action))} - - formEnctype(): string; - formEnctype(enctype: string | undefined): this; - formEnctype(enctype?: string) { return $.fluent(this, arguments, () => this.dom.formEnctype, () => $.set(this.dom, 'formEnctype', enctype))} - - formMethod(): string; - formMethod(method: string | undefined): this; - formMethod(method?: string) { return $.fluent(this, arguments, () => this.dom.formMethod, () => $.set(this.dom, 'formMethod', method))} - - formNoValidate(): boolean; - formNoValidate(boolean: boolean | undefined): this; - formNoValidate(boolean?: boolean) { return $.fluent(this, arguments, () => this.dom.formNoValidate, () => $.set(this.dom, 'formNoValidate', boolean))} - - formTarget(): string; - formTarget(target: string | undefined): this; - formTarget(target?: string) { return $.fluent(this, arguments, () => this.dom.formTarget, () => $.set(this.dom, 'formTarget', target))} -} \ No newline at end of file diff --git a/lib/node/$Canvas.ts b/lib/node/$Canvas.ts deleted file mode 100644 index eb46e8e..0000000 --- a/lib/node/$Canvas.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { $Container, $ContainerOptions } from "./$Container"; -export interface $CanvasOptions extends $ContainerOptions {} -export class $Canvas extends $Container { - constructor(options?: $CanvasOptions) { - super('canvas', options); - } - - height(): number; - height(height?: number): this; - height(height?: number) { return $.fluent(this, arguments, () => this.dom.height, () => { $.set(this.dom, 'height', height)}) } - - width(): number; - width(width?: number): this; - width(width?: number) { return $.fluent(this, arguments, () => this.dom.width, () => { $.set(this.dom, 'width', width)}) } - - captureStream(frameRequestRate?: number) { return this.dom.captureStream(frameRequestRate) } - - getContext(contextId: "2d", options?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D | null; - getContext(contextId: "bitmaprenderer", options?: ImageBitmapRenderingContextSettings): ImageBitmapRenderingContext | null; - getContext(contextId: "webgl", options?: WebGLContextAttributes): WebGLRenderingContext | null; - getContext(contextId: "webgl2", options?: WebGLContextAttributes): WebGL2RenderingContext | null; - getContext(contextId: string, options?: any): RenderingContext | null { return this.dom.getContext(contextId); } - - toBlob(callback: BlobCallback, type?: string, quality?: any) { this.dom.toBlob(callback, type, quality); return this;} - - toDataURL(type?: string, quality?: any) { return this.dom.toDataURL(type, quality) } - - transferControlToOffscreen() { return this.dom.transferControlToOffscreen() } -} \ No newline at end of file diff --git a/lib/node/$Container.ts b/lib/node/$Container.ts deleted file mode 100644 index 4706276..0000000 --- a/lib/node/$Container.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { $Element, $ElementOptions } from "./$Element"; -import { $NodeManager } from "../$NodeManager"; -import { $Node } from "./$Node"; -import { $State, $StateArgument } from "../$State"; -import { $Text } from "./$Text"; -import { $HTMLElement, $HTMLElementOptions } from "./$HTMLElement"; - -export interface $ContainerOptions extends $HTMLElementOptions {} -export class $Container extends $HTMLElement { - readonly children: $NodeManager = new $NodeManager(this); - constructor(tagname: string, options?: $ContainerOptions) { - super(tagname, options) - } - - /**Replace element to this element. - * @example Element.content([$('div')]) - * Element.content('Hello World')*/ - content(children: $ContainerContentBuilder): this { return $.fluent(this, arguments, () => this, () => { - this.children.removeAll(false); - this.insert(children); - })} - - /**Insert element to this element */ - insert(children: $ContainerContentBuilder): this { return $.fluent(this, arguments, () => this, () => { - if (children instanceof Function) children = children(this); - children = $.orArrayResolve(children); - for (const child of children) { - if (child === undefined) continue; - if (child instanceof Array) this.insert(child) - else if (child instanceof $State) { - const ele = new $Text(child.toString()); - child.use(ele, 'content'); - this.children.add(ele); - } else this.children.add(child); - } - this.children.render(); - })} - - /**Remove all children elemetn from this element */ - clear() { - this.children.removeAll(); - return this; - } - - //**Query selector one of child element */ - $(query: string): E | null { return $(this.dom.querySelector(query)) as E | null } - - //**Query selector of child elements */ - $all(query: string): E[] { return Array.from(this.dom.querySelectorAll(query)).map($dom => $($dom) as E) } - - get scrollHeight() { return this.dom.scrollHeight } - get scrollWidth() { return this.dom.scrollWidth } - - scrollTop(): number; - scrollTop(scrollTop: $StateArgument | undefined): this - scrollTop(scrollTop?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.scrollTop, () => $.set(this.dom, 'scrollTop', scrollTop as any))} - - scrollLeft(): number; - scrollLeft(scrollLeft: $StateArgument | undefined): this - scrollLeft(scrollLeft?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.scrollLeft, () => $.set(this.dom, 'scrollLeft', scrollLeft as any))} -} - -export type $ContainerContentBuilder

= OrMatrix<$ContainerContentType> | (($node: P) => OrMatrix<$ContainerContentType>) -export type $ContainerContentType = $Node | string | undefined | $State \ No newline at end of file diff --git a/lib/node/$Dialog.ts b/lib/node/$Dialog.ts deleted file mode 100644 index d0f8f21..0000000 --- a/lib/node/$Dialog.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { $Container, $ContainerOptions } from "./$Container"; -export interface $DialogOptions extends $ContainerOptions {} -export class $Dialog extends $Container { - constructor(options?: $DialogOptions) { - super('dialog', options); - } - - open(): boolean; - open(open?: boolean): this; - open(open?: boolean) { return $.fluent(this, arguments, () => this.dom.open, () => $.set(this.dom, 'open', open)) } - - returnValue(): string; - returnValue(returnValue?: string): this; - returnValue(returnValue?: string) { return $.fluent(this, arguments, () => this.dom.returnValue, () => $.set(this.dom, 'returnValue', returnValue)) } - - close() { this.dom.close(); return this; } - show() { this.dom.show(); return this; } - showModal() { this.dom.showModal(); return this; } -} \ No newline at end of file diff --git a/lib/node/$Document.ts b/lib/node/$Document.ts deleted file mode 100644 index 486a1d6..0000000 --- a/lib/node/$Document.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { $Element, $DOMRect } from "./$Element"; -import { $Node } from "./$Node"; -export class $Document extends $Node { - dom: Node; - constructor(document: Document) { - super() - this.dom = document; - this.dom.$ = this; - } - - domRect(target?: $Element | $DOMRect) { - const this_rect: $DOMRect = { - bottom: innerHeight, - height: innerHeight, - left: 0, - right: innerWidth, - top: 0, - width: innerWidth, - x: 0, - y: 0 - }; - if (!target) return this_rect; - const target_rect = target instanceof $Element ? target.dom.getBoundingClientRect() : target; - const rect: $DOMRect = { - ...this_rect, - top: this_rect.top - target_rect.top, - left: this_rect.left - target_rect.left, - right: this_rect.right - target_rect.left, - bottom: this_rect.bottom - target_rect.top, - x: this_rect.x - target_rect.x, - y: this_rect.y - target_rect.y, - } - return rect; - } - - static from(document: Document) { - if (document.$ instanceof $Document) return document.$ - else return new $Document(document); - } -} \ No newline at end of file diff --git a/lib/node/$Element.ts b/lib/node/$Element.ts deleted file mode 100644 index 6026ef6..0000000 --- a/lib/node/$Element.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { $Node } from "./$Node"; - -export interface $ElementOptions { - id?: string; - class?: string[]; - dom?: HTMLElement | SVGElement; -} - -export class $Element extends $Node { - readonly dom: H; - private static_classes = new Set(); - constructor(tagname: string, options?: $ElementOptions) { - super(); - this.dom = this.createDom(tagname, options) as H; - this.dom.$ = this; - this.setOptions(options); - } - - private createDom(tagname: string, options?: $ElementOptions) { - if (options?.dom) return options.dom; - if (tagname === 'svg') return document.createElementNS("http://www.w3.org/2000/svg", "svg"); - return document.createElement(tagname); - - } - - setOptions(options: $ElementOptions | undefined) { - this.id(options?.id) - if (options && options.class) this.class(...options.class) - return this; - } - - /**Replace id of element. @example Element.id('customId');*/ - id(): string; - id(name: string | undefined): this; - id(name?: string | undefined): this | string {return $.fluent(this, arguments, () => this.dom.id, () => $.set(this.dom, 'id', name as any))} - - /**Replace list of class name to element. @example Element.class('name1', 'name2') */ - class(): DOMTokenList; - class(...name: (string | undefined)[]): this; - class(...name: (string | undefined)[]): this | DOMTokenList {return $.fluent(this, arguments, () => this.dom.classList, () => {this.dom.classList.forEach(n => this.static_classes.has(n) ?? this.dom.classList.remove(n)); this.dom.classList.add(...name.detype())})} - /**Add class name to dom. */ - addClass(...name: (string | undefined)[]): this {return $.fluent(this, arguments, () => this, () => {this.dom.classList.add(...name.detype())})} - /**Remove class name from dom */ - removeClass(...name: (string | undefined)[]): this {return $.fluent(this, arguments, () => this, () => {this.dom.classList.remove(...name.detype())})} - - staticClass(): Set; - staticClass(...name: (string | undefined)[]): this; - staticClass(...name: (string | undefined)[]) {return $.fluent(this, arguments, () => this.static_classes, () => {this.removeClass(...this.static_classes); this.static_classes.clear(); this.addStaticClass(...name);})} - addStaticClass(...name: (string | undefined)[]) {return $.fluent(this, arguments, () => this, () => {name.detype().forEach(n => this.static_classes.add(n)); this.addClass(...name)})} - removeStaticClass(...name: (string | undefined)[]) {return $.fluent(this, arguments, () => this, () => {name.detype().forEach(n => this.static_classes.delete(n)); this.removeClass(...name)})} - - /**Modify css of element. */ - css(): CSSStyleDeclaration - css(style: Partial): this; - css(style?: Partial) { return $.fluent(this, arguments, () => this.dom.style, () => {Object.assign(this.dom.style, style)})} - - /** - * Get or set attribute from this element. - * @param qualifiedName Attribute name - * @param value Attribute value. Set `null` will remove attribute. - */ - attribute(qualifiedName: string | undefined): string | null; - attribute(qualifiedName: string | undefined, value?: string | number | boolean | null): this; - attribute(qualifiedName: string | undefined, value?: string | number | boolean | null): this | string | null { - if (!arguments.length) return null; - if (arguments.length === 1) { - if (qualifiedName === undefined) return null; - return this.dom.getAttribute(qualifiedName); - } - if (arguments.length === 2) { - if (!qualifiedName) return this; - if (value === null) this.dom.removeAttribute(qualifiedName); - else if (value !== undefined) this.dom.setAttribute(qualifiedName, `${value}`); - return this; - } - return this; - } - - tabIndex(): number; - tabIndex(tabIndex: number): this; - tabIndex(tabIndex?: number) { return $.fluent(this, arguments, () => this.dom.tabIndex, () => $.set(this.dom, 'tabIndex', tabIndex as any))} - - focus() { this.dom.focus(); return this; } - blur() { this.dom.blur(); return this; } - - animate(keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeAnimationOptions, callback?: (animation: Animation) => void) { - const animation = this.dom.animate(keyframes, options); - if (callback) callback(animation); - return this; - } - - getAnimations(options?: GetAnimationsOptions) { return this.dom.getAnimations(options) } - - get dataset() { return this.dom.dataset } - - domRect(target?: $Element | $DOMRect) { - const this_rect = this.dom.getBoundingClientRect(); - if (!target) return this_rect; - const target_rect = target instanceof $Element ? target.dom.getBoundingClientRect() : target; - const rect: $DOMRect = { - ...this_rect, - top: this_rect.top - target_rect.top, - left: this_rect.left - target_rect.left, - right: this_rect.right - target_rect.left, - bottom: this_rect.bottom - target_rect.top, - x: this_rect.x - target_rect.x, - y: this_rect.y - target_rect.y, - } - return rect; - } -} - -export type $DOMRect = Omit; \ No newline at end of file diff --git a/lib/node/$Form.ts b/lib/node/$Form.ts deleted file mode 100644 index 208b8db..0000000 --- a/lib/node/$Form.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { $Container, $ContainerOptions } from "./$Container"; -export interface $FormOptions extends $ContainerOptions {} -export class $Form extends $Container { - constructor(options?: $FormOptions) { - super('form', options); - } - - autocomplete(): AutoFill; - autocomplete(autocomplete: AutoFill | undefined): this; - autocomplete(autocomplete?: AutoFill) { return $.fluent(this, arguments, () => this.dom.autocomplete as AutoFill, () => $.set(this.dom, 'autocomplete', autocomplete as AutoFillBase))} - - action(): string; - action(action: string | undefined): this; - action(action?: string) { return $.fluent(this, arguments, () => this.dom.formAction, () => $.set(this.dom, 'formAction', action))} - - enctype(): string; - enctype(enctype: string | undefined): this; - enctype(enctype?: string) { return $.fluent(this, arguments, () => this.dom.formEnctype, () => $.set(this.dom, 'formEnctype', enctype))} - - method(): string; - method(method: string | undefined): this; - method(method?: string) { return $.fluent(this, arguments, () => this.dom.formMethod, () => $.set(this.dom, 'formMethod', method))} - - noValidate(): boolean; - noValidate(boolean: boolean | undefined): this; - noValidate(boolean?: boolean) { return $.fluent(this, arguments, () => this.dom.formNoValidate, () => $.set(this.dom, 'formNoValidate', boolean))} - - acceptCharset(): string; - acceptCharset(acceptCharset: string | undefined): this; - acceptCharset(acceptCharset?: string) { return $.fluent(this, arguments, () => this.dom.acceptCharset, () => $.set(this.dom, 'acceptCharset', acceptCharset))} - - target(): string; - target(target: string | undefined): this; - target(target?: string) { return $.fluent(this, arguments, () => this.dom.formTarget, () => $.set(this.dom, 'formTarget', target))} - - requestSubmit() { this.dom.requestSubmit(); return this } - reset(): this { this.dom.reset(); return this } - submit() { this.dom.submit(); return this } - checkValidity() { return this.dom.checkValidity() } - reportValidity() { return this.dom.reportValidity() } - - get length() { return this.dom.length } - get elements() { return Array.from(this.dom.elements).map(ele => $(ele)) } -} \ No newline at end of file diff --git a/lib/node/$HTMLElement.ts b/lib/node/$HTMLElement.ts deleted file mode 100644 index cac0bc9..0000000 --- a/lib/node/$HTMLElement.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { $Element, $ElementOptions } from "./$Element"; - -export interface $HTMLElementOptions extends $ElementOptions {} -export class $HTMLElement extends $Element { - constructor(tagname: string, options?: $HTMLElementOptions) { - super(tagname, options) - } - - autocapitalize(): Autocapitalize; - autocapitalize(autocapitalize?: Autocapitalize): this; - autocapitalize(autocapitalize?: Autocapitalize) { return $.fluent(this, arguments, () => this.dom.autocapitalize, () => $.set(this.dom, 'autocapitalize', autocapitalize as any))} - - innerText(): string; - innerText(text?: string): this; - innerText(text?: string) { return $.fluent(this, arguments, () => this.dom.innerText, () => $.set(this.dom, 'innerText', text as any))} - - title(): string; - title(title?: string): this; - title(title?: string) { return $.fluent(this, arguments, () => this.dom.title, () => $.set(this.dom, 'title', title as any))} - - dir(): TextDirection; - dir(dir?: TextDirection): this; - dir(dir?: TextDirection) { return $.fluent(this, arguments, () => this.dom.dir, () => $.set(this.dom, 'dir', dir as any))} - - translate(): boolean; - translate(translate?: boolean): this; - translate(translate?: boolean) { return $.fluent(this, arguments, () => this.dom.translate, () => $.set(this.dom, 'translate', translate as any))} - - popover(): string | null; - popover(popover?: string | null): this; - popover(popover?: string | null) { return $.fluent(this, arguments, () => this.dom.popover, () => $.set(this.dom, 'popover', popover as any))} - - spellcheck(): boolean; - spellcheck(spellcheck?: boolean): this; - spellcheck(spellcheck?: boolean) { return $.fluent(this, arguments, () => this.dom.spellcheck, () => $.set(this.dom, 'spellcheck', spellcheck as any))} - - inert(): boolean; - inert(inert?: boolean): this; - inert(inert?: boolean) { return $.fluent(this, arguments, () => this.dom.inert, () => $.set(this.dom, 'inert', inert as any))} - - lang(): string; - lang(lang?: string): this; - lang(lang?: string) { return $.fluent(this, arguments, () => this.dom.lang, () => $.set(this.dom, 'lang', lang as any))} - - draggable(): boolean; - draggable(draggable?: boolean): this; - draggable(draggable?: boolean) { return $.fluent(this, arguments, () => this.dom.draggable, () => $.set(this.dom, 'draggable', draggable as any))} - - hidden(): boolean; - hidden(hidden?: boolean): this; - hidden(hidden?: boolean) { return $.fluent(this, arguments, () => this.dom.hidden, () => $.set(this.dom, 'hidden', hidden as any))} - - click() { this.dom.click(); return this; } - attachInternals() { return this.dom.attachInternals(); } - hidePopover() { this.dom.hidePopover(); return this; } - showPopover() { this.dom.showPopover(); return this; } - togglePopover() { this.dom.togglePopover(); return this; } - - get accessKeyLabel() { return this.dom.accessKeyLabel } - get offsetHeight() { return this.dom.offsetHeight } - get offsetLeft() { return this.dom.offsetLeft } - get offsetParent() { return $(this.dom.offsetParent) } - get offsetTop() { return this.dom.offsetTop } - get offsetWidth() { return this.dom.offsetWidth } -} \ No newline at end of file diff --git a/lib/node/$Image.ts b/lib/node/$Image.ts deleted file mode 100644 index fdfbe26..0000000 --- a/lib/node/$Image.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { $HTMLElement, $HTMLElementOptions } from "./$HTMLElement"; -import { $StateArgument } from "../$State"; -export interface $ImageOptions extends $HTMLElementOptions {} -export class $Image extends $HTMLElement { - constructor(options?: $ImageOptions) { - super('img', options); - } - - async load(src: Promise | string): Promise<$Image> { - return new Promise(resolve => { - const $img = this.once('load', () => { - resolve($img) - }) - if (typeof src === 'string') $img.src(src); - else src.then(src => $img.src(src)); - }) - } - - static resize(src: string | File, size: number | [number, number]): Promise { - return new Promise(resolve => { - const img = new Image(); - img.addEventListener('load', () => { - const canvas = document.createElement('canvas'); - const context = canvas.getContext('2d'); - if (!context) throw '$Image.resize: context undefined'; - const ratio = img.width / img.height; - const [landscape, portrait, square] = [ratio > 1, ratio < 1, ratio === 1]; - const w = size instanceof Array ? size[0] : portrait ? size : size * ratio; - const h = size instanceof Array ? size[1] : landscape ? size : size / ratio; - canvas.height = h; canvas.width = w; - context.drawImage(img, 0, 0, w, h); - resolve(canvas.toDataURL()); - }, {once: true}) - if (src instanceof File) { - const fr = new FileReader() - fr.addEventListener('load', () => img.src = fr.result as string) - fr.readAsDataURL(src); - } else img.src = src; - }) - } - - /**HTMLImageElement base property */ - alt(): string; - alt(alt: string): this; - alt(alt?: string) { return $.fluent(this, arguments, () => this.dom.alt, () => $.set(this.dom, 'alt', alt))} - - /**HTMLImageElement base property */ - crossOrigin(): string | null; - crossOrigin(crossOrigin: string | null): this; - crossOrigin(crossOrigin?: string | null) { return $.fluent(this, arguments, () => this.dom.crossOrigin, () => $.set(this.dom, 'crossOrigin', crossOrigin))} - - /**HTMLImageElement base property */ - decoding(): ImageDecoding; - decoding(decoding: ImageDecoding): this; - decoding(decoding?: ImageDecoding) { return $.fluent(this, arguments, () => this.dom.decoding, () => $.set(this.dom, 'decoding', decoding))} - - /**HTMLImageElement base property */ - height(): number; - height(height: number): this; - height(height?: number) { return $.fluent(this, arguments, () => this.dom.height, () => $.set(this.dom, 'height', height))} - - /**HTMLImageElement base property */ - isMap(): boolean; - isMap(isMap: boolean): this; - isMap(isMap?: boolean) { return $.fluent(this, arguments, () => this.dom.isMap, () => $.set(this.dom, 'isMap', isMap))} - - /**HTMLImageElement base property */ - loading(): ImageLoading; - loading(loading: ImageLoading): this; - loading(loading?: ImageLoading) { return $.fluent(this, arguments, () => this.dom.loading, () => $.set(this.dom, 'loading', loading))} - - /**HTMLImageElement base property */ - referrerPolicy(): string; - referrerPolicy(referrerPolicy: string): this; - referrerPolicy(referrerPolicy?: string) { return $.fluent(this, arguments, () => this.dom.referrerPolicy, () => $.set(this.dom, 'referrerPolicy', referrerPolicy))} - - /**HTMLImageElement base property */ - sizes(): string; - sizes(sizes: string): this; - sizes(sizes?: string) { return $.fluent(this, arguments, () => this.dom.sizes, () => $.set(this.dom, 'sizes', sizes))} - - /**HTMLImageElement base property */ - src(): string; - src(src: $StateArgument): this; - src(src?: $StateArgument) { return $.fluent(this, arguments, () => this.dom.src, () => $.set(this.dom, 'src', src))} - - /**HTMLImageElement base property */ - srcset(): string; - srcset(srcset: string): this; - srcset(srcset?: string) { return $.fluent(this, arguments, () => this.dom.srcset, () => $.set(this.dom, 'srcset', srcset))} - - /**HTMLImageElement base property */ - useMap(): string; - useMap(useMap: string): this; - useMap(useMap?: string) { return $.fluent(this, arguments, () => this.dom.useMap, () => $.set(this.dom, 'useMap', useMap))} - - /**HTMLImageElement base property */ - width(): number; - width(width: number): this; - width(width?: number) { return $.fluent(this, arguments, () => this.dom.width, () => $.set(this.dom, 'width', width))} - - /**HTMLImageElement base method */ - decode() { return this.dom.decode() } - - /**HTMLImageElement base property */ - get complete() { return this.dom.complete } - /**HTMLImageElement base property */ - get currentSrc() { return this.dom.currentSrc } - /**HTMLImageElement base property */ - get naturalHeight() { return this.dom.naturalHeight } - /**HTMLImageElement base property */ - get naturalWidth() { return this.dom.naturalWidth } - /**HTMLImageElement base property */ - get x() { return this.dom.x } - /**HTMLImageElement base property */ - get y() { return this.dom.y } - -} \ No newline at end of file diff --git a/lib/node/$Input.ts b/lib/node/$Input.ts deleted file mode 100644 index 7cbb288..0000000 --- a/lib/node/$Input.ts +++ /dev/null @@ -1,231 +0,0 @@ -import { $Element, $ElementOptions } from "./$Element"; -import { $State, $StateArgument } from "../$State"; - -export interface $InputOptions extends $ElementOptions {} -export class $Input extends $Element { - constructor(options?: $InputOptions) { - super('input', options); - } - - value(): T; - value(value: $StateArgument): this; - value(value?: $StateArgument) { return $.fluent(this, arguments, () => { - if (this.type() === 'number') return Number(this.dom.value); - return this.dom.value as T; - }, () => $.set(this.dom, 'value', value as $State | string, (value$) => { - this.on('input', () => { - if (value$.attributes.has(this.dom) === false) return; - if (typeof value$.value === 'string') (value$ as $State).set(`${this.value()}`) - if (typeof value$.value === 'number') (value$ as unknown as $State).set(Number(this.value())) - }) - }))} - - type(): InputType; - type(type: T): $InputType; - type(type?: T) { return $.fluent(this, arguments, () => this.dom.type, () => $.set(this.dom, 'type', type)) as unknown as $InputType | InputType} - - capture(): string; - capture(capture: string): this; - capture(capture?: string) { return $.fluent(this, arguments, () => this.dom.capture, () => $.set(this.dom, 'capture', capture))} - - alt(): string; - alt(alt: string): this; - alt(alt?: string) { return $.fluent(this, arguments, () => this.dom.alt, () => $.set(this.dom, 'alt', alt))} - - height(): number; - height(height: number): this; - height(height?: number) { return $.fluent(this, arguments, () => this.dom.height, () => $.set(this.dom, 'height', height))} - - width(): number; - width(wdith: number): this; - width(width?: number) { return $.fluent(this, arguments, () => this.dom.width, () => $.set(this.dom, 'width', width))} - - autocomplete(): AutoFill; - autocomplete(autocomplete: AutoFill): this; - autocomplete(autocomplete?: AutoFill) { return $.fluent(this, arguments, () => this.dom.autocomplete, () => $.set(this.dom, 'autocomplete', autocomplete))} - - defaultValue(): string; - defaultValue(defaultValue: string): this; - defaultValue(defaultValue?: string) { return $.fluent(this, arguments, () => this.dom.defaultValue, () => $.set(this.dom, 'defaultValue', defaultValue))} - - dirName(): string; - dirName(dirName: string): this; - dirName(dirName?: string) { return $.fluent(this, arguments, () => this.dom.dirName, () => $.set(this.dom, 'dirName', dirName))} - - disabled(): boolean; - disabled(disabled: boolean): this; - disabled(disabled?: boolean) { return $.fluent(this, arguments, () => this.dom.disabled, () => $.set(this.dom, 'disabled', disabled))} - - pattern(): string; - pattern(pattern: string): this; - pattern(pattern?: string) { return $.fluent(this, arguments, () => this.dom.pattern, () => $.set(this.dom, 'pattern', pattern))} - - placeholder(): string; - placeholder(placeholder?: string): this; - placeholder(placeholder?: string) { return $.fluent(this, arguments, () => this.dom.placeholder, () => $.set(this.dom, 'placeholder', placeholder))} - - readOnly(): boolean; - readOnly(readOnly: boolean): this; - readOnly(readOnly?: boolean) { return $.fluent(this, arguments, () => this.dom.readOnly, () => $.set(this.dom, 'readOnly', readOnly))} - - required(): boolean; - required(required: boolean): this; - required(required?: boolean) { return $.fluent(this, arguments, () => this.dom.required, () => $.set(this.dom, 'required', required))} - - selectionDirection(): SelectionDirection | null; - selectionDirection(selectionDirection: SelectionDirection | null): this; - selectionDirection(selectionDirection?: SelectionDirection | null) { return $.fluent(this, arguments, () => this.dom.selectionDirection, () => $.set(this.dom, 'selectionDirection', selectionDirection))} - - selectionEnd(): number | null; - selectionEnd(selectionEnd: number | null): this; - selectionEnd(selectionEnd?: number | null) { return $.fluent(this, arguments, () => this.dom.selectionEnd, () => $.set(this.dom, 'selectionEnd', selectionEnd))} - - selectionStart(): number | null; - selectionStart(selectionStart: number | null): this; - selectionStart(selectionStart?: number | null) { return $.fluent(this, arguments, () => this.dom.selectionStart, () => $.set(this.dom, 'selectionStart', selectionStart))} - - size(): number; - size(size: number): this; - size(size?: number) { return $.fluent(this, arguments, () => this.dom.size, () => $.set(this.dom, 'size', size))} - - src(): string; - src(src: string): this; - src(src?: string) { return $.fluent(this, arguments, () => this.dom.src, () => $.set(this.dom, 'src', src))} - - inputMode(): InputMode; - inputMode(mode: InputMode): this; - inputMode(mode?: InputMode) { return $.fluent(this, arguments, () => this.dom.inputMode as InputMode, () => $.set(this.dom, 'inputMode', mode))} - - valueAsDate(): Date | null; - valueAsDate(date: Date | null): this; - valueAsDate(date?: Date | null) { return $.fluent(this, arguments, () => this.dom.valueAsDate, () => $.set(this.dom, 'valueAsDate', date))} - - valueAsNumber(): number; - valueAsNumber(number: number): this; - valueAsNumber(number?: number) { return $.fluent(this, arguments, () => this.dom.valueAsNumber, () => $.set(this.dom, 'valueAsNumber', number))} - - webkitdirectory(): boolean; - webkitdirectory(boolean: boolean): this; - webkitdirectory(boolean?: boolean) { return $.fluent(this, arguments, () => this.dom.webkitdirectory, () => $.set(this.dom, 'webkitdirectory', boolean))} - - select() { this.dom.select(); return this } - setCustomValidity(error: string) { this.dom.setCustomValidity(error); return this } - setRangeText(replacement: string): this; - setRangeText(replacement: string, start: number, end: number, selectionMode?: SelectionMode): this; - setRangeText(replacement: string, start?: number, end?: number, selectionMode?: SelectionMode) { - if (typeof start === 'number' && typeof end === 'number') this.dom.setRangeText(replacement, start, end, selectionMode) - this.dom.setRangeText(replacement); - return this - } - setSelectionRange(start: number | null, end: number | null, direction?: SelectionDirection) { this.dom.setSelectionRange(start, end, direction); return this } - showPicker() { this.dom.showPicker(); return this } - - checkValidity() { return this.dom.checkValidity() } - reportValidity() { return this.dom.reportValidity() } - get files() { return this.dom.files } - get webkitEntries() { return this.dom.webkitEntries } - - - formAction(): string; - formAction(action: string | undefined): this; - formAction(action?: string) { return $.fluent(this, arguments, () => this.dom.formAction, () => $.set(this.dom, 'formAction', action))} - - formEnctype(): string; - formEnctype(enctype: string | undefined): this; - formEnctype(enctype?: string) { return $.fluent(this, arguments, () => this.dom.formEnctype, () => $.set(this.dom, 'formEnctype', enctype))} - - formMethod(): string; - formMethod(method: string | undefined): this; - formMethod(method?: string) { return $.fluent(this, arguments, () => this.dom.formMethod, () => $.set(this.dom, 'formMethod', method))} - - formNoValidate(): boolean; - formNoValidate(boolean: boolean | undefined): this; - formNoValidate(boolean?: boolean) { return $.fluent(this, arguments, () => this.dom.formNoValidate, () => $.set(this.dom, 'formNoValidate', boolean))} - - formTarget(): string; - formTarget(target: string | undefined): this; - formTarget(target?: string) { return $.fluent(this, arguments, () => this.dom.formTarget, () => $.set(this.dom, 'formTarget', target))} - - name(): string; - name(name?: $StateArgument | undefined): this; - name(name?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.name, () => $.set(this.dom, 'name', name))} - - maxLength(): number; - maxLength(maxLength: number): this; - maxLength(maxLength?: number) { return $.fluent(this, arguments, () => this.dom.maxLength, () => $.set(this.dom, 'maxLength', maxLength))} - - minLength(): number; - minLength(minLength: number): this; - minLength(minLength?: number) { return $.fluent(this, arguments, () => this.dom.minLength, () => $.set(this.dom, 'minLength', minLength))} - - get form() { return this.dom.form ? $(this.dom.form) : null } - get labels() { return Array.from(this.dom.labels ?? []).map(label => $(label)) } - get validationMessage() { return this.dom.validationMessage } - get validity() { return this.dom.validity } - get willValidate() { return this.dom.willValidate } -} - -export class $NumberInput extends $Input { - constructor(options?: $InputOptions) { - super(options) - this.type('number') - } - - static from($input: $Input) { - return $.mixin($Input, this) as $NumberInput; - } - stepDown() { this.dom.stepDown(); return this } - stepUp() { this.dom.stepUp(); return this } - - max(): number; - max(max: number): this; - max(max?: number) { return $.fluent(this, arguments, () => this.dom.max === '' ? null : parseInt(this.dom.min), () => $.set(this.dom, 'max', max?.toString()))} - - min(): number; - min(min: number): this; - min(min?: number) { return $.fluent(this, arguments, () => this.dom.min === '' ? null : parseInt(this.dom.min), () => $.set(this.dom, 'min', min?.toString()))} - - step(): number; - step(step: number): this; - step(step?: number) { return $.fluent(this, arguments, () => Number(this.dom.step), () => $.set(this.dom, 'step', step?.toString()))} -} - -export class $CheckInput extends $Input { - constructor(options?: $InputOptions) { - super(options) - this.type('radio') - } - - static from($input: $Input) { - return $.mixin($Input, this) as $CheckInput; - } - - checked(): boolean; - checked(boolean: boolean): this; - checked(boolean?: boolean) { return $.fluent(this, arguments, () => this.dom.checked, () => $.set(this.dom, 'checked', boolean))} - - defaultChecked(): boolean; - defaultChecked(defaultChecked: boolean): this; - defaultChecked(defaultChecked?: boolean) { return $.fluent(this, arguments, () => this.dom.defaultChecked, () => $.set(this.dom, 'defaultChecked', defaultChecked))} -} - -export class $FileInput extends $Input { - constructor(options?: $InputOptions) { - super(options) - this.type('file') - } - - static from($input: $Input) { - return $.mixin($Input, this) as $CheckInput; - } - - multiple(): boolean; - multiple(multiple: boolean): this; - multiple(multiple?: boolean) { return $.fluent(this, arguments, () => this.dom.multiple, () => $.set(this.dom, 'multiple', multiple))} - - accept(): string[] - accept(...filetype: string[]): this - accept(...filetype: string[]) { return $.fluent(this, arguments, () => this.dom.accept.split(','), () => this.dom.accept = filetype.toString() )} -} - -export type $InputType = T extends 'number' ? $NumberInput : T extends 'radio' | 'checkbox' ? $CheckInput : T extends 'file' ? $FileInput : $Input; \ No newline at end of file diff --git a/lib/node/$Label.ts b/lib/node/$Label.ts deleted file mode 100644 index 976d80b..0000000 --- a/lib/node/$Label.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { $StateArgument } from "../$State"; -import { $Container, $ContainerOptions } from "./$Container"; -export interface $LabelOptions extends $ContainerOptions {} -export class $Label extends $Container { - constructor(options?: $LabelOptions) { - super('label', options); - } - - for(): string; - for(name: $StateArgument): this; - for(name?: $StateArgument) { return $.fluent(this, arguments, () => this.dom.htmlFor, () => { $.set(this.dom, 'htmlFor', name)}) } - - get form() { return this.dom.form } - get control() { return this.dom.control } -} \ No newline at end of file diff --git a/lib/node/$Node.ts b/lib/node/$Node.ts deleted file mode 100644 index 7591440..0000000 --- a/lib/node/$Node.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { $, $Element, $State, $Text } from "../../index"; -import { $Container } from "./$Container"; - -export abstract class $Node { - abstract readonly dom: N; - readonly __hidden: boolean = false; - private domEvents: {[key: string]: Map} = {}; - readonly parent?: $Container; - - on(type: K, callback: (event: HTMLElementEventMap[K], $node: this) => any, options?: AddEventListenerOptions | boolean) { - if (!this.domEvents[type]) this.domEvents[type] = new Map() - const middleCallback = (e: Event) => callback(e as HTMLElementEventMap[K], this); - this.domEvents[type].set(callback, middleCallback) - this.dom.addEventListener(type, middleCallback, options) - return this; - } - - off(type: K, callback: (event: HTMLElementEventMap[K], $node: this) => any, options?: AddEventListenerOptions | boolean) { - const middleCallback = this.domEvents[type]?.get(callback); - if (middleCallback) this.dom.removeEventListener(type, middleCallback as EventListener, options) - return this; - } - - once(type: K, callback: (event: HTMLElementEventMap[K], $node: this) => any, options?: AddEventListenerOptions | boolean) { - const onceFn = (event: Event) => { - this.dom.removeEventListener(type, onceFn, options) - callback(event as HTMLElementEventMap[K], this); - }; - this.dom.addEventListener(type, onceFn, options) - return this; - } - - hide(): boolean; - hide(hide?: boolean | $State, render?: boolean): this; - hide(hide?: boolean | $State, render = true) { return $.fluent(this, arguments, () => this.__hidden, () => { - if (hide === undefined) return; - if (hide instanceof $State) { (this as Mutable<$Node>).__hidden = hide.value; hide.use(this, 'hide')} - else (this as Mutable<$Node>).__hidden = hide; - if (render) this.parent?.children.render(); - return this; - })} - - /**Remove this element from parent */ - remove() { - this.parent?.children.remove(this).render(); - return this; - } - - /**Replace $Node with this element */ - replace($node: $Node) { - this.parent?.children.replace(this, $node).render(); - return this; - } - - contains(target: $Node | EventTarget | Node | null): boolean { - if (!target) return false; - if (target instanceof $Node) return this.dom.contains(target.dom); - else if (target instanceof EventTarget) return this.dom.contains($(target).dom) - else return this.dom.contains(target) - } - - self(callback: ($node: this) => void) { callback(this); return this; } - inDOM() { return document.contains(this.dom); } - isElement(): this is $Element { - if (this instanceof $Element) return true; - else return false; - } -} \ No newline at end of file diff --git a/lib/node/$OptGroup.ts b/lib/node/$OptGroup.ts deleted file mode 100644 index a99034a..0000000 --- a/lib/node/$OptGroup.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { $Container, $ContainerOptions } from "./$Container"; -import { $State, $StateArgument } from "../$State"; - -export interface $OptGroupOptions extends $ContainerOptions {} -export class $OptGroup extends $Container { - constructor(options?: $OptGroupOptions) { - super('optgroup', options); - } - - disabled(): boolean; - disabled(disabled: $StateArgument | undefined): this; - disabled(disabled?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.disabled, () => $.set(this.dom, 'disabled', disabled))} - - label(): string; - label(label: $StateArgument | undefined): this; - label(label?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.label, () => $.set(this.dom, 'label', label))} -} \ No newline at end of file diff --git a/lib/node/$Option.ts b/lib/node/$Option.ts deleted file mode 100644 index eabf21b..0000000 --- a/lib/node/$Option.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { $Container, $ContainerOptions } from "./$Container"; -import { $State, $StateArgument } from "../$State"; - -export interface $OptionOptions extends $ContainerOptions {} -export class $Option extends $Container { - constructor(options?: $OptionOptions) { - super('option', options); - } - - defaultSelected(): boolean; - defaultSelected(defaultSelected: $StateArgument | undefined): this; - defaultSelected(defaultSelected?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.defaultSelected, () => $.set(this.dom, 'defaultSelected', defaultSelected))} - - disabled(): boolean; - disabled(disabled: $StateArgument | undefined): this; - disabled(disabled?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.disabled, () => $.set(this.dom, 'disabled', disabled))} - - label(): string; - label(label: $StateArgument | undefined): this; - label(label?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.label, () => $.set(this.dom, 'label', label))} - - selected(): boolean; - selected(selected: $StateArgument | undefined): this; - selected(selected?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.selected, () => $.set(this.dom, 'selected', selected))} - - text(): string; - text(text: $StateArgument | undefined): this; - text(text?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.text, () => $.set(this.dom, 'text', text))} - - value(): string; - value(value: $StateArgument | undefined): this; - value(value?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.value, () => $.set(this.dom, 'value', value))} - - get form() { return this.dom.form ? $(this.dom.form) : null } - get index() { return this.dom.index } - -} \ No newline at end of file diff --git a/lib/node/$SVGElement.ts b/lib/node/$SVGElement.ts deleted file mode 100644 index 4128b46..0000000 --- a/lib/node/$SVGElement.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { $Element, $ElementOptions } from "./$Element" - -export interface $SVGOptions extends $ElementOptions {} -export class $SVGElement extends $Element { - constructor(tagname: string, options?: $SVGOptions) { - super(tagname, options); - } -} \ No newline at end of file diff --git a/lib/node/$Select.ts b/lib/node/$Select.ts deleted file mode 100644 index b72dbac..0000000 --- a/lib/node/$Select.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { $Container, $ContainerOptions } from "./$Container"; -import { $OptGroup } from "./$OptGroup"; -import { $Option } from "./$Option"; -import { $State, $StateArgument } from "../$State"; - -export interface $SelectOptions extends $ContainerOptions {} -export class $Select extends $Container { - constructor(options?: $SelectOptions) { - super('select') - } - - add(option: $SelectContentType | OrMatrix<$SelectContentType>) { - this.insert(option); - return this; - } - - item(index: number) { return $(this.dom.item(index)) } - namedItem(name: string) { return $(this.dom.namedItem(name)) } - - disabled(): boolean; - disabled(disabled: $StateArgument | undefined): this; - disabled(disabled?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.disabled, () => $.set(this.dom, 'disabled', disabled))} - - multiple(): boolean; - multiple(multiple: $StateArgument | undefined): this; - multiple(multiple?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.multiple, () => $.set(this.dom, 'multiple', multiple))} - - required(): boolean; - required(required: boolean): this; - required(required?: boolean) { return $.fluent(this, arguments, () => this.dom.required, () => $.set(this.dom, 'required', required))} - - autocomplete(): AutoFill; - autocomplete(autocomplete: AutoFill): this; - autocomplete(autocomplete?: AutoFill) { return $.fluent(this, arguments, () => this.dom.autocomplete, () => $.set(this.dom, 'autocomplete', autocomplete))} - - get length() { return this.dom.length } - get size() { return this.dom.size } - get options() { return Array.from(this.dom.options).map($option => $($option)) } - get selectedIndex() { return this.dom.selectedIndex } - get selectedOptions() { return Array.from(this.dom.selectedOptions).map($option => $($option)) } - - name(): string; - name(name?: $StateArgument | undefined): this; - name(name?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.name, () => $.set(this.dom, 'name', name))} - - value(): string; - value(value?: $StateArgument | undefined): this; - value(value?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.value, () => $.set(this.dom, 'value', value))} - - get form() { return this.dom.form ? $(this.dom.form) : null } - get labels() { return Array.from(this.dom.labels ?? []).map(label => $(label)) } - get validationMessage() { return this.dom.validationMessage } - get validity() { return this.dom.validity } - get willValidate() { return this.dom.willValidate } -} - -export type $SelectContentType = $Option | $OptGroup | undefined; \ No newline at end of file diff --git a/lib/node/$Text.ts b/lib/node/$Text.ts deleted file mode 100644 index d9f7018..0000000 --- a/lib/node/$Text.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { $Node } from "./$Node"; - -export class $Text extends $Node { - dom: Text; - constructor(data: string) { - super(); - this.dom = new Text(data); - this.dom.$ = this; - } - - content(): string; - content(text: string): this; - content(text?: string) { return $.fluent(this, arguments, () => this.dom.textContent, () => $.set(this.dom, 'textContent', text))} -} \ No newline at end of file diff --git a/lib/node/$Textarea.ts b/lib/node/$Textarea.ts deleted file mode 100644 index a195dce..0000000 --- a/lib/node/$Textarea.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { $Container, $ContainerOptions } from "./$Container"; -import { $StateArgument } from "../$State"; - -export interface $TextareaOptions extends $ContainerOptions {} -export class $Textarea extends $Container { - constructor(options?: $TextareaOptions) { - super('textarea', options); - } - - cols(): number; - cols(cols: number): this; - cols(cols?: number) { return $.fluent(this, arguments, () => this.dom.cols, () => $.set(this.dom, 'cols', cols))} - - name(): string; - name(name?: $StateArgument | undefined): this; - name(name?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.name, () => $.set(this.dom, 'name', name))} - - wrap(): string; - wrap(wrap?: $StateArgument | undefined): this; - wrap(wrap?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.wrap, () => $.set(this.dom, 'wrap', wrap))} - - value(): string; - value(value?: $StateArgument | undefined): this; - value(value?: $StateArgument | undefined) { return $.fluent(this, arguments, () => this.dom.value, () => $.set(this.dom, 'value', value))} - - maxLength(): number; - maxLength(maxLength: number): this; - maxLength(maxLength?: number) { return $.fluent(this, arguments, () => this.dom.maxLength, () => $.set(this.dom, 'maxLength', maxLength))} - - minLength(): number; - minLength(minLength: number): this; - minLength(minLength?: number) { return $.fluent(this, arguments, () => this.dom.minLength, () => $.set(this.dom, 'minLength', minLength))} - - autocomplete(): AutoFill; - autocomplete(autocomplete: AutoFill): this; - autocomplete(autocomplete?: AutoFill) { return $.fluent(this, arguments, () => this.dom.autocomplete, () => $.set(this.dom, 'autocomplete', autocomplete))} - - defaultValue(): string; - defaultValue(defaultValue: string): this; - defaultValue(defaultValue?: string) { return $.fluent(this, arguments, () => this.dom.defaultValue, () => $.set(this.dom, 'defaultValue', defaultValue))} - - dirName(): string; - dirName(dirName: string): this; - dirName(dirName?: string) { return $.fluent(this, arguments, () => this.dom.dirName, () => $.set(this.dom, 'dirName', dirName))} - - disabled(): boolean; - disabled(disabled: boolean): this; - disabled(disabled?: boolean) { return $.fluent(this, arguments, () => this.dom.disabled, () => $.set(this.dom, 'disabled', disabled))} - - placeholder(): string; - placeholder(placeholder?: string): this; - placeholder(placeholder?: string) { return $.fluent(this, arguments, () => this.dom.placeholder, () => $.set(this.dom, 'placeholder', placeholder))} - - readOnly(): boolean; - readOnly(readOnly: boolean): this; - readOnly(readOnly?: boolean) { return $.fluent(this, arguments, () => this.dom.readOnly, () => $.set(this.dom, 'readOnly', readOnly))} - - required(): boolean; - required(required: boolean): this; - required(required?: boolean) { return $.fluent(this, arguments, () => this.dom.required, () => $.set(this.dom, 'required', required))} - - selectionDirection(): SelectionDirection; - selectionDirection(selectionDirection: SelectionDirection): this; - selectionDirection(selectionDirection?: SelectionDirection) { return $.fluent(this, arguments, () => this.dom.selectionDirection, () => $.set(this.dom, 'selectionDirection', selectionDirection))} - - selectionEnd(): number; - selectionEnd(selectionEnd: number): this; - selectionEnd(selectionEnd?: number) { return $.fluent(this, arguments, () => this.dom.selectionEnd, () => $.set(this.dom, 'selectionEnd', selectionEnd))} - - selectionStart(): number; - selectionStart(selectionStart: number): this; - selectionStart(selectionStart?: number) { return $.fluent(this, arguments, () => this.dom.selectionStart, () => $.set(this.dom, 'selectionStart', selectionStart))} - - type(): InputType; - type(type: InputType): this; - type(type?: InputType) { return $.fluent(this, arguments, () => this.dom.type, () => $.set(this.dom, 'type', type))} - - inputMode(): InputMode; - inputMode(mode: InputMode): this; - inputMode(mode?: InputMode) { return $.fluent(this, arguments, () => this.dom.inputMode as InputMode, () => $.set(this.dom, 'inputMode', mode))} - - select() { this.dom.select(); return this } - setCustomValidity(error: string) { this.dom.setCustomValidity(error); return this } - setRangeText(replacement: string): this; - setRangeText(replacement: string, start: number, end: number, selectionMode?: SelectionMode): this; - setRangeText(replacement: string, start?: number, end?: number, selectionMode?: SelectionMode) { - if (typeof start === 'number' && typeof end === 'number') this.dom.setRangeText(replacement, start, end, selectionMode) - this.dom.setRangeText(replacement); - return this - } - setSelectionRange(start: number | null, end: number | null, direction?: SelectionDirection) { this.dom.setSelectionRange(start, end, direction); return this } - - checkValidity() { return this.dom.checkValidity() } - reportValidity() { return this.dom.reportValidity() } - - get validationMessage() { return this.dom.validationMessage } - get validity() { return this.dom.validity } - get form() { return this.dom.form ? $(this.dom.form) : null } - get labels() { return Array.from(this.dom.labels ?? []).map(label => $(label)) } -} \ No newline at end of file diff --git a/lib/node/$View.ts b/lib/node/$View.ts deleted file mode 100644 index 75ae1d6..0000000 --- a/lib/node/$View.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { $Container, $ContainerOptions } from "./$Container"; -import { $EventManager } from "../$EventManager"; -import { $Node } from "./$Node"; - -export interface $ViewOptions extends $ContainerOptions {} -export class $View extends $Container { - protected view_cache = new Map(); - event = new $EventManager<$ViewEventMap>().register('switch') - content_id: string | null = null; - constructor(options?: $ViewOptions) { - super('view', options); - } - - setView(id: string, $node: $Node) { - this.view_cache.set(id, $node); - return this; - } - - deleteView(id: string) { - this.view_cache.delete(id); - return this; - } - - deleteAllView() { - this.view_cache.clear(); - return this; - } - - switchView(id: string) { - const target_content = this.view_cache.get(id); - if (target_content === undefined) return this; - this.content(target_content); - this.content_id = id; - this.event.fire('switch', id); - return this; - } -} - -export interface $ViewEventMap { - 'switch': [id: string] -} \ No newline at end of file diff --git a/assets/logo_dark.png b/logo_dark.png similarity index 100% rename from assets/logo_dark.png rename to logo_dark.png diff --git a/assets/logo_light.png b/logo_light.png similarity index 100% rename from assets/logo_light.png rename to logo_light.png diff --git a/package.json b/package.json deleted file mode 100644 index 4c36500..0000000 --- a/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "elexis", - "description": "Build Web in Native JavaScript Syntax", - "version": "0.2.0", - "author": { - "name": "defaultkavy", - "email": "defaultkavy@gmail.com", - "url": "https://github.com/defaultkavy" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/defaultkavy/elexis.git" - }, - "module": "index.ts", - "bugs": { - "url": "https://github.com/defaultkavy/elexis/issues" - }, - "homepage": "https://github.com/defaultkavy/elexis", - "keywords": ["web", "front-end", "lib", "fluent", "framework"], - "license": "ISC", - "type": "module" -} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index c6d7f6f..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "lib": ["dom", "ES2022"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "experimentalDecorators": true - }, - } - \ No newline at end of file