feat: Reinitialize frontend with SvelteKit and TypeScript

- Delete old Vite+Svelte frontend
- Initialize new SvelteKit project with TypeScript
- Configure Tailwind CSS v4 + DaisyUI
- Implement JWT authentication with auto-refresh
- Create login page with form validation (Zod)
- Add protected route guards
- Update Docker configuration for single-stage build
- Add E2E tests with Playwright (6/11 passing)
- Fix Svelte 5 reactivity with $state() runes

Known issues:
- 5 E2E tests failing (timing/async issues)
- Token refresh implementation needs debugging
- Validation error display timing
This commit is contained in:
2026-02-17 16:19:59 -05:00
parent 54df6018f5
commit de2d83092e
28274 changed files with 3816354 additions and 90 deletions

View File

@@ -0,0 +1,114 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const PropertySymbol = __importStar(require("../PropertySymbol.cjs"));
const WindowBrowserContext_js_1 = __importDefault(require("../window/WindowBrowserContext.cjs"));
/**
* Custom element reaction stack.
*
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-reactions-stack
*/
class CustomElementReactionStack {
window;
/**
* Constructor.
*
* @param window Window.
*/
constructor(window) {
this.window = window;
}
/**
* Enqueues a custom element reaction.
*
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#enqueue-a-custom-element-callback-reaction
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#enqueue-an-element-on-the-appropriate-element-queue
* @param element Element.
* @param callbackName Callback name.
* @param [args] Arguments.
*/
enqueueReaction(element, callbackName, args) {
// If a polyfill is used, [PropertySymbol.registry] may be undefined
const definition = this.window.customElements[PropertySymbol.registry]?.get(element.localName);
if (!definition) {
return;
}
// If the element is not connected to the main document, we should not invoke the callback.
if (element[PropertySymbol.ownerDocument] !== this.window.document) {
return;
}
// According to the spec, we should use a queue for each element and then invoke the reactions in the order they were enqueued asynchronously.
// However, the browser seem to always invoke the reactions synchronously.
// TODO: Can we find an example where the reactions are invoked asynchronously? In that case we should use a queue for those cases.
switch (callbackName) {
case 'connectedCallback':
if (definition.livecycleCallbacks.connectedCallback) {
const returnValue = definition.livecycleCallbacks.connectedCallback.call(element);
/**
* It is common to import dependencies in the connectedCallback() method of web components.
* As Happy DOM doesn't have support for dynamic imports yet, this is a temporary solution to wait for imports in connectedCallback().
*
* @see https://github.com/capricorn86/happy-dom/issues/1442
*/
if (returnValue instanceof Promise) {
const asyncTaskManager = new WindowBrowserContext_js_1.default(this.window).getAsyncTaskManager();
if (asyncTaskManager) {
const taskID = asyncTaskManager.startTask();
returnValue
.then(() => asyncTaskManager.endTask(taskID))
.catch(() => asyncTaskManager.endTask(taskID));
}
}
}
break;
case 'disconnectedCallback':
if (definition.livecycleCallbacks.disconnectedCallback) {
definition.livecycleCallbacks.disconnectedCallback.call(element);
}
break;
case 'attributeChangedCallback':
if (definition.livecycleCallbacks.attributeChangedCallback &&
definition.observedAttributes.has(args[0])) {
definition.livecycleCallbacks.attributeChangedCallback.apply(element, args);
}
break;
}
}
}
exports.default = CustomElementReactionStack;
//# sourceMappingURL=CustomElementReactionStack.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CustomElementReactionStack.cjs","sourceRoot":"","sources":["../../src/custom-element/CustomElementReactionStack.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,qEAAuD;AACvD,gGAAqE;AAGrE;;;;GAIG;AACH,MAAqB,0BAA0B;IACtC,MAAM,CAAgB;IAE9B;;;;OAIG;IACH,YAAY,MAAqB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED;;;;;;;;OAQG;IACI,eAAe,CAAC,OAAgB,EAAE,YAAoB,EAAE,IAAY;QAC1E,oEAAoE;QACpE,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAE/F,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,OAAO;QACR,CAAC;QAED,2FAA2F;QAC3F,IAAI,OAAO,CAAC,cAAc,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpE,OAAO;QACR,CAAC;QAED,8IAA8I;QAC9I,0EAA0E;QAC1E,mIAAmI;QAEnI,QAAQ,YAAY,EAAE,CAAC;YACtB,KAAK,mBAAmB;gBACvB,IAAI,UAAU,CAAC,kBAAkB,CAAC,iBAAiB,EAAE,CAAC;oBACrD,MAAM,WAAW,GAAG,UAAU,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAElF;;;;;uBAKG;oBACH,IAAI,WAAW,YAAY,OAAO,EAAE,CAAC;wBACpC,MAAM,gBAAgB,GAAG,IAAI,iCAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,mBAAmB,EAAE,CAAC;wBACrF,IAAI,gBAAgB,EAAE,CAAC;4BACtB,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,EAAE,CAAC;4BAC5C,WAAW;iCACT,IAAI,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;iCAC5C,KAAK,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;wBACjD,CAAC;oBACF,CAAC;gBACF,CAAC;gBACD,MAAM;YACP,KAAK,sBAAsB;gBAC1B,IAAI,UAAU,CAAC,kBAAkB,CAAC,oBAAoB,EAAE,CAAC;oBACxD,UAAU,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAClE,CAAC;gBACD,MAAM;YACP,KAAK,0BAA0B;gBAC9B,IACC,UAAU,CAAC,kBAAkB,CAAC,wBAAwB;oBACtD,UAAU,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EACzC,CAAC;oBACF,UAAU,CAAC,kBAAkB,CAAC,wBAAwB,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC7E,CAAC;gBACD,MAAM;QACR,CAAC;IACF,CAAC;CACD;AA3ED,6CA2EC"}

View File

@@ -0,0 +1,27 @@
import BrowserWindow from '../window/BrowserWindow.cjs';
import Element from '../nodes/element/Element.cjs';
/**
* Custom element reaction stack.
*
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-reactions-stack
*/
export default class CustomElementReactionStack {
private window;
/**
* Constructor.
*
* @param window Window.
*/
constructor(window: BrowserWindow);
/**
* Enqueues a custom element reaction.
*
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#enqueue-a-custom-element-callback-reaction
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#enqueue-an-element-on-the-appropriate-element-queue
* @param element Element.
* @param callbackName Callback name.
* @param [args] Arguments.
*/
enqueueReaction(element: Element, callbackName: string, args?: any[]): void;
}
//# sourceMappingURL=CustomElementReactionStack.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CustomElementReactionStack.d.ts","sourceRoot":"","sources":["../../src/custom-element/CustomElementReactionStack.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,4BAA4B,CAAC;AAGvD,OAAO,OAAO,MAAM,6BAA6B,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,0BAA0B;IAC9C,OAAO,CAAC,MAAM,CAAgB;IAE9B;;;;OAIG;gBACS,MAAM,EAAE,aAAa;IAIjC;;;;;;;;OAQG;IACI,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI;CAsDlF"}

View File

@@ -0,0 +1,188 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const PropertySymbol = __importStar(require("../PropertySymbol.cjs"));
const NamespaceURI_js_1 = __importDefault(require("../config/NamespaceURI.cjs"));
const StringUtility_js_1 = __importDefault(require("../utilities/StringUtility.cjs"));
const CustomElementUtility_js_1 = __importDefault(require("./CustomElementUtility.cjs"));
/**
* Custom elements registry.
*/
class CustomElementRegistry {
[PropertySymbol.registry] = new Map();
[PropertySymbol.classRegistry] = new Map();
[PropertySymbol.callbacks] = new Map();
[PropertySymbol.destroyed] = false;
#window;
/**
* Constructor.
*
* @param window Window.
*/
constructor(window) {
if (!window) {
throw new TypeError('Illegal constructor');
}
this.#window = window;
}
/**
* Defines a custom element class.
*
* @param name Tag name of element.
* @param elementClass Element class.
* @param [options] Options.
* @param [options.extends] Extends tag name.
*/
define(name, elementClass, options) {
if (this[PropertySymbol.destroyed]) {
return;
}
if (!CustomElementUtility_js_1.default.isValidCustomElementName(name)) {
throw new this.#window.DOMException(`Failed to execute 'define' on 'CustomElementRegistry': "${name}" is not a valid custom element name`);
}
if (this[PropertySymbol.registry].has(name)) {
throw new this.#window.DOMException(`Failed to execute 'define' on 'CustomElementRegistry': the name "${name}" has already been used with this registry`);
}
if (this[PropertySymbol.classRegistry].has(elementClass)) {
throw new this.#window.DOMException("Failed to execute 'define' on 'CustomElementRegistry': this constructor has already been used with this registry");
}
const tagName = StringUtility_js_1.default.asciiUpperCase(name);
elementClass.prototype[PropertySymbol.window] = this.#window;
elementClass.prototype[PropertySymbol.ownerDocument] = this.#window.document;
elementClass.prototype[PropertySymbol.tagName] = tagName;
elementClass.prototype[PropertySymbol.localName] = name;
elementClass.prototype[PropertySymbol.namespaceURI] = NamespaceURI_js_1.default.html;
// ObservedAttributes should only be called once by CustomElementRegistry (see #117)
const observedAttributes = new Set();
const elementObservervedAttributes = elementClass.observedAttributes;
if (Array.isArray(elementObservervedAttributes)) {
for (const attribute of elementObservervedAttributes) {
observedAttributes.add(String(attribute).toLowerCase());
}
}
this[PropertySymbol.registry].set(name, {
elementClass,
extends: options && options.extends ? options.extends.toLowerCase() : null,
observedAttributes,
livecycleCallbacks: {
connectedCallback: elementClass.prototype.connectedCallback,
disconnectedCallback: elementClass.prototype.disconnectedCallback,
attributeChangedCallback: elementClass.prototype.attributeChangedCallback
}
});
this[PropertySymbol.classRegistry].set(elementClass, name);
const callbacks = this[PropertySymbol.callbacks].get(name);
if (callbacks) {
this[PropertySymbol.callbacks].delete(name);
for (const callback of callbacks) {
callback();
}
}
}
/**
* Returns a defined element class.
*
* @param name Tag name of element.
* @returns HTMLElement Class defined or undefined.
*/
get(name) {
return this[PropertySymbol.registry].get(name)?.elementClass;
}
/**
* Upgrades a custom element directly, even before it is connected to its shadow root.
*
* Not implemented yet.
*
* @param _root Root node.
*/
upgrade(_root) {
// Do nothing
}
/**
* When defined.
*
* @param name Tag name of element.
*/
whenDefined(name) {
if (this[PropertySymbol.destroyed]) {
return Promise.reject(new this.#window.DOMException(`Failed to execute 'whenDefined' on 'CustomElementRegistry': The custom element registry has been destroyed.`));
}
if (!CustomElementUtility_js_1.default.isValidCustomElementName(name)) {
return Promise.reject(new this.#window.DOMException(`Failed to execute 'whenDefined' on 'CustomElementRegistry': Invalid custom element name: "${name}"`));
}
if (this.get(name)) {
return Promise.resolve();
}
return new Promise((resolve) => {
const callbacks = this[PropertySymbol.callbacks].get(name);
if (callbacks) {
callbacks.push(resolve);
}
else {
this[PropertySymbol.callbacks].set(name, [resolve]);
}
});
}
/**
* Reverse lookup searching for name by given element class.
*
* @param elementClass Class constructor.
* @returns Found tag name or `null`.
*/
getName(elementClass) {
return this[PropertySymbol.classRegistry].get(elementClass) || null;
}
/**
* Destroys the registry.
*/
[PropertySymbol.destroy]() {
this[PropertySymbol.destroyed] = true;
for (const definition of this[PropertySymbol.registry].values()) {
definition.elementClass.prototype[PropertySymbol.window] = null;
definition.elementClass.prototype[PropertySymbol.ownerDocument] = null;
definition.elementClass.prototype[PropertySymbol.tagName] = null;
definition.elementClass.prototype[PropertySymbol.localName] = null;
definition.elementClass.prototype[PropertySymbol.namespaceURI] = null;
}
this[PropertySymbol.registry] = new Map();
this[PropertySymbol.classRegistry] = new Map();
this[PropertySymbol.callbacks] = new Map();
}
}
exports.default = CustomElementRegistry;
//# sourceMappingURL=CustomElementRegistry.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CustomElementRegistry.cjs","sourceRoot":"","sources":["../../src/custom-element/CustomElementRegistry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qEAAuD;AAIvD,gFAAqD;AACrD,qFAA0D;AAC1D,wFAA6D;AAG7D;;GAEG;AACH,MAAqB,qBAAqB;IAClC,CAAC,cAAc,CAAC,QAAQ,CAAC,GAA0C,IAAI,GAAG,EAAE,CAAC;IAC7E,CAAC,cAAc,CAAC,aAAa,CAAC,GAAoC,IAAI,GAAG,EAAE,CAAC;IAC5E,CAAC,cAAc,CAAC,SAAS,CAAC,GAAmC,IAAI,GAAG,EAAE,CAAC;IACvE,CAAC,cAAc,CAAC,SAAS,CAAC,GAAY,KAAK,CAAC;IACnD,OAAO,CAAgB;IAEvB;;;;OAIG;IACH,YAAY,MAAqB;QAChC,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CACZ,IAAY,EACZ,YAAgC,EAChC,OAA8B;QAE9B,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,OAAO;QACR,CAAC;QAED,IAAI,CAAC,iCAAoB,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1D,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,CAClC,2DAA2D,IAAI,sCAAsC,CACrG,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,CAClC,oEAAoE,IAAI,4CAA4C,CACpH,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YAC1D,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,CAClC,kHAAkH,CAClH,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAAG,0BAAa,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAEnD,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7D,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC7E,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;QACzD,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;QACxD,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,YAAY,CAAC,GAAG,yBAAY,CAAC,IAAI,CAAC;QAExE,oFAAoF;QACpF,MAAM,kBAAkB,GAAgB,IAAI,GAAG,EAAE,CAAC;QAClD,MAAM,4BAA4B,GAAG,YAAY,CAAC,kBAAkB,CAAC;QAErE,IAAI,KAAK,CAAC,OAAO,CAAC,4BAA4B,CAAC,EAAE,CAAC;YACjD,KAAK,MAAM,SAAS,IAAI,4BAA4B,EAAE,CAAC;gBACtD,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YACzD,CAAC;QACF,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE;YACvC,YAAY;YACZ,OAAO,EAAE,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI;YAC1E,kBAAkB;YAClB,kBAAkB,EAAE;gBACnB,iBAAiB,EAAE,YAAY,CAAC,SAAS,CAAC,iBAAiB;gBAC3D,oBAAoB,EAAE,YAAY,CAAC,SAAS,CAAC,oBAAoB;gBACjE,wBAAwB,EAAE,YAAY,CAAC,SAAS,CAAC,wBAAwB;aACzE;SACD,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAE3D,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBAClC,QAAQ,EAAE,CAAC;YACZ,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACI,GAAG,CAAC,IAAY;QACtB,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;IAC9D,CAAC;IAED;;;;;;OAMG;IACI,OAAO,CAAC,KAAW;QACzB,aAAa;IACd,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,IAAY;QAC9B,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,OAAO,OAAO,CAAC,MAAM,CACpB,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,CAC5B,6GAA6G,CAC7G,CACD,CAAC;QACH,CAAC;QACD,IAAI,CAAC,iCAAoB,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1D,OAAO,OAAO,CAAC,MAAM,CACpB,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,CAC5B,6FAA6F,IAAI,GAAG,CACpG,CACD,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC9B,MAAM,SAAS,GAAsB,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9E,IAAI,SAAS,EAAE,CAAC;gBACf,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACP,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;YACrD,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACI,OAAO,CAAC,YAAgC;QAC9C,OAAO,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC;IACrE,CAAC;IAED;;OAEG;IACI,CAAC,cAAc,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;QACtC,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YACjE,UAAU,CAAC,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;YAChE,UAAU,CAAC,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;YACvE,UAAU,CAAC,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;YACjE,UAAU,CAAC,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;YACnE,UAAU,CAAC,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;QACvE,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;QAC1C,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;QAC/C,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;IAC5C,CAAC;CACD;AA7KD,wCA6KC"}

View File

@@ -0,0 +1,65 @@
import * as PropertySymbol from '../PropertySymbol.cjs';
import HTMLElement from '../nodes/html-element/HTMLElement.cjs';
import Node from '../nodes/node/Node.cjs';
import BrowserWindow from '../window/BrowserWindow.cjs';
import ICustomElementDefinition from './ICustomElementDefinition.cjs';
/**
* Custom elements registry.
*/
export default class CustomElementRegistry {
#private;
[PropertySymbol.registry]: Map<string, ICustomElementDefinition>;
[PropertySymbol.classRegistry]: Map<typeof HTMLElement, string>;
[PropertySymbol.callbacks]: Map<string, Array<() => void>>;
[PropertySymbol.destroyed]: boolean;
/**
* Constructor.
*
* @param window Window.
*/
constructor(window: BrowserWindow);
/**
* Defines a custom element class.
*
* @param name Tag name of element.
* @param elementClass Element class.
* @param [options] Options.
* @param [options.extends] Extends tag name.
*/
define(name: string, elementClass: typeof HTMLElement, options?: {
extends?: string;
}): void;
/**
* Returns a defined element class.
*
* @param name Tag name of element.
* @returns HTMLElement Class defined or undefined.
*/
get(name: string): typeof HTMLElement | undefined;
/**
* Upgrades a custom element directly, even before it is connected to its shadow root.
*
* Not implemented yet.
*
* @param _root Root node.
*/
upgrade(_root: Node): void;
/**
* When defined.
*
* @param name Tag name of element.
*/
whenDefined(name: string): Promise<void>;
/**
* Reverse lookup searching for name by given element class.
*
* @param elementClass Class constructor.
* @returns Found tag name or `null`.
*/
getName(elementClass: typeof HTMLElement): string | null;
/**
* Destroys the registry.
*/
[PropertySymbol.destroy](): void;
}
//# sourceMappingURL=CustomElementRegistry.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CustomElementRegistry.d.ts","sourceRoot":"","sources":["../../src/custom-element/CustomElementRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,WAAW,MAAM,sCAAsC,CAAC;AAC/D,OAAO,IAAI,MAAM,uBAAuB,CAAC;AACzC,OAAO,aAAa,MAAM,4BAA4B,CAAC;AAIvD,OAAO,wBAAwB,MAAM,+BAA+B,CAAC;AAErE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAqB;;IAClC,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAa;IAC7E,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,OAAO,WAAW,EAAE,MAAM,CAAC,CAAa;IAC5E,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAa;IACvE,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,OAAO,CAAS;IAGnD;;;;OAIG;gBACS,MAAM,EAAE,aAAa;IAOjC;;;;;;;OAOG;IACI,MAAM,CACZ,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,OAAO,WAAW,EAChC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5B,IAAI;IA8DP;;;;;OAKG;IACI,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,WAAW,GAAG,SAAS;IAIxD;;;;;;OAMG;IACI,OAAO,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI;IAIjC;;;;OAIG;IACI,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4B/C;;;;;OAKG;IACI,OAAO,CAAC,YAAY,EAAE,OAAO,WAAW,GAAG,MAAM,GAAG,IAAI;IAI/D;;OAEG;IACI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,IAAI;CAavC"}

View File

@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const PCEN_CHAR = '[-_.]|[0-9]|[a-z]|\u{B7}|[\u{C0}-\u{D6}]|[\u{D8}-\u{F6}]' +
'|[\u{F8}-\u{37D}]|[\u{37F}-\u{1FFF}]' +
'|[\u{200C}-\u{200D}]|[\u{203F}-\u{2040}]|[\u{2070}-\u{218F}]' +
'|[\u{2C00}-\u{2FEF}]|[\u{3001}-\u{D7FF}]' +
'|[\u{F900}-\u{FDCF}]|[\u{FDF0}-\u{FFFD}]|[\u{10000}-\u{EFFFF}]';
const PCEN_REGEXP = new RegExp(`^[a-z](${PCEN_CHAR})*-(${PCEN_CHAR})*$`, 'u');
const RESERVED_NAMES = [
'annotation-xml',
'color-profile',
'font-face',
'font-face-src',
'font-face-uri',
'font-face-format',
'font-face-name',
'missing-glyph'
];
/**
* Custom element utility.
*/
class CustomElementUtility {
/**
* Returns true if the tag name is a valid custom element name.
*
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
* @param name Tag name.
* @returns True if valid.
*/
static isValidCustomElementName(name) {
return PCEN_REGEXP.test(name) && !RESERVED_NAMES.includes(name);
}
}
exports.default = CustomElementUtility;
//# sourceMappingURL=CustomElementUtility.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CustomElementUtility.cjs","sourceRoot":"","sources":["../../src/custom-element/CustomElementUtility.ts"],"names":[],"mappings":";;AAAA,MAAM,SAAS,GACd,0DAA0D;IAC1D,sCAAsC;IACtC,8DAA8D;IAC9D,0CAA0C;IAC1C,gEAAgE,CAAC;AAElE,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,UAAU,SAAS,OAAO,SAAS,KAAK,EAAE,GAAG,CAAC,CAAC;AAC9E,MAAM,cAAc,GAAG;IACtB,gBAAgB;IAChB,eAAe;IACf,WAAW;IACX,eAAe;IACf,eAAe;IACf,kBAAkB;IAClB,gBAAgB;IAChB,eAAe;CACf,CAAC;AAEF;;GAEG;AACH,MAAqB,oBAAoB;IACxC;;;;;;OAMG;IACI,MAAM,CAAC,wBAAwB,CAAC,IAAY;QAClD,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjE,CAAC;CACD;AAXD,uCAWC"}

View File

@@ -0,0 +1,14 @@
/**
* Custom element utility.
*/
export default class CustomElementUtility {
/**
* Returns true if the tag name is a valid custom element name.
*
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
* @param name Tag name.
* @returns True if valid.
*/
static isValidCustomElementName(name: string): boolean;
}
//# sourceMappingURL=CustomElementUtility.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CustomElementUtility.d.ts","sourceRoot":"","sources":["../../src/custom-element/CustomElementUtility.ts"],"names":[],"mappings":"AAmBA;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACxC;;;;;;OAMG;WACW,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAG7D"}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=ICustomElementDefinition.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ICustomElementDefinition.cjs","sourceRoot":"","sources":["../../src/custom-element/ICustomElementDefinition.ts"],"names":[],"mappings":""}

View File

@@ -0,0 +1,12 @@
import HTMLElement from '../nodes/html-element/HTMLElement.cjs';
export default interface ICustomElementDefinition {
elementClass: typeof HTMLElement;
extends: string;
observedAttributes: Set<string>;
livecycleCallbacks: {
connectedCallback: () => void;
disconnectedCallback: () => void;
attributeChangedCallback: (name: string, oldValue: string | null, newValue: string | null) => void;
};
}
//# sourceMappingURL=ICustomElementDefinition.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ICustomElementDefinition.d.ts","sourceRoot":"","sources":["../../src/custom-element/ICustomElementDefinition.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,sCAAsC,CAAC;AAE/D,MAAM,CAAC,OAAO,WAAW,wBAAwB;IAChD,YAAY,EAAE,OAAO,WAAW,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,kBAAkB,EAAE;QACnB,iBAAiB,EAAE,MAAM,IAAI,CAAC;QAC9B,oBAAoB,EAAE,MAAM,IAAI,CAAC;QACjC,wBAAwB,EAAE,CACzB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,KACnB,IAAI,CAAC;KACV,CAAC;CACF"}