(function() { "use strict"; const NONCE_HEADER = "X-WP-Nonce"; function injectRestNonce(input, init) { const nonce = readRestNonce(); if (!nonce) { return init; } const url = resolveUrl(input); if (!url || !isSameOriginRestUrl(url)) { return init; } const baseHeaders = init?.headers ?? (typeof Request !== "undefined" && input instanceof Request ? input.headers : void 0); const headers = new Headers(baseHeaders ?? {}); if (headers.has(NONCE_HEADER)) { return init; } headers.set(NONCE_HEADER, nonce); return { ...init ?? {}, headers }; } function readRestNonce() { if (typeof window === "undefined") { return void 0; } const cfg = window.desktopModeConfig; const value = cfg?.restNonce; return typeof value === "string" && value.length > 0 ? value : void 0; } function resolveUrl(input) { try { const base = typeof window !== "undefined" && window.location ? window.location.href : void 0; if (typeof input === "string") { return new URL(input, base); } if (input instanceof URL) { return input; } if (typeof Request !== "undefined" && input instanceof Request) { return new URL(input.url, base); } return null; } catch { return null; } } function isSameOriginRestUrl(url) { if (typeof window === "undefined" || !window.location || url.origin !== window.location.origin) { return false; } if (url.pathname.includes("/wp-json/")) { return true; } if (url.searchParams.has("rest_route")) { return true; } return false; } function trackedFetch(input, init, opts = {}) { const fn = window.wp?.desktop?.fetch; if (typeof fn === "function") { return fn(input, init, opts); } const finalInit = injectRestNonce(input, init); return fetch(input, finalInit); } const TEXT_DOMAIN = "desktop-mode"; function i18n() { return window.wp?.i18n; } function __(text, domain = TEXT_DOMAIN) { return i18n()?.__(text, domain) ?? text; } function sprintf(format, ...args) { const impl = i18n()?.sprintf; if (impl) { return impl(format, ...args); } let i = 0; return format.replace(/%[sd]/g, () => String(args[i++] ?? "")); } function html(strings, ...values) { return { __wpdHtml: true, strings, values }; } function isTemplateResult$1(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 render(result, container) { const existing = mountState.get(container); if (existing && existing.strings === result.strings) { applyValues(existing.parts, result.values); return; } const compiled = compile(result.strings); const fragment = compiled.template.content.cloneNode(true); const parts = compiled.buildParts(fragment); while (container.firstChild) { container.removeChild(container.firstChild); } container.appendChild(fragment); applyValues(parts, result.values); mountState.set(container, { strings: result.strings, parts }); } 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$1(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.13.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 `

${escapeHtml(title)}

${escapeHtml(lede)}

`; } function escapeHtml(s) { const t = document.createElement("div"); t.textContent = s; return t.innerHTML; } const introDialog = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, showPluginsIntroDialog }, Symbol.toStringTag, { value: "Module" })); })();