@openleaf-editor/ui 0.1.0-beta.0
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/LICENSE +202 -0
- package/dist/dialog.d.ts +25 -0
- package/dist/dialog.d.ts.map +1 -0
- package/dist/dialog.js +266 -0
- package/dist/dialog.js.map +1 -0
- package/dist/icons.d.ts +53 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/icons.js +143 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/items.d.ts +13 -0
- package/dist/items.d.ts.map +1 -0
- package/dist/items.js +190 -0
- package/dist/items.js.map +1 -0
- package/dist/openleaf.css +426 -0
- package/dist/registry.d.ts +85 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +77 -0
- package/dist/registry.js.map +1 -0
- package/dist/skins.d.ts +114 -0
- package/dist/skins.d.ts.map +1 -0
- package/dist/skins.js +226 -0
- package/dist/skins.js.map +1 -0
- package/dist/styles.d.ts +65 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +532 -0
- package/dist/styles.js.map +1 -0
- package/dist/toolbar.d.ts +76 -0
- package/dist/toolbar.d.ts.map +1 -0
- package/dist/toolbar.js +509 -0
- package/dist/toolbar.js.map +1 -0
- package/package.json +39 -0
package/dist/icons.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The icon set, as one inline SVG `<symbol>` sprite.
|
|
3
|
+
*
|
|
4
|
+
* Why a sprite of stroke paths rather than the alternatives:
|
|
5
|
+
*
|
|
6
|
+
* Icon font -- rejected. A flash of unstyled text, screen readers that
|
|
7
|
+
* read the private-use codepoint aloud, and more bytes
|
|
8
|
+
* than the paths themselves.
|
|
9
|
+
* Inline per use -- rejected. The same path repeated for every button.
|
|
10
|
+
* Letterforms -- rejected, and this is the non-obvious one. "B" for bold
|
|
11
|
+
* and "I" for italic bake English into the interface. Bold
|
|
12
|
+
* is *gras* in French, *fett* in German; a "B" icon is a
|
|
13
|
+
* translation bug wearing a costume.
|
|
14
|
+
*
|
|
15
|
+
* All 16 icons are a 24x24 viewBox with `stroke="currentColor"`, so they inherit
|
|
16
|
+
* text colour for free and need no separate dark-mode set. Roughly 2 KB raw,
|
|
17
|
+
* under 1 KB gzipped.
|
|
18
|
+
*
|
|
19
|
+
* Everything here is built with DOM APIs rather than `innerHTML`. Strict
|
|
20
|
+
* government CSPs commonly pair `style-src` with
|
|
21
|
+
* `require-trusted-types-for 'script'`, which exempts stylesheets but not
|
|
22
|
+
* dynamic HTML -- a string-concatenated sprite would be blocked in exactly the
|
|
23
|
+
* deployments this project exists to serve.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Symbol id -> path data. Every icon is stroked; none are filled.
|
|
27
|
+
*
|
|
28
|
+
* Mutable, because plugins add their own. An opt-in bundle should not force its
|
|
29
|
+
* icons into the core download -- the eleven table icons would otherwise cost
|
|
30
|
+
* every deployment that has tables switched off.
|
|
31
|
+
*/
|
|
32
|
+
const PATHS = {
|
|
33
|
+
bold: 'M6 4h8a4 4 0 0 1 0 8H6zM6 12h9a4 4 0 0 1 0 8H6z',
|
|
34
|
+
italic: 'M19 4h-9M14 20H5M15 4L9 20',
|
|
35
|
+
underline: 'M6 4v6a6 6 0 0 0 12 0V4M4 20h16',
|
|
36
|
+
strikethrough: 'M16 4H9a3 3 0 0 0-2.83 4M14 12a4 4 0 0 1 0 8H6M4 12h16',
|
|
37
|
+
code: 'M16 18l6-6-6-6M8 6l-6 6 6 6',
|
|
38
|
+
bulletList: 'M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01',
|
|
39
|
+
orderedList: 'M10 6h11M10 12h11M10 18h11M4 4h1v4M4 8h2M6 18H4c0-1 2-1.5 2-2.5S5 14 4 14.5',
|
|
40
|
+
blockquote: 'M4 4v16M9 7h11M9 12h11M9 17h7',
|
|
41
|
+
codeBlock: 'M3 5h18v14H3zM9 10l-2 2 2 2M15 10l2 2-2 2',
|
|
42
|
+
link: 'M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71',
|
|
43
|
+
unlink: 'M18.84 12.25l1.72-1.71a5 5 0 0 0-7.07-7.07l-1.72 1.71M5.17 11.75l-1.71 1.71a5 5 0 0 0 7.07 7.07l1.71-1.71M2 2l20 20',
|
|
44
|
+
image: 'M3 3h18v18H3zM8.5 9.5a1.5 1.5 0 1 0 .01 0M21 15l-5-5L5 21',
|
|
45
|
+
horizontalRule: 'M4 12h16',
|
|
46
|
+
undo: 'M3 7v6h6M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13',
|
|
47
|
+
redo: 'M21 7v6h-6M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13',
|
|
48
|
+
source: 'M18 16l4-4-4-4M6 8l-4 4 4 4M14.5 4l-5 16',
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Icons whose meaning depends on reading direction, and which must therefore be
|
|
52
|
+
* mirrored in an RTL document. Bold and italic must NOT be in this set -- a
|
|
53
|
+
* mirrored letterform-derived glyph is just wrong, not localised.
|
|
54
|
+
*/
|
|
55
|
+
const DIRECTIONAL = new Set([
|
|
56
|
+
'undo',
|
|
57
|
+
'redo',
|
|
58
|
+
'code',
|
|
59
|
+
'codeBlock',
|
|
60
|
+
'source',
|
|
61
|
+
'blockquote',
|
|
62
|
+
'bulletList',
|
|
63
|
+
'orderedList',
|
|
64
|
+
]);
|
|
65
|
+
export function iconNames() {
|
|
66
|
+
return Object.keys(PATHS);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Add icons, from a plugin.
|
|
70
|
+
*
|
|
71
|
+
* If the sprite is already in the document -- which it will be whenever an
|
|
72
|
+
* editor exists before a deferred bundle finishes loading -- the new symbols are
|
|
73
|
+
* appended to it. Without that, a plugin's buttons render as empty squares and
|
|
74
|
+
* the failure looks like a CSS problem.
|
|
75
|
+
*/
|
|
76
|
+
export function registerIcons(paths, doc) {
|
|
77
|
+
const added = [];
|
|
78
|
+
for (const [name, d] of Object.entries(paths)) {
|
|
79
|
+
if (PATHS[name] === d)
|
|
80
|
+
continue;
|
|
81
|
+
PATHS[name] = d;
|
|
82
|
+
added.push(name);
|
|
83
|
+
}
|
|
84
|
+
if (added.length === 0)
|
|
85
|
+
return;
|
|
86
|
+
const target = doc ?? (typeof document !== 'undefined' ? document : undefined);
|
|
87
|
+
const sprite = target?.getElementById(SPRITE_ID);
|
|
88
|
+
if (!target || !sprite)
|
|
89
|
+
return;
|
|
90
|
+
for (const name of added) {
|
|
91
|
+
if (target.getElementById(`ol-i-${name}`))
|
|
92
|
+
continue;
|
|
93
|
+
sprite.appendChild(makeSymbol(name, PATHS[name], target));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
97
|
+
const SPRITE_ID = 'ol-icon-sprite';
|
|
98
|
+
/** Inject the sprite once per document. Safe to call repeatedly. */
|
|
99
|
+
export function ensureSprite(doc) {
|
|
100
|
+
if (doc.getElementById(SPRITE_ID))
|
|
101
|
+
return;
|
|
102
|
+
const svg = doc.createElementNS(SVG_NS, 'svg');
|
|
103
|
+
svg.setAttribute('id', SPRITE_ID);
|
|
104
|
+
svg.setAttribute('aria-hidden', 'true');
|
|
105
|
+
svg.setAttribute('focusable', 'false');
|
|
106
|
+
svg.setAttribute('style', 'display:none');
|
|
107
|
+
for (const [name, d] of Object.entries(PATHS)) {
|
|
108
|
+
svg.appendChild(makeSymbol(name, d, doc));
|
|
109
|
+
}
|
|
110
|
+
doc.body.appendChild(svg);
|
|
111
|
+
}
|
|
112
|
+
function makeSymbol(name, d, doc) {
|
|
113
|
+
const symbol = doc.createElementNS(SVG_NS, 'symbol');
|
|
114
|
+
symbol.setAttribute('id', `ol-i-${name}`);
|
|
115
|
+
symbol.setAttribute('viewBox', '0 0 24 24');
|
|
116
|
+
symbol.setAttribute('fill', 'none');
|
|
117
|
+
symbol.setAttribute('stroke', 'currentColor');
|
|
118
|
+
symbol.setAttribute('stroke-width', '2');
|
|
119
|
+
symbol.setAttribute('stroke-linecap', 'round');
|
|
120
|
+
symbol.setAttribute('stroke-linejoin', 'round');
|
|
121
|
+
const path = doc.createElementNS(SVG_NS, 'path');
|
|
122
|
+
path.setAttribute('d', d);
|
|
123
|
+
symbol.appendChild(path);
|
|
124
|
+
return symbol;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* An `<svg><use></svg>` referencing a sprite symbol.
|
|
128
|
+
*
|
|
129
|
+
* `aria-hidden` and `focusable="false"` are both required: the icon is
|
|
130
|
+
* decorative because the button carries the accessible name, and without
|
|
131
|
+
* `focusable="false"` older engines put the SVG in the tab order.
|
|
132
|
+
*/
|
|
133
|
+
export function iconElement(name, doc) {
|
|
134
|
+
const svg = doc.createElementNS(SVG_NS, 'svg');
|
|
135
|
+
svg.setAttribute('class', DIRECTIONAL.has(name) ? 'ol-icon ol-icon--directional' : 'ol-icon');
|
|
136
|
+
svg.setAttribute('aria-hidden', 'true');
|
|
137
|
+
svg.setAttribute('focusable', 'false');
|
|
138
|
+
const use = doc.createElementNS(SVG_NS, 'use');
|
|
139
|
+
use.setAttribute('href', `#ol-i-${name}`);
|
|
140
|
+
svg.appendChild(use);
|
|
141
|
+
return svg;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=icons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.js","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Toolbar, type ToolbarOptions } from './toolbar.js';
|
|
2
|
+
export { DEFAULT_LAYOUT, allToolbarItems, clearToolbarItems, getToolbarItem, onRegistryChange, registerToolbarItem, type ToolbarContext, type ToolbarItemSpec, } from './registry.js';
|
|
3
|
+
export { SOURCE_TOGGLE_EVENT, registerDefaultItems } from './items.js';
|
|
4
|
+
export { CSS, ensureStyles, markStylesExternal, registerStyles } from './styles.js';
|
|
5
|
+
export { ensureSprite, iconElement, iconNames, registerIcons, type IconName } from './icons.js';
|
|
6
|
+
export { promptForImage, promptForLink, type ImageResult, type LinkResult } from './dialog.js';
|
|
7
|
+
export { BUILT_IN_SKINS, applyColourScheme, applySkin, availableSkins, ensureSkins, registerSkin, type ColourScheme, type Skin, } from './skins.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACtE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACnF,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC/F,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAC9F,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,cAAc,EACd,WAAW,EACX,YAAY,EACZ,KAAK,YAAY,EACjB,KAAK,IAAI,GACV,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Toolbar } from './toolbar.js';
|
|
2
|
+
export { DEFAULT_LAYOUT, allToolbarItems, clearToolbarItems, getToolbarItem, onRegistryChange, registerToolbarItem, } from './registry.js';
|
|
3
|
+
export { SOURCE_TOGGLE_EVENT, registerDefaultItems } from './items.js';
|
|
4
|
+
export { CSS, ensureStyles, markStylesExternal, registerStyles } from './styles.js';
|
|
5
|
+
export { ensureSprite, iconElement, iconNames, registerIcons } from './icons.js';
|
|
6
|
+
export { promptForImage, promptForLink } from './dialog.js';
|
|
7
|
+
export { BUILT_IN_SKINS, applyColourScheme, applySkin, availableSkins, ensureSkins, registerSkin, } from './skins.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAuB,MAAM,cAAc,CAAA;AAC3D,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,GAGpB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACtE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACnF,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAA;AAC/F,OAAO,EAAE,cAAc,EAAE,aAAa,EAAqC,MAAM,aAAa,CAAA;AAC9F,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,cAAc,EACd,WAAW,EACX,YAAY,GAGb,MAAM,YAAY,CAAA"}
|
package/dist/items.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default toolbar items.
|
|
3
|
+
*
|
|
4
|
+
* Every one is a thin binding of a core command to a label and an icon. No
|
|
5
|
+
* editing logic lives here -- if a button needs to know something about the
|
|
6
|
+
* document, that knowledge belongs in `@openleaf-editor/core` where a keyboard
|
|
7
|
+
* shortcut and a test can reach it too.
|
|
8
|
+
*/
|
|
9
|
+
/** Event the host listens for to switch between rich and source views. */
|
|
10
|
+
export declare const SOURCE_TOGGLE_EVENT = "openleaf:toggle-source";
|
|
11
|
+
/** Register the built-in items. Idempotent. */
|
|
12
|
+
export declare function registerDefaultItems(): void;
|
|
13
|
+
//# sourceMappingURL=items.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"items.d.ts","sourceRoot":"","sources":["../src/items.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA2BH,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,2BAA2B,CAAA;AAI3D,+CAA+C;AAC/C,wBAAgB,oBAAoB,IAAI,IAAI,CAuM3C"}
|
package/dist/items.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default toolbar items.
|
|
3
|
+
*
|
|
4
|
+
* Every one is a thin binding of a core command to a label and an icon. No
|
|
5
|
+
* editing logic lives here -- if a button needs to know something about the
|
|
6
|
+
* document, that knowledge belongs in `@openleaf-editor/core` where a keyboard
|
|
7
|
+
* shortcut and a test can reach it too.
|
|
8
|
+
*/
|
|
9
|
+
import { activeLink, insertHorizontalRule, insertImage, isMarkActive, isNodeActive, redo, setLink, toggleBlockquote, toggleBold, toggleBulletList, toggleCodeBlock, toggleInlineCode, toggleItalic, toggleOrderedList, toggleStrike, toggleUnderline, undo, unsetLink, } from '@openleaf-editor/core';
|
|
10
|
+
import { promptForImage, promptForLink } from './dialog.js';
|
|
11
|
+
import { registerToolbarItem } from './registry.js';
|
|
12
|
+
/** Event the host listens for to switch between rich and source views. */
|
|
13
|
+
export const SOURCE_TOGGLE_EVENT = 'openleaf:toggle-source';
|
|
14
|
+
let registered = false;
|
|
15
|
+
/** Register the built-in items. Idempotent. */
|
|
16
|
+
export function registerDefaultItems() {
|
|
17
|
+
if (registered)
|
|
18
|
+
return;
|
|
19
|
+
registered = true;
|
|
20
|
+
registerToolbarItem({
|
|
21
|
+
id: 'undo',
|
|
22
|
+
type: 'button',
|
|
23
|
+
kind: 'action',
|
|
24
|
+
label: 'Undo',
|
|
25
|
+
icon: 'undo',
|
|
26
|
+
command: undo,
|
|
27
|
+
shortcut: 'Undo',
|
|
28
|
+
});
|
|
29
|
+
registerToolbarItem({
|
|
30
|
+
id: 'redo',
|
|
31
|
+
type: 'button',
|
|
32
|
+
kind: 'action',
|
|
33
|
+
label: 'Redo',
|
|
34
|
+
icon: 'redo',
|
|
35
|
+
command: redo,
|
|
36
|
+
shortcut: 'Redo',
|
|
37
|
+
});
|
|
38
|
+
const markItems = [
|
|
39
|
+
{ id: 'bold', label: 'Bold', icon: 'bold', mark: 'strong', command: toggleBold },
|
|
40
|
+
{ id: 'italic', label: 'Italic', icon: 'italic', mark: 'em', command: toggleItalic },
|
|
41
|
+
{
|
|
42
|
+
id: 'underline',
|
|
43
|
+
label: 'Underline',
|
|
44
|
+
icon: 'underline',
|
|
45
|
+
mark: 'underline',
|
|
46
|
+
command: toggleUnderline,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'strikethrough',
|
|
50
|
+
label: 'Strikethrough',
|
|
51
|
+
icon: 'strikethrough',
|
|
52
|
+
mark: 'strike',
|
|
53
|
+
command: toggleStrike,
|
|
54
|
+
},
|
|
55
|
+
{ id: 'code', label: 'Inline code', icon: 'code', mark: 'code', command: toggleInlineCode },
|
|
56
|
+
];
|
|
57
|
+
for (const item of markItems) {
|
|
58
|
+
registerToolbarItem({
|
|
59
|
+
id: item.id,
|
|
60
|
+
type: 'button',
|
|
61
|
+
kind: 'toggle',
|
|
62
|
+
label: item.label,
|
|
63
|
+
icon: item.icon,
|
|
64
|
+
command: item.command,
|
|
65
|
+
isActive: (state) => isMarkActive(state, item.mark),
|
|
66
|
+
shortcut: item.label,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/* ---- block structure ----
|
|
70
|
+
These get toggle semantics too. A blockquote or a list is a state the
|
|
71
|
+
cursor is either in or not, exactly like bold, and leaving them as plain
|
|
72
|
+
actions means a screen reader user cannot tell whether they are inside a
|
|
73
|
+
list without moving the caret and inferring it. */
|
|
74
|
+
registerToolbarItem({
|
|
75
|
+
id: 'bulletList',
|
|
76
|
+
type: 'button',
|
|
77
|
+
kind: 'toggle',
|
|
78
|
+
label: 'Bulleted list',
|
|
79
|
+
icon: 'bulletList',
|
|
80
|
+
command: toggleBulletList,
|
|
81
|
+
isActive: (state) => isNodeActive(state, 'bullet_list'),
|
|
82
|
+
shortcut: 'Bulleted list',
|
|
83
|
+
});
|
|
84
|
+
registerToolbarItem({
|
|
85
|
+
id: 'orderedList',
|
|
86
|
+
type: 'button',
|
|
87
|
+
kind: 'toggle',
|
|
88
|
+
label: 'Numbered list',
|
|
89
|
+
icon: 'orderedList',
|
|
90
|
+
command: toggleOrderedList,
|
|
91
|
+
isActive: (state) => isNodeActive(state, 'ordered_list'),
|
|
92
|
+
shortcut: 'Numbered list',
|
|
93
|
+
});
|
|
94
|
+
registerToolbarItem({
|
|
95
|
+
id: 'blockquote',
|
|
96
|
+
type: 'button',
|
|
97
|
+
kind: 'toggle',
|
|
98
|
+
label: 'Blockquote',
|
|
99
|
+
icon: 'blockquote',
|
|
100
|
+
command: toggleBlockquote,
|
|
101
|
+
isActive: (state) => isNodeActive(state, 'blockquote'),
|
|
102
|
+
shortcut: 'Blockquote',
|
|
103
|
+
});
|
|
104
|
+
registerToolbarItem({
|
|
105
|
+
id: 'codeBlock',
|
|
106
|
+
type: 'button',
|
|
107
|
+
kind: 'toggle',
|
|
108
|
+
label: 'Code block',
|
|
109
|
+
icon: 'codeBlock',
|
|
110
|
+
command: toggleCodeBlock,
|
|
111
|
+
isActive: (state) => isNodeActive(state, 'code_block'),
|
|
112
|
+
shortcut: 'Code block',
|
|
113
|
+
});
|
|
114
|
+
/* ---- insertions ---- */
|
|
115
|
+
registerToolbarItem({
|
|
116
|
+
id: 'link',
|
|
117
|
+
type: 'button',
|
|
118
|
+
kind: 'toggle',
|
|
119
|
+
label: 'Link',
|
|
120
|
+
icon: 'link',
|
|
121
|
+
// Enabled only with a selection: a link needs text to attach to, and
|
|
122
|
+
// silently doing nothing on an empty caret is worse than being disabled.
|
|
123
|
+
isEnabled: (state) => !state.selection.empty,
|
|
124
|
+
isActive: (state) => activeLink(state) !== null,
|
|
125
|
+
run: ({ view, host }) => {
|
|
126
|
+
const existing = activeLink(view.state);
|
|
127
|
+
void promptForLink(host.ownerDocument, {
|
|
128
|
+
href: existing?.['href'] ?? '',
|
|
129
|
+
target: existing?.['target'] ?? null,
|
|
130
|
+
}).then((result) => {
|
|
131
|
+
if (!result) {
|
|
132
|
+
view.focus();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
setLink(result)(view.state, view.dispatch, view);
|
|
136
|
+
view.focus();
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
registerToolbarItem({
|
|
141
|
+
id: 'unlink',
|
|
142
|
+
type: 'button',
|
|
143
|
+
kind: 'action',
|
|
144
|
+
label: 'Remove link',
|
|
145
|
+
icon: 'unlink',
|
|
146
|
+
command: unsetLink,
|
|
147
|
+
});
|
|
148
|
+
registerToolbarItem({
|
|
149
|
+
id: 'image',
|
|
150
|
+
type: 'button',
|
|
151
|
+
kind: 'action',
|
|
152
|
+
label: 'Insert image',
|
|
153
|
+
icon: 'image',
|
|
154
|
+
run: ({ view, host }) => {
|
|
155
|
+
void promptForImage(host.ownerDocument).then((result) => {
|
|
156
|
+
if (!result) {
|
|
157
|
+
view.focus();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
insertImage({ src: result.src, alt: result.alt })(view.state, view.dispatch, view);
|
|
161
|
+
view.focus();
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
registerToolbarItem({
|
|
166
|
+
id: 'horizontalRule',
|
|
167
|
+
type: 'button',
|
|
168
|
+
kind: 'action',
|
|
169
|
+
label: 'Horizontal rule',
|
|
170
|
+
icon: 'horizontalRule',
|
|
171
|
+
command: insertHorizontalRule,
|
|
172
|
+
shortcut: 'Horizontal rule',
|
|
173
|
+
});
|
|
174
|
+
/* ---- mode ---- */
|
|
175
|
+
registerToolbarItem({
|
|
176
|
+
id: 'source',
|
|
177
|
+
type: 'button',
|
|
178
|
+
kind: 'toggle',
|
|
179
|
+
label: 'HTML source',
|
|
180
|
+
icon: 'source',
|
|
181
|
+
// Source view is host state, not document state, so no predicate can derive
|
|
182
|
+
// it. The host pushes the value with setItemState -- which is exactly why
|
|
183
|
+
// that escape hatch exists.
|
|
184
|
+
isActive: () => false,
|
|
185
|
+
run: ({ host }) => {
|
|
186
|
+
host.dispatchEvent(new CustomEvent(SOURCE_TOGGLE_EVENT, { bubbles: true }));
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=items.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"items.js","sourceRoot":"","sources":["../src/items.ts"],"names":[],"mappings":"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"}
|