@openleaf-editor/ui 0.1.0-beta.3 → 0.1.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -68,6 +68,11 @@ custom-control contract is strict about focus: exactly one focusable element in
68
68
  what you return, and if it is not a `button.ol-btn` then name it as `focusable`.
69
69
  Two makes the bar two tab stops where the author expects one.
70
70
 
71
+ Tab itself is never captured inside the editor, including in a code block —
72
+ it is how a keyboard user leaves. Indent a code sample by typing spaces.
73
+ The F1 dialog lists Tab as "leave the editor" and Alt+F10 as the toolbar
74
+ shortcut.
75
+
71
76
  [Authoring OpenLeaf plugins](../../docs/authoring-plugins.md) documents the rest,
72
77
  including the `mousedown` `preventDefault` that keeps the selection alive and why
73
78
  `destroy` runs before every re-render rather than only on teardown.
@@ -80,6 +85,39 @@ is required and nothing is injected inline. Every colour is a custom property;
80
85
  costing the author their undo history. On a browser without
81
86
  `adoptedStyleSheets`, link `openleaf.css` and call `markStylesExternal()`.
82
87
 
88
+ Underline and strikethrough (`<u>`, `<s>`, `<del>`) paint in the text colour,
89
+ including when a colour mark is nested inside the decoration — schema order
90
+ wraps the line around the colour span, so a rule on `u`/`s` alone cannot retint
91
+ an ancestor's line. Stored HTML stays `<u>`/`<s>`; this is a canvas paint rule.
92
+ Highlight (`background-color`) does not change the line: it still matches the
93
+ foreground.
94
+ The main toolbar (`.ol-toolbar`, not a floating bar) is `position: sticky`, so
95
+ it stays on screen while the editor is in view. Fullscreen does not need this:
96
+ the host is a column flex and only the content pane scrolls, so the bar never
97
+ left. Integrators with a fixed site header set `--openleaf-toolbar-sticky-offset`
98
+ to that header's height (default `0px`) on `.ol-editor` or an ancestor. The
99
+ menubar is not sticky: stacking it with the toolbar needs a height the
100
+ stylesheet cannot know, and two bars at the same `top` would overlap. A second
101
+ toolbar (`toolbar2`) stays in flow for the same reason, including when it is
102
+ the only bar (`toolbar="none"`).
103
+
104
+ The overflow "More" panel is `position: fixed` from the trigger's viewport box,
105
+ so an open panel still lands under the button when the bar is stuck.
106
+
107
+ ## Floating toolbars
108
+
109
+ `selection-toolbar` and `insert-toolbar` on the element create the two floating
110
+ bars. They are shown only while the view is focused, the editor is editable,
111
+ and the selection covers some unlocked content. A range that lives entirely
112
+ inside `contenteditable="false"` or *is* a preserved atom hides the bar; a
113
+ Select All that merely *contains* a locked block does not, because the
114
+ unlocked text is still formattable. A pointer-down inside the canvas still
115
+ counts as focused: some
116
+ engines have not moved focus into the view yet while a drag-select is
117
+ establishing the range, and a naive `hasFocus()` guard would hide the selection
118
+ bar for that gesture. Placement itself stays pointer-driven — a keyboard user
119
+ already has Alt+F10 for the main toolbar.
120
+
83
121
  ## License
84
122
 
85
123
  Apache-2.0.
package/dist/css.d.ts CHANGED
@@ -19,5 +19,5 @@
19
19
  * `dist/openleaf.css` is generated from this constant by `scripts/emit-css.mjs`,
20
20
  * so the constructable-stylesheet path and the linked-file path cannot drift.
21
21
  */
22
- export declare const CSS = "\n.ol-editor {\n /* Two families, named before either is public API. A singular\n `--openleaf-font` implies \"the\" font, and source view already has a\n monospace surface -- bolting a mono token on beside a singular name later\n is the awkward outcome worth avoiding now. `--openleaf-font` is still\n honoured as a fallback. */\n --ol-font: var(--openleaf-font-ui, var(--openleaf-font, system-ui, -apple-system, \"Segoe UI\", sans-serif));\n --ol-font-mono: var(--openleaf-font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);\n --ol-font-size: var(--openleaf-font-size, 14px);\n --ol-radius: var(--openleaf-radius, 4px);\n --ol-text: var(--openleaf-color-text, #1f2328);\n --ol-text-muted: var(--openleaf-color-text-muted, #59636e);\n --ol-surface: var(--openleaf-color-surface, #ffffff);\n --ol-surface-hover: var(--openleaf-color-surface-hover, #f0f1f3);\n --ol-surface-active: var(--openleaf-color-surface-active, #dbe9ff);\n --ol-border: var(--openleaf-color-border, #d1d9e0);\n /* Control boundaries, not decoration. See \"Two border tokens\" above. */\n --ol-border-strong: var(--openleaf-color-border-strong, #6e7781);\n --ol-accent: var(--openleaf-color-accent, #0550ae);\n --ol-focus: var(--openleaf-color-focus, #0969da);\n --ol-danger: var(--openleaf-color-danger, #cf222e);\n --ol-button-size: var(--openleaf-button-size, 32px);\n --ol-icon-size: var(--openleaf-icon-size, 16px);\n --ol-gap: var(--openleaf-gap, 2px);\n /* A 2009 WordPress admin bar sits at z-index 99999 and Drupal's toolbar plays\n similar games. Without a sanctioned escape hatch integrators fix a toolbar\n rendered behind a sticky host header with !important -- the exact thing the\n token API exists to prevent. */\n --ol-z: var(--openleaf-z-index, 1);\n /* Thickness and offset, not just colour: \"you can change the colour but not\n the thickness\" is a poor answer to a Section 508 team citing WCAG 2.2\n Focus Appearance. */\n --ol-focus-width: var(--openleaf-focus-width, 2px);\n --ol-focus-offset: var(--openleaf-focus-offset, 1px);\n\n display: block;\n position: relative;\n color: var(--ol-text);\n}\n\n/* Three ways into the dark palette, and one way out of it.\n `data-ol-scheme` is set from the applied skin's declared scheme, and a skin\n that declares one outranks both the attribute and the system -- it has to,\n because its tokens have already replaced the palette outright. Without the\n `:not()` guards a light skin on a dark machine would take these fallbacks for\n every token it did not itself set, which is a light surface carrying dark-mode\n muted text. */\n@media (prefers-color-scheme: dark) {\n .ol-editor:not([data-ol-theme=\"light\"]):not([data-ol-scheme]) {\n --ol-text: var(--openleaf-color-text, #e6edf3);\n --ol-text-muted: var(--openleaf-color-text-muted, #9198a1);\n --ol-surface: var(--openleaf-color-surface, #0d1117);\n --ol-surface-hover: var(--openleaf-color-surface-hover, #21262d);\n --ol-surface-active: var(--openleaf-color-surface-active, #1f3a5f);\n --ol-border: var(--openleaf-color-border, #3d444d);\n --ol-border-strong: var(--openleaf-color-border-strong, #8b949e);\n --ol-accent: var(--openleaf-color-accent, #79c0ff);\n --ol-focus: var(--openleaf-color-focus, #79c0ff);\n --ol-danger: var(--openleaf-color-danger, #ff8182);\n}\n}\n\n.ol-editor[data-ol-theme=\"dark\"]:not([data-ol-scheme]) {\n --ol-text: var(--openleaf-color-text, #e6edf3);\n --ol-text-muted: var(--openleaf-color-text-muted, #9198a1);\n --ol-surface: var(--openleaf-color-surface, #0d1117);\n --ol-surface-hover: var(--openleaf-color-surface-hover, #21262d);\n --ol-surface-active: var(--openleaf-color-surface-active, #1f3a5f);\n --ol-border: var(--openleaf-color-border, #3d444d);\n --ol-border-strong: var(--openleaf-color-border-strong, #8b949e);\n --ol-accent: var(--openleaf-color-accent, #79c0ff);\n --ol-focus: var(--openleaf-color-focus, #79c0ff);\n --ol-danger: var(--openleaf-color-danger, #ff8182);\n}\n\n.ol-editor[data-ol-scheme=\"dark\"] {\n --ol-text: var(--openleaf-color-text, #e6edf3);\n --ol-text-muted: var(--openleaf-color-text-muted, #9198a1);\n --ol-surface: var(--openleaf-color-surface, #0d1117);\n --ol-surface-hover: var(--openleaf-color-surface-hover, #21262d);\n --ol-surface-active: var(--openleaf-color-surface-active, #1f3a5f);\n --ol-border: var(--openleaf-color-border, #3d444d);\n --ol-border-strong: var(--openleaf-color-border-strong, #8b949e);\n --ol-accent: var(--openleaf-color-accent, #79c0ff);\n --ol-focus: var(--openleaf-color-focus, #79c0ff);\n --ol-danger: var(--openleaf-color-danger, #ff8182);\n}\n\n/* Native widget chrome -- the popup a `select` opens, scrollbars, the caret,\n form control backgrounds -- is painted by the browser from `color-scheme`,\n not from any property we can hand an integrator. Left alone it follows the\n page, which is right while the editor's own palette also follows the page and\n wrong the moment either attribute pins the editor to one world. So it is set\n exactly when the editor stops following along, and inherited from the host\n otherwise. */\n.ol-editor[data-ol-theme=\"light\"] { color-scheme: light; }\n.ol-editor[data-ol-theme=\"dark\"] { color-scheme: dark; }\n.ol-editor[data-ol-scheme=\"light\"] { color-scheme: light; }\n.ol-editor[data-ol-scheme=\"dark\"] { color-scheme: dark; }\n\n/* Wrapping, not scrolling and not an overflow menu. Both of those hide\n controls -- one off-screen, one behind a click -- and a formatting control\n the author cannot see is a control they do not have. */\n.ol-editor .ol-toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--ol-gap);\n box-sizing: border-box;\n margin: 0;\n padding: 4px;\n border: 1px solid var(--ol-border-strong);\n border-bottom: 0;\n border-radius: var(--ol-radius) var(--ol-radius) 0 0;\n background: var(--ol-surface);\n font: inherit;\n position: relative;\n z-index: var(--ol-z);\n}\n\n.ol-editor .ol-group {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--ol-gap);\n}\n\n/* The divider is a BORDER on the group, not a standalone flex item.\n As its own element it could wrap onto the trailing edge of a row with nothing\n after it -- a stranded line floating at the end of a row. Wrapping begins\n around 690-740px, well inside ordinary desktop widths (a CMS sidebar, a\n half-width split pane), so this was not a 360px-only edge case.\n border-inline-start rather than border-left, so it flips under RTL.\n\n This selector is why the renderer emits NO element between groups. It used to\n emit an .ol-sep div, which made the two groups non-adjacent and stopped this\n rule from ever matching -- so no divider rendered in any theme, and every bar\n carried inert empty divs. Adding a separator element back here breaks this. */\n.ol-editor .ol-group + .ol-group {\n border-inline-start: 1px solid var(--ol-border);\n padding-inline-start: 5px;\n margin-inline-start: 1px;\n}\n\n/* Every property a host reset or `button {}` rule is likely to touch is set\n here explicitly. Specificity is (0,2,0) via the descendant selector, which\n beats a bare element or single-class host rule without resorting to\n !important. */\n.ol-editor .ol-btn {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: var(--ol-button-size);\n height: var(--ol-button-size);\n min-width: var(--ol-button-size);\n min-height: var(--ol-button-size);\n max-width: none;\n padding: 0;\n margin: 0;\n border: 1px solid transparent;\n border-radius: var(--ol-radius);\n background: transparent;\n color: var(--ol-text);\n font: inherit;\n font-family: var(--ol-font);\n font-size: var(--ol-font-size);\n font-weight: 400;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n text-align: center;\n text-decoration: none;\n text-shadow: none;\n box-shadow: none;\n opacity: 1;\n cursor: pointer;\n appearance: none;\n -webkit-appearance: none;\n outline-offset: var(--ol-focus-offset);\n -webkit-tap-highlight-color: transparent;\n transition: background-color 120ms ease, border-color 120ms ease;\n}\n\n.ol-editor .ol-btn:hover {\n background: var(--ol-surface-hover);\n}\n\n/* :focus-visible only, so a mouse click does not leave a ring behind, but the\n ring is never removed for keyboard users. */\n.ol-editor .ol-btn:focus-visible {\n outline: var(--ol-focus-width) solid var(--ol-focus);\n outline-offset: var(--ol-focus-offset);\n}\n\n/* Pressed state is distinguished from hover by THREE signals, not just colour:\n a filled background, a visible border, and an inset shadow that reads as\n physically depressed. Colour alone would fail for a colour-blind author and\n would be invisible in forced-colours mode. */\n.ol-editor .ol-btn[aria-pressed=\"true\"] {\n background: var(--ol-surface-active);\n border-color: var(--ol-accent);\n color: var(--ol-accent);\n box-shadow: inset 0 1px 2px rgb(0 0 0 / 12%);\n}\n\n.ol-editor .ol-btn[aria-pressed=\"true\"]:hover {\n background: var(--ol-surface-active);\n border-color: var(--ol-accent);\n}\n\n/* aria-disabled rather than the disabled attribute: a disabled button is\n removed from the roving tabindex and cannot be reached or announced, so an\n author using a screen reader cannot discover that the control exists. */\n.ol-editor .ol-btn[aria-disabled=\"true\"] {\n opacity: 0.55;\n cursor: default;\n}\n\n.ol-editor .ol-btn[aria-disabled=\"true\"]:hover {\n background: transparent;\n}\n\n.ol-editor .ol-icon {\n width: var(--ol-icon-size);\n height: var(--ol-icon-size);\n display: block;\n pointer-events: none;\n flex: 0 0 auto;\n}\n\n/* Block-type select. Sized and coloured to sit level with the icon buttons so\n it does not read as bolted on, but it stays a native <select> -- a custom\n listbox is a large amount of ARIA that would then owe real screen reader\n testing to be worth anything. */\n.ol-editor .ol-select {\n box-sizing: border-box;\n height: var(--ol-button-size);\n max-width: 11em;\n padding: 0 22px 0 6px;\n margin: 0;\n border: 1px solid var(--ol-border-strong);\n border-radius: var(--ol-radius);\n background-color: transparent;\n background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),\n linear-gradient(135deg, currentColor 50%, transparent 50%);\n background-position: right 10px center, right 6px center;\n background-size: 4px 4px, 4px 4px;\n background-repeat: no-repeat;\n color: var(--ol-text);\n font-family: var(--ol-font);\n font-size: var(--ol-font-size);\n font-weight: 400;\n line-height: 1;\n text-transform: none;\n letter-spacing: normal;\n box-shadow: none;\n cursor: pointer;\n appearance: none;\n -webkit-appearance: none;\n}\n\n.ol-editor .ol-select--wide {\n max-width: 14em;\n}\n\n.ol-editor .ol-select:hover {\n background-color: var(--ol-surface-hover);\n}\n\n.ol-editor .ol-select:focus-visible {\n outline: var(--ol-focus-width) solid var(--ol-focus);\n outline-offset: var(--ol-focus-offset);\n}\n\n/* The option list is painted by the OS, which does not inherit our tokens, so\n give it explicit colours or dark mode shows black text on black. */\n.ol-editor .ol-select option {\n background: var(--ol-surface);\n color: var(--ol-text);\n}\n\n.ol-editor .ol-content {\n box-sizing: border-box;\n border: 1px solid var(--ol-border-strong);\n border-radius: 0 0 var(--ol-radius) var(--ol-radius);\n background: var(--ol-surface);\n}\n\n/* Deliberately minimal: the content area inherits the host's typography, which\n is the entire reason this project does not use Shadow DOM. Only padding and\n the focus ring are ours. */\n.ol-editor .ol-content .ProseMirror {\n padding: 12px;\n min-height: 8rem;\n outline: none;\n}\n\n.ol-editor .ol-content:focus-within {\n outline: 2px solid var(--ol-focus);\n outline-offset: -1px;\n}\n\n/* Tables.\n These styles live in core, not in the opt-in table plugin, because table\n NODES live in core: every deployment reads and renders tables even where\n editing them is switched off. Unstyled tables would render as runs of\n undelimited text. */\n.ol-editor .ol-content .ProseMirror table {\n border-collapse: collapse;\n table-layout: fixed;\n width: 100%;\n margin: 0 0 1em;\n overflow: hidden;\n}\n\n.ol-editor .ol-content .ProseMirror td,\n.ol-editor .ol-content .ProseMirror th {\n border: 1px solid var(--ol-border);\n padding: 6px 8px;\n vertical-align: top;\n /* A zero-width cell cannot be clicked into, so it cannot be repaired. */\n min-width: 2em;\n position: relative;\n}\n\n/* Presentational valign is otherwise beaten by the rule above, which would\n make the cell-properties dialog a no-op on screen. */\n.ol-editor .ol-content .ProseMirror td[valign=\"middle\"],\n.ol-editor .ol-content .ProseMirror th[valign=\"middle\"] { vertical-align: middle; }\n.ol-editor .ol-content .ProseMirror td[valign=\"bottom\"],\n.ol-editor .ol-content .ProseMirror th[valign=\"bottom\"] { vertical-align: bottom; }\n.ol-editor .ol-content .ProseMirror td[valign=\"baseline\"],\n.ol-editor .ol-content .ProseMirror th[valign=\"baseline\"] { vertical-align: baseline; }\n\n.ol-editor .ol-content .ProseMirror th {\n background: var(--ol-surface-hover);\n font-weight: 600;\n text-align: start;\n}\n\n/* prosemirror-tables marks cells in a rectangular selection with this class.\n An ::after overlay rather than a background so it composes with a cell that\n already has one, and so a header cell still reads as a header.\n\n The ring, not the tint, is the indicator -- see \"Cell selection\" above. */\n.ol-editor .ol-content .ProseMirror .selectedCell {\n outline: 2px solid var(--ol-accent);\n outline-offset: -2px;\n}\n.ol-editor .ol-content .ProseMirror .selectedCell::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background: var(--ol-surface-active);\n opacity: 0.4;\n pointer-events: none;\n}\n\n/* The column resize handle, drawn by prosemirror-tables' columnResizing. */\n.ol-editor .ol-content .ProseMirror .column-resize-handle {\n position: absolute;\n right: -2px;\n top: 0;\n bottom: 0;\n width: 4px;\n background: var(--ol-accent);\n pointer-events: none;\n z-index: 20;\n}\n\n.ol-editor .ol-content .ProseMirror.resize-cursor {\n cursor: col-resize;\n}\n\n.ol-editor .ol-content .ProseMirror img.ol-float-left {\n float: left;\n margin: 0 1em 0.5em 0;\n}\n.ol-editor .ol-content .ProseMirror img.ol-float-right {\n float: right;\n margin: 0 0 0.5em 1em;\n}\n.ol-editor .ol-content .ProseMirror img.ol-align-center {\n display: block;\n margin: 0 auto 0.5em;\n}\n.ol-editor .ol-content .ProseMirror figure {\n margin: 0 0 1em;\n}\n.ol-editor .ol-content .ProseMirror figcaption {\n font-size: .9em;\n opacity: .8;\n margin-top: .35em;\n}\n.ol-editor .ol-content .ProseMirror details {\n border: 1px solid var(--ol-border);\n border-radius: var(--ol-radius);\n padding: .5em .75em;\n margin: 0 0 1em;\n}\n.ol-editor .ol-content .ProseMirror summary {\n cursor: pointer;\n font-weight: 600;\n}\n.ol-editor .ol-content .ProseMirror hr.ol-pagebreak {\n border: 0;\n border-top: 2px dashed var(--ol-border);\n margin: 1.5em 0;\n}\n.ol-editor .ol-content .ProseMirror iframe,\n.ol-editor .ol-content .ProseMirror video,\n.ol-editor .ol-content .ProseMirror audio {\n max-width: 100%;\n}\n\n/* Preserved-but-unrecognised markup, surfaced rather than hidden. */\n.ol-editor .ol-content .ProseMirror-selectednode {\n outline: 2px solid var(--ol-focus);\n outline-offset: 2px;\n border-radius: 2px;\n}\n\n.ol-editor .ol-source {\n box-sizing: border-box;\n display: block;\n width: 100%;\n min-height: 12rem;\n padding: 12px;\n border: 1px solid var(--ol-border-strong);\n border-radius: 0 0 var(--ol-radius) var(--ol-radius);\n background: var(--ol-surface);\n color: var(--ol-text);\n font-family: var(--ol-font-mono);\n font-size: 13px;\n line-height: 1.5;\n resize: vertical;\n white-space: pre-wrap;\n}\n\n/* Directional icons under RTL.\n Group order reverses for free with flexbox, but a curved undo arrow does not:\n in an RTL document \"back\" points the other way. Only genuinely directional\n icons are flipped -- bold and italic must not be mirrored. */\n.ol-editor[dir=\"rtl\"] .ol-icon--directional,\n[dir=\"rtl\"] .ol-editor .ol-icon--directional {\n transform: scaleX(-1);\n}\n\n/* The announcement region. Visually hidden but not display:none, which would\n remove it from the accessibility tree and silence it. */\n.ol-editor .ol-live {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n\n/* Menubar, menus, floating chrome, visual aids, fullscreen, inline. */\n.ol-editor .ol-menubar {\n display: flex;\n flex-wrap: wrap;\n gap: var(--ol-gap);\n box-sizing: border-box;\n margin: 0;\n padding: 2px 4px;\n border: 1px solid var(--ol-border-strong);\n border-bottom: 0;\n border-radius: var(--ol-radius) var(--ol-radius) 0 0;\n background: var(--ol-surface);\n position: relative;\n z-index: var(--ol-z);\n}\n.ol-editor .ol-menubar + .ol-toolbar {\n border-radius: 0;\n}\n.ol-editor .ol-menu-trigger {\n box-sizing: border-box;\n margin: 0;\n padding: 4px 8px;\n border: 1px solid transparent;\n border-radius: var(--ol-radius);\n background: transparent;\n color: var(--ol-text);\n font: inherit;\n font-family: var(--ol-font);\n font-size: var(--ol-font-size);\n cursor: pointer;\n appearance: none;\n}\n.ol-editor .ol-menu-trigger:hover,\n.ol-editor .ol-menu-trigger[aria-expanded=\"true\"] {\n background: var(--ol-surface-hover);\n}\n.ol-editor .ol-menu-trigger:focus-visible {\n outline: var(--ol-focus-width) solid var(--ol-focus);\n outline-offset: var(--ol-focus-offset);\n}\n.ol-editor .ol-menu {\n position: absolute;\n z-index: calc(var(--ol-z) + 20);\n min-width: 12rem;\n /* Capped, so a deep menu opened low on a short window can be flipped above\n its trigger instead of running off the bottom of the page. */\n max-height: 60vh;\n overflow-y: auto;\n margin: 0;\n padding: 4px;\n border: 1px solid var(--ol-border-strong);\n border-radius: var(--ol-radius);\n background: var(--ol-surface);\n box-shadow: 0 8px 24px rgb(0 0 0 / 12%);\n}\n.ol-editor .ol-menu-item {\n display: block;\n box-sizing: border-box;\n width: 100%;\n margin: 0;\n padding: 6px 10px;\n border: 0;\n border-radius: var(--ol-radius);\n background: transparent;\n color: var(--ol-text);\n font: inherit;\n font-family: var(--ol-font);\n font-size: var(--ol-font-size);\n text-align: start;\n cursor: pointer;\n appearance: none;\n}\n.ol-editor .ol-menu-item:hover {\n background: var(--ol-surface-hover);\n}\n/* Was outline:none plus a 1.13:1 background swap. See \"Menu focus\" above. */\n.ol-editor .ol-menu-item:focus-visible {\n background: var(--ol-surface-hover);\n outline: var(--ol-focus-width) solid var(--ol-focus);\n outline-offset: -2px;\n}\n/* 0.55, not 0.4: see \"Disabled is not invisible\" above. */\n.ol-editor .ol-menu-item[aria-disabled=\"true\"] {\n opacity: 0.55;\n cursor: default;\n}\n.ol-editor .ol-menu-sep {\n height: 1px;\n margin: 4px 0;\n background: var(--ol-border);\n}\n/* `display: flex` on .ol-toolbar above outranks the UA's `[hidden]` rule --\n a class selector beats an attribute selector on specificity -- so setting\n `el.hidden = true` in floating.ts styled a hidden bar and showed it anyway.\n Both floating bars sat over the prose at rest, with no selection to format.\n The overflow panel needed the same rule for the same reason; see below. */\n.ol-editor .ol-toolbar.ol-floating[hidden] {\n display: none;\n}\n.ol-editor .ol-toolbar.ol-floating {\n position: absolute;\n flex-wrap: nowrap;\n border: 1px solid var(--ol-border);\n border-radius: var(--ol-radius);\n box-shadow: 0 8px 24px rgb(0 0 0 / 12%);\n z-index: calc(var(--ol-z) + 10);\n}\n.ol-editor .ol-toolbar.ol-toolbar--overflow {\n flex-wrap: nowrap;\n overflow: hidden;\n}\n/* The More panel. Positioned in viewport coordinates from script, because the\n bar it belongs to may live inside a host with `overflow: hidden` -- which is\n the situation the whole feature exists for. */\n.ol-editor .ol-overflow-menu {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--ol-gap);\n max-height: 70vh;\n overflow-y: auto;\n}\n.ol-editor .ol-overflow-menu[hidden] {\n display: none;\n}\n/* Vertical: the panel exists because there is no horizontal room left. */\n.ol-editor .ol-overflow-menu .ol-group {\n flex-direction: column;\n align-items: stretch;\n}\n.ol-editor .ol-overflow-menu .ol-group + .ol-group {\n border-inline-start: 0;\n border-block-start: 1px solid var(--ol-border);\n padding-inline-start: 0;\n margin-inline-start: 0;\n padding-block-start: 4px;\n margin-block-start: 3px;\n}\n.ol-editor.ol-visual-aids .ol-empty-block {\n outline: 1px dashed var(--ol-border);\n outline-offset: 2px;\n min-height: 1.2em;\n}\n.ol-editor.ol-visual-aids .ol-nbsp {\n background: color-mix(in srgb, var(--ol-accent) 25%, transparent);\n box-shadow: inset 0 -1px 0 var(--ol-accent);\n}\n.ol-editor.ol-visual-aids .ol-hidden-structure {\n outline: 1px dotted var(--ol-accent);\n outline-offset: 2px;\n}\n.ol-editor .ol-noneditable {\n cursor: default;\n background: repeating-linear-gradient(\n -45deg,\n transparent,\n transparent 6px,\n color-mix(in srgb, var(--ol-border) 35%, transparent) 6px,\n color-mix(in srgb, var(--ol-border) 35%, transparent) 7px\n );\n}\n.ol-editor.ol-fullscreen {\n position: fixed;\n inset: 0;\n z-index: 2147483000;\n margin: 0;\n border-radius: 0;\n background: var(--ol-surface);\n display: flex;\n flex-direction: column;\n}\n.ol-editor.ol-fullscreen .ol-content,\n.ol-editor.ol-fullscreen .ol-source {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n}\n.ol-editor.ol-autoresize .ol-content .ProseMirror {\n overflow: hidden;\n}\n.ol-editor.ol-inline:not(.ol-inline-active) .ol-toolbar,\n.ol-editor.ol-inline:not(.ol-inline-active) .ol-menubar {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n}\n.ol-editor.ol-inline .ol-content {\n border-radius: var(--ol-radius);\n}\n.ol-help-table {\n width: 100%;\n border-collapse: collapse;\n font: inherit;\n}\n.ol-help-table th,\n.ol-help-table td {\n padding: 4px 8px;\n text-align: start;\n vertical-align: top;\n border-bottom: 1px solid var(--openleaf-color-border, #d1d9e0);\n}\n.ol-help-table th {\n font-weight: 600;\n white-space: nowrap;\n}\n\n/* Coarse pointers get a larger target. WCAG 2.2 SC 2.5.8 asks for 24x24 CSS px\n minimum; 32 clears that on a mouse and 40 is comfortable on a thumb. */\n@media (pointer: coarse) {\n .ol-editor {\n --ol-button-size: var(--openleaf-button-size, 40px);\n --ol-gap: var(--openleaf-gap, 4px);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ol-editor .ol-btn {\n transition: none;\n }\n}\n\n/* Forced colours (Windows high contrast) replaces our palette wholesale. The\n pressed state must not depend on a background we no longer control, so it is\n re-expressed as a border, which the mode preserves. */\n@media (forced-colors: active) {\n .ol-editor .ol-btn {\n border-color: ButtonBorder;\n color: ButtonText;\n }\n .ol-editor .ol-btn[aria-pressed=\"true\"] {\n border-color: Highlight;\n color: Highlight;\n box-shadow: none;\n }\n .ol-editor .ol-btn:focus-visible {\n outline-color: Highlight;\n }\n .ol-editor .ol-btn[aria-disabled=\"true\"] {\n color: GrayText;\n opacity: 1;\n }\n .ol-editor .ol-menu-item:focus-visible {\n outline-color: Highlight;\n }\n .ol-editor .ol-menu-item[aria-disabled=\"true\"] {\n color: GrayText;\n opacity: 1;\n }\n .ol-editor .ol-menu-trigger[aria-expanded=\"true\"] {\n border-color: Highlight;\n color: Highlight;\n }\n .ol-editor .ol-content .ProseMirror .selectedCell {\n outline-color: Highlight;\n }\n .ol-editor .ol-content .ProseMirror .selectedCell::after {\n background: transparent;\n }\n .ol-editor .ol-content .ProseMirror .column-resize-handle {\n background: Highlight;\n }\n .ol-editor.ol-visual-aids .ol-nbsp {\n background: transparent;\n box-shadow: inset 0 -2px 0 Highlight;\n }\n .ol-editor.ol-visual-aids .ol-hidden-structure {\n outline-color: Highlight;\n }\n .ol-editor.ol-visual-aids .ol-empty-block {\n outline-color: GrayText;\n }\n .ol-editor .ol-noneditable {\n background: transparent;\n outline: 1px dashed GrayText;\n }\n}\n";
22
+ export declare const CSS = "\n.ol-editor {\n /* Two families, named before either is public API. A singular\n `--openleaf-font` implies \"the\" font, and source view already has a\n monospace surface -- bolting a mono token on beside a singular name later\n is the awkward outcome worth avoiding now. `--openleaf-font` is still\n honoured as a fallback. */\n --ol-font: var(--openleaf-font-ui, var(--openleaf-font, system-ui, -apple-system, \"Segoe UI\", sans-serif));\n --ol-font-mono: var(--openleaf-font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);\n --ol-font-size: var(--openleaf-font-size, 14px);\n --ol-radius: var(--openleaf-radius, 4px);\n --ol-text: var(--openleaf-color-text, #1f2328);\n --ol-text-muted: var(--openleaf-color-text-muted, #59636e);\n --ol-surface: var(--openleaf-color-surface, #ffffff);\n --ol-surface-hover: var(--openleaf-color-surface-hover, #f0f1f3);\n --ol-surface-active: var(--openleaf-color-surface-active, #dbe9ff);\n --ol-border: var(--openleaf-color-border, #d1d9e0);\n /* Control boundaries, not decoration. See \"Two border tokens\" above. */\n --ol-border-strong: var(--openleaf-color-border-strong, #6e7781);\n --ol-accent: var(--openleaf-color-accent, #0550ae);\n --ol-focus: var(--openleaf-color-focus, #0969da);\n --ol-danger: var(--openleaf-color-danger, #cf222e);\n --ol-button-size: var(--openleaf-button-size, 32px);\n --ol-icon-size: var(--openleaf-icon-size, 16px);\n --ol-gap: var(--openleaf-gap, 2px);\n /* A 2009 WordPress admin bar sits at z-index 99999 and Drupal's toolbar plays\n similar games. Without a sanctioned escape hatch integrators fix a toolbar\n rendered behind a sticky host header with !important -- the exact thing the\n token API exists to prevent. */\n --ol-z: var(--openleaf-z-index, 1);\n /* Thickness and offset, not just colour: \"you can change the colour but not\n the thickness\" is a poor answer to a Section 508 team citing WCAG 2.2\n Focus Appearance. */\n --ol-focus-width: var(--openleaf-focus-width, 2px);\n --ol-focus-offset: var(--openleaf-focus-offset, 1px);\n --ol-toolbar-sticky-offset: var(--openleaf-toolbar-sticky-offset, 0px);\n\n display: block;\n position: relative;\n color: var(--ol-text);\n}\n\n/* Three ways into the dark palette, and one way out of it.\n `data-ol-scheme` is set from the applied skin's declared scheme, and a skin\n that declares one outranks both the attribute and the system -- it has to,\n because its tokens have already replaced the palette outright. Without the\n `:not()` guards a light skin on a dark machine would take these fallbacks for\n every token it did not itself set, which is a light surface carrying dark-mode\n muted text. */\n@media (prefers-color-scheme: dark) {\n .ol-editor:not([data-ol-theme=\"light\"]):not([data-ol-scheme]) {\n --ol-text: var(--openleaf-color-text, #e6edf3);\n --ol-text-muted: var(--openleaf-color-text-muted, #9198a1);\n --ol-surface: var(--openleaf-color-surface, #0d1117);\n --ol-surface-hover: var(--openleaf-color-surface-hover, #21262d);\n --ol-surface-active: var(--openleaf-color-surface-active, #1f3a5f);\n --ol-border: var(--openleaf-color-border, #3d444d);\n --ol-border-strong: var(--openleaf-color-border-strong, #8b949e);\n --ol-accent: var(--openleaf-color-accent, #79c0ff);\n --ol-focus: var(--openleaf-color-focus, #79c0ff);\n --ol-danger: var(--openleaf-color-danger, #ff8182);\n}\n}\n\n.ol-editor[data-ol-theme=\"dark\"]:not([data-ol-scheme]) {\n --ol-text: var(--openleaf-color-text, #e6edf3);\n --ol-text-muted: var(--openleaf-color-text-muted, #9198a1);\n --ol-surface: var(--openleaf-color-surface, #0d1117);\n --ol-surface-hover: var(--openleaf-color-surface-hover, #21262d);\n --ol-surface-active: var(--openleaf-color-surface-active, #1f3a5f);\n --ol-border: var(--openleaf-color-border, #3d444d);\n --ol-border-strong: var(--openleaf-color-border-strong, #8b949e);\n --ol-accent: var(--openleaf-color-accent, #79c0ff);\n --ol-focus: var(--openleaf-color-focus, #79c0ff);\n --ol-danger: var(--openleaf-color-danger, #ff8182);\n}\n\n.ol-editor[data-ol-scheme=\"dark\"] {\n --ol-text: var(--openleaf-color-text, #e6edf3);\n --ol-text-muted: var(--openleaf-color-text-muted, #9198a1);\n --ol-surface: var(--openleaf-color-surface, #0d1117);\n --ol-surface-hover: var(--openleaf-color-surface-hover, #21262d);\n --ol-surface-active: var(--openleaf-color-surface-active, #1f3a5f);\n --ol-border: var(--openleaf-color-border, #3d444d);\n --ol-border-strong: var(--openleaf-color-border-strong, #8b949e);\n --ol-accent: var(--openleaf-color-accent, #79c0ff);\n --ol-focus: var(--openleaf-color-focus, #79c0ff);\n --ol-danger: var(--openleaf-color-danger, #ff8182);\n}\n\n/* Native widget chrome -- the popup a `select` opens, scrollbars, the caret,\n form control backgrounds -- is painted by the browser from `color-scheme`,\n not from any property we can hand an integrator. Left alone it follows the\n page, which is right while the editor's own palette also follows the page and\n wrong the moment either attribute pins the editor to one world. So it is set\n exactly when the editor stops following along, and inherited from the host\n otherwise. */\n.ol-editor[data-ol-theme=\"light\"] { color-scheme: light; }\n.ol-editor[data-ol-theme=\"dark\"] { color-scheme: dark; }\n.ol-editor[data-ol-scheme=\"light\"] { color-scheme: light; }\n.ol-editor[data-ol-scheme=\"dark\"] { color-scheme: dark; }\n\n/* Wrapping, not scrolling and not an overflow menu. Both of those hide\n controls -- one off-screen, one behind a click -- and a formatting control\n the author cannot see is a control they do not have. */\n.ol-editor .ol-toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--ol-gap);\n box-sizing: border-box;\n margin: 0;\n padding: 4px;\n border: 1px solid var(--ol-border-strong);\n border-bottom: 0;\n border-radius: var(--ol-radius) var(--ol-radius) 0 0;\n background: var(--ol-surface);\n font: inherit;\n position: sticky;\n top: var(--ol-toolbar-sticky-offset);\n z-index: var(--ol-z);\n}\n\n.ol-editor .ol-toolbar--secondary {\n position: relative;\n top: auto;\n}\n\n.ol-editor .ol-group {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--ol-gap);\n}\n\n/* The divider is a BORDER on the group, not a standalone flex item.\n As its own element it could wrap onto the trailing edge of a row with nothing\n after it -- a stranded line floating at the end of a row. Wrapping begins\n around 690-740px, well inside ordinary desktop widths (a CMS sidebar, a\n half-width split pane), so this was not a 360px-only edge case.\n border-inline-start rather than border-left, so it flips under RTL.\n\n This selector is why the renderer emits NO element between groups. It used to\n emit an .ol-sep div, which made the two groups non-adjacent and stopped this\n rule from ever matching -- so no divider rendered in any theme, and every bar\n carried inert empty divs. Adding a separator element back here breaks this. */\n.ol-editor .ol-group + .ol-group {\n border-inline-start: 1px solid var(--ol-border);\n padding-inline-start: 5px;\n margin-inline-start: 1px;\n}\n\n/* Every property a host reset or `button {}` rule is likely to touch is set\n here explicitly. Specificity is (0,2,0) via the descendant selector, which\n beats a bare element or single-class host rule without resorting to\n !important. */\n.ol-editor .ol-btn {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: var(--ol-button-size);\n height: var(--ol-button-size);\n min-width: var(--ol-button-size);\n min-height: var(--ol-button-size);\n max-width: none;\n padding: 0;\n margin: 0;\n border: 1px solid transparent;\n border-radius: var(--ol-radius);\n background: transparent;\n color: var(--ol-text);\n font: inherit;\n font-family: var(--ol-font);\n font-size: var(--ol-font-size);\n font-weight: 400;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n text-align: center;\n text-decoration: none;\n text-shadow: none;\n box-shadow: none;\n opacity: 1;\n cursor: pointer;\n appearance: none;\n -webkit-appearance: none;\n outline-offset: var(--ol-focus-offset);\n -webkit-tap-highlight-color: transparent;\n transition: background-color 120ms ease, border-color 120ms ease;\n}\n\n.ol-editor .ol-btn:hover {\n background: var(--ol-surface-hover);\n}\n\n/* :focus-visible only, so a mouse click does not leave a ring behind, but the\n ring is never removed for keyboard users. */\n.ol-editor .ol-btn:focus-visible {\n outline: var(--ol-focus-width) solid var(--ol-focus);\n outline-offset: var(--ol-focus-offset);\n}\n\n/* Pressed state is distinguished from hover by THREE signals, not just colour:\n a filled background, a visible border, and an inset shadow that reads as\n physically depressed. Colour alone would fail for a colour-blind author and\n would be invisible in forced-colours mode. */\n.ol-editor .ol-btn[aria-pressed=\"true\"] {\n background: var(--ol-surface-active);\n border-color: var(--ol-accent);\n color: var(--ol-accent);\n box-shadow: inset 0 1px 2px rgb(0 0 0 / 12%);\n}\n\n.ol-editor .ol-btn[aria-pressed=\"true\"]:hover {\n background: var(--ol-surface-active);\n border-color: var(--ol-accent);\n}\n\n/* aria-disabled rather than the disabled attribute: a disabled button is\n removed from the roving tabindex and cannot be reached or announced, so an\n author using a screen reader cannot discover that the control exists. */\n.ol-editor .ol-btn[aria-disabled=\"true\"] {\n opacity: 0.55;\n cursor: default;\n}\n\n.ol-editor .ol-btn[aria-disabled=\"true\"]:hover {\n background: transparent;\n}\n\n.ol-editor .ol-icon {\n width: var(--ol-icon-size);\n height: var(--ol-icon-size);\n display: block;\n pointer-events: none;\n flex: 0 0 auto;\n}\n\n/* Block-type select. Sized and coloured to sit level with the icon buttons so\n it does not read as bolted on, but it stays a native <select> -- a custom\n listbox is a large amount of ARIA that would then owe real screen reader\n testing to be worth anything. */\n.ol-editor .ol-select {\n box-sizing: border-box;\n height: var(--ol-button-size);\n max-width: 11em;\n padding: 0 22px 0 6px;\n margin: 0;\n border: 1px solid var(--ol-border-strong);\n border-radius: var(--ol-radius);\n background-color: transparent;\n background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),\n linear-gradient(135deg, currentColor 50%, transparent 50%);\n background-position: right 10px center, right 6px center;\n background-size: 4px 4px, 4px 4px;\n background-repeat: no-repeat;\n color: var(--ol-text);\n font-family: var(--ol-font);\n font-size: var(--ol-font-size);\n font-weight: 400;\n line-height: 1;\n text-transform: none;\n letter-spacing: normal;\n box-shadow: none;\n cursor: pointer;\n appearance: none;\n -webkit-appearance: none;\n}\n\n.ol-editor .ol-select--wide {\n max-width: 14em;\n}\n\n.ol-editor .ol-select:hover {\n background-color: var(--ol-surface-hover);\n}\n\n.ol-editor .ol-select:focus-visible {\n outline: var(--ol-focus-width) solid var(--ol-focus);\n outline-offset: var(--ol-focus-offset);\n}\n\n/* The option list is painted by the OS, which does not inherit our tokens, so\n give it explicit colours or dark mode shows black text on black. */\n.ol-editor .ol-select option {\n background: var(--ol-surface);\n color: var(--ol-text);\n}\n\n.ol-editor .ol-content {\n box-sizing: border-box;\n border: 1px solid var(--ol-border-strong);\n border-radius: 0 0 var(--ol-radius) var(--ol-radius);\n background: var(--ol-surface);\n}\n\n/* Deliberately minimal: the content area inherits the host's typography, which\n is the entire reason this project does not use Shadow DOM. Only padding and\n the focus ring are ours. */\n.ol-editor .ol-content .ProseMirror {\n padding: 12px;\n min-height: 8rem;\n outline: none;\n}\n\n.ol-editor .ol-content .ProseMirror :is(u, s, del) {\n text-decoration-color: currentColor;\n}\n.ol-editor .ol-content .ProseMirror u [style^=\"color:\"] {\n text-decoration: underline currentColor;\n}\n.ol-editor .ol-content .ProseMirror :is(s, del) [style^=\"color:\"] {\n text-decoration: line-through currentColor;\n}\n.ol-editor .ol-content .ProseMirror u :is(s, del) [style^=\"color:\"] {\n text-decoration: underline line-through currentColor;\n}\n\n.ol-editor .ol-content:focus-within {\n outline: 2px solid var(--ol-focus);\n outline-offset: -1px;\n}\n\n/* Tables.\n These styles live in core, not in the opt-in table plugin, because table\n NODES live in core: every deployment reads and renders tables even where\n editing them is switched off. Unstyled tables would render as runs of\n undelimited text. */\n.ol-editor .ol-content .ProseMirror table {\n border-collapse: collapse;\n table-layout: fixed;\n width: 100%;\n margin: 0 0 1em;\n overflow: hidden;\n}\n\n.ol-editor .ol-content .ProseMirror td,\n.ol-editor .ol-content .ProseMirror th {\n border: 1px solid var(--ol-border);\n padding: 6px 8px;\n vertical-align: top;\n /* A zero-width cell cannot be clicked into, so it cannot be repaired. */\n min-width: 2em;\n position: relative;\n}\n\n/* Presentational valign is otherwise beaten by the rule above, which would\n make the cell-properties dialog a no-op on screen. */\n.ol-editor .ol-content .ProseMirror td[valign=\"middle\"],\n.ol-editor .ol-content .ProseMirror th[valign=\"middle\"] { vertical-align: middle; }\n.ol-editor .ol-content .ProseMirror td[valign=\"bottom\"],\n.ol-editor .ol-content .ProseMirror th[valign=\"bottom\"] { vertical-align: bottom; }\n.ol-editor .ol-content .ProseMirror td[valign=\"baseline\"],\n.ol-editor .ol-content .ProseMirror th[valign=\"baseline\"] { vertical-align: baseline; }\n\n.ol-editor .ol-content .ProseMirror th {\n background: var(--ol-surface-hover);\n font-weight: 600;\n text-align: start;\n}\n\n/* prosemirror-tables marks cells in a rectangular selection with this class.\n An ::after overlay rather than a background so it composes with a cell that\n already has one, and so a header cell still reads as a header.\n\n The ring, not the tint, is the indicator -- see \"Cell selection\" above. */\n.ol-editor .ol-content .ProseMirror .selectedCell {\n outline: 2px solid var(--ol-accent);\n outline-offset: -2px;\n}\n.ol-editor .ol-content .ProseMirror .selectedCell::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background: var(--ol-surface-active);\n opacity: 0.4;\n pointer-events: none;\n}\n\n/* The column resize handle, drawn by prosemirror-tables' columnResizing. */\n.ol-editor .ol-content .ProseMirror .column-resize-handle {\n position: absolute;\n right: -2px;\n top: 0;\n bottom: 0;\n width: 4px;\n background: var(--ol-accent);\n pointer-events: none;\n z-index: 20;\n}\n\n.ol-editor .ol-content .ProseMirror.resize-cursor {\n cursor: col-resize;\n}\n\n.ol-editor .ol-content .ProseMirror img.ol-float-left {\n float: left;\n margin: 0 1em 0.5em 0;\n}\n.ol-editor .ol-content .ProseMirror img.ol-float-right {\n float: right;\n margin: 0 0 0.5em 1em;\n}\n.ol-editor .ol-content .ProseMirror img.ol-align-center {\n display: block;\n margin: 0 auto 0.5em;\n}\n.ol-editor .ol-content .ProseMirror figure {\n margin: 0 0 1em;\n}\n.ol-editor .ol-content .ProseMirror figcaption {\n font-size: .9em;\n opacity: .8;\n margin-top: .35em;\n}\n.ol-editor .ol-content .ProseMirror details {\n border: 1px solid var(--ol-border);\n border-radius: var(--ol-radius);\n padding: .5em .75em;\n margin: 0 0 1em;\n}\n.ol-editor .ol-content .ProseMirror summary {\n cursor: pointer;\n font-weight: 600;\n}\n.ol-editor .ol-content .ProseMirror hr.ol-pagebreak {\n border: 0;\n border-top: 2px dashed var(--ol-border);\n margin: 1.5em 0;\n}\n.ol-editor .ol-content .ProseMirror iframe,\n.ol-editor .ol-content .ProseMirror video,\n.ol-editor .ol-content .ProseMirror audio {\n max-width: 100%;\n}\n\n/* Preserved-but-unrecognised markup, surfaced rather than hidden. */\n.ol-editor .ol-content .ProseMirror-selectednode {\n outline: 2px solid var(--ol-focus);\n outline-offset: 2px;\n border-radius: 2px;\n}\n\n/* Gap cursor: the caret beside a block atom or isolating node, where no\n textblock exists. Hidden until the view is focused so it cannot paint over\n an inactive canvas. */\n.ol-editor .ol-content .ProseMirror-gapcursor {\n display: none;\n pointer-events: none;\n position: absolute;\n}\n.ol-editor .ol-content .ProseMirror-gapcursor:after {\n content: \"\";\n display: block;\n position: absolute;\n top: -2px;\n width: 20px;\n border-top: 1px solid var(--ol-text);\n animation: ol-gapcursor-blink 1.1s steps(2, start) infinite;\n}\n@keyframes ol-gapcursor-blink {\n to { visibility: hidden; }\n}\n.ol-editor .ol-content .ProseMirror-focused .ProseMirror-gapcursor {\n display: block;\n}\n\n.ol-editor .ol-source {\n box-sizing: border-box;\n display: block;\n width: 100%;\n min-height: 12rem;\n padding: 12px;\n border: 1px solid var(--ol-border-strong);\n border-radius: 0 0 var(--ol-radius) var(--ol-radius);\n background: var(--ol-surface);\n color: var(--ol-text);\n font-family: var(--ol-font-mono);\n font-size: 13px;\n line-height: 1.5;\n resize: vertical;\n white-space: pre-wrap;\n}\n\n/* Directional icons under RTL.\n Group order reverses for free with flexbox, but a curved undo arrow does not:\n in an RTL document \"back\" points the other way. Only genuinely directional\n icons are flipped -- bold and italic must not be mirrored. */\n.ol-editor[dir=\"rtl\"] .ol-icon--directional,\n[dir=\"rtl\"] .ol-editor .ol-icon--directional {\n transform: scaleX(-1);\n}\n\n/* The announcement region. Visually hidden but not display:none, which would\n remove it from the accessibility tree and silence it. */\n.ol-editor .ol-live {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n\n/* Menubar, menus, floating chrome, visual aids, fullscreen, inline. */\n.ol-editor .ol-menubar {\n display: flex;\n flex-wrap: wrap;\n gap: var(--ol-gap);\n box-sizing: border-box;\n margin: 0;\n padding: 2px 4px;\n border: 1px solid var(--ol-border-strong);\n border-bottom: 0;\n border-radius: var(--ol-radius) var(--ol-radius) 0 0;\n background: var(--ol-surface);\n position: relative;\n z-index: var(--ol-z);\n}\n.ol-editor .ol-menubar + .ol-toolbar {\n border-radius: 0;\n}\n.ol-editor .ol-menu-trigger {\n box-sizing: border-box;\n margin: 0;\n padding: 4px 8px;\n border: 1px solid transparent;\n border-radius: var(--ol-radius);\n background: transparent;\n color: var(--ol-text);\n font: inherit;\n font-family: var(--ol-font);\n font-size: var(--ol-font-size);\n cursor: pointer;\n appearance: none;\n}\n.ol-editor .ol-menu-trigger:hover,\n.ol-editor .ol-menu-trigger[aria-expanded=\"true\"] {\n background: var(--ol-surface-hover);\n}\n.ol-editor .ol-menu-trigger:focus-visible {\n outline: var(--ol-focus-width) solid var(--ol-focus);\n outline-offset: var(--ol-focus-offset);\n}\n.ol-editor .ol-menu {\n position: absolute;\n z-index: calc(var(--ol-z) + 20);\n min-width: 12rem;\n /* Capped, so a deep menu opened low on a short window can be flipped above\n its trigger instead of running off the bottom of the page. */\n max-height: 60vh;\n overflow-y: auto;\n margin: 0;\n padding: 4px;\n border: 1px solid var(--ol-border-strong);\n border-radius: var(--ol-radius);\n background: var(--ol-surface);\n box-shadow: 0 8px 24px rgb(0 0 0 / 12%);\n}\n.ol-editor .ol-menu-item {\n display: block;\n box-sizing: border-box;\n width: 100%;\n margin: 0;\n padding: 6px 10px;\n border: 0;\n border-radius: var(--ol-radius);\n background: transparent;\n color: var(--ol-text);\n font: inherit;\n font-family: var(--ol-font);\n font-size: var(--ol-font-size);\n text-align: start;\n cursor: pointer;\n appearance: none;\n}\n.ol-editor .ol-menu-item:hover {\n background: var(--ol-surface-hover);\n}\n/* Was outline:none plus a 1.13:1 background swap. See \"Menu focus\" above. */\n.ol-editor .ol-menu-item:focus-visible {\n background: var(--ol-surface-hover);\n outline: var(--ol-focus-width) solid var(--ol-focus);\n outline-offset: -2px;\n}\n/* 0.55, not 0.4: see \"Disabled is not invisible\" above. */\n.ol-editor .ol-menu-item[aria-disabled=\"true\"] {\n opacity: 0.55;\n cursor: default;\n}\n/* Third time for the same specificity trap, after the floating bar and the\n overflow panel below: `.ol-editor .ol-btn` is (0,2,0) and its\n `display: inline-flex` outranks the UA's `[hidden]` rule, so\n `button.hidden = true` set the attribute and painted the button anyway. A bar\n wide enough to need no overflow still showed its More trigger, and pressing\n it opened an empty panel. */\n.ol-editor .ol-btn[hidden] {\n display: none;\n}\n.ol-editor .ol-menu-sep {\n height: 1px;\n margin: 4px 0;\n background: var(--ol-border);\n}\n/* `display: flex` on .ol-toolbar above outranks the UA's `[hidden]` rule --\n a class selector beats an attribute selector on specificity -- so setting\n `el.hidden = true` in floating.ts styled a hidden bar and showed it anyway.\n Both floating bars sat over the prose at rest, with no selection to format.\n The overflow panel needed the same rule for the same reason; see below. */\n.ol-editor .ol-toolbar.ol-floating[hidden] {\n display: none;\n}\n.ol-editor .ol-toolbar.ol-floating {\n position: absolute;\n flex-wrap: nowrap;\n border: 1px solid var(--ol-border);\n border-radius: var(--ol-radius);\n box-shadow: 0 8px 24px rgb(0 0 0 / 12%);\n z-index: calc(var(--ol-z) + 10);\n}\n.ol-editor .ol-toolbar.ol-toolbar--overflow {\n flex-wrap: nowrap;\n overflow: hidden;\n}\n/* The More panel. Positioned in viewport coordinates from script, because the\n bar it belongs to may live inside a host with `overflow: hidden` -- which is\n the situation the whole feature exists for. */\n.ol-editor .ol-overflow-menu {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--ol-gap);\n max-height: 70vh;\n overflow-y: auto;\n}\n.ol-editor .ol-overflow-menu[hidden] {\n display: none;\n}\n/* Vertical: the panel exists because there is no horizontal room left. */\n.ol-editor .ol-overflow-menu .ol-group {\n flex-direction: column;\n align-items: stretch;\n}\n.ol-editor .ol-overflow-menu .ol-group + .ol-group {\n border-inline-start: 0;\n border-block-start: 1px solid var(--ol-border);\n padding-inline-start: 0;\n margin-inline-start: 0;\n padding-block-start: 4px;\n margin-block-start: 3px;\n}\n.ol-editor.ol-visual-aids .ol-empty-block {\n outline: 1px dashed var(--ol-border);\n outline-offset: 2px;\n min-height: 1.2em;\n}\n.ol-editor.ol-visual-aids .ol-nbsp {\n background: color-mix(in srgb, var(--ol-accent) 25%, transparent);\n box-shadow: inset 0 -1px 0 var(--ol-accent);\n}\n.ol-editor.ol-visual-aids .ol-hidden-structure {\n outline: 1px dotted var(--ol-accent);\n outline-offset: 2px;\n}\n.ol-editor .ol-noneditable {\n cursor: default;\n background: repeating-linear-gradient(\n -45deg,\n transparent,\n transparent 6px,\n color-mix(in srgb, var(--ol-border) 35%, transparent) 6px,\n color-mix(in srgb, var(--ol-border) 35%, transparent) 7px\n );\n}\n.ol-editor.ol-fullscreen {\n position: fixed;\n inset: 0;\n z-index: 2147483000;\n margin: 0;\n border-radius: 0;\n background: var(--ol-surface);\n display: flex;\n flex-direction: column;\n}\n.ol-editor.ol-fullscreen .ol-content,\n.ol-editor.ol-fullscreen .ol-source {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n}\n.ol-editor.ol-autoresize .ol-content .ProseMirror {\n overflow: hidden;\n}\n.ol-editor.ol-inline:not(.ol-inline-active) .ol-toolbar,\n.ol-editor.ol-inline:not(.ol-inline-active) .ol-menubar {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n}\n.ol-editor.ol-inline .ol-content {\n border-radius: var(--ol-radius);\n}\n.ol-help-table {\n width: 100%;\n border-collapse: collapse;\n font: inherit;\n}\n.ol-help-table th,\n.ol-help-table td {\n padding: 4px 8px;\n text-align: start;\n vertical-align: top;\n border-bottom: 1px solid var(--openleaf-color-border, #d1d9e0);\n}\n.ol-help-table th {\n font-weight: 600;\n white-space: nowrap;\n}\n\n/* Coarse pointers get a larger target. WCAG 2.2 SC 2.5.8 asks for 24x24 CSS px\n minimum; 32 clears that on a mouse and 40 is comfortable on a thumb. */\n@media (pointer: coarse) {\n .ol-editor {\n --ol-button-size: var(--openleaf-button-size, 40px);\n --ol-gap: var(--openleaf-gap, 4px);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ol-editor .ol-btn {\n transition: none;\n }\n}\n\n/* Forced colours (Windows high contrast) replaces our palette wholesale. The\n pressed state must not depend on a background we no longer control, so it is\n re-expressed as a border, which the mode preserves. */\n@media (forced-colors: active) {\n .ol-editor .ol-btn {\n border-color: ButtonBorder;\n color: ButtonText;\n }\n .ol-editor .ol-btn[aria-pressed=\"true\"] {\n border-color: Highlight;\n color: Highlight;\n box-shadow: none;\n }\n .ol-editor .ol-btn:focus-visible {\n outline-color: Highlight;\n }\n .ol-editor .ol-btn[aria-disabled=\"true\"] {\n color: GrayText;\n opacity: 1;\n }\n .ol-editor .ol-menu-item:focus-visible {\n outline-color: Highlight;\n }\n .ol-editor .ol-menu-item[aria-disabled=\"true\"] {\n color: GrayText;\n opacity: 1;\n }\n .ol-editor .ol-menu-trigger[aria-expanded=\"true\"] {\n border-color: Highlight;\n color: Highlight;\n }\n .ol-editor .ol-content .ProseMirror .selectedCell {\n outline-color: Highlight;\n }\n .ol-editor .ol-content .ProseMirror .selectedCell::after {\n background: transparent;\n }\n .ol-editor .ol-content .ProseMirror .column-resize-handle {\n background: Highlight;\n }\n .ol-editor.ol-visual-aids .ol-nbsp {\n background: transparent;\n box-shadow: inset 0 -2px 0 Highlight;\n }\n .ol-editor.ol-visual-aids .ol-hidden-structure {\n outline-color: Highlight;\n }\n .ol-editor.ol-visual-aids .ol-empty-block {\n outline-color: GrayText;\n }\n .ol-editor .ol-noneditable {\n background: transparent;\n outline: 1px dashed GrayText;\n }\n}\n";
23
23
  //# sourceMappingURL=css.d.ts.map
package/dist/css.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAkFH,eAAO,MAAM,GAAG,k2wBAwsBf,CAAA"}
1
+ {"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAqHH,eAAO,MAAM,GAAG,6n0BA6vBf,CAAA"}
package/dist/css.js CHANGED
@@ -84,6 +84,41 @@
84
84
  * had no indicator at all: which menu is open, which menu item has focus, which
85
85
  * cells are selected, and every one of the visual aids -- whose entire output
86
86
  * is a colour.
87
+ *
88
+ * ### Sticky toolbar
89
+ *
90
+ * The main bar sticks to the nearest scrolling ancestor. Page scroll is the
91
+ * one that used to take it off-screen: autoresize grows the canvas
92
+ * (`overflow: hidden` on `.ProseMirror`, a descendant, so it is not a
93
+ * sticky-killing scrollport above the bar) and the page moves. The host
94
+ * itself has no overflow. Fullscreen is a column flex whose `.ol-content` /
95
+ * `.ol-source` scroll -- the bar is not in that scroller, so sticky is a
96
+ * no-op there and the bar already stays put. Do not "fix" fullscreen.
97
+ *
98
+ * Floating bars re-specify `position: absolute` at (0,3,0), so they are not
99
+ * stuck. A second toolbar (`toolbar2`) carries `.ol-toolbar--secondary` and
100
+ * is reset to `relative`: two sticky bars at the same `top` would paint on
101
+ * top of each other, and a sibling selector would miss the supported
102
+ * `toolbar="none" toolbar2="..."` layout, where this bar is the first
103
+ * `.ol-toolbar`. The menubar is not sticky for the same stacking reason.
104
+ * `--openleaf-toolbar-sticky-offset` is the host-header pad; 0px so a host
105
+ * that never heard of the token still gets a bar that stays on screen.
106
+ *
107
+ * ### Decoration colour
108
+ *
109
+ * CSS Text Decorations paint the line in the originating element's colour.
110
+ * Schema order wraps `<u>`/`<s>` around the colour span, so a rule on `u, s`
111
+ * that sets `text-decoration-color: currentColor` is a no-op -- that is
112
+ * already the initial value, and it is the paragraph colour, not the glyphs'.
113
+ * A descendant cannot retint an ancestor's already-painted line. The colour
114
+ * span therefore re-establishes the same line in *its* `currentColor`; the
115
+ * ancestor's line remains and is covered (measured in Chromium and WebKit).
116
+ * The opposite nest -- colour wrapping `<u>`/`<s>` -- already inherits, and
117
+ * the first rule is what that nest needs if an engine's UA default is not
118
+ * `currentColor`. Highlight is background only: the line should still match
119
+ * the foreground, which the first rule does. Combined underline+strike
120
+ * re-establishes both lines, because a later `line-through` rule would
121
+ * otherwise leave the underline in the paragraph colour.
87
122
  */
88
123
  const DARK_TOKENS = `
89
124
  --ol-text: var(--openleaf-color-text, #e6edf3);
@@ -132,6 +167,7 @@ export const CSS = `
132
167
  Focus Appearance. */
133
168
  --ol-focus-width: var(--openleaf-focus-width, 2px);
134
169
  --ol-focus-offset: var(--openleaf-focus-offset, 1px);
170
+ --ol-toolbar-sticky-offset: var(--openleaf-toolbar-sticky-offset, 0px);
135
171
 
136
172
  display: block;
137
173
  position: relative;
@@ -181,10 +217,16 @@ export const CSS = `
181
217
  border-radius: var(--ol-radius) var(--ol-radius) 0 0;
182
218
  background: var(--ol-surface);
183
219
  font: inherit;
184
- position: relative;
220
+ position: sticky;
221
+ top: var(--ol-toolbar-sticky-offset);
185
222
  z-index: var(--ol-z);
186
223
  }
187
224
 
225
+ .ol-editor .ol-toolbar--secondary {
226
+ position: relative;
227
+ top: auto;
228
+ }
229
+
188
230
  .ol-editor .ol-group {
189
231
  display: flex;
190
232
  flex-wrap: wrap;
@@ -364,6 +406,19 @@ export const CSS = `
364
406
  outline: none;
365
407
  }
366
408
 
409
+ .ol-editor .ol-content .ProseMirror :is(u, s, del) {
410
+ text-decoration-color: currentColor;
411
+ }
412
+ .ol-editor .ol-content .ProseMirror u [style^="color:"] {
413
+ text-decoration: underline currentColor;
414
+ }
415
+ .ol-editor .ol-content .ProseMirror :is(s, del) [style^="color:"] {
416
+ text-decoration: line-through currentColor;
417
+ }
418
+ .ol-editor .ol-content .ProseMirror u :is(s, del) [style^="color:"] {
419
+ text-decoration: underline line-through currentColor;
420
+ }
421
+
367
422
  .ol-editor .ol-content:focus-within {
368
423
  outline: 2px solid var(--ol-focus);
369
424
  outline-offset: -1px;
@@ -489,6 +544,30 @@ export const CSS = `
489
544
  border-radius: 2px;
490
545
  }
491
546
 
547
+ /* Gap cursor: the caret beside a block atom or isolating node, where no
548
+ textblock exists. Hidden until the view is focused so it cannot paint over
549
+ an inactive canvas. */
550
+ .ol-editor .ol-content .ProseMirror-gapcursor {
551
+ display: none;
552
+ pointer-events: none;
553
+ position: absolute;
554
+ }
555
+ .ol-editor .ol-content .ProseMirror-gapcursor:after {
556
+ content: "";
557
+ display: block;
558
+ position: absolute;
559
+ top: -2px;
560
+ width: 20px;
561
+ border-top: 1px solid var(--ol-text);
562
+ animation: ol-gapcursor-blink 1.1s steps(2, start) infinite;
563
+ }
564
+ @keyframes ol-gapcursor-blink {
565
+ to { visibility: hidden; }
566
+ }
567
+ .ol-editor .ol-content .ProseMirror-focused .ProseMirror-gapcursor {
568
+ display: block;
569
+ }
570
+
492
571
  .ol-editor .ol-source {
493
572
  box-sizing: border-box;
494
573
  display: block;
@@ -616,6 +695,15 @@ export const CSS = `
616
695
  opacity: 0.55;
617
696
  cursor: default;
618
697
  }
698
+ /* Third time for the same specificity trap, after the floating bar and the
699
+ overflow panel below: \`.ol-editor .ol-btn\` is (0,2,0) and its
700
+ \`display: inline-flex\` outranks the UA's \`[hidden]\` rule, so
701
+ \`button.hidden = true\` set the attribute and painted the button anyway. A bar
702
+ wide enough to need no overflow still showed its More trigger, and pressing
703
+ it opened an empty panel. */
704
+ .ol-editor .ol-btn[hidden] {
705
+ display: none;
706
+ }
619
707
  .ol-editor .ol-menu-sep {
620
708
  height: 1px;
621
709
  margin: 4px 0;
package/dist/css.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"css.js","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;GAOG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAEH,MAAM,WAAW,GAAG;;;;;;;;;;;CAWnB,CAAA;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mEAiDgD,WAAW;;;0DAGpB,WAAW;;qCAEhC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkpB/C,CAAA"}
1
+ {"version":3,"file":"css.js","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;GAOG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4FG;AAEH,MAAM,WAAW,GAAG;;;;;;;;;;;CAWnB,CAAA;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mEAkDgD,WAAW;;;0DAGpB,WAAW;;qCAEhC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAssB/C,CAAA"}
@@ -7,8 +7,17 @@
7
7
  * extra job, and it is deliberately pointer-driven: a keyboard user already
8
8
  * has Alt+F10 for the main toolbar, and a second bar that jumps around under
9
9
  * arrow keys is a focus trap waiting to happen.
10
+ *
11
+ * Visibility is not selection-shape alone. The bars follow the same rule the
12
+ * main toolbar already uses in inline mode -- shown while the editor is the
13
+ * thing the author is using -- plus two extra gates the main bar does not
14
+ * need because its buttons disable in place: the editor is editable, and the
15
+ * selection is not inside a locked node. Without those, a click on the host
16
+ * page left the selection bar painted, a readonly empty editor showed the
17
+ * insert bar on mount, and a range inside `contenteditable="false"` still
18
+ * offered Bold.
10
19
  */
11
- import type { EditorState } from 'prosemirror-state';
20
+ import { type EditorState } from 'prosemirror-state';
12
21
  import type { EditorView } from 'prosemirror-view';
13
22
  export declare const DEFAULT_SELECTION_LAYOUT = "bold italic underline | link";
14
23
  export declare const DEFAULT_INSERT_LAYOUT = "link image horizontalRule";
@@ -1 +1 @@
1
- {"version":3,"file":"floating.d.ts","sourceRoot":"","sources":["../src/floating.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAGlD,eAAO,MAAM,wBAAwB,iCAAiC,CAAA;AACtE,eAAO,MAAM,qBAAqB,8BAA8B,CAAA;AAEhE,qBAAa,gBAAgB;;gBASzB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE;QACP,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC5B,8EAA8E;QAC9E,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KACvB;IA2BH,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IA6B7B,8EAA8E;IAC9E,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKpC,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAMhC,OAAO,IAAI,IAAI;CA0ChB"}
1
+ {"version":3,"file":"floating.d.ts","sourceRoot":"","sources":["../src/floating.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAKlD,eAAO,MAAM,wBAAwB,iCAAiC,CAAA;AACtE,eAAO,MAAM,qBAAqB,8BAA8B,CAAA;AAEhE,qBAAa,gBAAgB;;gBAoBzB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE;QACP,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC5B,8EAA8E;QAC9E,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KACvB;IA0BH,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IA0C7B,8EAA8E;IAC9E,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKpC,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAMhC,OAAO,IAAI,IAAI;CA6FhB"}
package/dist/floating.js CHANGED
@@ -7,20 +7,41 @@
7
7
  * extra job, and it is deliberately pointer-driven: a keyboard user already
8
8
  * has Alt+F10 for the main toolbar, and a second bar that jumps around under
9
9
  * arrow keys is a focus trap waiting to happen.
10
+ *
11
+ * Visibility is not selection-shape alone. The bars follow the same rule the
12
+ * main toolbar already uses in inline mode -- shown while the editor is the
13
+ * thing the author is using -- plus two extra gates the main bar does not
14
+ * need because its buttons disable in place: the editor is editable, and the
15
+ * selection is not inside a locked node. Without those, a click on the host
16
+ * page left the selection bar painted, a readonly empty editor showed the
17
+ * insert bar on mount, and a range inside `contenteditable="false"` still
18
+ * offered Bold.
10
19
  */
20
+ import { isNonEditableNode } from '@openleaf-editor/core';
21
+ import { NodeSelection } from 'prosemirror-state';
11
22
  import { Toolbar } from './toolbar.js';
12
23
  export const DEFAULT_SELECTION_LAYOUT = 'bold italic underline | link';
13
24
  export const DEFAULT_INSERT_LAYOUT = 'link image horizontalRule';
14
25
  export class FloatingToolbars {
15
26
  #host;
16
- #doc;
17
27
  #view = null;
18
28
  #resize = null;
29
+ #readonlyObserver = null;
19
30
  #selection;
20
31
  #insert;
32
+ /**
33
+ * True between a pointerdown inside the canvas and the matching pointerup.
34
+ *
35
+ * `view.hasFocus()` is false during the pointer sequence that is
36
+ * *establishing* the selection in some engines -- the range updates, the
37
+ * transaction runs, `#position` runs, and focus has not moved into the view
38
+ * yet. A naive `hasFocus()` guard then hides the selection bar on a normal
39
+ * drag-select. Pointer-driven placement is intentional; this flag is what
40
+ * keeps it from becoming a focus trap under a hide-unless-focused rule.
41
+ */
42
+ #pointerSelecting = false;
21
43
  constructor(host, doc, options) {
22
44
  this.#host = host;
23
- this.#doc = doc;
24
45
  const locale = options.locale ?? null;
25
46
  this.#selection = options.selectionLayout
26
47
  ? new Toolbar(host, doc, {
@@ -47,6 +68,20 @@ export class FloatingToolbars {
47
68
  this.#view = view;
48
69
  this.#selection?.mount(view);
49
70
  this.#insert?.mount(view);
71
+ view.dom.addEventListener('focusin', this.#sync);
72
+ view.dom.addEventListener('focusout', this.#onFocusOut);
73
+ view.dom.addEventListener('pointerdown', this.#onPointerDown);
74
+ const doc = view.dom.ownerDocument;
75
+ doc.addEventListener('pointerup', this.#onPointerUp);
76
+ doc.addEventListener('pointercancel', this.#onPointerUp);
77
+ // Workaround: `OpenLeafEditor.#applyReadonly` updates the main bars and
78
+ // not these. The cleaner fix is `this.#floating?.update(view.state)`
79
+ // there; this file cannot reach it. Watching the attribute covers mount
80
+ // and a later `readonly` without that hook.
81
+ if (typeof MutationObserver !== 'undefined') {
82
+ this.#readonlyObserver = new MutationObserver(this.#sync);
83
+ this.#readonlyObserver.observe(this.#host, { attributes: true, attributeFilter: ['readonly'] });
84
+ }
50
85
  // Position from the state we are mounted with, not from the first
51
86
  // transaction after it. An editor that opens on an empty paragraph -- a new
52
87
  // post, the commonest way to meet one -- has the caret in exactly the place
@@ -55,7 +90,9 @@ export class FloatingToolbars {
55
90
  //
56
91
  // This was invisible while `hidden` did nothing: both bars were painted
57
92
  // whatever the state said, so the missing initial position looked like a
58
- // working feature. Fixing the CSS is what made it observable.
93
+ // working feature. Fixing the CSS is what made it observable. The focus /
94
+ // readonly / lock gates below apply here too: an unfocused or readonly
95
+ // editor that opens on an empty block still must not show the insert bar.
59
96
  this.#position(view.state);
60
97
  // Reposition when the editor's box actually changes, rather than chasing
61
98
  // each thing that can change it. An editor revealed from a hidden tab, a
@@ -63,11 +100,7 @@ export class FloatingToolbars {
63
100
  // resize -- none of them dispatch an editor transaction, and all of them
64
101
  // move the caret out from under a bar placed in viewport coordinates.
65
102
  if (typeof ResizeObserver !== 'undefined') {
66
- this.#resize = new ResizeObserver(() => {
67
- const current = this.#view;
68
- if (current && !current.isDestroyed)
69
- this.#position(current.state);
70
- });
103
+ this.#resize = new ResizeObserver(this.#sync);
71
104
  this.#resize.observe(view.dom);
72
105
  }
73
106
  }
@@ -82,13 +115,30 @@ export class FloatingToolbars {
82
115
  this.#position(state);
83
116
  }
84
117
  destroy() {
118
+ const view = this.#view;
119
+ if (view?.dom) {
120
+ view.dom.removeEventListener('focusin', this.#sync);
121
+ view.dom.removeEventListener('focusout', this.#onFocusOut);
122
+ view.dom.removeEventListener('pointerdown', this.#onPointerDown);
123
+ const doc = view.dom.ownerDocument;
124
+ doc.removeEventListener('pointerup', this.#onPointerUp);
125
+ doc.removeEventListener('pointercancel', this.#onPointerUp);
126
+ }
127
+ this.#pointerSelecting = false;
85
128
  this.#resize?.disconnect();
86
129
  this.#resize = null;
130
+ this.#readonlyObserver?.disconnect();
131
+ this.#readonlyObserver = null;
87
132
  this.#selection?.destroy();
88
133
  this.#insert?.destroy();
89
134
  this.#selection?.el.remove();
90
135
  this.#insert?.el.remove();
91
136
  }
137
+ #sync = () => {
138
+ const view = this.#view;
139
+ if (view && !view.isDestroyed)
140
+ this.#position(view.state);
141
+ };
92
142
  #position(state) {
93
143
  const view = this.#view;
94
144
  if (!view)
@@ -97,34 +147,113 @@ export class FloatingToolbars {
97
147
  // -- a hidden tab, a collapsed dialog -- measures every caret at 0,0, and a
98
148
  // bar shown there sits in the corner of the page rather than by the text.
99
149
  // It stays hidden until the box exists; the observer above brings it back.
150
+ //
151
+ // Shown only while the author is actually using this editor on unlocked
152
+ // content. Inline mode already clips every `.ol-toolbar` until the host is
153
+ // focused; framed mode had no equivalent, which is how a leftover range
154
+ // painted a second toolbar over an inactive page. `view.editable` is the
155
+ // live reading of `readonly` (and of anything else that flipped
156
+ // `editable()`), so a consumer that never sets the attribute still hides.
100
157
  const box = view.dom.getBoundingClientRect();
101
- if (box.width === 0 && box.height === 0) {
102
- if (this.#selection)
103
- this.#selection.el.hidden = true;
104
- if (this.#insert)
105
- this.#insert.el.hidden = true;
106
- return;
107
- }
108
- const empty = state.selection.empty;
158
+ const sel = state.selection;
159
+ const empty = sel.empty;
160
+ const allowed = (box.width !== 0 || box.height !== 0) &&
161
+ !this.#host.hasAttribute('readonly') &&
162
+ view.editable !== false &&
163
+ (view.hasFocus() || this.#pointerSelecting) &&
164
+ !selectionInLockedContent(state);
109
165
  if (this.#selection) {
110
- this.#selection.el.hidden = empty;
111
- if (!empty)
112
- this.#place(this.#selection.el, view, state.selection.from);
166
+ const show = allowed && !empty;
167
+ this.#selection.el.hidden = !show;
168
+ if (show)
169
+ this.#place(this.#selection.el, view, sel.from);
113
170
  }
114
171
  if (this.#insert) {
115
- const $from = state.selection.$from;
116
- const showInsert = empty && $from.parent.isTextblock && $from.parent.content.size === 0;
117
- this.#insert.el.hidden = !showInsert;
118
- if (showInsert)
119
- this.#place(this.#insert.el, view, state.selection.from);
172
+ const parent = sel.$from.parent;
173
+ const show = allowed && empty && parent.isTextblock && parent.content.size === 0;
174
+ this.#insert.el.hidden = !show;
175
+ if (show)
176
+ this.#place(this.#insert.el, view, sel.from);
120
177
  }
121
178
  }
179
+ #onFocusOut = (event) => {
180
+ if (this.#pointerSelecting)
181
+ return;
182
+ const next = event.relatedTarget;
183
+ // Focus moving to chrome we own -- a main-toolbar button, a floating
184
+ // button whose `mousedown` `preventDefault` failed -- is not a blur of
185
+ // the editor as far as the author is concerned.
186
+ if (next instanceof Node && this.#host.contains(next))
187
+ return;
188
+ // Some engines deliver `focusout` with a null `relatedTarget` before the
189
+ // next target is focused, or before the view has taken focus during the
190
+ // pointer sequence. Recheck after the event; `hasFocus()` is then honest.
191
+ queueMicrotask(this.#sync);
192
+ };
193
+ #onPointerDown = (event) => {
194
+ if ('button' in event && event.button !== 0)
195
+ return;
196
+ this.#pointerSelecting = true;
197
+ this.#sync();
198
+ };
199
+ #onPointerUp = () => {
200
+ if (!this.#pointerSelecting)
201
+ return;
202
+ this.#pointerSelecting = false;
203
+ this.#sync();
204
+ };
122
205
  #place(el, view, pos) {
123
206
  const coords = view.coordsAtPos(pos);
124
207
  const hostBox = this.#host.getBoundingClientRect();
125
208
  el.style.left = `${coords.left - hostBox.left}px`;
126
209
  el.style.top = `${coords.bottom - hostBox.top + 8}px`;
127
- void this.#doc;
128
210
  }
129
211
  }
212
+ /**
213
+ * True when the selection covers no unlocked content.
214
+ *
215
+ * Hide the bar over a caret or a range that lives entirely inside a locked
216
+ * node (or *is* a preserved atom): Bold would no-op, and offering it on text
217
+ * the author cannot change is the original bug. Do not hide it merely because
218
+ * the range *contains* a locked node. Select All, and a drag that starts
219
+ * before a `contenteditable="false"` block and ends after it, still have
220
+ * unlocked text the author can format -- `filterTransaction` already refuses
221
+ * the locked interior. Walking only `[from, to]` (and stopping at the first
222
+ * unlocked text) keeps this off the empty-caret keystroke path.
223
+ *
224
+ * `isNonEditableNode` is the same predicate the transaction filter uses.
225
+ * Preserved atoms (`unknown_block` / `unknown_inline`) are uneditable as a
226
+ * whole. Other atoms (an image, a rule) are not locked in that sense.
227
+ */
228
+ function selectionInLockedContent(state) {
229
+ const sel = state.selection;
230
+ if (sel.empty)
231
+ return lockedAncestor(sel.$from);
232
+ if (sel instanceof NodeSelection)
233
+ return isLockedNode(sel.node);
234
+ let unlocked = false;
235
+ state.doc.nodesBetween(sel.from, sel.to, (node) => {
236
+ if (unlocked)
237
+ return false;
238
+ if (isLockedNode(node))
239
+ return false;
240
+ if (node.isText && (node.text?.length ?? 0) > 0) {
241
+ unlocked = true;
242
+ return false;
243
+ }
244
+ return true;
245
+ });
246
+ return !unlocked;
247
+ }
248
+ function lockedAncestor($pos) {
249
+ for (let depth = $pos.depth; depth > 0; depth -= 1) {
250
+ if (isLockedNode($pos.node(depth)))
251
+ return true;
252
+ }
253
+ return false;
254
+ }
255
+ function isLockedNode(node) {
256
+ const name = node.type.name;
257
+ return isNonEditableNode(node) || name === 'unknown_block' || name === 'unknown_inline';
258
+ }
130
259
  //# sourceMappingURL=floating.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"floating.js","sourceRoot":"","sources":["../src/floating.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"floating.js","sourceRoot":"","sources":["../src/floating.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA4BH,wBAAgB,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,CAElE"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoCH,wBAAgB,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,CAElE"}