(function() {
"use strict";
function html(strings, ...values) {
return { __wpdHtml: true, strings, values };
}
function isTemplateResult(v) {
return !!v && v.__wpdHtml === true;
}
const MARKER_PREFIX = "$$wpd$$";
const MARKER_RE = /\$\$wpd\$\$(\d+)\$\$/g;
function joinWithMarkers(strings) {
let out = strings[0];
for (let i = 1; i < strings.length; i++) {
out += `${MARKER_PREFIX}${i - 1}$$` + strings[i];
}
return out;
}
const compiledCache = /* @__PURE__ */ new WeakMap();
function compile(strings) {
const cached = compiledCache.get(strings);
if (cached) {
return cached;
}
const template = document.createElement("template");
template.innerHTML = joinWithMarkers(strings);
const recipes = [];
const walk = (node, path) => {
if (node.nodeType === Node.ELEMENT_NODE) {
const el = node;
for (const attr of Array.from(el.attributes)) {
const rawName = attr.name;
const rawValue = attr.value;
const prefix = rawName[0];
if (MARKER_RE.test(rawValue)) {
MARKER_RE.lastIndex = 0;
if (prefix === "@") {
const match = MARKER_RE.exec(rawValue);
MARKER_RE.lastIndex = 0;
recipes.push({
path,
kind: "event",
name: rawName.slice(1),
valueIndex: match ? Number(match[1]) : 0
});
el.removeAttribute(rawName);
} else if (prefix === ".") {
const match = MARKER_RE.exec(rawValue);
MARKER_RE.lastIndex = 0;
recipes.push({
path,
kind: "prop",
name: rawName.slice(1),
valueIndex: match ? Number(match[1]) : 0
});
el.removeAttribute(rawName);
} else if (prefix === "?") {
const match = MARKER_RE.exec(rawValue);
MARKER_RE.lastIndex = 0;
recipes.push({
path,
kind: "bool",
name: rawName.slice(1),
valueIndex: match ? Number(match[1]) : 0
});
el.removeAttribute(rawName);
} else {
const fragments = [];
const indices = [];
let lastEnd = 0;
let m;
MARKER_RE.lastIndex = 0;
while ((m = MARKER_RE.exec(rawValue)) !== null) {
fragments.push(rawValue.slice(lastEnd, m.index));
indices.push(Number(m[1]));
lastEnd = m.index + m[0].length;
}
fragments.push(rawValue.slice(lastEnd));
recipes.push({
path,
kind: "attr",
name: rawName,
template: fragments,
valueIndices: indices
});
el.setAttribute(rawName, "");
}
}
}
}
const children = Array.from(node.childNodes);
let shift = 0;
for (let i = 0; i < children.length; i++) {
const child = children[i];
const liveIndex = i + shift;
if (child.nodeType === Node.TEXT_NODE) {
const text = child.textContent || "";
if (!MARKER_RE.test(text)) {
MARKER_RE.lastIndex = 0;
continue;
}
MARKER_RE.lastIndex = 0;
const parent = child.parentNode;
let lastEnd = 0;
let m;
const newNodes = [];
const newRecipes = [];
MARKER_RE.lastIndex = 0;
while ((m = MARKER_RE.exec(text)) !== null) {
if (m.index > lastEnd) {
newNodes.push(document.createTextNode(text.slice(lastEnd, m.index)));
}
const placeholder = document.createTextNode("");
newNodes.push(placeholder);
newRecipes.push({
path: [...path, liveIndex + newNodes.length - 1],
kind: "node",
valueIndex: Number(m[1])
});
lastEnd = m.index + m[0].length;
}
if (lastEnd < text.length) {
newNodes.push(document.createTextNode(text.slice(lastEnd)));
}
for (const nn of newNodes) {
parent.insertBefore(nn, child);
}
parent.removeChild(child);
shift += newNodes.length - 1;
recipes.push(...newRecipes);
} else {
walk(child, [...path, liveIndex]);
}
}
};
walk(template.content, []);
const buildParts = (fragment) => {
const out = [];
for (const r of recipes) {
let node = fragment;
for (const idx of r.path) {
node = node.childNodes[idx];
}
if (r.kind === "node") {
out.push({
kind: "node",
valueIndex: r.valueIndex,
child: {
anchor: node,
state: null
}
});
} else if (r.kind === "attr") {
out.push({
kind: "attr",
element: node,
name: r.name,
template: r.template,
valueIndices: r.valueIndices
});
} else if (r.kind === "event") {
out.push({
kind: "event",
valueIndex: r.valueIndex,
element: node,
name: r.name
});
} else if (r.kind === "prop") {
out.push({
kind: "prop",
valueIndex: r.valueIndex,
element: node,
name: r.name
});
} else if (r.kind === "bool") {
out.push({
kind: "bool",
valueIndex: r.valueIndex,
element: node,
name: r.name
});
}
}
return out;
};
const entry = { template, buildParts };
compiledCache.set(strings, entry);
return entry;
}
const mountState = /* @__PURE__ */ new WeakMap();
function mountIntact(state, container) {
for (const node of state.nodes) {
if (node.parentNode !== container) {
return false;
}
}
return true;
}
function render(result, container) {
const existing = mountState.get(container);
if (existing && existing.strings === result.strings && mountIntact(existing, container)) {
applyValues(existing.parts, result.values);
return;
}
const compiled = compile(result.strings);
const fragment = compiled.template.content.cloneNode(true);
const parts = compiled.buildParts(fragment);
const nodes = Array.from(fragment.childNodes);
while (container.firstChild) {
container.removeChild(container.firstChild);
}
container.appendChild(fragment);
applyValues(parts, result.values);
mountState.set(container, { strings: result.strings, parts, nodes });
}
function applyValues(parts, values) {
for (const part of parts) {
if (part.kind === "node") {
updateChildPart(part.child, values[part.valueIndex]);
} else if (part.kind === "attr") {
let composed = part.template[0];
for (let i = 0; i < part.valueIndices.length; i++) {
composed += formatText(values[part.valueIndices[i]]);
composed += part.template[i + 1];
}
if (composed !== part.last) {
part.last = composed;
if (composed === "") {
part.element.removeAttribute(part.name);
} else {
part.element.setAttribute(part.name, composed);
}
}
} else if (part.kind === "event") {
const next = values[part.valueIndex];
if (next !== part.current) {
if (part.current) {
part.element.removeEventListener(part.name, part.current);
}
if (next) {
part.element.addEventListener(part.name, next);
}
part.current = next;
}
} else if (part.kind === "prop") {
const next = values[part.valueIndex];
if (next !== part.last) {
part.last = next;
part.element[part.name] = next;
}
} else if (part.kind === "bool") {
const next = !!values[part.valueIndex];
if (next !== part.last) {
part.last = next;
if (next) {
part.element.setAttribute(part.name, "");
} else {
part.element.removeAttribute(part.name);
}
}
}
}
}
function updateChildPart(child, value) {
if (value === null || value === void 0 || value === false) {
if (child.state) {
disposeChildState(child.state);
child.state = null;
}
return;
}
if (Array.isArray(value)) {
updateArrayChild(child, value);
return;
}
if (isTemplateResult(value)) {
updateTemplateChild(child, value);
return;
}
if (value instanceof Node) {
updateNodeChild(child, value);
return;
}
updateTextChild(child, formatText(value));
}
function updateNodeChild(child, node) {
const old = child.state;
if (old?.shape === "node" && old.node === node) {
return;
}
if (old) {
disposeChildState(old);
}
insertBeforeAnchor(child, [node]);
child.state = { shape: "node", node };
}
function updateTextChild(child, text) {
const old = child.state;
if (old?.shape === "text") {
if (old.text !== text) {
old.node.textContent = text;
old.text = text;
}
return;
}
if (old) {
disposeChildState(old);
}
const node = document.createTextNode(text);
insertBeforeAnchor(child, [node]);
child.state = { shape: "text", node, text };
}
function updateTemplateChild(child, result) {
const old = child.state;
if (old?.shape === "template" && old.strings === result.strings) {
applyValues(old.parts, result.values);
return;
}
if (old) {
disposeChildState(old);
}
const compiled = compile(result.strings);
const fragment = compiled.template.content.cloneNode(true);
const parts = compiled.buildParts(fragment);
const topNodes = Array.from(fragment.childNodes);
insertBeforeAnchor(child, [fragment]);
applyValues(parts, result.values);
child.state = {
shape: "template",
strings: result.strings,
parts,
nodes: topNodes
};
}
function updateArrayChild(child, arr) {
const old = child.state;
if (old?.shape === "array" && old.entries.length === arr.length) {
for (let i = 0; i < arr.length; i++) {
updateChildPart(old.entries[i], arr[i]);
}
return;
}
if (old) {
disposeChildState(old);
}
const entries = [];
for (const v of arr) {
const entryAnchor = document.createTextNode("");
insertBeforeAnchor(child, [entryAnchor]);
const entry = { anchor: entryAnchor, state: null };
updateChildPart(entry, v);
entries.push(entry);
}
child.state = { shape: "array", entries };
}
function insertBeforeAnchor(child, nodes) {
const parent = child.anchor.parentNode;
if (!parent) {
return;
}
for (const node of nodes) {
parent.insertBefore(node, child.anchor);
}
}
function disposeChildState(state) {
if (state.shape === "text") {
state.node.remove();
return;
}
if (state.shape === "template") {
for (const node of state.nodes) {
if (node.parentNode) {
node.parentNode.removeChild(node);
}
}
return;
}
if (state.shape === "node") {
if (state.node.parentNode) {
state.node.parentNode.removeChild(state.node);
}
return;
}
for (const entry of state.entries) {
if (entry.state) {
disposeChildState(entry.state);
}
entry.anchor.remove();
}
}
function formatText(v) {
if (v === null || v === void 0 || v === false) {
return "";
}
return String(v);
}
const _Component = class _Component extends HTMLElement {
constructor() {
super();
this._renderScheduled = false;
this._propValues = {};
const ctor = this.constructor;
if (ctor.shadow) {
this.attachShadow({ mode: "open" });
this._renderRoot = this.shadowRoot;
} else {
this._renderRoot = this;
}
this._installPropAccessors();
}
static get observedAttributes() {
return this.props.map(kebab);
}
connectedCallback() {
this._adoptStyles();
this.requestUpdate();
}
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue === newValue) {
return;
}
const prop = camel(name);
this._propValues[prop] = newValue;
this.requestUpdate();
}
/**
* Declarative class-name setter. Assign an array (or a
* space-separated string) and the host's `class` attribute is
* rewritten to match. Intended for programmatic styling — when
* a plugin has enqueued its own stylesheet and wants to apply
* one of those classes to a shell component:
*
* ```js
* element.classNames = [ 'my-plugin-brand', 'is-active' ];
* // →
* ```
*
* The plain HTML `class="…"` attribute works just the same and
* is always preferred when writing markup by hand — this setter
* exists for the JS-API case where the caller has an array of
* conditional classes in hand.
*
* Getter returns the current `classList` as a plain array for
* symmetric read/write.
*
* @since 0.5.0
*/
get classNames() {
return Array.from(this.classList);
}
set classNames(next) {
if (next === null || next === void 0) {
this.removeAttribute("class");
return;
}
const list = Array.isArray(next) ? next : String(next).split(/\s+/);
const cleaned = list.map((s) => String(s).trim()).filter((s) => s !== "");
this.className = cleaned.join(" ");
}
/**
* Request a re-render explicitly. Components rarely need this —
* declare state via props + attribute observers and the render
* loop picks up changes automatically.
*/
requestUpdate() {
this._scheduleRender();
}
/**
* Dispatch a `CustomEvent` with a `detail`. Bubbles + composed
* by default (matches typical WC UX — events cross shadow
* boundaries, parents can listen without knowing about internal
* structure).
*/
emit(name, detail) {
return this.dispatchEvent(
new CustomEvent(name, {
detail,
bubbles: true,
composed: true
})
);
}
// ------------------------------------------------------------------
// Internals
// ------------------------------------------------------------------
/**
* Wire every `static props` entry to a matched property getter +
* setter on the element. Setting the property reflects into the
* attribute (so downstream observers + CSS selectors see it);
* reading the property falls back to the attribute.
*/
_installPropAccessors() {
const ctor = this.constructor;
for (const prop of ctor.props) {
if (Object.getOwnPropertyDescriptor(this, prop)) {
continue;
}
const attr = kebab(prop);
Object.defineProperty(this, prop, {
get: () => {
if (prop in this._propValues) {
return this._propValues[prop];
}
return this.getAttribute(attr);
},
set: (value) => {
let str;
if (value === null || value === void 0 || value === false) {
str = null;
} else if (value === true) {
str = "";
} else {
str = String(value);
}
this._propValues[prop] = str;
if (str === null) {
this.removeAttribute(attr);
} else {
this.setAttribute(attr, str);
}
this.requestUpdate();
},
enumerable: true,
configurable: true
});
}
}
/**
* Schedule a render on the next microtask. Multiple property
* assignments in the same tick collapse into a single render.
*/
_scheduleRender() {
if (this._renderScheduled || !this.isConnected) {
return;
}
this._renderScheduled = true;
queueMicrotask(() => {
this._renderScheduled = false;
if (!this.isConnected) {
return;
}
render(this.render(), this._renderRoot);
});
}
/**
* Mount adoptable stylesheets onto the shadow root (via
* `adoptedStyleSheets`) or the light DOM (via one `