@openleaf-editor/plugins-insert 0.1.0-beta.2 → 0.1.0-beta.4

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
@@ -1,11 +1,26 @@
1
1
  # `@openleaf-editor/plugins-insert`
2
2
 
3
- Insert and structure tools for [OpenLeaf](https://github.com/PeytonNowlin/openleaf): media embeds, collapsible sections, named anchors, a character map, emoji, date and time, page breaks, snippets, and image resize handles.
3
+ Insert and structure tools for [OpenLeaf](https://github.com/PeytonNowlin/openleaf): media embeds, collapsible sections, named anchors, a character map, emoji, date and time, page breaks, snippets, and drag-resize handles for images and video.
4
4
 
5
5
  The matching **schema nodes live in `@openleaf-editor/core`**, so stored `<video>`, `<iframe>`, `<details>` and `<figure>` round-trip whether or not this package is loaded. This bundle is the editing chrome.
6
6
 
7
+ The **Anchor** control inserts an empty named destination (`<a id="…"></a>`), the TinyMCE-style jump target. That is a modelled atom, including pretty-printed whitespace-only interiors. An `<a id>` that *wraps* text — `<h2><a id="sec">Title</a></h2>` — is not that atom: core parses it as a `link` mark with `id` and no `href`, so the heading stays editable and the id round-trips. `<a id href>` is an ordinary link. `<a name>` is unmatched and preserved.
8
+
7
9
  Iframes are stored only when their `src` is an `https:` URL on a known player host (`youtube.com/embed`, `player.vimeo.com/video`, and the rest of the allowlist). Arbitrary iframes are still dropped.
8
10
 
11
+ A `<video>` renders as an inert preview in the editor — no control bar, and no pointer events — because native media chrome takes those events for itself, and in Firefox it takes them for the whole element: nothing in the editor would ever see the click, so ProseMirror would never select the node and the player could be inserted once and never edited again. Selecting a video puts a play button of this package's own over the frame; pressing it hands that one element its controls and its pointer events back for as long as it stays selected, and moving the selection away or pressing Escape returns it to a preview. Stored HTML is serialized from the node rather than from the editing DOM, so `controls` round-trips untouched in every state and the player is fully interactive on the published page. A caption track the author turned on stays on across a resize: the `<source>` and `<track>` children are rebuilt only when the stored markup changes, since a fresh `<track>` element means a fresh `TextTrack` with its `mode` back at `disabled`.
12
+
13
+ > **Editor output is untrusted input.** Whatever the editor produces — and
14
+ > whatever a user pasted into it — must be sanitized **on your server** before it
15
+ > is stored or rendered as HTML. Client-side sanitization is a user-experience
16
+ > feature, not a security control: anything the editor strips can be put back
17
+ > with developer tools, because the editor runs under the user's control.
18
+ >
19
+ > [`@openleaf-editor/sanitize`](https://github.com/PeytonNowlin/openleaf/tree/main/packages/sanitize) ships the
20
+ > canonical allowlist as data and generates configuration for DOMPurify, Python
21
+ > `bleach` and PHP HTMLPurifier from it, so client and server enforce the same
22
+ > rules. Read [SECURITY.md](https://github.com/PeytonNowlin/openleaf/blob/main/SECURITY.md) before you ship.
23
+
9
24
  ## Install
10
25
 
11
26
  ```bash
@@ -52,3 +67,30 @@ registerLinkList([
52
67
  registerImageList([{ title: 'Hero', value: '/media/hero.jpg' }])
53
68
  registerImageClasses(['align-left', 'full-width'])
54
69
  ```
70
+
71
+ ## Toolbar item ids
72
+
73
+ | Id | Control |
74
+ | --- | --- |
75
+ | `media` | Insert media (video, audio, allowlisted embed) — or edit the selected player |
76
+ | `details` | Collapsible section |
77
+ | `anchor` | Named anchor |
78
+ | `charmap` | Character map |
79
+ | `emoji` | Emoji picker |
80
+ | `datetime` | Insert date and time |
81
+ | `pagebreak` | Page break |
82
+ | `nbsp` | Non-breaking space |
83
+ | `snippet` | Snippet |
84
+
85
+ Name the ones you want in the element's `toolbar` attribute. An id nothing has
86
+ registered logs a warning rather than being skipped silently.
87
+
88
+ ## Character map and emoji
89
+
90
+ Both pickers are the same control: a toolbar trigger and a grid of named glyphs.
91
+ Arrow keys move by one and by a row, Home and End go to the ends of a row,
92
+ Escape closes and returns focus to the trigger, and Tab leaves the widget
93
+ (there is one tab stop inside the grid). The grid is `role="grid"` with row and
94
+ gridcell structure, matching the colour picker, so a screen reader can say
95
+ which cell the author is on.
96
+
package/dist/glyphs.d.ts CHANGED
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Columns per row in the character and emoji grids.
3
+ *
4
+ * The keyboard model (arrow keys, Home, End) reads this, not a CSS value. The
5
+ * stylesheet's `repeat(8, 2rem)` has to stay in lockstep -- that is why the
6
+ * colour picker exports `PALETTE_COLUMNS` rather than counting cells at runtime.
7
+ */
8
+ export declare const GLYPH_COLUMNS = 8;
1
9
  /** Common typographic characters, named for the grid's accessible labels. */
2
10
  export declare const CHARACTERS: ReadonlyArray<{
3
11
  char: string;
@@ -1 +1 @@
1
- {"version":3,"file":"glyphs.d.ts","sourceRoot":"","sources":["../src/glyphs.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAyCpE,CAAA;AAED,eAAO,MAAM,KAAK,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAiC/D,CAAA"}
1
+ {"version":3,"file":"glyphs.d.ts","sourceRoot":"","sources":["../src/glyphs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,IAAI,CAAA;AAE9B,6EAA6E;AAC7E,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAyCpE,CAAA;AAED,eAAO,MAAM,KAAK,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAiC/D,CAAA"}
package/dist/glyphs.js CHANGED
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Columns per row in the character and emoji grids.
3
+ *
4
+ * The keyboard model (arrow keys, Home, End) reads this, not a CSS value. The
5
+ * stylesheet's `repeat(8, 2rem)` has to stay in lockstep -- that is why the
6
+ * colour picker exports `PALETTE_COLUMNS` rather than counting cells at runtime.
7
+ */
8
+ export const GLYPH_COLUMNS = 8;
1
9
  /** Common typographic characters, named for the grid's accessible labels. */
2
10
  export const CHARACTERS = [
3
11
  { char: '©', name: 'Copyright' },
@@ -1 +1 @@
1
- {"version":3,"file":"glyphs.js","sourceRoot":"","sources":["../src/glyphs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"glyphs.js","sourceRoot":"","sources":["../src/glyphs.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAO3F,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE;IACP,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACrD,GACA,cAAc,CAkHhB"}
1
+ {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AA+B3F,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE;IACP,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACrD,GACA,cAAc,CAoPhB"}
package/dist/grid.js CHANGED
@@ -1,6 +1,30 @@
1
1
  import { iconElement } from '@openleaf-editor/ui';
2
2
  import { insertText } from '@openleaf-editor/core';
3
+ import { GLYPH_COLUMNS } from './glyphs.js';
3
4
  const SUPPORTS_POPOVER = typeof HTMLElement !== 'undefined' && 'popover' in HTMLElement.prototype;
5
+ /**
6
+ * True when focus is moving into one of `roots`, including across shadow trees.
7
+ *
8
+ * `document.activeElement` is the shadow host from outside the tree, so a
9
+ * deferred check against it closes the panel the moment a glyph is focused.
10
+ * `relatedTarget` is the node that actually received focus; walking its
11
+ * composed ancestors covers a retargeted event the same way.
12
+ */
13
+ function relatedInside(event, ...roots) {
14
+ let node = event.relatedTarget instanceof Node ? event.relatedTarget : null;
15
+ while (node) {
16
+ const current = node;
17
+ if (roots.some((root) => current === root || root.contains(current)))
18
+ return true;
19
+ if (current.parentNode) {
20
+ node = current.parentNode;
21
+ continue;
22
+ }
23
+ const tree = current.getRootNode();
24
+ node = tree instanceof ShadowRoot ? tree.host : null;
25
+ }
26
+ return false;
27
+ }
4
28
  export function buildGlyphPicker(ctx, options) {
5
29
  const { view, host } = ctx;
6
30
  const doc = host.ownerDocument;
@@ -8,48 +32,63 @@ export function buildGlyphPicker(ctx, options) {
8
32
  const trigger = doc.createElement('button');
9
33
  trigger.type = 'button';
10
34
  trigger.className = 'ol-btn';
11
- trigger.dataset['olId'] = options.label;
35
+ trigger.dataset['olId'] = ctx.id ?? options.label;
12
36
  trigger.setAttribute('aria-label', options.label);
13
- trigger.setAttribute('aria-haspopup', 'true');
37
+ trigger.setAttribute('aria-haspopup', 'grid');
14
38
  trigger.setAttribute('aria-expanded', 'false');
15
39
  trigger.appendChild(iconElement(options.icon, doc));
40
+ /*
41
+ * A real grid, not a pile of buttons under role="menu". menu requires
42
+ * menuitem children; a <button>'s implicit role is button, so a reader
43
+ * announced a menu with no items while forty focusable buttons sat inside
44
+ * it. Follows plugins-colour/src/picker.ts, which follows plugins-table.
45
+ */
16
46
  const grid = doc.createElement('div');
17
47
  grid.className = 'ol-insert-grid';
18
- grid.setAttribute('role', 'menu');
48
+ grid.setAttribute('role', 'grid');
19
49
  grid.setAttribute('aria-label', options.label);
20
50
  if (SUPPORTS_POPOVER)
21
51
  grid.setAttribute('popover', 'manual');
22
- for (const item of options.items) {
52
+ const cells = [];
53
+ let row = null;
54
+ options.items.forEach((item, index) => {
55
+ if (index % GLYPH_COLUMNS === 0) {
56
+ row = doc.createElement('div');
57
+ row.className = 'ol-insert-row';
58
+ row.setAttribute('role', 'row');
59
+ grid.appendChild(row);
60
+ }
23
61
  const button = doc.createElement('button');
24
62
  button.type = 'button';
25
63
  button.textContent = item.char;
64
+ button.setAttribute('role', 'gridcell');
26
65
  button.setAttribute('aria-label', item.name);
27
66
  button.title = item.name;
67
+ // One tab stop for the whole grid; the arrow keys move within it.
68
+ button.tabIndex = index === 0 ? 0 : -1;
28
69
  button.addEventListener('click', () => {
29
70
  insertText(item.char)(view.state, view.dispatch, view);
30
71
  close();
31
72
  view.focus();
32
73
  });
33
- grid.appendChild(button);
34
- }
74
+ cells.push(button);
75
+ row?.appendChild(button);
76
+ });
35
77
  wrap.appendChild(trigger);
36
- if (!SUPPORTS_POPOVER)
37
- wrap.appendChild(grid);
38
- else
39
- doc.body.appendChild(grid);
40
78
  const isOpen = () => SUPPORTS_POPOVER ? grid.matches(':popover-open') : !grid.hidden;
41
- const close = () => {
79
+ const close = (options = {}) => {
42
80
  trigger.setAttribute('aria-expanded', 'false');
43
81
  if (!SUPPORTS_POPOVER) {
44
82
  grid.hidden = true;
45
- return;
46
83
  }
47
- // Guarded: hidePopover() throws on an element that is not showing, and
48
- // destroy() closes whether or not the picker was ever opened.
49
- if (grid.matches(':popover-open')) {
84
+ else if (grid.matches(':popover-open')) {
85
+ // Guarded: hidePopover() throws on an element that is not showing, and
86
+ // destroy() closes whether or not the picker was ever opened.
50
87
  ;
51
88
  grid.hidePopover();
52
89
  }
90
+ if (options.returnFocus)
91
+ trigger.focus();
53
92
  };
54
93
  /**
55
94
  * Anchor the grid under its trigger, and keep it on screen.
@@ -74,7 +113,22 @@ export function buildGlyphPicker(ctx, options) {
74
113
  grid.style.left = `${Math.round(left)}px`;
75
114
  grid.style.top = `${Math.round(top)}px`;
76
115
  };
116
+ const focusCell = (button) => {
117
+ if (!button)
118
+ return;
119
+ for (const cell of cells)
120
+ cell.tabIndex = cell === button ? 0 : -1;
121
+ button.focus();
122
+ };
77
123
  const open = () => {
124
+ if (!grid.isConnected) {
125
+ // On the host, not document.body. A body-mounted popover leaves a
126
+ // shadow-root editor, so document.activeElement is the host and a 0ms
127
+ // focusout timeout closes the panel as it opens. Same reason the colour
128
+ // picker and table grid append here -- and so skin tokens scoped to
129
+ // `.ol-editor` actually reach the panel.
130
+ host.appendChild(grid);
131
+ }
78
132
  trigger.setAttribute('aria-expanded', 'true');
79
133
  if (!SUPPORTS_POPOVER)
80
134
  grid.hidden = false;
@@ -83,7 +137,8 @@ export function buildGlyphPicker(ctx, options) {
83
137
  grid.showPopover();
84
138
  }
85
139
  place();
86
- grid.querySelector('button')?.focus();
140
+ const current = cells.find((cell) => cell.tabIndex === 0);
141
+ focusCell(current ?? cells[0]);
87
142
  };
88
143
  // `hidden` is the fallback path's only lever. On the popover path the popover
89
144
  // state is what closes the grid, and leaving `hidden` set as well would fight
@@ -91,26 +146,122 @@ export function buildGlyphPicker(ctx, options) {
91
146
  // that `[hidden]` still keeps at display:none.
92
147
  if (!SUPPORTS_POPOVER)
93
148
  grid.hidden = true;
149
+ // Custom controls bypass the toolbar's own `#invoke` guard entirely, so the
150
+ // `aria-disabled` it writes onto the trigger is decoration unless the control
151
+ // reads it back. The colour picker does; this one did not.
152
+ trigger.addEventListener('mousedown', (event) => event.preventDefault());
94
153
  trigger.addEventListener('click', () => {
95
154
  if (isOpen())
96
155
  close();
97
- else
156
+ else if (!host.hasAttribute('readonly') && trigger.getAttribute('aria-disabled') !== 'true') {
98
157
  open();
158
+ }
99
159
  });
100
160
  grid.addEventListener('keydown', (event) => {
101
161
  if (event.key === 'Escape') {
102
162
  event.preventDefault();
103
- close();
104
- trigger.focus();
163
+ close({ returnFocus: true });
164
+ return;
165
+ }
166
+ /*
167
+ * Tab is handled, and that reverses the note below about leaving it alone.
168
+ *
169
+ * Leaving it to the engine is correct in Chromium: Tab walks off the
170
+ * grid's single tab stop and the focusout handler closes the panel.
171
+ * Firefox does not move focus at all -- measured, not inferred: after
172
+ * Tab, focus is still the cell and the popover is still open. That is a
173
+ * keyboard trap (WCAG 2.1.2 No Keyboard Trap), and Escape being the only
174
+ * way out is exactly the failure the arrow-key model was added to prevent.
175
+ *
176
+ * So the widget decides instead of the engine, the same way it decides for
177
+ * Escape: close, return focus to the trigger, and do NOT preventDefault, so
178
+ * the browser's own Tab then runs from the trigger and lands wherever it
179
+ * would have landed had the panel never been open. Shift+Tab keeps working
180
+ * backwards for free, which an interception would have had to reimplement.
181
+ */
182
+ if (event.key === 'Tab') {
183
+ close({ returnFocus: true });
184
+ return;
185
+ }
186
+ const index = cells.indexOf(event.target);
187
+ if (index < 0)
188
+ return;
189
+ const move = (next) => {
190
+ event.preventDefault();
191
+ focusCell(cells[Math.max(0, Math.min(next, cells.length - 1))]);
192
+ };
193
+ const rowIndex = Math.floor(index / GLYPH_COLUMNS);
194
+ switch (event.key) {
195
+ case 'ArrowRight':
196
+ move(index + 1);
197
+ break;
198
+ case 'ArrowLeft':
199
+ move(index - 1);
200
+ break;
201
+ case 'ArrowDown':
202
+ move(index + GLYPH_COLUMNS);
203
+ break;
204
+ case 'ArrowUp':
205
+ move(index - GLYPH_COLUMNS);
206
+ break;
207
+ case 'Home':
208
+ move(rowIndex * GLYPH_COLUMNS);
209
+ break;
210
+ case 'End':
211
+ move(rowIndex * GLYPH_COLUMNS + GLYPH_COLUMNS - 1);
212
+ break;
213
+ default:
214
+ break;
105
215
  }
106
216
  });
217
+ // Leaving by any route closes -- pointer, Escape, Tab, or focus moving for a
218
+ // reason this widget never hears about. The colour picker's failure mode was a
219
+ // hand-rolled popover left open with nowhere to go.
220
+ //
221
+ // Tab is handled above rather than swallowed. Swallowing it outright is what
222
+ // once closed the panel while focus sat on the first glyph, which left one of
223
+ // forty characters reachable from the keyboard; moving focus first and letting
224
+ // the default action run is the part that makes it safe.
225
+ grid.addEventListener('focusout', (event) => {
226
+ if (!isOpen())
227
+ return;
228
+ if (relatedInside(event, grid, trigger))
229
+ return;
230
+ close();
231
+ });
232
+ /*
233
+ * Four behaviours the colour picker records as necessary. The first three
234
+ * this grid already had: keeping the selection through a mousedown -- whose
235
+ * absence WebKit turns into a control that closes as though it had worked --
236
+ * dismissal by a click elsewhere, and closing when the page moves under a
237
+ * panel positioned against the viewport. The fourth is the keyboard model
238
+ * above: arrows, Home, End, a roving tabindex, and Tab left alone.
239
+ */
240
+ for (const button of cells) {
241
+ button.addEventListener('mousedown', (event) => event.preventDefault());
242
+ }
243
+ const onPointerDown = (event) => {
244
+ const target = event.target;
245
+ if (!(target instanceof Node) || grid.contains(target) || trigger.contains(target))
246
+ return;
247
+ close();
248
+ };
249
+ const onViewportChange = () => {
250
+ if (isOpen())
251
+ close();
252
+ };
253
+ doc.addEventListener('pointerdown', onPointerDown, true);
254
+ doc.defaultView?.addEventListener('scroll', onViewportChange, true);
255
+ doc.defaultView?.addEventListener('resize', onViewportChange);
107
256
  return {
108
257
  el: wrap,
109
258
  update: (_state) => undefined,
110
259
  destroy: () => {
111
260
  close();
112
- if (SUPPORTS_POPOVER)
113
- grid.remove();
261
+ doc.removeEventListener('pointerdown', onPointerDown, true);
262
+ doc.defaultView?.removeEventListener('scroll', onViewportChange, true);
263
+ doc.defaultView?.removeEventListener('resize', onViewportChange);
264
+ grid.remove();
114
265
  },
115
266
  };
116
267
  }
package/dist/grid.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"grid.js","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"grid.js","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export interface InsertOptions {
14
14
  snippets?: readonly HtmlSnippet[];
15
15
  }
16
16
  export declare function installInsertTools(options?: InsertOptions): void;
17
- export { CHARACTERS, EMOJI } from './glyphs.js';
17
+ export { CHARACTERS, EMOJI, GLYPH_COLUMNS } from './glyphs.js';
18
18
  export { listedSnippets, registerHtmlSnippets, type HtmlSnippet } from './snippets.js';
19
- export { imageResizePlugin } from './resize.js';
19
+ export { imageResizePlugin, mediaResizePlugin, RESIZABLE_MEDIA, type ResizableKind } from './resize.js';
20
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,eAAe,CAAA;AAGtF,eAAO,MAAM,oBAAoB,yGAUvB,CAAA;AAEV,eAAO,MAAM,oBAAoB,QAAyC,CAAA;AAE1E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;CAClC;AAID,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,aAAkB,GAAG,IAAI,CAuGpE;AAED,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAA;AACtF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,eAAe,CAAA;AAGtF,eAAO,MAAM,oBAAoB,yGAUvB,CAAA;AAEV,eAAO,MAAM,oBAAoB,QAAyC,CAAA;AAE1E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;CAClC;AAID,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,aAAkB,GAAG,IAAI,CAuGpE;AAED,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAA;AACtF,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA"}
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import { CHARACTERS, EMOJI } from './glyphs.js';
13
13
  import { buildGlyphPicker } from './grid.js';
14
14
  import { INSERT_ICONS } from './icons.js';
15
15
  import { promptInsertAnchor, promptInsertDetails, promptInsertMedia, promptInsertSnippet } from './prompts.js';
16
- import { imageResizePlugin } from './resize.js';
16
+ import { mediaResizePlugin } from './resize.js';
17
17
  import { listedSnippets, registerHtmlSnippets } from './snippets.js';
18
18
  import { INSERT_CSS } from './styles.js';
19
19
  export const INSERT_TOOLBAR_ITEMS = [
@@ -37,7 +37,7 @@ export function installInsertTools(options = {}) {
37
37
  registerHtmlSnippets(options.snippets);
38
38
  registerIcons(INSERT_ICONS);
39
39
  registerStyles(INSERT_CSS);
40
- registerEditorPlugin(() => [imageResizePlugin()]);
40
+ registerEditorPlugin(() => [mediaResizePlugin()]);
41
41
  registerToolbarItem({
42
42
  id: 'media',
43
43
  type: 'button',
@@ -124,7 +124,7 @@ export function installInsertTools(options = {}) {
124
124
  },
125
125
  });
126
126
  }
127
- export { CHARACTERS, EMOJI } from './glyphs.js';
127
+ export { CHARACTERS, EMOJI, GLYPH_COLUMNS } from './glyphs.js';
128
128
  export { listedSnippets, registerHtmlSnippets } from './snippets.js';
129
- export { imageResizePlugin } from './resize.js';
129
+ export { imageResizePlugin, mediaResizePlugin, RESIZABLE_MEDIA } from './resize.js';
130
130
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,6 @@
1
1
  .ol-insert-grid {
2
2
  box-sizing: border-box;
3
3
  display: grid;
4
- grid-template-columns: repeat(8, 2rem);
5
4
  gap: 2px;
6
5
  padding: 8px;
7
6
  max-height: 16rem;
@@ -22,11 +21,21 @@
22
21
  * emoji panel floating in the middle of the page on load, following the scroll.
23
22
  *
24
23
  * The attribute selector on the second rule matters: on a browser without
25
- * popover support the grid carries no such attribute and lives in the toolbar,
24
+ * popover support the grid carries no such attribute and lives on the host,
26
25
  * where a bare :not(:popover-open) would match forever and hide it for good.
27
26
  */
28
27
  .ol-insert-grid[hidden] { display: none; }
29
28
  .ol-insert-grid[popover]:not(:popover-open) { display: none; }
29
+ /*
30
+ * Must match GLYPH_COLUMNS in glyphs.ts: the keyboard model steps by this
31
+ * width, and a CSS-only column count would let arrows land in a different
32
+ * cell than the one the reader announced.
33
+ */
34
+ .ol-insert-row {
35
+ display: grid;
36
+ grid-template-columns: repeat(8, 2rem);
37
+ gap: 2px;
38
+ }
30
39
  .ol-insert-grid button {
31
40
  box-sizing: border-box;
32
41
  width: 2rem; height: 2rem; margin: 0; padding: 0;
@@ -38,7 +47,55 @@
38
47
  outline: none;
39
48
  }
40
49
  .ol-img-resize { position: relative; display: inline-block; max-width: 100%; }
41
- .ol-img-resize img { display: block; max-width: 100%; height: auto; }
50
+ .ol-img-resize :is(img, video) { display: block; max-width: 100%; height: auto; }
51
+ /* The video is a preview, not a player: without this the engine's native media
52
+ chrome eats the click and the node can never be selected -- in Firefox for the
53
+ whole element, so the player could be inserted and never edited again. Stored
54
+ HTML is serialized from the node, so the real page is unaffected. */
55
+ .ol-img-resize video { pointer-events: none; }
56
+ /* ...until the author asks for one. The node view puts this class on a single
57
+ selected video and takes it off when the selection moves on, so at most one
58
+ player is live at a time. Specificity, not !important: one class more than the
59
+ rule above, and after it. */
60
+ .ol-img-resize.ol-media-live video { pointer-events: auto; }
61
+
62
+ /* The activation gesture: our button, not the engine's -- Firefox routes the
63
+ whole of a <video controls> into its native chrome, so a listener on the
64
+ element never hears the pointerdown. Present only while the node is selected,
65
+ so the first click on a video is still the one that selects it. */
66
+ .ol-media-play {
67
+ box-sizing: border-box;
68
+ position: absolute;
69
+ inset: 0;
70
+ margin: auto;
71
+ display: flex;
72
+ align-items: center;
73
+ justify-content: center;
74
+ width: 44px; height: 44px; padding: 0;
75
+ border: 2px solid var(--openleaf-color-surface, #fff);
76
+ border-radius: 50%;
77
+ background: var(--openleaf-color-accent, #0550ae);
78
+ color: var(--openleaf-color-surface, #fff);
79
+ cursor: pointer;
80
+ }
81
+ /* The same trap as the insert grid above: display:flex here is an author
82
+ declaration and the UA's display:none for [hidden] is not, so without this
83
+ the button would sit on every video, selected or not. */
84
+ .ol-media-play[hidden] { display: none; }
85
+ .ol-media-play:focus-visible {
86
+ outline: 2px solid var(--openleaf-color-accent, #0550ae);
87
+ outline-offset: 3px;
88
+ }
89
+ /* A border triangle: no font can be relied on for a play glyph. */
90
+ .ol-media-play::before {
91
+ content: "";
92
+ width: 0; height: 0;
93
+ margin-left: 4px;
94
+ border-left: 13px solid currentColor;
95
+ border-top: 8px solid transparent;
96
+ border-bottom: 8px solid transparent;
97
+ }
98
+
42
99
  .ol-img-handle {
43
100
  position: absolute; right: 0; bottom: 0;
44
101
  width: 12px; height: 12px; margin: 0; padding: 0;
package/dist/prompts.d.ts CHANGED
@@ -1,4 +1,13 @@
1
1
  import type { EditorView } from 'prosemirror-view';
2
+ /**
3
+ * Insert a player, or edit the one that is selected.
4
+ *
5
+ * The same toolbar button does both, because "insert" and "edit" are the same
6
+ * dialog with the fields already filled in, and a separate control for editing
7
+ * is one the author has to discover. `selectedMedia` returning null is what
8
+ * distinguishes them -- and it insists on a real node selection, so a caret that
9
+ * merely sits near a player still inserts a new one.
10
+ */
2
11
  export declare function promptInsertMedia(view: EditorView, host: HTMLElement): Promise<void>;
3
12
  export declare function promptInsertDetails(view: EditorView, host: HTMLElement): Promise<void>;
4
13
  export declare function promptInsertAnchor(view: EditorView, host: HTMLElement): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AA2DlD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB1F;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAU5F;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAY3F;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5F"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAqFlD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAoD1F;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAU5F;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAY3F;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5F"}