Skip to content

Shadow DOM isolation + JS optimizer opt-out for wp-admin panel - #225

Open
jackgranatowski wants to merge 2 commits into
mainfrom
claude/konfigurator-opcje-tokeny-rmorrr
Open

Shadow DOM isolation + JS optimizer opt-out for wp-admin panel#225
jackgranatowski wants to merge 2 commits into
mainfrom
claude/konfigurator-opcje-tokeny-rmorrr

Conversation

@jackgranatowski

@jackgranatowski jackgranatowski commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Hardens the wp-admin configurator panel against interference from other WordPress admin plugins' CSS and JavaScript by mounting it inside a Shadow DOM (when available), and adds opt-out attributes to prevent third-party JS optimizers (LiteSpeed Cache, SG Optimizer, WP Rocket, Perfmatters, Cloudflare Rocket Loader) from breaking the native ES module by combining or deferring it.

The panel now:

  • Mounts into Shadow DOM when the host supports it and a same-origin stylesheet URL is available, isolating it from the host page's CSS/JS
  • Falls back to light DOM mounting (styled by the existing app.css in <head>) if Shadow DOM is unavailable or the stylesheet URL is cross-origin
  • Defers mount until the panel stylesheet loads (up to 5s timeout) to prevent unstyled flash in Shadow DOM mode
  • Emits data-no-optimize, data-no-defer, data-no-delay, data-no-minify, and data-cfasync attributes on both the module script and its inline hydration scripts to prevent optimizer plugins from breaking the module scope (which would leave the panel rendered but unresponsive)
  • Applies the same optimizer opt-out to the frontend overlay

Also adds a note to the "Link visited" color override in ColorsPanel explaining that browsers restrict :visited styling for privacy, so the preview can't show live changes (though the override still applies on real visited links on the published site).

Type

  • fix
  • feat
  • docs
  • chore / tooling

Checklist

  • Conventional Commit messages (feat:, fix:, docs:, …)
  • npm test passes
  • npm run lint passes (stylelint + php -l)
  • npm run verify passes (version metadata in sync)
  • Generated artifacts not hand-edited (dist/, data/inventory.json, data/classes-hints.json come from update-framework / build:data)
  • CHANGELOG.md updated under ## [Unreleased] (for user-facing changes)
  • Built SPA assets committed if editor-app/admin-app source changed

Notes

The vendored manifest was updated to reflect a local sync (the source field changed from github:codeslash-dev/slashed@v0.7.30 to local:SLASHED_CONFIGURATOR_SRC), which is expected when syncing from a local framework checkout. The actual source code changes are in plugin-main.ts (Shadow DOM mount logic), class-token-page.php and class-frontend-configurator.php (optimizer opt-out attributes), and ColorsPanel.svelte (UX note for the visited link color).

https://claude.ai/code/session_01PtvNAKsrEE1mynifQbjSun

Summary by CodeRabbit

  • New Features
    • Added explanatory notes for visited-link color settings.
    • Improved embedded app styling with isolated loading when supported.
  • Bug Fixes
    • Prevented optimization tools from altering required app scripts, improving reliability in WordPress.
    • Added a fallback mounting experience when isolated styling or stylesheets are unavailable.
    • Prevented frontend overlay interactions until the interface has finished loading.
  • Compatibility
    • Improved behavior across standalone and WordPress admin environments.
    • Added more reliable support for embedded app styling across supported browsers.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 85393b83-efa9-4615-94f7-cb09aaa288ed

📥 Commits

Reviewing files that changed from the base of the PR and between a898bab and 3d191ab.

⛔ Files ignored due to path filters (3)
  • SLASHED-for-WP/admin-app/package-lock.json is excluded by !**/package-lock.json
  • SLASHED-for-WP/integrations/bricks/editor-app/package-lock.json is excluded by !**/package-lock.json
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • SLASHED-for-WP/admin-app/.vendored-manifest.json
  • SLASHED-for-WP/admin-app/src/main.ts
  • SLASHED-for-WP/assets/admin-app/app.js
  • SLASHED-for-WP/includes/class-frontend-configurator.php
  • SLASHED-for-WP/includes/class-token-page.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • SLASHED-for-WP/admin-app/.vendored-manifest.json

📝 Walkthrough

Walkthrough

The admin app now supports isolated Shadow DOM styling in WordPress, with a light-DOM fallback. WordPress script tags receive optimizer exclusions. The frontend overlay blocks pointer events before mounting. Semantic color overrides can display explanatory notes.

Changes

Admin app integration

Layer / File(s) Summary
Embedded admin app mounting
SLASHED-for-WP/admin-app/src/main.ts, SLASHED-for-WP/includes/class-token-page.php, SLASHED-for-WP/admin-app/.vendored-manifest.json
The app validates the localized stylesheet URL, mounts standalone and WordPress hosts separately, and loads same-origin styles in a Shadow DOM before mounting. It falls back to light-DOM mounting when required.
Script optimizer exclusions
SLASHED-for-WP/includes/class-frontend-configurator.php, SLASHED-for-WP/includes/class-token-page.php
Frontend and admin module and inline scripts receive optimizer opt-out attributes through registered filters.
Overlay and semantic override support
SLASHED-for-WP/includes/class-frontend-configurator.php, SLASHED-for-WP/admin-app/src/components/panels/ColorsPanel.svelte
The overlay container disables pointer events until mounting completes. Semantic override notes are typed and rendered beneath color inputs.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Slashed_Token_Page
  participant slashedApp
  participant admin_app_main
  participant ShadowRoot
  participant App
  Slashed_Token_Page->>slashedApp: Provide app.css URL
  admin_app_main->>slashedApp: Read and validate cssUrl
  admin_app_main->>ShadowRoot: Attach shadow root and load stylesheet
  ShadowRoot-->>admin_app_main: Load, error, or five-second timeout
  admin_app_main->>App: Apply theme and mount
Loading

Possibly related PRs

Suggested labels: codex

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two main changes: Shadow DOM isolation and JavaScript optimizer opt-outs for the WordPress admin configurator.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/konfigurator-opcje-tokeny-rmorrr

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the codex label Aug 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@SLASHED-for-WP/admin-app/src/main.ts`:
- Around line 77-102: Update the shadow-style loading flow around `go`,
`settle`, and `attachShadow` so Shadow DOM is created and mounted only after the
stylesheet loads successfully. On stylesheet error, clear the fallback timer and
mount via the existing light-DOM path using `wpHost`, preserving the light-DOM
stylesheet; retain the timeout fallback behavior without attaching Shadow DOM
prematurely.
- Around line 27-107: Move the Shadow DOM changes from
SLASHED-for-WP/admin-app/src/main.ts (lines 27-107) and the semantic-note
changes from SLASHED-for-WP/admin-app/src/components/panels/ColorsPanel.svelte
(lines 156-161 and 1106-1108) into their framework/configurator source so npm
run sync regenerates them correctly; alternatively, add explicit .syncignore
entries for all affected files.

In `@SLASHED-for-WP/includes/class-frontend-configurator.php`:
- Line 35: Add data-nowprocket="1" to both module attribute constants and both
inline attribute filters. Update
SLASHED-for-WP/includes/class-frontend-configurator.php at lines 35 and 55-56,
and SLASHED-for-WP/includes/class-token-page.php at lines 437 and 451-452,
preserving the existing exclusion attributes.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e771dad-8b71-40ac-91cb-ba6c2a8c1627

📥 Commits

Reviewing files that changed from the base of the PR and between 7e32ab0 and a898bab.

📒 Files selected for processing (6)
  • SLASHED-for-WP/admin-app/.vendored-manifest.json
  • SLASHED-for-WP/admin-app/src/components/panels/ColorsPanel.svelte
  • SLASHED-for-WP/admin-app/src/main.ts
  • SLASHED-for-WP/assets/admin-app/app.js
  • SLASHED-for-WP/includes/class-frontend-configurator.php
  • SLASHED-for-WP/includes/class-token-page.php

Comment thread SLASHED-for-WP/admin-app/src/main.ts
Comment thread SLASHED-for-WP/admin-app/src/main.ts Outdated
Comment thread SLASHED-for-WP/includes/class-frontend-configurator.php Outdated
…timizers

The admin token editor (admin.php?page=slashed-tokens) mounted into the
shared wp-admin document, so another admin plugin's CSS/JS could leave the
panel rendered but completely unresponsive — confirmed on a real site where
window.wp.svgPainter was clobbered and svg-painter.js threw during init.
The frontend "/ Design" overlay kept working there precisely because it
mounts in an isolated Shadow DOM.

Give the admin panel the same encapsulation:
- Localize a same-origin cssUrl so the vendored main.ts mounts the panel
  inside a Shadow DOM and links the panel stylesheet inside it. app.css
  stays enqueued in <head> so the light-DOM fallback (no Shadow DOM /
  cross-origin URL / stylesheet load failure) is still styled.
- Opt the SPA scripts out of JS optimizers that break ES modules (LiteSpeed,
  SG Optimizer, WP Rocket incl. Delay-JS via data-nowprocket, Perfmatters,
  Cloudflare Rocket Loader), on both the module tag and the inline hydration
  scripts, for the admin panel and the frontend overlay.
- Fix a real click-trap: the empty #slashed-frontend-overlay fixed layer
  swallowed clicks before mount; start it at pointer-events:none.
- Re-vendor + rebuild the admin bundle so the shipped app.js carries the
  isolated-mount logic.

Shadow DOM here is CSS/DOM encapsulation, not a JS sandbox, but it is what
the failure needs: host styles no longer reach the panel and Svelte's
delegated listeners bind to the shadow-internal root. Verified headlessly:
under a hostile `* { pointer-events: none !important }` rule plus a clobbered
window.wp the panel renders fully and responds to clicks; a 404 stylesheet
falls back to a styled light-DOM mount.

Note: src/main.ts and ColorsPanel.svelte are vendored from
codeslash-dev/slashed; the matching framework change ships the same edits
upstream, so the next release sync stays clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PtvNAKsrEE1mynifQbjSun
@jackgranatowski
jackgranatowski force-pushed the claude/konfigurator-opcje-tokeny-rmorrr branch from a898bab to 93a1e17 Compare August 8, 2026 22:49

Copy link
Copy Markdown
Contributor Author

CI status — two remaining red checks are expected, not regressions

Fixed in 93a1e17:

  • Reworded the commits to Conventional Commits → Lint commit messages now passes.
  • Addressed the CodeRabbit review findings: light-DOM fallback is now preserved when the panel stylesheet errors (shadow root is attached only after a successful load); added data-nowprocket="1" for WP Rocket's Delay-JS; the framework-side notes/whitespace-URL fixes ship in the matching PR.

The two checks still red are not caused by this diff:

  1. Lint, test, version & drift checks — fails only on the vendoring drift gate. Per the job log, lint/test/version passed; the single failure is:

    stale  src/components/panels/ColorsPanel.svelte (differs from upstream)
    stale  src/main.ts (differs from upstream)
    

    This is by design: npm run check clones the framework at the pinned SLASHED_CSS_REF release tag and compares. The matching framework change is feat: Shadow DOM isolation for WP plugin with deferred CSS loading SLASHED#664; this gate clears once that merges + ships in a framework release and the plugin re-pins via npm run update-framework. It can't go green from the plugin side alone.

  2. Dependency vulnerability audit — pre-existing on main (the Dependabot alerts predate this branch). This PR changes no package.json/lockfiles, so it neither introduces nor can resolve it.

The functional change (admin panel mounts in a Shadow DOM; light-DOM fallback; optimizer opt-outs; overlay click-trap fix) is verified headlessly — under a hostile * { pointer-events: none !important } rule plus a clobbered window.wp, the panel renders fully and responds to clicks, and a 404 stylesheet falls back to a styled light-DOM mount.


Generated by Claude Code

npm audit flagged high-severity advisories in transitive dev/build
dependencies (fast-uri, js-yaml, nanoid, postcss, and related) across the
root toolchain and both bundled Svelte apps (admin-app, editor-app). All are
fixable without breaking changes, so `npm audit fix` bumps them to patched
versions in each lockfile. Only the three package-lock.json files change; the
committed admin-app/editor-app bundles rebuild identically, and both builds
still succeed. `npm audit --audit-level=high` now reports 0 vulnerabilities
in all three trees, clearing that portion of the Dependency vulnerability
audit gate (the drift gate remains until the framework change is released and
this plugin re-pins).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PtvNAKsrEE1mynifQbjSun
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants