typed-dom
Advanced tools
Comparing version 0.0.255 to 0.0.256
@@ -1,2 +0,2 @@ | ||
/*! typed-dom v0.0.255 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
/*! typed-dom v0.0.256 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
require = function () { | ||
@@ -677,4 +677,5 @@ function r(e, n, t) { | ||
return build(void 0, attrs, factory); | ||
attrs !== null && attrs !== void 0 ? attrs : attrs = {}; | ||
const node = formatter(elem(factory, attrs, children)); | ||
return node.nodeType === 1 ? new proxy_1.Elem(node, children) : new proxy_1.Elem(node.host, children, node); | ||
return node.nodeType === 1 ? new proxy_1.Elem(node, attrs, children) : new proxy_1.Elem(node.host, attrs, children, node); | ||
}; | ||
@@ -694,3 +695,3 @@ function isElChildren(param) { | ||
function elem(factory, attrs, children) { | ||
const el = factory ? (0, dom_1.define)(factory(baseFactory, tag, attrs !== null && attrs !== void 0 ? attrs : {}, children), attrs) : baseFactory(tag, attrs); | ||
const el = factory ? (0, dom_1.define)(factory(baseFactory, tag, attrs, children), attrs) : baseFactory(tag, attrs); | ||
if (tag !== el.tagName.toLowerCase()) | ||
@@ -713,5 +714,5 @@ throw new Error(`TypedDOM: Expected tag name is "${ tag }" but actually "${ el.tagName.toLowerCase() }".`); | ||
'use strict'; | ||
var _a, _b, _c, _d; | ||
var _a, _b, _c, _d, _e; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
exports.proxy = exports.Elem = void 0; | ||
exports.Elem = void 0; | ||
const global_1 = _dereq_('spica/global'); | ||
@@ -723,2 +724,3 @@ const alias_1 = _dereq_('spica/alias'); | ||
(function (privates) { | ||
privates.events = Symbol.for('typed-dom::events'); | ||
privates.id = Symbol('id'); | ||
@@ -739,8 +741,18 @@ privates.id_ = Symbol('id_'); | ||
class Elem { | ||
constructor(element, children, container = element) { | ||
constructor(element, attrs, children, container = element) { | ||
var _f, _g, _h; | ||
this.element = element; | ||
this[_a] = ''; | ||
this[_a] = { | ||
connect: false, | ||
disconnect: false, | ||
mutate: false | ||
}; | ||
this[_b] = ''; | ||
this[_c] = false; | ||
this[_d] = true; | ||
this[_c] = ''; | ||
this[_d] = false; | ||
this[_e] = true; | ||
const events = this[privates.events]; | ||
events.connect = ((_f = attrs === null || attrs === void 0 ? void 0 : attrs['onconnect']) !== null && _f !== void 0 ? _f : void 0) !== void 0; | ||
events.disconnect = ((_g = attrs === null || attrs === void 0 ? void 0 : attrs['ondisconnect']) !== null && _g !== void 0 ? _g : void 0) !== void 0; | ||
events.mutate = ((_h = attrs === null || attrs === void 0 ? void 0 : attrs['onmutate']) !== null && _h !== void 0 ? _h : void 0) !== void 0; | ||
this[privates.children] = children; | ||
@@ -764,4 +776,3 @@ this[privates.container] = container; | ||
} | ||
throwErrorIfNotUsable(this, null); | ||
proxies.set(this.element, this); | ||
throwErrorIfNotUsable(this); | ||
switch (this[privates.type]) { | ||
@@ -776,3 +787,2 @@ case 0: | ||
case 2: | ||
this[privates.container].replaceChildren(); | ||
this[privates.children] = []; | ||
@@ -792,3 +802,3 @@ this.children = children; | ||
} | ||
get [(_a = privates.id_, privates.id)]() { | ||
get [(_a = privates.events, _b = privates.id_, privates.id)]() { | ||
if (this[privates.id_]) | ||
@@ -807,3 +817,3 @@ return this[privates.id_]; | ||
} | ||
get [(_b = privates.query_, privates.query)]() { | ||
get [(_c = privates.query_, privates.query)]() { | ||
if (this[privates.query_]) | ||
@@ -830,3 +840,3 @@ return this[privates.query_]; | ||
} | ||
[(_c = privates.isObserverUpdate, privates.observe)](children) { | ||
[(_d = privates.isObserverUpdate, privates.observe)](children) { | ||
const descs = {}; | ||
@@ -837,3 +847,2 @@ for (const name of (0, alias_1.ObjectKeys)(children)) { | ||
let child = children[name]; | ||
throwErrorIfNotUsable(child, null); | ||
descs[name] = { | ||
@@ -866,2 +875,3 @@ configurable: true, | ||
set children(children) { | ||
var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q; | ||
const container = this[privates.container]; | ||
@@ -892,6 +902,7 @@ const isInit = this[privates.isInit]; | ||
isMutated || (isMutated = newChild.element !== oldChild.element); | ||
throwErrorIfNotUsable(newChild, container); | ||
if (newChild.element.parentNode !== container) { | ||
throwErrorIfNotUsable(newChild, this.element); | ||
if (((_f = newChild.parent) === null || _f === void 0 ? void 0 : _f.element) !== this.element) { | ||
newChild.parent = this; | ||
this[privates.scope](newChild); | ||
addedChildren.push(newChild); | ||
((_g = newChild[privates.events]) === null || _g === void 0 ? void 0 : _g.connect) && addedChildren.push(newChild); | ||
} | ||
@@ -904,3 +915,4 @@ } | ||
if (oldChild.element.parentNode !== container) { | ||
removedChildren.push(oldChild); | ||
oldChild.parent = void 0; | ||
((_h = oldChild[privates.events]) === null || _h === void 0 ? void 0 : _h.disconnect) && removedChildren.push(oldChild); | ||
} | ||
@@ -923,6 +935,6 @@ } | ||
isMutated = true; | ||
throwErrorIfNotUsable(newChild, container); | ||
if (isInit || newChild !== oldChild && newChild.element.parentNode !== oldChild.element.parentNode) { | ||
throwErrorIfNotUsable(newChild, this.element); | ||
if (isInit || newChild !== oldChild && ((_j = newChild.parent) === null || _j === void 0 ? void 0 : _j.element) !== ((_k = oldChild.parent) === null || _k === void 0 ? void 0 : _k.element)) { | ||
this[privates.scope](newChild); | ||
addedChildren.push(newChild); | ||
((_l = newChild[privates.events]) === null || _l === void 0 ? void 0 : _l.connect) && addedChildren.push(newChild); | ||
if (isInit) { | ||
@@ -933,4 +945,6 @@ container.appendChild(newChild.element); | ||
container.removeChild(oldChild.element); | ||
removedChildren.push(oldChild); | ||
oldChild.parent = void 0; | ||
((_m = oldChild[privates.events]) === null || _m === void 0 ? void 0 : _m.disconnect) && removedChildren.push(oldChild); | ||
} | ||
newChild.parent = this; | ||
} else { | ||
@@ -964,3 +978,3 @@ const ref = newChild.element.nextSibling; | ||
} | ||
if (isMutated) { | ||
if (isMutated && ((_q = this[privates.events]) === null || _q === void 0 ? void 0 : _q.mutate)) { | ||
this.element.dispatchEvent(new global_1.Event('mutate', { | ||
@@ -974,11 +988,7 @@ bubbles: false, | ||
exports.Elem = Elem; | ||
privates.type, privates.container, _d = privates.isInit, privates.children; | ||
const proxies = new global_1.WeakMap(); | ||
function proxy(el) { | ||
return proxies.get(el); | ||
} | ||
exports.proxy = proxy; | ||
function throwErrorIfNotUsable(child, container) { | ||
const parent = child.element.parentElement; | ||
if (!parent || container === parent || !proxies.has(parent)) | ||
privates.type, privates.container, _e = privates.isInit, privates.children; | ||
function throwErrorIfNotUsable(child, newParent) { | ||
var _f; | ||
const oldParent = (_f = child.parent) === null || _f === void 0 ? void 0 : _f.element; | ||
if (!oldParent || newParent === oldParent) | ||
return; | ||
@@ -1209,3 +1219,3 @@ throw new Error(`TypedDOM: Typed DOM children must not be used to another typed DOM.`); | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
exports.identity = exports.apply = exports.currentTarget = exports.wait = exports.once = exports.bind = exports.delegate = exports.listen = exports.defrag = exports.define = exports.element = exports.text = exports.svg = exports.html = exports.frag = exports.shadow = exports.proxy = exports.API = exports.SVG = exports.HTML = exports.Shadow = void 0; | ||
exports.identity = exports.apply = exports.currentTarget = exports.wait = exports.once = exports.bind = exports.delegate = exports.listen = exports.defrag = exports.define = exports.element = exports.text = exports.svg = exports.html = exports.frag = exports.shadow = exports.API = exports.SVG = exports.HTML = exports.Shadow = void 0; | ||
_dereq_('spica/global'); | ||
@@ -1237,9 +1247,2 @@ var builder_1 = _dereq_('./src/builder'); | ||
}); | ||
var proxy_1 = _dereq_('./src/proxy'); | ||
Object.defineProperty(exports, 'proxy', { | ||
enumerable: true, | ||
get: function () { | ||
return proxy_1.proxy; | ||
} | ||
}); | ||
var dom_1 = _dereq_('./src/util/dom'); | ||
@@ -1348,3 +1351,2 @@ Object.defineProperty(exports, 'shadow', { | ||
'./src/builder': 12, | ||
'./src/proxy': 13, | ||
'./src/util/dom': 14, | ||
@@ -1351,0 +1353,0 @@ './src/util/identity': 15, |
@@ -40,4 +40,4 @@ import { Symbol, document } from 'spica/global'; | ||
export interface Factory<M extends TagNameMap> { | ||
<T extends Extract<keyof M, string>>(tag: T, children?: Children): M[T]; | ||
<T extends Extract<keyof M, string>>(tag: T, attrs?: Attrs, children?: Children): M[T]; | ||
<T extends keyof M & string>(tag: T, children?: Children): M[T]; | ||
<T extends keyof M & string>(tag: T, attrs?: Attrs, children?: Children): M[T]; | ||
} | ||
@@ -44,0 +44,0 @@ |
import 'spica/global'; | ||
export { Shadow, HTML, SVG, API } from './src/builder'; | ||
export { El, proxy } from './src/proxy'; | ||
export { El } from './src/proxy'; | ||
export { NS, shadow, frag, html, svg, text, element, define, defrag } from './src/util/dom'; | ||
@@ -6,0 +6,0 @@ export { listen, delegate, bind, once, wait, currentTarget } from './src/util/listener'; |
{ | ||
"name": "typed-dom", | ||
"version": "0.0.255", | ||
"version": "0.0.256", | ||
"description": "A DOM component builder creating type-level DOM structures.", | ||
@@ -5,0 +5,0 @@ "private": false, |
@@ -134,3 +134,2 @@ # typed-dom | ||
- El | ||
- proxy | ||
- NS | ||
@@ -311,3 +310,3 @@ - frag | ||
import { API, html } from 'typed-dom'; | ||
import { Attrs, Children } from 'typed-dom/internal'; | ||
import { Attrs } from 'typed-dom/internal'; | ||
@@ -327,20 +326,6 @@ const i18n = i18next.createInstance({ | ||
} | ||
const Trans = API<HTMLElementTagNameMap>(( | ||
tag: keyof HTMLElementTagNameMap, | ||
_?: Attrs | Children, | ||
children?: keyof TransDataMap, | ||
data?: TransDataMap[keyof TransDataMap], | ||
) => | ||
html(tag, { | ||
onmutate: children | ||
? ev => | ||
i18n.init((err, t) => | ||
(ev.target as HTMLElement).textContent = err | ||
? 'Failed to init i18next.' | ||
: t(children, data)) | ||
: void 0, | ||
})); | ||
const data = <K extends keyof TransDataMap>(data: TransDataMap[K]) => | ||
const Trans = API<HTMLElementTagNameMap>(html); | ||
const bind = <K extends keyof TransDataMap>(data: TransDataMap[K]) => | ||
<T extends string, E extends Element>( | ||
factory: (tag: T, attrs: Attrs, children: string, data: TransDataMap[keyof TransDataMap]) => E, | ||
factory: (tag: T, attrs: Attrs, children: K) => E, | ||
tag: T, | ||
@@ -350,5 +335,11 @@ attrs: Attrs, | ||
): E => | ||
factory(tag, attrs, children, data); | ||
factory(tag, Object.assign<Attrs, Attrs>(attrs, { | ||
onmutate: ev => | ||
i18n.init((err, t) => | ||
(ev.target as HTMLElement).textContent = err | ||
? 'Failed to init i18next.' | ||
: t(children, data)), | ||
}), children); | ||
const el = Trans.span('a', data({ data: 'A' })); | ||
const el = Trans.span('a', bind({ data: 'A' })); | ||
assert(el.children === 'A'); | ||
@@ -355,0 +346,0 @@ assert(el.element.textContent === 'A'); |
@@ -8,4 +8,4 @@ import { Symbol } from 'spica/global'; | ||
<M extends TagNameMap, F extends Factory<M> = Factory<M>> = | ||
BuilderFunction<M, Extract<keyof M, string>, Element, F> & | ||
{ readonly [P in Extract<keyof M, string>]: BuilderMethod<M, P, Extract<M[P], Element>, F>; }; | ||
BuilderFunction<M, F> & | ||
{ readonly [P in K<M>]: BuilderMethod<M, F, P, E<M[P]>>; }; | ||
export function API | ||
@@ -23,28 +23,30 @@ <M extends TagNameMap, F extends Factory<M> = Factory<M>> | ||
type Empty = readonly []; | ||
type ElFactory<M extends TagNameMap, F extends Factory<M>, T extends string, C extends El.Children, E extends Element> = (baseFactory: F, tag: T, attrs: Attrs, children: C) => E; | ||
type ElFactory<M extends TagNameMap, F extends Factory<M>, T extends K<M>, C extends El.Children, E extends Element> = (baseFactory: F, tag: T, attrs: Attrs, children: C) => E; | ||
type K<M> = keyof M & string; | ||
type E<V> = Extract<V, Element>; | ||
interface BuilderFunction<M extends TagNameMap, T extends string, E extends Element, F extends Factory<M>> { | ||
(tag: T, factory?: ElFactory<M, F, T, El.Children.Void, E>): El<T, E, El.Children.Void>; | ||
<C extends Empty >(tag: T, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, El.Children.Array>; | ||
<C extends El.Children.Text >(tag: T, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, string>; | ||
<C extends El.Children.Array >(tag: T, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, Readonly<C>>; | ||
<C extends El.Children.Struct>(tag: T, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, C>; | ||
(tag: T, attrs?: Attrs, factory?: ElFactory<M, F, T, El.Children.Void, E>): El<T, E, El.Children.Void>; | ||
<C extends Empty >(tag: T, attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, El.Children.Array>; | ||
<C extends El.Children.Text >(tag: T, attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, string>; | ||
<C extends El.Children.Array >(tag: T, attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, Readonly<C>>; | ||
<C extends El.Children.Struct>(tag: T, attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, C>; | ||
interface BuilderFunction<M extends TagNameMap, F extends Factory<M>> { | ||
<T extends K<M>, C extends El.Children.Void >(tag: T, factory?: ElFactory<M, F, T, C, E<M[T]>>): El<T, E<M[T]>, El.Children.Void>; | ||
<T extends K<M>, C extends Empty >(tag: T, children?: C, factory?: ElFactory<M, F, T, C, E<M[T]>>): El<T, E<M[T]>, El.Children.Array>; | ||
<T extends K<M>, C extends El.Children.Text >(tag: T, children?: C, factory?: ElFactory<M, F, T, C, E<M[T]>>): El<T, E<M[T]>, string>; | ||
<T extends K<M>, C extends El.Children.Array >(tag: T, children?: C, factory?: ElFactory<M, F, T, C, E<M[T]>>): El<T, E<M[T]>, Readonly<C>>; | ||
<T extends K<M>, C extends El.Children.Struct>(tag: T, children?: C, factory?: ElFactory<M, F, T, C, E<M[T]>>): El<T, E<M[T]>, C>; | ||
<T extends K<M>, C extends El.Children.Void >(tag: T, attrs?: Attrs, factory?: ElFactory<M, F, T, C, E<M[T]>>): El<T, E<M[T]>, El.Children.Void>; | ||
<T extends K<M>, C extends Empty >(tag: T, attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E<M[T]>>): El<T, E<M[T]>, El.Children.Array>; | ||
<T extends K<M>, C extends El.Children.Text >(tag: T, attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E<M[T]>>): El<T, E<M[T]>, string>; | ||
<T extends K<M>, C extends El.Children.Array >(tag: T, attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E<M[T]>>): El<T, E<M[T]>, Readonly<C>>; | ||
<T extends K<M>, C extends El.Children.Struct>(tag: T, attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E<M[T]>>): El<T, E<M[T]>, C>; | ||
} | ||
interface BuilderMethod<M extends TagNameMap, T extends string, E extends Element, F extends Factory<M>> { | ||
( factory?: ElFactory<M, F, T, El.Children.Void, E>): El<T, E, El.Children.Void>; | ||
<C extends Empty >( children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, El.Children.Array>; | ||
<C extends El.Children.Text >( children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, string>; | ||
<C extends El.Children.Array >( children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, Readonly<C>>; | ||
<C extends El.Children.Struct>( children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, C>; | ||
( attrs?: Attrs, factory?: ElFactory<M, F, T, El.Children.Void, E>): El<T, E, El.Children.Void>; | ||
<C extends Empty >( attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, El.Children.Array>; | ||
<C extends El.Children.Text >( attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, string>; | ||
<C extends El.Children.Array >( attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, Readonly<C>>; | ||
<C extends El.Children.Struct>( attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, C>; | ||
interface BuilderMethod<M extends TagNameMap, F extends Factory<M>, T extends K<M>, E extends Element> { | ||
<C extends El.Children.Void >( factory?: ElFactory<M, F, T, C, E> ): El<T, E, El.Children.Void>; | ||
<C extends Empty >( children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, El.Children.Array>; | ||
<C extends El.Children.Text >( children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, string>; | ||
<C extends El.Children.Array >( children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, Readonly<C>>; | ||
<C extends El.Children.Struct>( children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, C>; | ||
<C extends El.Children.Void >( attrs?: Attrs, factory?: ElFactory<M, F, T, C, E> ): El<T, E, El.Children.Void>; | ||
<C extends Empty >( attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, El.Children.Array>; | ||
<C extends El.Children.Text >( attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, string>; | ||
<C extends El.Children.Array >( attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, Readonly<C>>; | ||
<C extends El.Children.Struct>( attrs?: Attrs, children?: C, factory?: ElFactory<M, F, T, C, E> ): El<T, E, C>; | ||
} | ||
@@ -63,14 +65,15 @@ | ||
? target[prop] | ||
: target[prop] = builder(prop as Extract<keyof M, string>, baseFactory), | ||
: target[prop] = builder(prop as keyof M & string, baseFactory), | ||
}; | ||
function builder(tag: Extract<keyof M, string>, baseFactory: F): (attrs?: Attrs, children?: El.Children, factory?: () => Element) => El { | ||
return function build(attrs?: Attrs | El.Children , children?: El.Children, factory?: ElFactory<M, F, Extract<keyof M, string>, El.Children, Element>): El { | ||
function builder(tag: keyof M & string, baseFactory: F): (attrs?: Attrs, children?: El.Children, factory?: () => Element) => El { | ||
return function build(attrs?: Attrs | El.Children, children?: El.Children, factory?: ElFactory<M, F, keyof M & string, El.Children, Element>): El { | ||
if (typeof children === 'function') return build(attrs, void 0, children); | ||
if (typeof attrs === 'function') return build(void 0, void 0, attrs); | ||
if (isElChildren(attrs)) return build(void 0, attrs, factory); | ||
const node = formatter(elem(factory, attrs as Attrs, children)); | ||
attrs ??= {} as typeof attrs; | ||
const node = formatter(elem(factory, attrs, children)); | ||
return node.nodeType === 1 | ||
? new Elem(node as Element, children) | ||
: new Elem((node as ShadowRoot).host, children, node); | ||
? new Elem(node as Element, attrs, children) | ||
: new Elem((node as ShadowRoot).host, attrs, children, node); | ||
}; | ||
@@ -88,5 +91,5 @@ | ||
function elem(factory: ElFactory<M, F, Extract<keyof M, string>, El.Children, Element> | undefined, attrs: Attrs | undefined, children: El.Children): Element { | ||
function elem(factory: ElFactory<M, F, keyof M & string, El.Children, Element> | undefined, attrs: Attrs, children: El.Children): Element { | ||
const el = factory | ||
? define(factory(baseFactory as F, tag, attrs ?? {}, children), attrs) | ||
? define(factory(baseFactory as F, tag, attrs, children), attrs) | ||
: baseFactory(tag, attrs) as unknown as Element; | ||
@@ -93,0 +96,0 @@ if (tag !== el.tagName.toLowerCase()) throw new Error(`TypedDOM: Expected tag name is "${tag}" but actually "${el.tagName.toLowerCase()}".`); |
@@ -1,3 +0,4 @@ | ||
import { WeakMap, Event } from 'spica/global'; | ||
import { Event } from 'spica/global'; | ||
import { isArray, ObjectDefineProperties, ObjectKeys } from 'spica/alias'; | ||
import { Attrs } from './util/dom'; | ||
import { identity } from './util/identity'; | ||
@@ -13,2 +14,3 @@ | ||
readonly [tag]?: T; | ||
readonly parent?: El; | ||
readonly element: E; | ||
@@ -24,3 +26,3 @@ children: C; | ||
export namespace Children { | ||
export type Void = undefined; | ||
export type Void = void; | ||
export type Text = string; | ||
@@ -39,2 +41,3 @@ export type Array = readonly El[]; | ||
namespace privates { | ||
export const events = Symbol.for('typed-dom::events'); | ||
export const id = Symbol('id'); | ||
@@ -63,5 +66,10 @@ export const id_ = Symbol('id_'); | ||
public readonly element: E, | ||
attrs: Attrs, | ||
children: C, | ||
container: Element | ShadowRoot = element, | ||
) { | ||
const events = this[privates.events]; | ||
events.connect = (attrs?.['onconnect'] ?? void 0) !== void 0; | ||
events.disconnect = (attrs?.['ondisconnect'] ?? void 0) !== void 0; | ||
events.mutate = (attrs?.['onmutate'] ?? void 0) !== void 0; | ||
this[privates.children] = children; | ||
@@ -85,4 +93,3 @@ this[privates.container] = container; | ||
} | ||
throwErrorIfNotUsable(this, null); | ||
proxies.set(this.element, this); | ||
throwErrorIfNotUsable(this); | ||
switch (this[privates.type]) { | ||
@@ -97,3 +104,2 @@ case ElChildType.Void: | ||
case ElChildType.Array: | ||
this[privates.container].replaceChildren(); | ||
this[privates.children] = [] as El.Children.Array as C; | ||
@@ -114,2 +120,7 @@ this.children = children; | ||
public readonly [tag]: T; | ||
private readonly [privates.events] = { | ||
connect: false, | ||
disconnect: false, | ||
mutate: false, | ||
}; | ||
private [privates.id_] = ''; | ||
@@ -156,3 +167,2 @@ private get [privates.id](): string { | ||
let child = children[name]; | ||
throwErrorIfNotUsable(child, null); | ||
descs[name] = { | ||
@@ -215,7 +225,9 @@ configurable: true, | ||
isMutated ||= newChild.element !== oldChild.element; | ||
throwErrorIfNotUsable(newChild, container); | ||
if (newChild.element.parentNode !== container) { | ||
throwErrorIfNotUsable(newChild, this.element); | ||
if (newChild.parent?.element !== this.element) { | ||
// @ts-expect-error | ||
newChild.parent = this; | ||
this[privates.scope](newChild); | ||
assert(!addedChildren.includes(newChild)); | ||
addedChildren.push(newChild); | ||
newChild[privates.events]?.connect && addedChildren.push(newChild); | ||
} | ||
@@ -228,4 +240,6 @@ } | ||
if (oldChild.element.parentNode !== container) { | ||
// @ts-expect-error | ||
oldChild.parent = void 0; | ||
assert(!removedChildren.includes(oldChild)); | ||
removedChildren.push(oldChild); | ||
oldChild[privates.events]?.disconnect && removedChildren.push(oldChild); | ||
assert(isMutated); | ||
@@ -248,7 +262,7 @@ } | ||
isMutated = true; | ||
throwErrorIfNotUsable(newChild, container); | ||
if (isInit || newChild !== oldChild && newChild.element.parentNode !== oldChild.element.parentNode) { | ||
throwErrorIfNotUsable(newChild, this.element); | ||
if (isInit || newChild !== oldChild && newChild.parent?.element !== oldChild.parent?.element) { | ||
this[privates.scope](newChild); | ||
assert(!addedChildren.includes(newChild)); | ||
addedChildren.push(newChild); | ||
newChild[privates.events]?.connect && addedChildren.push(newChild); | ||
if (isInit) { | ||
@@ -260,8 +274,12 @@ container.appendChild(newChild.element); | ||
container.removeChild(oldChild.element); | ||
// @ts-expect-error | ||
oldChild.parent = void 0; | ||
assert(!removedChildren.includes(oldChild)); | ||
removedChildren.push(oldChild); | ||
oldChild[privates.events]?.disconnect && removedChildren.push(oldChild); | ||
} | ||
// @ts-expect-error | ||
newChild.parent = this; | ||
} | ||
else { | ||
assert(newChild.element.parentNode === oldChild.element.parentNode); | ||
assert(newChild.parent?.element === oldChild.parent?.element); | ||
const ref = newChild.element.nextSibling; | ||
@@ -290,3 +308,3 @@ container.insertBefore(newChild.element, oldChild.element); | ||
assert(isMutated || removedChildren.length + addedChildren.length === 0); | ||
if (isMutated) { | ||
if (isMutated && this[privates.events]?.mutate) { | ||
this.element.dispatchEvent(new Event('mutate', { bubbles: false, cancelable: true })); | ||
@@ -297,15 +315,6 @@ } | ||
const proxies = new WeakMap<Element, El>(); | ||
export function proxy<C extends El.Children>(el: Element): El<string, Element, C> | undefined; | ||
export function proxy<E extends Element, C extends El.Children = El.Children>(el: E): El<string, E, C> | undefined; | ||
export function proxy<T extends string, E extends Element, C extends El.Children = El.Children>(el: E): El<T, E, C> | undefined; | ||
export function proxy(el: Element): El | undefined { | ||
return proxies.get(el); | ||
} | ||
function throwErrorIfNotUsable(child: El, container: Element | ShadowRoot | null): void { | ||
const parent = child.element.parentElement; | ||
if (!parent || container === parent || !proxies.has(parent)) return; | ||
function throwErrorIfNotUsable(child: El, newParent?: Element): void { | ||
const oldParent = child.parent?.element; | ||
if (!oldParent || newParent === oldParent) return; | ||
throw new Error(`TypedDOM: Typed DOM children must not be used to another typed DOM.`); | ||
} |
@@ -40,4 +40,4 @@ import { Symbol, document } from 'spica/global'; | ||
export interface Factory<M extends TagNameMap> { | ||
<T extends Extract<keyof M, string>>(tag: T, children?: Children): M[T]; | ||
<T extends Extract<keyof M, string>>(tag: T, attrs?: Attrs, children?: Children): M[T]; | ||
<T extends keyof M & string>(tag: T, children?: Children): M[T]; | ||
<T extends keyof M & string>(tag: T, attrs?: Attrs, children?: Children): M[T]; | ||
} | ||
@@ -44,0 +44,0 @@ |
import { Shadow, HTML, SVG, API, El, shadow, html } from '../../index'; | ||
import { Coroutine } from 'spica/coroutine'; | ||
import { Sequence } from 'spica/sequence'; | ||
import { Attrs, Children } from '../../internal'; | ||
import { Attrs } from '../../internal'; | ||
@@ -22,3 +22,2 @@ declare global { | ||
assert(HTML('p', 'a').element.outerHTML === '<p>a</p>'); | ||
assert(HTML('p', undefined, 'a').element.outerHTML === '<p>a</p>'); | ||
assert(HTML('p', { class: 'class' }, 'a', (h, t) => h(t, { id: 'id' })).element.outerHTML === '<p id="id" class="class">a</p>'); | ||
@@ -257,2 +256,4 @@ }); | ||
assert.deepStrictEqual(dom.children, {}); | ||
assert.deepStrictEqual(HTML('div', undefined, {}, html => html('div', 'a')).children, {}); | ||
assert.deepStrictEqual(HTML.div(undefined, {}, html => html('div', 'a')).children, {}); | ||
}); | ||
@@ -539,20 +540,6 @@ | ||
} | ||
const Trans = API<HTMLElementTagNameMap>(( | ||
tag: keyof HTMLElementTagNameMap, | ||
_?: Attrs | Children, | ||
children?: keyof TransDataMap, | ||
data?: TransDataMap[keyof TransDataMap], | ||
) => | ||
html(tag, { | ||
onmutate: children | ||
? ev => | ||
i18n.init((err, t) => | ||
(ev.target as HTMLElement).textContent = err | ||
? 'Failed to init i18next.' | ||
: t(children, data)) | ||
: void 0, | ||
})); | ||
const data = <K extends keyof TransDataMap>(data: TransDataMap[K]) => | ||
const Trans = API<HTMLElementTagNameMap>(html); | ||
const bind = <K extends keyof TransDataMap>(data: TransDataMap[K]) => | ||
<T extends string, E extends Element>( | ||
factory: (tag: T, attrs: Attrs, children: string, data: TransDataMap[keyof TransDataMap]) => E, | ||
factory: (tag: T, attrs: Attrs, children: K) => E, | ||
tag: T, | ||
@@ -562,5 +549,11 @@ attrs: Attrs, | ||
): E => | ||
factory(tag, attrs, children, data); | ||
factory(tag, Object.assign<Attrs, Attrs>(attrs, { | ||
onmutate: ev => | ||
i18n.init((err, t) => | ||
(ev.target as HTMLElement).textContent = err | ||
? 'Failed to init i18next.' | ||
: t(children, data)), | ||
}), children); | ||
const el = Trans.span('a', data({ data: 'A' })); | ||
const el = Trans.span('a', bind({ data: 'A' })); | ||
assert(el.children === 'A'); | ||
@@ -567,0 +560,0 @@ assert(el.element.textContent === 'A'); |
@@ -1,2 +0,2 @@ | ||
import { Shadow, HTML, SVG, API, proxy, NS, shadow, frag, html, svg, text, element, define, defrag, listen, once, wait, bind, delegate, currentTarget, apply, identity } from '../../index'; | ||
import { Shadow, HTML, SVG, API, NS, shadow, frag, html, svg, text, element, define, defrag, listen, once, wait, bind, delegate, currentTarget, apply, identity } from '../../index'; | ||
@@ -22,6 +22,2 @@ describe('Interface: Package', function () { | ||
it('proxy', function () { | ||
assert(typeof proxy === 'function'); | ||
}); | ||
}); | ||
@@ -28,0 +24,0 @@ |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
655136
15486
348