Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions SLASHED-for-WP/admin-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion SLASHED-for-WP/admin-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
"dev": "vite",
"prebuild": "node scripts/sync-core.mjs",
"build": "vite build",
"precheck": "node scripts/sync-core.mjs",
"check": "svelte-check --tsconfig ./tsconfig.json"
},
"dependencies": {
"@lucide/svelte": "^1.23.0",
"fflate": "^0.8.3",
"lucide-svelte": "^1.0.1",
"motion": "^12.23.24"
},
Comment thread
qodo-code-review[bot] marked this conversation as resolved.
"devDependencies": {
Expand Down
31 changes: 22 additions & 9 deletions SLASHED-for-WP/admin-app/src/AppOverlay.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
import SidebarNav from './components/shell/SidebarNav.svelte';
import DomainPanel from './components/DomainPanel.svelte';
import CommandPalette from './components/CommandPalette.svelte';
import { fa } from './lib/codec';
import { generateCSS } from './lib/codec';
import { loadInitialOverrides, injectLivePreview, saveOverrides } from './lib/persistence';
import { registerPreviewDoc } from './lib/previewResolver.svelte';
import { domainOf } from './lib/domains';
import tokensRaw from './data/api-index.generated.json';
import {
ChevronRight, Undo2, Redo2, Trash2, FolderOpen, Download, Save, Check, Loader2,
} from 'lucide-svelte';
} from '@lucide/svelte';

const ALL_TOKENS = ((tokensRaw as any).tokens ?? tokensRaw) as SlashedToken[];

Expand Down Expand Up @@ -103,13 +103,26 @@
// here, resolveColor()/resolveColorForTheme() always return "" and every
// swatch that depends on them (the whole Semantic colors grid) renders
// blank/transparent instead of the resolved color.
// Coalesced into a single rAF like PreviewPanel.svelte's SL-020 fix: a
// fast-changing control (dragging a slider) can re-run this effect many
// times per frame, but injectLivePreview()'s <style> rewrite + derived-
// token recompute only need to happen once per paint. `overrides` must be
// read here, synchronously in the effect body, not inside the rAF
// callback — $effect only tracks reads that happen during its own
// synchronous execution, so reading it only inside the (later-firing) rAF
// callback would silently stop the effect from re-running on override
// changes after the first paint.
$effect(() => {
injectLivePreview(overrides);
// registerPreviewDoc() bumps previewVersion itself (on both the
// first-registration and already-registered paths), so panels reading
// previewVersion.value re-resolve on every override change without a
// separate explicit bump here.
registerPreviewDoc(document);
const ov = overrides;
const rafId = requestAnimationFrame(() => {
injectLivePreview(ov);
// registerPreviewDoc() bumps previewVersion itself (on both the
// first-registration and already-registered paths), so panels reading
// previewVersion.value re-resolve on every override change without a
// separate explicit bump here.
registerPreviewDoc(document);
});
return () => cancelAnimationFrame(rafId);
});
Comment thread
qodo-code-review[bot] marked this conversation as resolved.

// On desktop push page content left; on mobile the panel is a full overlay.
Expand Down Expand Up @@ -200,7 +213,7 @@
}

function handleExport() {
const css = fa(overrides, { mode: 'layer', banner: true });
const css = generateCSS(overrides, { mode: 'layer', banner: true });
const blob = new Blob([css], { type: 'text/css' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
Expand Down
33 changes: 31 additions & 2 deletions SLASHED-for-WP/admin-app/src/plugin-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,30 @@ import './main.ts';
import { mount } from 'svelte';
import AppOverlay from './AppOverlay.svelte';

// vite-env.d.ts (vendored, upstream configurator) already types
// window.slashedApp generically ([key: string]: unknown), so it has no
// reason to know about cssUrl — that field only exists because this
// plugin's PHP additionally localizes it (class-frontend-configurator.php).
// A local intersection type here, mirroring the same pattern persistence.ts
// already uses for its own window.slashedApp read, avoids re-declaring (and
// risking a conflicting merge with) the vendored global Window.slashedApp
// interface.
interface PluginSlashedAppBoot {
cssUrl?: string;
}

function getCssUrl(): string | undefined {
return (window as Window & { slashedApp?: PluginSlashedAppBoot }).slashedApp?.cssUrl;
}

function isSameOrigin(url: string): boolean {
try {
return new URL(url, location.href).origin === location.origin;
} catch {
return false;
}
}

function mountOverlay() {
const overlayTarget = document.getElementById('slashed-frontend-overlay');
if (!overlayTarget) return;
Expand All @@ -33,8 +57,13 @@ function mountOverlay() {
overlayTarget.setAttribute('data-slashed-ready', '');
};

const cssUrl = (window as any).slashedApp?.cssUrl as string | undefined;
if (cssUrl) {
const cssUrl = getCssUrl();
// window.slashedApp is a plain global — any other script on the page (a
// theme, another plugin) can clobber it before this module runs. It's
// normally same-origin PHP output (esc_url_raw() over the plugin's own
// asset path, see class-frontend-configurator.php), but don't set it as a
// stylesheet href without checking that invariant still holds.
if (cssUrl && isSameOrigin(cssUrl)) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = cssUrl;
Expand Down