You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(VCST-5704): page-wide anchor links in rich text fields (#160)
* feat(VCST-5704): page-wide anchor links in rich text fields
CKEditor lists only the anchors of the field its link dialog was opened from, so a content
manager could not build a table of contents or a jump link targeting another section. The
option cannot be configured away either: "Link to anchor in the text" is hardcoded in the
link plugin dialog definition and is unaffected by removePlugins: "anchor", which only drops
the toolbar button.
Collect the anchors of the whole page from the editor model — the anchor setting of each
section and block, falling back to the generated id, plus in-text <a name> anchors and ids
authored through the source view — and feed them to the dialog by overriding
CKEDITOR.plugins.link.getEditorAnchors. The picker lists them as "<item name> (<anchor>)",
keeps an anchor that is no longer on the page selected instead of silently clearing the link,
and hides the now empty "By Element Id" list so the picker uses the full row.
Rich-text controls live in core while the page model belongs to the lazily loaded editor
feature, so the list is passed through a PAGE_ANCHORS_PROVIDER token registered by the editor
route. The edit panel also shows the anchor of the current section, with a copy button.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(VCST-5704): read the anchors provider of the active editor route
The CKEditor patches live on the global CKEDITOR namespace and outlive the editor route, while
PageAnchorsService is route scoped and replaced on every visit. Capturing the provider in the
closure meant that after leaving /pages and coming back, the link dialog kept reading the
destroyed service: its toSignal subscription is gone, so the anchor list was frozen or empty,
silently falling back to field-local anchors.
Keep a reference to the current provider that every install call refreshes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* style(VCST-5704): align CKEditor dialogs with the designer look
The moono-lisa skin applies `background: transparent` and `font: normal normal normal 12px Arial`
to every descendant of a dialog through `.cke_reset_all *`. That erases the arrow
@tailwindcss/forms draws on a select and replaces the application typography, which left the
anchor picker without a dropdown indicator and with mismatched, misaligned text. The skin also
lays the select wrapper out as a table, so the field shrank to its content instead of filling the
row.
Restore the arrow, give inputs, selects and labels the application's typography, sizing and focus
ring, tidy the fieldset the anchor picker sits in, and paint the footer buttons in the
application accent.
Overrides live in the previously empty external.scss and are scoped under `.cke_dialog`: the skin
rule is specificity (0,1,0) and its stylesheet is injected after the bundle, so order alone
cannot win. This applies to every CKEditor dialog, not only the link one.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(VCST-5704): drop the anchors provider when the editor route is gone
The rich-text patches live on the global CKEditor namespace and kept a reference to the route scoped
provider, which was only ever replaced by the next editor visit. A link dialog opened in another
module — a theme, say — therefore listed the anchors of the page that happened to be open last
instead of falling back to its own field-local ones.
The active provider now lives in the seam next to the token, and the route scoped service steps down
in ngOnDestroy. A provider that a later route has already replaced is ignored, so navigating between
pages never clears its successor.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(VCST-5704): tie the anchors registration to the editor route's component
Bugbot is right that the previous take never fired: route `providers` live in an EnvironmentInjector
the router keeps alive for the whole application unless `withExperimentalAutoCleanupInjectors` is
enabled, so PageAnchorsService.ngOnDestroy would never have run and the link dialog in /themes would
still have listed the anchors of the page opened last.
TemplateEditorHostComponent — created and destroyed with the route itself — now publishes the
provider and takes it down again, and the CKEditor patch is installed without one: it always reads
whichever route is active, falling back to the field-local anchors when none is.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(VCST-5704): stretch the anchor picker to the dialog width
Stock CKEditor lays the anchor picker out as a 260px fieldset centred in the
link dialog, since it carries two selects side by side under a "Select an
Anchor" legend. Page anchors leave only the name select, so the frame and the
centring only made that row look unlike the URL, e-mail and phone fields.
The dialog definition is patched, not the setup functions: width and alignment
are baked into the container markup when the dialog is built.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>