UNPKG

@pictogrammers/element

Version:

Web Component Element for TypeScript

740 lines 106 kB
import './global.js'; import { Mutation, createProxy, addObserver, swapObserver, hasObserver, isProxy, getTarget } from './proxy.js'; class PropError extends Error { constructor(message, ignore) { super(message); this.name = 'PropError'; // @ts-ignore if (Error.captureStackTrace) { // @ts-ignore Error.captureStackTrace(this, ignore); } } } export const index = Symbol('index'); const init = Symbol('init'); const template = Symbol('template'); const style = Symbol('style'); const parent = Symbol('parent'); const renderList = Symbol('renderList'); export function getProxyValue(obj) { return obj[isProxy] && obj[getTarget]; } function extendTemplate(base, append) { if (append && append.match(/<parent\/>/)) { return append.replace(/<parent\/>/, base); } else if (base.match(/<child\/>/)) { return base.replace(/<child\/>/, append || ''); } else { return `${base}${append || ''}`; } } function camelToDash(str) { return str.replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase(); } function dashToCamel(str) { return str.replace(/-([a-z])/g, m => m[1].toUpperCase()); } export function Component(config = {}) { return function (cls, context) { if (context.kind !== 'class') { throw new Error('@Component() can only decorate a class'); } // webpack removes class names, override name Reflect.defineProperty(cls, 'name', { value: config.selector, writable: false, configurable: false, }); // ToDo: Clean up naming. cls is not used only render if (cls[parent]) { cls[parent] = [...cls[parent], cls]; if (cls.prototype.render) { cls[renderList] = [...cls[renderList], cls.prototype.render]; } if (config.style) { cls[style] = [...cls[style], config.style]; } cls[template] = extendTemplate(cls[parent][cls[parent].length - 1][template], config.template || null); } else if (cls.prototype instanceof HTMLElement) { cls[parent] = [cls]; cls[renderList] = cls.prototype.render ? [cls.prototype.render] : []; cls[style] = config.style ? [config.style] : []; cls[template] = config.template || ''; } else { throw new Error(`Must extend from HTMLElement`); } const connectedCallback = cls.prototype.connectedCallback || (() => { }); const disconnectedCallback = cls.prototype.disconnectedCallback || (() => { }); cls.prototype.connectedCallback = function () { if (!this[init] && config.template === undefined && config.style === undefined) { if (config.useShadow === false) { // Base class with no template } else { this.attachShadow({ mode: 'open' }); } } else if (!this[init]) { if (config.useShadow === false) { throw new Error('unsupported'); } else { const $template = document.createElement('template'); $template.innerHTML = cls[template] || ''; const $node = document.importNode($template.content, true); const shadowRoot = this.attachShadow({ mode: 'open' }); shadowRoot.adoptedStyleSheets = cls[style].reduce((acc, value) => { if (!value) { return acc; } if (value instanceof CSSStyleSheet) { acc.push(value); return acc; } var s = new CSSStyleSheet(); s.replaceSync(value.toString()); acc.push(s); return acc; }, []); shadowRoot.appendChild($node); } } else if (this[init] && config.style) { /*if (this.shadowRoot) { const style = document.createElement('style'); style.appendChild(document.createTextNode(config.style)); this.appendChild(style); }*/ // } else if (this[init] && config.template) { // This is allowed now via <parent/> // throw new Error('template from base class cannot be overriden. Fix: remove template from @Component'); } else if (this[init] && config.selector && !config.template) { throw new Error('You need to pass a template for an extended element.'); } const tags = new Set(); for (const ele of this.shadowRoot.querySelectorAll('*')) { if (ele.localName.indexOf('-') !== -1) { tags.add(ele.localName); } } const promises = Array.from(tags.values()).map(tag => { return customElements.get(tag) ? Promise.resolve() : customElements.whenDefined(tag); }); const render = () => { this.constructor[renderList].map((renderFn) => { renderFn.call(this, cls.observedAttributes ? cls.observedAttributes.reduce((a, c) => { const n = dashToCamel(c); a[n] = true; return a; }, {}) : {}); }); }; if (promises.length === 0) { this[init] = true; connectedCallback.call(this); render(); } else { Promise.all(promises).then(() => { this[init] = true; connectedCallback.call(this); // dispatch slotchange for (const slot of this.shadowRoot.querySelectorAll('slot')) { slot.dispatchEvent(new CustomEvent('slotchange')); } render(); }); } }; cls.prototype.disconnectedCallback = function () { disconnectedCallback.call(this); }; cls.prototype.attributeChangedCallback = function (name, oldValue, newValue) { const normalizedName = dashToCamel(name); this[normalizedName] = newValue; }; // Base components may not define a selector context.addInitializer(function () { if (config.selector) { if (window.customElements.get(config.selector)) { throw new Error(`@Component() ${context.name} duplicate selector '${config.selector}'`); } window.customElements.define(config.selector, cls); } }); }; } const transmute = Symbol('transmute'); export function TransmutePart(part, selector) { return function (cls) { if (cls.prototype[transmute]) { cls.prototype[transmute][part] = selector; } else { cls.prototype[transmute] = { [part]: selector }; } }; } function isArray(a) { return (!!a) && (a.constructor === Array); } function isObject(a) { return (!!a) && (a.constructor === Object); } function render(self, propertyKey) { if (self[init]) { self.constructor[renderList].map((renderFn) => { renderFn.call(self, { [propertyKey]: true }); }); } } function getSymbolType(value) { if (value === null) { return 'null'; } return isArray(value) ? 'array' : typeof value; } export function Prop(normalize) { return function (_, context) { const propertyKey = context.name; const symbol = Symbol(propertyKey); const symbolType = Symbol(`${propertyKey}:type`); const symbolMeta = Symbol(`${propertyKey}:meta`); context.addInitializer(function () { if (context.private) { return; } Reflect.defineProperty(this, propertyKey, { get: () => { if (this[symbolType] === 'object') { if (this[symbol][isProxy]) { return this[symbol]; } else { return createProxy(this[symbol]); } } if (this[symbolType] === 'array') { if (this[symbol][isProxy]) { return this[symbol]; } else { return createProxy(this[symbol]); } } return this[symbol]; }, set: (value) => { // ToDo: cleanup const newSymbolType = getSymbolType(normalize ? normalize(value) : value); if (propertyKey !== 'index' && this[symbolType] !== newSymbolType && this[symbolType] !== 'null' && newSymbolType !== 'null') { throw new Error(`@Prop() ${propertyKey} with type '${this[symbolType]}' cannot be set to ${newSymbolType}.`); } if (this[symbolType] === 'array') { if (!isArray(value)) { throw new PropError(`Array "${propertyKey}" (Prop) initialized already. Reassignments must be array type.`, Object.getOwnPropertyDescriptor(this, propertyKey)?.set); } if (this[symbol] === value) { throw new Error('Setting an array to itself is not allowed.'); } const proxified = createProxy(this[symbol]); if (proxified[hasObserver](this)) { const unproxyValue = value[isProxy] ? value[getTarget] : value; proxified[swapObserver](this, unproxyValue); this[symbol] = value; // render(this, propertyKey); // do we need to trigger this for arrays being remapped? } else { this[symbol] = value; } } else { this[symbol] = normalize ? normalize(value) : value; render(this, propertyKey); } } }); }); return function (initialValue) { if (initialValue === undefined && propertyKey !== 'index') { throw new Error(`@Prop() ${propertyKey} must have an initial value defined.`); } else if (initialValue !== undefined && propertyKey === 'index') { throw new Error(`@Prop() index must not have an initial value defined.`); } if (initialValue === true) { throw new Error(`@Prop() ${propertyKey} boolean must initialize to false.`); } // Web Component, todo: refactor to only be called once if (!context.private) { const { constructor } = this; constructor.observedAttributes ??= []; if (!constructor.symbols) { constructor.symbols = {}; } const { symbols } = constructor; const normalizedPropertyKey = camelToDash(propertyKey); if (!symbols[propertyKey]) { constructor.observedAttributes.push(normalizedPropertyKey); symbols[propertyKey] = symbol; } } // Rest this[symbolType] = getSymbolType(initialValue); if (this[symbolType] === 'array') { this[symbol] = initialValue; if (context.private) { return createProxy(initialValue); } return new Proxy(initialValue, { get: (target, key) => { if (key === meta) { return this[symbolMeta]; } return Reflect.get(this[symbol], key); }, set: (target, key, v) => { if (key === meta) { this[symbolMeta] = v; return true; } const x = Reflect.set(target, key, v); if (!(key === 'length' && this[symbol].length === v)) { render(this, propertyKey); } this[symbol] = v; return x; } }); } // todo watch objects??? if (context.private) { this[symbol] = normalize ? normalize(initialValue) : initialValue; return this[symbol]; } this[symbol] = normalize ? normalize(this.getAttribute(propertyKey) ?? initialValue) : this.getAttribute(propertyKey) ?? initialValue; return this[symbol]; }; }; } export function Part() { return function (_, context) { const propertyKey = context.name; const key = propertyKey.replace(/^\$/, ''); context.addInitializer(function () { let cache = null; Reflect.defineProperty(this, propertyKey, { get() { return cache ?? (cache = this.shadowRoot?.querySelector(`[part~=${key}]`)); } }); }); }; } /** * Store data via a Map into LocalStorage * @param key String * @returns Value */ export function Local(key) { return function (_, context) { const propertyKey = context.name; return function (initialValue) { if (!(initialValue instanceof Map)) { throw new Error('@Local(key) property must be type Map'); } return new Proxy(initialValue, { get(target, prop) { switch (prop) { case 'get': return (k) => { if (!initialValue.has(k)) { throw new Error(`@Local(key) missing key ${k}`); } const storeKey = `${key}:${k}`; if (window.localStorage.getItem(storeKey) === null) { const keyValue = initialValue.get(k); return Array.isArray(keyValue) || isObject(keyValue) ? JSON.parse(JSON.stringify(keyValue)) : keyValue; } else { return JSON.parse(window.localStorage.getItem(storeKey) ?? 'null'); } }; case 'set': return (k, v) => { if (!initialValue.has(k)) { throw new Error(`@Local(key) missing key ${k}`); } const storeKey = `${key}:${k}`; if (v === null || JSON.stringify(v) === JSON.stringify(initialValue.get(k))) { window.localStorage.removeItem(storeKey); } else { window.localStorage.setItem(storeKey, JSON.stringify(v)); } }; default: throw new Error(`@Local(key) supported method ${prop}`); } } }); }; }; } export function node(template, init) { const $template = document.createElement('template'); $template.innerHTML = template; const $node = document.importNode($template.content, true); for (const [part, attributes] of Object.entries(init)) { const $part = $node.querySelector(`[part~="${part}"]`); if ($part) { for (const [prop, value] of Object.entries(attributes)) { if (value instanceof Function) { const val = value(); if (val === null) { $part.removeAttribute(prop); } else { $part.setAttribute(prop, value()); } } else { $part[prop] = value; } } } } return $node; } export function normalizeInt(value) { return parseInt(`${value}`, 10); } export function normalizeFloat(value) { return parseFloat(`${value}`); } export function normalizeBoolean(value) { return value === '' || value === true ? true : value === null || value === false ? false : value || true; } export function normalizeString(value) { return `${value}`; } const trackProxy = Symbol('hasProxy'); function hasProxy(obj) { if (obj === null || typeof obj !== "object") return false; return obj[trackProxy]; } const meta = Symbol('meta'); function intersect(arr1, arr2) { const set1 = new Set(arr1); return arr2.filter(item => set1.has(item)); } function difference(arr1, arr2) { return arr1.filter(str => !arr2.includes(str)); } const PROP_ALIAS = { id: 'itemId' }; function mapPropKey(key, allProps) { const alias = PROP_ALIAS[key]; return alias && allProps.includes(alias) ? alias : key; } export function forEach({ container, items, type, create, connect, disconnect, update }) { if (!Array.isArray(items)) { throw new Error('forEach `items` must be an array'); } const elementMap = new WeakMap(); // Tracks raw item objects in items-array order; used to recover pre-mutation state. const localItems = []; function raw(item) { return item && item[isProxy] ? item[getTarget] : item; } function isRendered(rawItem) { return elementMap.has(rawItem); } function renderedCountBefore(logicalIndex) { let count = 0; for (let i = 0; i < logicalIndex && i < localItems.length; i++) { if (isRendered(localItems[i])) count++; } return count; } function newItem(item, domIndex) { const comp = type(item); if (comp === null) return null; const $new = document.createElement(camelToDash(comp.name), comp); const allProps = Object.keys(comp.symbols); const props = intersect(Object.keys(item), allProps); if (allProps.includes('index')) { //@ts-ignore $new['index'] = domIndex; } props.forEach((attr) => { // index is already written if (attr === 'index') { return; } //@ts-ignore $new[attr] = item[attr]; }); // Apply prop aliases (e.g., data `id` → component `itemId`) when not already set above for (const [dataKey, compKey] of Object.entries(PROP_ALIAS)) { if (dataKey in item && allProps.includes(compKey) && !props.includes(compKey)) { //@ts-ignore $new[compKey] = item[dataKey]; } } const rawItem = raw(item); create && create($new, createProxy(rawItem)); createProxy(rawItem)[addObserver]($new, (prop, value) => { // @ts-ignore $new[mapPropKey(prop, allProps)] = value; }); elementMap.set(rawItem, $new); return $new; } // Add initial items let initDomIndex = 0; items.forEach((item) => { const rawItem = raw(item); localItems.push(rawItem); const $new = newItem(item, initDomIndex); if ($new === null) return; container.appendChild($new); connect && connect($new, createProxy(rawItem)); initDomIndex++; }); // Handle each mutation items[addObserver](container, (target, prop, args) => { if (prop === Mutation.swap) { const oldLength = localItems.length; items = createProxy(args[0]); // re-use splice to delete old nodes and add new ones (performance?) prop = Mutation.splice; args = [0, oldLength, ...args[0]]; } switch (prop) { case Mutation.fill: { const [value, start, end] = args; const fillStart = start || 0; const fillEnd = end || localItems.length; let domFillIdx = renderedCountBefore(fillStart); for (let i = fillStart; i < fillEnd; i++) { if (isRendered(localItems[i])) { const $child = container.children[domFillIdx]; const childAllProps = Object.keys($child.constructor?.symbols ?? {}); Object.keys(value).forEach((key) => { // @ts-ignore $child[mapPropKey(key, childAllProps)] = value[key]; }); domFillIdx++; } localItems[i] = value; } break; } case Mutation.pop: { const poppedRaw = localItems[localItems.length - 1]; if (poppedRaw !== undefined && isRendered(poppedRaw)) { const $el = elementMap.get(poppedRaw); disconnect && disconnect($el, createProxy(poppedRaw)); $el.remove(); elementMap.delete(poppedRaw); } localItems.pop(); break; } case Mutation.push: { [...args].forEach((item) => { const rawItem = raw(item); localItems.push(rawItem); const $new = newItem(item, container.children.length); if ($new === null) return; container.appendChild($new); connect && connect($new, createProxy(rawItem)); }); break; } case Mutation.reverse: { for (var i = 1; i < container.children.length; i++) { container.insertBefore(container.children[i], container.children[0]); } localItems.reverse(); break; } case Mutation.shift: { const shiftedRaw = localItems[0]; if (shiftedRaw !== undefined && isRendered(shiftedRaw)) { const $el = elementMap.get(shiftedRaw); disconnect && disconnect($el, createProxy(shiftedRaw)); $el.remove(); elementMap.delete(shiftedRaw); } localItems.shift(); for (let i = 0; i < container.children.length; i++) { // @ts-ignore container.children[i].index = i; } break; } case Mutation.sort: { target.forEach((item) => { const rawItem = raw(item); const $el = elementMap.get(rawItem); if ($el) container.appendChild($el); }); for (let i = 0; i < container.children.length; i++) { // @ts-ignore container.children[i].index = i; } localItems.length = 0; target.forEach((item) => localItems.push(raw(item))); break; } case Mutation.splice: { const [startIndex, deleteCount, ...newItems] = args; if (startIndex < 0) { throw new Error('invalid startIndex, must be greater than or equal to 0'); } // Determine the DOM insertion/deletion point by counting rendered items before startIndex. const domStart = renderedCountBefore(startIndex); // Remove deleted items from DOM (always remove at domStart since children shift up). const deletedRaws = localItems.slice(startIndex, startIndex + deleteCount); deletedRaws.forEach((rawItem) => { if (isRendered(rawItem)) { const $el = elementMap.get(rawItem); disconnect && disconnect($el, createProxy(rawItem)); $el.remove(); elementMap.delete(rawItem); } }); // Create elements for new items, skipping null-typed ones. const nItems = []; newItems.forEach((item) => { const $new = newItem(item, domStart + nItems.length); if ($new !== null) nItems.push($new); }); if (nItems.length > 0) { if (domStart === 0) { container.prepend(...nItems); } else { container.children[domStart - 1].after(...nItems); } } // Update indices for all items from the insertion point onward. for (let i = domStart; i < container.children.length; i++) { // @ts-ignore container.children[i].index = i; } // Fire connect for each newly rendered item. let nIdx = 0; newItems.forEach((item) => { const rawItem = raw(item); if (isRendered(rawItem)) { connect && connect(nItems[nIdx++], createProxy(rawItem)); } }); localItems.splice(startIndex, deleteCount, ...newItems.map(raw)); break; } case Mutation.unshift: { const unshiftItems = [...args]; const firstChild = container.children.length ? container.children[0] : null; const nItems = []; unshiftItems.forEach((item) => { const $new = newItem(item, nItems.length); if ($new !== null) nItems.push($new); }); if (nItems.length > 0) { if (firstChild) { firstChild.before(...nItems); } else { container.append(...nItems); } } // Update indices for all items (new ones first, then existing). for (let i = 0; i < container.children.length; i++) { // @ts-ignore container.children[i].index = i; } localItems.unshift(...unshiftItems.map(raw)); // Fire connect for each newly rendered item. let nIdx = 0; unshiftItems.forEach((item) => { const rawItem = raw(item); if (isRendered(rawItem)) { connect && connect(nItems[nIdx++], createProxy(rawItem)); } }); break; } } }); } // JEST export function selectComponent(tagName) { const component = document.querySelector(tagName); const tags = new Set(); let shadowRoot; try { shadowRoot = component.shadowRoot; } catch (error) { throw new Error('Add the component via document.body.appendChild(...) before selectComponent.'); } for (const ele of shadowRoot.querySelectorAll('*')) { if (ele.localName.indexOf('-') !== -1) { tags.add(ele.localName); } } for (var it = tags.values(), tag = null; tag = it.next().value;) { if (!customElements.get(tag)) { const namespaceMatch = tag.match(/^([^-]+)/); if (namespaceMatch === null || namespaceMatch.length > 1) { throw new Error('Failed to parse namespace.'); } const namespace = namespaceMatch[1]; const componentMatch = tag.match(/^[^-]+-(.+)/); if (componentMatch === null || componentMatch.length > 1) { throw new Error('Failed to parse component name.'); } const componentName = dashToCamel(componentMatch[1]); throw new Error(`Missing \`import '../${componentName}/${componentName}';\` in spec.ts file.`); } } return component; } export function selectPart(component, name) { return component.shadowRoot.querySelector(`[part=${name}]`); } export function getProps(tag) { const { symbols } = customElements.get(tag); return Object.keys(symbols ?? {}); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlbWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9lbGVtZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFDTCxRQUFRLEVBQ1IsV0FBVyxFQUNYLFdBQVcsRUFFWCxZQUFZLEVBQ1osV0FBVyxFQUNYLE9BQU8sRUFDUCxTQUFTLEVBQ1YsTUFBTSxZQUFZLENBQUM7QUFjcEIsTUFBTSxTQUFVLFNBQVEsS0FBSztJQUMzQixZQUFZLE9BQWUsRUFBRSxNQUFXO1FBQ3RDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDO1FBQ3hCLGFBQWE7UUFDYixJQUFJLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzVCLGFBQWE7WUFDYixLQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3hDLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFFRCxNQUFNLENBQUMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3JDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM1QixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDcEMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzlCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNoQyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7QUFFeEMsTUFBTSxVQUFVLGFBQWEsQ0FBQyxHQUFRO0lBQ3BDLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUN4QyxDQUFDO0FBRUQsU0FBUyxjQUFjLENBQUMsSUFBWSxFQUFFLE1B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