Polish four framework surfaces for plugin authors#229
Conversation
…redock functionality
|
@claude do your awesome review here |
|
Claude finished @AllTerrainDeveloper's task in 2m 30s —— View job PR #229 Review
Overall: This is solid, additive work that follows the codebase's own patterns well. Four changes, each self-contained. I found one real doc inaccuracy, one misleading JSDoc phrase, and one missing test case. No bugs in the implementation.
|
| Area | Status |
|---|---|
redock() promotion + facade + tests |
✅ Ready |
DESKTOP_ICONS_RENDERED payload |
✅ Ready |
WINDOW_GEOMETRY implementation + types |
✅ Ready |
WINDOW_GEOMETRY docs (state type) |
|
JSDoc phrasing in hooks.ts |
💬 Minor wording nit |
Test for source: 'restored' |
💬 Nice-to-have gap |
The doc fix for state?: is the only change I'd consider before merge — it's a public API guarantee that will confuse plugin authors when they discover 'snapped-left' isn't in the declared type union. Everything else is correct and well-structured.
✅ WordPress Plugin Check Report
📊 ReportAll checks passed! No errors or warnings found. 🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check |
… callerPinned flags
|
Manual testing passed :) |
…nd context for callerPinned
Four small, additive APIs requested by the ODD plugin author. Each one removes a workaround that third-party code was carrying.
What changed
wp.desktop.widgets.redock( id )— stable namespace;WidgetLayer.redock()promoted from private, sowp.desktop.widgetLayer.redock( id )also works. Idempotent + null-safe.HOOKS.DESKTOP_ICONS_RENDEREDpayload now ships{ ids, container, tiles }.tilesis a frozenid → tile <button>map, mirroringDOCK_AFTER_RENDER.tileElements.idsretained for back-compat — existing subscribers keep working.HOOKS.WINDOW_GEOMETRY(new filter) — last call beforeWindowConfigis baked. Signature:( geometry, ctx ) => geometry, withctx = { windowId, baseId, hasSavedGeometry, callerPinned, desktopRect }. The booleans are the only useful distinctions a filter actually needs:hasSavedGeometryflags a restored user layout (bail to respect their choice);callerPinnedflags caller-passed dims (usuallytruefor native windows because their registry passes defaultwidth/height; the filter is free to override). Lets plugins place / size their own windows declaratively instead of compensating afteropen()lands. Filter return is re-clamped tominWidth/minHeight.Files
src/widgets/layer.ts—private redock()→public redock().src/api/facade.ts,src/desktop.ts— addwp.desktop.widgetsnamespace + reserved key.src/desktop-icons.ts— build atilesmap during render; includecontainer+tilesin the payload.src/hooks.ts— newWINDOW_GEOMETRYconstant; updatedDESKTOP_ICONS_RENDEREDJSDoc.src/window-manager/index.ts—applyFilters( HOOKS.WINDOW_GEOMETRY, … )after geometry resolution; exportsResolvedWindowGeometry,WindowGeometryContext.Docs
docs/javascript-reference.md—wp.desktop.widgets.redocksection,WINDOW_GEOMETRYrow in the window-hook table + a full recipe section.docs/examples/register-icon.md— decorator recipe usingtilesfrom the icons payload.Test plan
./node_modules/.bin/tsc --noEmit— clean.npm run lint— clean.npm run test:js— 1327/1327 (11 new tests acrosswidgets.test.ts,desktop-icons-render.test.ts,window-manager-hooks.test.ts).npm run build— all 17 bundles compile;WINDOW_GEOMETRYconstant,applyFilterscall site,hasSavedGeometry+callerPinnedfields all confirmed inassets/js/desktop.min.js.Manual: open Heartbeat widget, liberate it, call
wp.desktop.widgets.redock( 'desktop-mode/heartbeat' )from console — card snaps back into the column. (Note the namespaced id — the redock is idempotent + silent on unknown ids, so a bare'heartbeat'no-ops without error.)Manual (optional — filter is exhaustively unit-tested): drop the following snippet into the browser console BEFORE opening Posts (or after closing it first), then click Posts in the dock. It should land in the bottom-right corner. Drag it somewhere else, close, reopen — it stays where YOU put it (filter bails on
hasSavedGeometry: true).Want to scope to a single window (e.g. just Posts)? Add an early bail:
Defensive coverage for
WINDOW_GEOMETRYThe filter is wrapped in try/catch + a defensive coalesce so a buggy plugin can't break window opens. Tests pin:
callerPinned: true) → filter still runs and can override (regression test for the native-window case).hasSavedGeometry: trueset when localStorage has a saved geometry for the window — plugins use this to respect the user's saved layout.minWidth/minHeight→ re-clamped.{ width }only) → missing fields fall through to pre-filter values.NaN/Infinityreturns → falls through.HOOKS.SHELL_ERROR.undefinedreturn → falls through.