Canvas extensions cannot move the selection, which blocks structural authoring plugins
- Dominant language
- JavaScript
- Stars
- 34
- Forks
- 71
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 31
Description
### Summary
A canvas panel extension can read the document and insert into it, but it has no way to **move the selection to a known place in the document**. That one gap blocks a class of "manage the structure of this page" plugins, and it is the only thing standing between the current extension API and a working authoring tool we have prototyped.
### Context
We are prototyping author tooling for section-scoped personalization on a customer site: sections carry an audience via section metadata (`Style: audience-member, audience-silver`), and each targeted section carries a generated note. Authoring this by hand is error-prone — the audience list is an unvalidated string, and a typo silently shows the section to everyone.
We built the tooling as a **BYO panel extension**, deliberately, to avoid asking for core changes. That works well for two of three jobs:
- **Read** — the handshake in `setupIframeChannel` provides `{ org, repo, ref, path }` plus the IMS token, so the plugin fetches the page source from `admin.da.live` and reports what each section targets. This is more capable than we first assumed and worth calling out in the docs.
- **Insert** — `sendHTML` reaches `insertHTML`, which does `replaceRange(from, to, …)`, so a plugin can insert correctly-formed content through the editor and stay collab-safe.
- **Locate / edit an existing section** — not possible.
### The gap
`channel.port1.onmessage` in `blocks/canvas/ew-panel-extensions/iframe-protocol.js` handles `sendText`, `sendHTML`, `setHash`, `setHref`, `closeLibrary`, `showPanel`, `setPrompt` and `getSelection`. None of these can position the selection, and the canvas hash carries no node anchor. So a plugin cannot:
1. **Jump the canvas to a section** the way `ew-page-outline` does when you click an entry. Clicking an item in a plugin's own list of sections can't scroll the editor to it.
2. **Edit an existing section.** Because `insertHTML` replaces the current selection, the edit loop already works — but only if something can put the selection on the right node first. Without that, the only route left is writing the source via `admin.da.live` underneath a live collab session, which risks clobbering or being clobbered by the y.js document. We are not doing that, so editing is simply unavailable to plugins.
### Proposed change
Expose what the outline rail already does internally, as one action:
```js
if (action === 'selectSection') {
const ok = editorView ? selectSection(editorView, details?.index) : false;
channel.port1.postMessage({ action: 'selectSectionResult', details: { ok } });
return;
}
```
backed by a `selectSection(view, sectionIndex)` helper in `editor-utils/blocks.js`, which reuses the same "split top-level nodes on `horizontal_rule`" walk that `deleteSection` and `moveSection` already use, and ends in `TextSelection` + `scrollIntoView()`.
Selecting the whole section rather than just scrolling to it is deliberate: it gives the plugin the jump **and** leaves a replaceable range under `sendHTML`, so the existing insert action covers editing with no second API.
Happy to be told this belongs somewhere else, or should be shaped differently (a node/prose-index address rather than a section index would be more general, but section index is what the existing helpers already speak).
### Not asking for
Anything that lets a plugin mutate the document without going through the editor. The value here is precisely that edits stay inside ProseMirror and collab.
Contributor guide
Research direction
Start in blocks/canvas/ew-panel-extensions/iframe-protocol.js and trace the existing canvas actions, then inspect the section-walking helpers in editor-utils/blocks.js, especially deleteSection and moveSection. Done means a panel action can select and scroll to a section, leave its range selected, and let the existing sendHTML flow replace that section through the editor.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- api, frontend
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100