diff --git a/$index.ts b/$index.ts index 80b13c1..9d7918b 100644 --- a/$index.ts +++ b/$index.ts @@ -1,4 +1,6 @@ -import { $Node, $State, $StateOption } from "./index"; +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"; @@ -60,7 +62,7 @@ export function $(resolver: any) { } } else return new $Container(resolver); } - if (resolver instanceof HTMLElement || resolver instanceof Text || resolver instanceof SVGElement) { + if (resolver instanceof Node) { if (resolver.$) return resolver.$; else return $Util.from(resolver); } @@ -71,6 +73,7 @@ export namespace $ { export let anchorPreventDefault: boolean = false; export const routers = new Set; export const TagNameElementMap = { + 'document': $Document, 'body': $Container, 'a': $Anchor, 'p': $Container, @@ -158,10 +161,11 @@ export namespace $ { * @returns */ export function set( - object: O, key: K, + object: O, + key: K, value: O[K] extends (...args: any) => any - ? (Parameters | $State | undefined>) - : (O[K] | undefined | $State), + ? (undefined | $StateArgument>) + : (undefined | $StateArgument), methodKey?: string) { if (value === undefined) return; if (value instanceof $State && object instanceof Node) { diff --git a/index.ts b/index.ts index 2e65871..f48887d 100644 --- a/index.ts +++ b/index.ts @@ -48,4 +48,5 @@ export * from "./lib/node/$Option"; export * from "./lib/node/$OptGroup"; export * from "./lib/node/$Textarea"; export * from "./lib/node/$Image"; -export * from "./lib/node/$AsyncNode"; \ No newline at end of file +export * from "./lib/node/$AsyncNode"; +export * from "./lib/node/$Document"; \ No newline at end of file diff --git a/lib/$Util.ts b/lib/$Util.ts index 0d06872..48b41b6 100644 --- a/lib/$Util.ts +++ b/lib/$Util.ts @@ -1,5 +1,7 @@ import { $State } from "./$State"; +import { $AsyncNode } from "./node/$AsyncNode"; 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"; @@ -38,14 +40,18 @@ export namespace $Util { return new $State(value) } - export function from(element: HTMLElement | Text | Node): $Node { + 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 ? new instance(element.tagName, {dom: element}) : new instance({dom: element} as any); + const $node = instance === $Container + ? 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)); + $node.children.add($(childnode as any)); } return $node as $Node; } diff --git a/lib/node/$AsyncNode.ts b/lib/node/$AsyncNode.ts index 5f233ec..4865332 100644 --- a/lib/node/$AsyncNode.ts +++ b/lib/node/$AsyncNode.ts @@ -1,12 +1,13 @@ import { $Node } from "./$Node"; - +export interface $AsyncNodeOptions { + dom?: Node; +} export class $AsyncNode extends $Node { dom: Node = document.createElement('async'); loaded: boolean = false; - constructor($node?: Promise) { + constructor(options?: $AsyncNodeOptions) { super() this.dom.$ = this; - if ($node) $node.then($node => this._loaded($node)); } await($node: Promise) { diff --git a/lib/node/$Container.ts b/lib/node/$Container.ts index 06b2b66..8ce02e3 100644 --- a/lib/node/$Container.ts +++ b/lib/node/$Container.ts @@ -1,7 +1,7 @@ import { $Element, $ElementOptions } from "./$Element"; import { $NodeManager } from "../$NodeManager"; import { $Node } from "./$Node"; -import { $State } from "../$State"; +import { $State, $StateArgument } from "../$State"; import { $Text } from "./$Text"; import { $HTMLElement, $HTMLElementOptions } from "./$HTMLElement"; @@ -47,6 +47,17 @@ export class $Container extends $HTMLElemen //**Query selector of child elements */ $all(query: string) { 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>) diff --git a/lib/node/$Document.ts b/lib/node/$Document.ts new file mode 100644 index 0000000..486a1d6 --- /dev/null +++ b/lib/node/$Document.ts @@ -0,0 +1,40 @@ +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 index 3537a38..6026ef6 100644 --- a/lib/node/$Element.ts +++ b/lib/node/$Element.ts @@ -92,4 +92,22 @@ export class $Element extends getAnimations(options?: GetAnimationsOptions) { return this.dom.getAnimations(options) } get dataset() { return this.dom.dataset } -} \ No newline at end of file + + 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/$Node.ts b/lib/node/$Node.ts index 59d0194..e62be09 100644 --- a/lib/node/$Node.ts +++ b/lib/node/$Node.ts @@ -60,9 +60,9 @@ export abstract class $Node { self(callback: ($node: this) => void) { callback(this); return this; } inDOM() { return document.contains(this.dom); } - isElement(): $Element | undefined { - if (this instanceof $Element) return this; - else return undefined; + isElement(): this is $Element { + if (this instanceof $Element) return true; + else return false; } get parent() { diff --git a/package.json b/package.json index 0aaa293..105c9bb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "fluentx", "description": "Fast, fluent, simple web builder", - "version": "0.0.7", + "version": "0.0.9", "type": "module", "module": "index.ts", "author": {