typed-dom
Advanced tools
Comparing version 0.0.256 to 0.0.257
@@ -1,2 +0,2 @@ | ||
/*! typed-dom v0.0.256 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
/*! typed-dom v0.0.257 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
require = function () { | ||
@@ -678,4 +678,5 @@ function r(e, n, t) { | ||
attrs !== null && attrs !== void 0 ? attrs : attrs = {}; | ||
const node = formatter(elem(factory, attrs, children)); | ||
return node.nodeType === 1 ? new proxy_1.Elem(node, attrs, children) : new proxy_1.Elem(node.host, attrs, children, node); | ||
const el = elem(factory, attrs, children); | ||
const node = formatter(el); | ||
return node !== el && 'host' in node ? new proxy_1.Elem(el, attrs, children, node) : new proxy_1.Elem(el, attrs, children); | ||
}; | ||
@@ -720,2 +721,3 @@ function isElChildren(param) { | ||
const tag = Symbol.for('typed-dom::tag'); | ||
const proxy = Symbol.for('typed-dom::proxy'); | ||
var privates; | ||
@@ -774,2 +776,3 @@ (function (privates) { | ||
throwErrorIfNotUsable(this); | ||
this.element[proxy] = this; | ||
switch (this[privates.type]) { | ||
@@ -789,3 +792,2 @@ case 0: | ||
case 3: | ||
this[privates.container].replaceChildren(); | ||
this[privates.children] = this[privates.observe](children); | ||
@@ -868,5 +870,4 @@ this.children = children; | ||
set children(children) { | ||
var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q; | ||
var _f, _g, _h, _j, _k; | ||
const container = this[privates.container]; | ||
const isInit = this[privates.isInit]; | ||
const removedChildren = []; | ||
@@ -879,5 +880,9 @@ const addedChildren = []; | ||
case 1: { | ||
if (!this[privates.events].mutate) { | ||
container.textContent = children; | ||
break; | ||
} | ||
const newText = children; | ||
const oldText = this.children; | ||
if (!isInit && newText === oldText) | ||
if (!this[privates.isInit] && newText === oldText) | ||
return; | ||
@@ -895,8 +900,7 @@ isMutated = true; | ||
const oldChild = targetChildren[i]; | ||
throwErrorIfNotUsable(newChild, this[privates.container]); | ||
isMutated || (isMutated = newChild.element !== oldChild.element); | ||
throwErrorIfNotUsable(newChild, this.element); | ||
if (((_f = newChild.parent) === null || _f === void 0 ? void 0 : _f.element) !== this.element) { | ||
newChild.parent = this; | ||
if (newChild.element.parentNode !== this.element) { | ||
this[privates.scope](newChild); | ||
((_g = newChild[privates.events]) === null || _g === void 0 ? void 0 : _g.connect) && addedChildren.push(newChild); | ||
((_f = events(newChild)) === null || _f === void 0 ? void 0 : _f.connect) && addedChildren.push(newChild); | ||
} | ||
@@ -909,4 +913,3 @@ } | ||
if (oldChild.element.parentNode !== container) { | ||
oldChild.parent = void 0; | ||
((_h = oldChild[privates.events]) === null || _h === void 0 ? void 0 : _h.disconnect) && removedChildren.push(oldChild); | ||
((_g = events(oldChild)) === null || _g === void 0 ? void 0 : _g.disconnect) && removedChildren.push(oldChild); | ||
} | ||
@@ -917,4 +920,19 @@ } | ||
case 3: { | ||
if (this[privates.isInit]) { | ||
container.firstChild && container.replaceChildren(); | ||
const sourceChildren = children; | ||
for (const name of (0, alias_1.ObjectKeys)(sourceChildren)) { | ||
const newChild = sourceChildren[name]; | ||
throwErrorIfNotUsable(newChild, this[privates.container]); | ||
isMutated = true; | ||
this[privates.scope](newChild); | ||
((_h = events(newChild)) === null || _h === void 0 ? void 0 : _h.connect) && addedChildren.push(newChild); | ||
container.appendChild(newChild.element); | ||
} | ||
break; | ||
} | ||
const sourceChildren = children; | ||
const targetChildren = this[privates.children]; | ||
if (sourceChildren === targetChildren) | ||
break; | ||
for (const name of (0, alias_1.ObjectKeys)(sourceChildren)) { | ||
@@ -927,18 +945,12 @@ if (name in {}) | ||
continue; | ||
if (!isInit && newChild === oldChild) | ||
if (newChild === oldChild) | ||
continue; | ||
throwErrorIfNotUsable(newChild, this[privates.container]); | ||
isMutated = true; | ||
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)) { | ||
if (newChild !== oldChild && newChild.element.parentNode !== oldChild.element.parentNode) { | ||
this[privates.scope](newChild); | ||
((_l = newChild[privates.events]) === null || _l === void 0 ? void 0 : _l.connect) && addedChildren.push(newChild); | ||
if (isInit) { | ||
container.appendChild(newChild.element); | ||
} else { | ||
container.insertBefore(newChild.element, oldChild.element); | ||
container.removeChild(oldChild.element); | ||
oldChild.parent = void 0; | ||
((_m = oldChild[privates.events]) === null || _m === void 0 ? void 0 : _m.disconnect) && removedChildren.push(oldChild); | ||
} | ||
newChild.parent = this; | ||
((_j = events(newChild)) === null || _j === void 0 ? void 0 : _j.connect) && addedChildren.push(newChild); | ||
container.insertBefore(newChild.element, oldChild.element); | ||
container.removeChild(oldChild.element); | ||
((_k = events(oldChild)) === null || _k === void 0 ? void 0 : _k.disconnect) && removedChildren.push(oldChild); | ||
} else { | ||
@@ -956,19 +968,15 @@ const ref = newChild.element.nextSibling; | ||
} | ||
if (removedChildren.length) { | ||
for (const child of removedChildren) { | ||
child.element.dispatchEvent(new global_1.Event('disconnect', { | ||
bubbles: false, | ||
cancelable: true | ||
})); | ||
} | ||
for (let i = 0; i < removedChildren.length; ++i) { | ||
removedChildren[i].element.dispatchEvent(new global_1.Event('disconnect', { | ||
bubbles: false, | ||
cancelable: true | ||
})); | ||
} | ||
if (addedChildren.length) { | ||
for (const child of addedChildren) { | ||
child.element.dispatchEvent(new global_1.Event('connect', { | ||
bubbles: false, | ||
cancelable: true | ||
})); | ||
} | ||
for (let i = 0; i < addedChildren.length; ++i) { | ||
addedChildren[i].element.dispatchEvent(new global_1.Event('connect', { | ||
bubbles: false, | ||
cancelable: true | ||
})); | ||
} | ||
if (isMutated && ((_q = this[privates.events]) === null || _q === void 0 ? void 0 : _q.mutate)) { | ||
if (isMutated && this[privates.events].mutate) { | ||
this.element.dispatchEvent(new global_1.Event('mutate', { | ||
@@ -983,6 +991,9 @@ bubbles: false, | ||
privates.type, privates.container, _e = privates.isInit, privates.children; | ||
function events(child) { | ||
var _f, _g; | ||
return (_f = child[privates.events]) !== null && _f !== void 0 ? _f : (_g = child.element[proxy]) === null || _g === void 0 ? void 0 : _g[privates.events]; | ||
} | ||
function throwErrorIfNotUsable(child, newParent) { | ||
var _f; | ||
const oldParent = (_f = child.parent) === null || _f === void 0 ? void 0 : _f.element; | ||
if (!oldParent || newParent === oldParent) | ||
const oldParent = child.element.parentNode; | ||
if (!oldParent || oldParent === newParent || !(proxy in oldParent)) | ||
return; | ||
@@ -1056,4 +1067,3 @@ throw new Error(`TypedDOM: Typed DOM children must not be used to another typed DOM.`); | ||
return el; | ||
for (let i = 0, names = (0, alias_1.ObjectKeys)(attrs); i < names.length; ++i) { | ||
const name = names[i]; | ||
for (const name of (0, alias_1.ObjectKeys)(attrs)) { | ||
const value = attrs[name]; | ||
@@ -1068,4 +1078,3 @@ switch (typeof value) { | ||
const names = name.split(/\s+/); | ||
for (let i = 0; i < names.length; ++i) { | ||
const name = names[i]; | ||
for (const name of names) { | ||
if (name.slice(0, 2) !== 'on') | ||
@@ -1215,5 +1224,11 @@ throw new Error(`TypedDOM: Attribute names for event listeners must start with "on" but got "${ name }".`); | ||
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.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.SVG = exports.HTML = exports.Shadow = exports.API = void 0; | ||
_dereq_('spica/global'); | ||
var builder_1 = _dereq_('./src/builder'); | ||
Object.defineProperty(exports, 'API', { | ||
enumerable: true, | ||
get: function () { | ||
return builder_1.API; | ||
} | ||
}); | ||
Object.defineProperty(exports, 'Shadow', { | ||
@@ -1237,8 +1252,2 @@ enumerable: true, | ||
}); | ||
Object.defineProperty(exports, 'API', { | ||
enumerable: true, | ||
get: function () { | ||
return builder_1.API; | ||
} | ||
}); | ||
var dom_1 = _dereq_('./src/util/dom'); | ||
@@ -1245,0 +1254,0 @@ Object.defineProperty(exports, 'shadow', { |
@@ -114,4 +114,3 @@ import { Symbol, document } from 'spica/global'; | ||
if (!attrs) return el; | ||
for (let i = 0, names = ObjectKeys(attrs); i < names.length; ++i) { | ||
const name = names[i]; | ||
for (const name of ObjectKeys(attrs)) { | ||
const value = attrs[name]; | ||
@@ -125,4 +124,3 @@ switch (typeof value) { | ||
const names = name.split(/\s+/); | ||
for (let i = 0; i < names.length; ++i) { | ||
const name = names[i]; | ||
for (const name of names) { | ||
if (name.slice(0, 2) !== 'on') throw new Error(`TypedDOM: Attribute names for event listeners must start with "on" but got "${name}".`); | ||
@@ -129,0 +127,0 @@ el.addEventListener(name.slice(2), value, { |
import 'spica/global'; | ||
export { Shadow, HTML, SVG, API } from './src/builder'; | ||
export { API, Shadow, HTML, SVG } from './src/builder'; | ||
export { El } from './src/proxy'; | ||
@@ -5,0 +5,0 @@ export { NS, shadow, frag, html, svg, text, element, define, defrag } from './src/util/dom'; |
{ | ||
"name": "typed-dom", | ||
"version": "0.0.256", | ||
"version": "0.0.257", | ||
"description": "A DOM component builder creating type-level DOM structures.", | ||
@@ -5,0 +5,0 @@ "private": false, |
@@ -46,3 +46,3 @@ # typed-dom | ||
Create an HTML element proxy creating open shadow DOM to append children. | ||
Create an element proxy appending the children to the own open shadow DOM. | ||
@@ -63,3 +63,3 @@ - attrs: Record<string, string | EventListener | null | undefined> | ||
All exposed APIs to create a proxy can be redefined as follows: | ||
All the exposed proxy APIs can be redefined as follows: | ||
@@ -137,4 +137,4 @@ ```ts | ||
- NS | ||
- shadow | ||
- frag | ||
- shadow | ||
- html | ||
@@ -141,0 +141,0 @@ - svg |
@@ -72,6 +72,9 @@ import { Symbol } from 'spica/global'; | ||
attrs ??= {} as typeof attrs; | ||
const node = formatter(elem(factory, attrs, children)); | ||
return node.nodeType === 1 | ||
? new Elem(node as Element, attrs, children) | ||
: new Elem((node as ShadowRoot).host, attrs, children, node); | ||
const el = elem(factory, attrs, children); | ||
const node = formatter(el); | ||
return node !== el && 'host' in node | ||
// Shadow | ||
? new Elem(el, attrs, children, node) | ||
// Element | ||
: new Elem(el, attrs, children); | ||
}; | ||
@@ -78,0 +81,0 @@ |
@@ -7,2 +7,3 @@ import { Event } from 'spica/global'; | ||
const tag = Symbol.for('typed-dom::tag'); | ||
const proxy = Symbol.for('typed-dom::proxy'); | ||
@@ -15,3 +16,2 @@ export interface El< | ||
readonly [tag]?: T; | ||
readonly parent?: El; | ||
readonly element: E; | ||
@@ -62,3 +62,3 @@ children: C; | ||
C extends El.Children, | ||
> { | ||
> implements El<T, E, C> { | ||
constructor( | ||
@@ -93,2 +93,3 @@ public readonly element: E, | ||
throwErrorIfNotUsable(this); | ||
this.element[proxy] = this; | ||
switch (this[privates.type]) { | ||
@@ -108,3 +109,2 @@ case ElChildType.Void: | ||
case ElChildType.Struct: | ||
this[privates.container].replaceChildren(); | ||
this[privates.children] = this[privates.observe](children as El.Children.Struct) as C; | ||
@@ -199,3 +199,2 @@ this.children = children; | ||
const container = this[privates.container]; | ||
const isInit = this[privates.isInit]; | ||
const removedChildren: El[] = []; | ||
@@ -208,5 +207,9 @@ const addedChildren: El[] = []; | ||
case ElChildType.Text: { | ||
if (!this[privates.events].mutate) { | ||
container.textContent = children as El.Children.Text; | ||
break; | ||
} | ||
const newText = children; | ||
const oldText = this.children; | ||
if (!isInit && newText === oldText) return; | ||
if (!this[privates.isInit] && newText === oldText) return; | ||
isMutated = true; | ||
@@ -223,10 +226,8 @@ container.textContent = newText as El.Children.Text; | ||
const oldChild = targetChildren[i]; | ||
throwErrorIfNotUsable(newChild, this[privates.container]); | ||
isMutated ||= newChild.element !== oldChild.element; | ||
throwErrorIfNotUsable(newChild, this.element); | ||
if (newChild.parent?.element !== this.element) { | ||
// @ts-expect-error | ||
newChild.parent = this; | ||
if (newChild.element.parentNode !== this.element) { | ||
this[privates.scope](newChild); | ||
assert(!addedChildren.includes(newChild)); | ||
newChild[privates.events]?.connect && addedChildren.push(newChild); | ||
events(newChild)?.connect && addedChildren.push(newChild); | ||
} | ||
@@ -239,6 +240,4 @@ } | ||
if (oldChild.element.parentNode !== container) { | ||
// @ts-expect-error | ||
oldChild.parent = void 0; | ||
assert(!removedChildren.includes(oldChild)); | ||
oldChild[privates.events]?.disconnect && removedChildren.push(oldChild); | ||
events(oldChild)?.disconnect && removedChildren.push(oldChild); | ||
assert(isMutated); | ||
@@ -252,4 +251,20 @@ } | ||
case ElChildType.Struct: { | ||
if (this[privates.isInit]) { | ||
container.firstChild && container.replaceChildren(); | ||
const sourceChildren = children as El.Children.Struct; | ||
for (const name of ObjectKeys(sourceChildren)) { | ||
assert(name in {} === false); | ||
const newChild = sourceChildren[name]; | ||
throwErrorIfNotUsable(newChild, this[privates.container]); | ||
isMutated = true; | ||
this[privates.scope](newChild); | ||
assert(!addedChildren.includes(newChild)); | ||
events(newChild)?.connect && addedChildren.push(newChild); | ||
container.appendChild(newChild.element); | ||
} | ||
break; | ||
} | ||
const sourceChildren = children as El.Children.Struct; | ||
const targetChildren = this[privates.children] as El.Children.Struct; | ||
if (sourceChildren === targetChildren) break; | ||
for (const name of ObjectKeys(sourceChildren)) { | ||
@@ -260,25 +275,16 @@ if (name in {}) continue; | ||
if (!newChild || !oldChild) continue; | ||
if (!isInit && newChild === oldChild) continue; | ||
if (newChild === oldChild) continue; | ||
throwErrorIfNotUsable(newChild, this[privates.container]); | ||
isMutated = true; | ||
throwErrorIfNotUsable(newChild, this.element); | ||
if (isInit || newChild !== oldChild && newChild.parent?.element !== oldChild.parent?.element) { | ||
if (newChild !== oldChild && newChild.element.parentNode !== oldChild.element.parentNode) { | ||
this[privates.scope](newChild); | ||
assert(!addedChildren.includes(newChild)); | ||
newChild[privates.events]?.connect && addedChildren.push(newChild); | ||
if (isInit) { | ||
container.appendChild(newChild.element); | ||
} | ||
else { | ||
container.insertBefore(newChild.element, oldChild.element); | ||
container.removeChild(oldChild.element); | ||
// @ts-expect-error | ||
oldChild.parent = void 0; | ||
assert(!removedChildren.includes(oldChild)); | ||
oldChild[privates.events]?.disconnect && removedChildren.push(oldChild); | ||
} | ||
// @ts-expect-error | ||
newChild.parent = this; | ||
events(newChild)?.connect && addedChildren.push(newChild); | ||
container.insertBefore(newChild.element, oldChild.element); | ||
container.removeChild(oldChild.element); | ||
assert(!removedChildren.includes(oldChild)); | ||
events(oldChild)?.disconnect && removedChildren.push(oldChild); | ||
} | ||
else { | ||
assert(newChild.parent?.element === oldChild.parent?.element); | ||
assert(newChild.element.parentNode === oldChild.element.parentNode); | ||
const ref = newChild.element.nextSibling; | ||
@@ -296,14 +302,10 @@ container.insertBefore(newChild.element, oldChild.element); | ||
} | ||
if (removedChildren.length) { | ||
for (const child of removedChildren) { | ||
child.element.dispatchEvent(new Event('disconnect', { bubbles: false, cancelable: true })); | ||
} | ||
for (let i = 0; i < removedChildren.length; ++i) { | ||
removedChildren[i].element.dispatchEvent(new Event('disconnect', { bubbles: false, cancelable: true })); | ||
} | ||
if (addedChildren.length) { | ||
for (const child of addedChildren) { | ||
child.element.dispatchEvent(new Event('connect', { bubbles: false, cancelable: true })); | ||
} | ||
for (let i = 0; i < addedChildren.length; ++i) { | ||
addedChildren[i].element.dispatchEvent(new Event('connect', { bubbles: false, cancelable: true })); | ||
} | ||
assert(isMutated || removedChildren.length + addedChildren.length === 0); | ||
if (isMutated && this[privates.events]?.mutate) { | ||
if (isMutated && this[privates.events].mutate) { | ||
this.element.dispatchEvent(new Event('mutate', { bubbles: false, cancelable: true })); | ||
@@ -314,6 +316,10 @@ } | ||
function throwErrorIfNotUsable(child: El, newParent?: Element): void { | ||
const oldParent = child.parent?.element; | ||
if (!oldParent || newParent === oldParent) return; | ||
function events(child: El): Elem<string, Element, El.Children>[typeof privates.events] | undefined { | ||
return child[privates.events] ?? child.element[proxy]?.[privates.events]; | ||
} | ||
function throwErrorIfNotUsable(child: El, newParent?: ParentNode): void { | ||
const oldParent = child.element.parentNode; | ||
if (!oldParent || oldParent === newParent || !(proxy in oldParent)) return; | ||
throw new Error(`TypedDOM: Typed DOM children must not be used to another typed DOM.`); | ||
} |
@@ -114,4 +114,3 @@ import { Symbol, document } from 'spica/global'; | ||
if (!attrs) return el; | ||
for (let i = 0, names = ObjectKeys(attrs); i < names.length; ++i) { | ||
const name = names[i]; | ||
for (const name of ObjectKeys(attrs)) { | ||
const value = attrs[name]; | ||
@@ -125,4 +124,3 @@ switch (typeof value) { | ||
const names = name.split(/\s+/); | ||
for (let i = 0; i < names.length; ++i) { | ||
const name = names[i]; | ||
for (const name of names) { | ||
if (name.slice(0, 2) !== 'on') throw new Error(`TypedDOM: Attribute names for event listeners must start with "on" but got "${name}".`); | ||
@@ -129,0 +127,0 @@ el.addEventListener(name.slice(2), value, { |
@@ -1,2 +0,2 @@ | ||
import { Shadow, HTML, SVG, API, El, shadow, html } from '../../index'; | ||
import { API, Shadow, HTML, SVG, El, shadow, html } from '../..'; | ||
import { Coroutine } from 'spica/coroutine'; | ||
@@ -420,2 +420,3 @@ import { Sequence } from 'spica/sequence'; | ||
assert(Shadow.section([HTML.p()]).element.outerHTML === '<section></section>'); | ||
assert(Shadow.section([HTML.p()]).element.shadowRoot instanceof ShadowRoot); | ||
assert(Shadow.section([HTML.p()]).element.shadowRoot!.innerHTML === '<p></p>'); | ||
@@ -428,2 +429,8 @@ assert(Shadow.section([HTML.p()]).children[0].element.outerHTML === '<p></p>'); | ||
assert(Shadow.section([HTML.p()], (h, t) => shadow(h(t), { mode: 'closed' }).host as HTMLElement).children[0].element.outerHTML === '<p></p>'); | ||
const el = HTML.div([Shadow.section([HTML.p('a')])]); | ||
assert(el.element.outerHTML === '<div><section></section></div>'); | ||
assert(el.children[0].children[0].element.outerHTML === '<p>a</p>'); | ||
el.children[0].children[0].children = 'b'; | ||
assert(el.element.outerHTML === '<div><section></section></div>'); | ||
assert(el.element.firstElementChild!.shadowRoot!.innerHTML === '<p>b</p>'); | ||
}); | ||
@@ -430,0 +437,0 @@ |
@@ -1,5 +0,10 @@ | ||
import { Shadow, HTML, SVG, API, NS, shadow, frag, html, svg, text, element, define, defrag, listen, once, wait, bind, delegate, currentTarget, apply, identity } from '../../index'; | ||
import { API, Shadow, HTML, SVG, NS, shadow, frag, html, svg, text, element, define, defrag, listen, once, wait, bind, delegate, currentTarget, apply, identity } from '../..'; | ||
describe('Interface: Package', function () { | ||
describe('Typed', function () { | ||
it('API', function () { | ||
assert((): API<HTMLElementTagNameMap> => HTML); | ||
assert((): typeof HTML => API(html)); | ||
}); | ||
it('Shadow', function () { | ||
@@ -17,7 +22,2 @@ assert(typeof Shadow === 'function'); | ||
it('API', function () { | ||
assert((): API<HTMLElementTagNameMap> => HTML); | ||
assert((): typeof HTML => API(html)); | ||
}); | ||
}); | ||
@@ -24,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
656522
15506