@pictogrammers/element
Version:
Web Component Element for TypeScript
740 lines • 106 kB
JavaScript
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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