@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/skins.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skins.
|
|
3
|
+
*
|
|
4
|
+
* ## What a skin is here, and why it is not what TinyMCE means
|
|
5
|
+
*
|
|
6
|
+
* TinyMCE ships skins as directories of compiled CSS that replace the editor's
|
|
7
|
+
* stylesheet wholesale. That is powerful and it is also why upgrading TinyMCE
|
|
8
|
+
* can break a custom skin: the skin knows the editor's internal class names, so
|
|
9
|
+
* every internal rename is a breaking change for anyone who wrote one.
|
|
10
|
+
*
|
|
11
|
+
* A skin here is **a block of custom properties and nothing else**. It cannot
|
|
12
|
+
* reference an internal class, so it cannot be broken by an internal rename --
|
|
13
|
+
* which is the whole reason the token API exists. The cost is that a skin cannot
|
|
14
|
+
* restructure the toolbar; it can only restyle it. That trade is deliberate: a
|
|
15
|
+
* theme that survives upgrades is worth more than one that can move a button.
|
|
16
|
+
*
|
|
17
|
+
* Anything a skin can do, an integrator can do inline by setting the same
|
|
18
|
+
* properties. Skins exist so a look can be *named, shared and switched*, not to
|
|
19
|
+
* unlock capability.
|
|
20
|
+
*
|
|
21
|
+
* ## The one thing a skin declares that is not a property
|
|
22
|
+
*
|
|
23
|
+
* `scheme`. Some of what an editor looks like is decided by the browser rather
|
|
24
|
+
* than by us -- the popup a native `select` opens, scrollbar chrome, the syntax
|
|
25
|
+
* palette in the opt-in highlighting bundle -- and none of it reads custom
|
|
26
|
+
* properties. Those follow the *colour scheme*, so a skin that replaces the
|
|
27
|
+
* surface has to say which scheme its palette belongs to or they keep following
|
|
28
|
+
* the visitor's system and contradict it. That is one declared word, not a
|
|
29
|
+
* selector, so the guarantee above is intact.
|
|
30
|
+
*/
|
|
31
|
+
export interface Skin {
|
|
32
|
+
/** Used in the `skin` attribute and `applySkin`. */
|
|
33
|
+
name: string;
|
|
34
|
+
/** Shown in a picker. */
|
|
35
|
+
label: string;
|
|
36
|
+
/** Custom-property declarations. No selectors -- they are scoped for you. */
|
|
37
|
+
tokens: string;
|
|
38
|
+
/**
|
|
39
|
+
* Which world this skin's palette lives in. Omit for a skin that does not
|
|
40
|
+
* set `--openleaf-color-surface` -- a density skin, or one that only brands
|
|
41
|
+
* the accent.
|
|
42
|
+
*
|
|
43
|
+
* A skin that sets the surface has taken the palette over: it looks the same
|
|
44
|
+
* whether the visitor's system is light or dark, which is the point, and it
|
|
45
|
+
* therefore also decides which world everything keyed off the *scheme* rather
|
|
46
|
+
* than off a token belongs to. That is not a small list -- syntax
|
|
47
|
+
* highlighting, native `select` popups, scrollbars, form control chrome --
|
|
48
|
+
* and none of it can be expressed as a custom property.
|
|
49
|
+
*
|
|
50
|
+
* Undeclared, those follow the system instead, which is how a light skin ends
|
|
51
|
+
* up with a dark code block on a machine set to dark: exactly the bug this
|
|
52
|
+
* field exists to make unrepresentable.
|
|
53
|
+
*/
|
|
54
|
+
scheme?: 'light' | 'dark';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Built-in skins.
|
|
58
|
+
*
|
|
59
|
+
* Each sets the full palette rather than patching a few values, so a skin looks
|
|
60
|
+
* the same whether the visitor's system is in light or dark mode. A skin that
|
|
61
|
+
* only overrode two tokens would inherit the rest from whichever scheme happened
|
|
62
|
+
* to be active, which is how a carefully chosen palette ends up with one
|
|
63
|
+
* unreadable colour on somebody else's laptop.
|
|
64
|
+
*/
|
|
65
|
+
export declare const BUILT_IN_SKINS: readonly Skin[];
|
|
66
|
+
/**
|
|
67
|
+
* Add a skin, or replace one by name.
|
|
68
|
+
*
|
|
69
|
+
* ```ts
|
|
70
|
+
* registerSkin({
|
|
71
|
+
* name: 'acme',
|
|
72
|
+
* label: 'Acme brand',
|
|
73
|
+
* tokens: '--openleaf-color-accent: #c2185b; --openleaf-radius: 12px;',
|
|
74
|
+
* })
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* A skin that replaces the surface must also say which world it is in, or the
|
|
78
|
+
* parts of the editor that cannot be reached by a custom property -- syntax
|
|
79
|
+
* colours, native widget chrome -- keep following the visitor's system and end
|
|
80
|
+
* up contradicting it:
|
|
81
|
+
*
|
|
82
|
+
* ```ts
|
|
83
|
+
* registerSkin({
|
|
84
|
+
* name: 'acme-dark',
|
|
85
|
+
* label: 'Acme dark',
|
|
86
|
+
* scheme: 'dark',
|
|
87
|
+
* tokens: '--openleaf-color-surface: #101418; --openleaf-color-text: #e8eef4;',
|
|
88
|
+
* })
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare function registerSkin(skin: Skin, doc?: Document): void;
|
|
92
|
+
export declare function availableSkins(): readonly Skin[];
|
|
93
|
+
/** Ensure the built-in skins are available. Idempotent. */
|
|
94
|
+
export declare function ensureSkins(doc?: Document): void;
|
|
95
|
+
/**
|
|
96
|
+
* Apply a skin to one editor, or clear it with null.
|
|
97
|
+
*
|
|
98
|
+
* Per element rather than per page: a CMS with an article body and a comment box
|
|
99
|
+
* may legitimately want them to look different, and there is no reason a global
|
|
100
|
+
* setting should prevent that.
|
|
101
|
+
*/
|
|
102
|
+
export declare function applySkin(host: HTMLElement, name: string | null): void;
|
|
103
|
+
/**
|
|
104
|
+
* Force light or dark, or follow the visitor's system setting.
|
|
105
|
+
*
|
|
106
|
+
* A colour skin outranks this, and has to: its tokens set the palette outright,
|
|
107
|
+
* so `theme="dark"` under the paper skin cannot actually darken the surface. It
|
|
108
|
+
* would only darken the few things a token cannot reach -- which is how you get
|
|
109
|
+
* a dark code block in a cream editor. Better that the skin wins wholly than
|
|
110
|
+
* that it wins in part.
|
|
111
|
+
*/
|
|
112
|
+
export type ColourScheme = 'light' | 'dark' | 'auto';
|
|
113
|
+
export declare function applyColourScheme(host: HTMLElement, scheme: ColourScheme): void;
|
|
114
|
+
//# sourceMappingURL=skins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skins.d.ts","sourceRoot":"","sources":["../src/skins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,MAAM,WAAW,IAAI;IACnB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAA;IACd;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAC1B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,IAAI,EAyEzC,CAAA;AAmBD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAI7D;AAuBD,wBAAgB,cAAc,IAAI,SAAS,IAAI,EAAE,CAEhD;AAED,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAEhD;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAuBtE;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;AAEpD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAQ/E"}
|
package/dist/skins.js
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skins.
|
|
3
|
+
*
|
|
4
|
+
* ## What a skin is here, and why it is not what TinyMCE means
|
|
5
|
+
*
|
|
6
|
+
* TinyMCE ships skins as directories of compiled CSS that replace the editor's
|
|
7
|
+
* stylesheet wholesale. That is powerful and it is also why upgrading TinyMCE
|
|
8
|
+
* can break a custom skin: the skin knows the editor's internal class names, so
|
|
9
|
+
* every internal rename is a breaking change for anyone who wrote one.
|
|
10
|
+
*
|
|
11
|
+
* A skin here is **a block of custom properties and nothing else**. It cannot
|
|
12
|
+
* reference an internal class, so it cannot be broken by an internal rename --
|
|
13
|
+
* which is the whole reason the token API exists. The cost is that a skin cannot
|
|
14
|
+
* restructure the toolbar; it can only restyle it. That trade is deliberate: a
|
|
15
|
+
* theme that survives upgrades is worth more than one that can move a button.
|
|
16
|
+
*
|
|
17
|
+
* Anything a skin can do, an integrator can do inline by setting the same
|
|
18
|
+
* properties. Skins exist so a look can be *named, shared and switched*, not to
|
|
19
|
+
* unlock capability.
|
|
20
|
+
*
|
|
21
|
+
* ## The one thing a skin declares that is not a property
|
|
22
|
+
*
|
|
23
|
+
* `scheme`. Some of what an editor looks like is decided by the browser rather
|
|
24
|
+
* than by us -- the popup a native `select` opens, scrollbar chrome, the syntax
|
|
25
|
+
* palette in the opt-in highlighting bundle -- and none of it reads custom
|
|
26
|
+
* properties. Those follow the *colour scheme*, so a skin that replaces the
|
|
27
|
+
* surface has to say which scheme its palette belongs to or they keep following
|
|
28
|
+
* the visitor's system and contradict it. That is one declared word, not a
|
|
29
|
+
* selector, so the guarantee above is intact.
|
|
30
|
+
*/
|
|
31
|
+
import { registerStyles } from './styles.js';
|
|
32
|
+
/**
|
|
33
|
+
* Built-in skins.
|
|
34
|
+
*
|
|
35
|
+
* Each sets the full palette rather than patching a few values, so a skin looks
|
|
36
|
+
* the same whether the visitor's system is in light or dark mode. A skin that
|
|
37
|
+
* only overrode two tokens would inherit the rest from whichever scheme happened
|
|
38
|
+
* to be active, which is how a carefully chosen palette ends up with one
|
|
39
|
+
* unreadable colour on somebody else's laptop.
|
|
40
|
+
*/
|
|
41
|
+
export const BUILT_IN_SKINS = [
|
|
42
|
+
{
|
|
43
|
+
name: 'midnight',
|
|
44
|
+
label: 'Midnight',
|
|
45
|
+
scheme: 'dark',
|
|
46
|
+
tokens: `
|
|
47
|
+
--openleaf-color-text: #e6edf3;
|
|
48
|
+
--openleaf-color-text-muted: #9198a1;
|
|
49
|
+
--openleaf-color-surface: #0d1117;
|
|
50
|
+
--openleaf-color-surface-hover: #21262d;
|
|
51
|
+
--openleaf-color-surface-active: #1f3a5f;
|
|
52
|
+
--openleaf-color-border: #3d444d;
|
|
53
|
+
--openleaf-color-accent: #79c0ff;
|
|
54
|
+
--openleaf-color-focus: #79c0ff;
|
|
55
|
+
`,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'paper',
|
|
59
|
+
label: 'Paper',
|
|
60
|
+
scheme: 'light',
|
|
61
|
+
tokens: `
|
|
62
|
+
--openleaf-color-text: #2b2621;
|
|
63
|
+
--openleaf-color-text-muted: #6b6157;
|
|
64
|
+
--openleaf-color-surface: #fbf7f0;
|
|
65
|
+
--openleaf-color-surface-hover: #f0e9dd;
|
|
66
|
+
--openleaf-color-surface-active: #e6dcc8;
|
|
67
|
+
--openleaf-color-border: #d8cdb9;
|
|
68
|
+
--openleaf-color-accent: #8a5a20;
|
|
69
|
+
--openleaf-color-focus: #8a5a20;
|
|
70
|
+
--openleaf-radius: 2px;
|
|
71
|
+
`,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
/*
|
|
75
|
+
* Not a style preference. Every pair here clears WCAG 1.4.3 for body text
|
|
76
|
+
* and 1.4.11 for the control boundaries, and the focus ring is thickened
|
|
77
|
+
* rather than merely recoloured -- colour alone is what fails first for
|
|
78
|
+
* someone who needs this skin.
|
|
79
|
+
*/
|
|
80
|
+
name: 'contrast',
|
|
81
|
+
label: 'High contrast',
|
|
82
|
+
scheme: 'light',
|
|
83
|
+
tokens: `
|
|
84
|
+
--openleaf-color-text: #000000;
|
|
85
|
+
--openleaf-color-text-muted: #1a1a1a;
|
|
86
|
+
--openleaf-color-surface: #ffffff;
|
|
87
|
+
--openleaf-color-surface-hover: #e8e8e8;
|
|
88
|
+
--openleaf-color-surface-active: #d0d0d0;
|
|
89
|
+
--openleaf-color-border: #000000;
|
|
90
|
+
--openleaf-color-accent: #0000c0;
|
|
91
|
+
--openleaf-color-focus: #0000c0;
|
|
92
|
+
--openleaf-focus-width: 3px;
|
|
93
|
+
--openleaf-focus-offset: 2px;
|
|
94
|
+
`,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
/*
|
|
98
|
+
* Density, not colour -- so it composes with any of the others, and so it
|
|
99
|
+
* declares no `scheme`: it has no opinion about the palette and must not
|
|
100
|
+
* override whichever one is already in force. The button stays at 28px
|
|
101
|
+
* because WCAG 2.2 SC 2.5.8 asks for 24 CSS px minimum and "compact" is not
|
|
102
|
+
* a licence to go under it.
|
|
103
|
+
*/
|
|
104
|
+
name: 'compact',
|
|
105
|
+
label: 'Compact',
|
|
106
|
+
tokens: `
|
|
107
|
+
--openleaf-button-size: 28px;
|
|
108
|
+
--openleaf-icon-size: 14px;
|
|
109
|
+
--openleaf-gap: 1px;
|
|
110
|
+
--openleaf-font-size: 13px;
|
|
111
|
+
--openleaf-radius: 3px;
|
|
112
|
+
`,
|
|
113
|
+
},
|
|
114
|
+
];
|
|
115
|
+
const skins = new Map(BUILT_IN_SKINS.map((skin) => [skin.name, skin]));
|
|
116
|
+
let installedSheet = '';
|
|
117
|
+
function css() {
|
|
118
|
+
return [...skins.values()]
|
|
119
|
+
.map((skin) => `.ol-editor[data-ol-skin="${skin.name}"] {${skin.tokens}}`)
|
|
120
|
+
.join('\n');
|
|
121
|
+
}
|
|
122
|
+
/** Install the skin stylesheet. Re-run when a skin is added. */
|
|
123
|
+
function sync(doc) {
|
|
124
|
+
const next = css();
|
|
125
|
+
if (next === installedSheet)
|
|
126
|
+
return;
|
|
127
|
+
installedSheet = next;
|
|
128
|
+
registerStyles(next, doc);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Add a skin, or replace one by name.
|
|
132
|
+
*
|
|
133
|
+
* ```ts
|
|
134
|
+
* registerSkin({
|
|
135
|
+
* name: 'acme',
|
|
136
|
+
* label: 'Acme brand',
|
|
137
|
+
* tokens: '--openleaf-color-accent: #c2185b; --openleaf-radius: 12px;',
|
|
138
|
+
* })
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* A skin that replaces the surface must also say which world it is in, or the
|
|
142
|
+
* parts of the editor that cannot be reached by a custom property -- syntax
|
|
143
|
+
* colours, native widget chrome -- keep following the visitor's system and end
|
|
144
|
+
* up contradicting it:
|
|
145
|
+
*
|
|
146
|
+
* ```ts
|
|
147
|
+
* registerSkin({
|
|
148
|
+
* name: 'acme-dark',
|
|
149
|
+
* label: 'Acme dark',
|
|
150
|
+
* scheme: 'dark',
|
|
151
|
+
* tokens: '--openleaf-color-surface: #101418; --openleaf-color-text: #e8eef4;',
|
|
152
|
+
* })
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export function registerSkin(skin, doc) {
|
|
156
|
+
warnIfSchemeMissing(skin);
|
|
157
|
+
skins.set(skin.name, skin);
|
|
158
|
+
sync(doc);
|
|
159
|
+
}
|
|
160
|
+
/*
|
|
161
|
+
* Setting the surface without declaring the scheme is silently half a skin, and
|
|
162
|
+
* the half that is missing only shows up on a machine set to the opposite mode
|
|
163
|
+
* -- which is rarely the machine the skin was written on. This is the one thing
|
|
164
|
+
* worth a console message, because nothing about the result looks like a
|
|
165
|
+
* mistake locally.
|
|
166
|
+
*/
|
|
167
|
+
const schemeWarned = new Set();
|
|
168
|
+
function warnIfSchemeMissing(skin) {
|
|
169
|
+
if (skin.scheme || !skin.tokens.includes('--openleaf-color-surface:'))
|
|
170
|
+
return;
|
|
171
|
+
if (schemeWarned.has(skin.name))
|
|
172
|
+
return;
|
|
173
|
+
schemeWarned.add(skin.name);
|
|
174
|
+
console.warn(`@openleaf-editor/ui: skin "${skin.name}" sets --openleaf-color-surface but declares ` +
|
|
175
|
+
'no scheme, so syntax highlighting and native widgets inside it keep ' +
|
|
176
|
+
"following the visitor's system setting and can contradict the palette. " +
|
|
177
|
+
"Add scheme: 'light' or scheme: 'dark'.");
|
|
178
|
+
}
|
|
179
|
+
export function availableSkins() {
|
|
180
|
+
return [...skins.values()];
|
|
181
|
+
}
|
|
182
|
+
/** Ensure the built-in skins are available. Idempotent. */
|
|
183
|
+
export function ensureSkins(doc) {
|
|
184
|
+
sync(doc);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Apply a skin to one editor, or clear it with null.
|
|
188
|
+
*
|
|
189
|
+
* Per element rather than per page: a CMS with an article body and a comment box
|
|
190
|
+
* may legitimately want them to look different, and there is no reason a global
|
|
191
|
+
* setting should prevent that.
|
|
192
|
+
*/
|
|
193
|
+
export function applySkin(host, name) {
|
|
194
|
+
ensureSkins(host.ownerDocument);
|
|
195
|
+
if (name === null || name === '' || name === 'default') {
|
|
196
|
+
host.removeAttribute('data-ol-skin');
|
|
197
|
+
host.removeAttribute('data-ol-scheme');
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const skin = skins.get(name);
|
|
201
|
+
if (!skin) {
|
|
202
|
+
console.warn(`@openleaf-editor/ui: no skin named "${name}". Available: ` +
|
|
203
|
+
`${[...skins.keys()].join(', ')}. The editor keeps its current appearance.`);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
host.setAttribute('data-ol-skin', name);
|
|
207
|
+
// A separate attribute from the skin's name because it is a separate
|
|
208
|
+
// question: stylesheets that must branch on the scheme -- the highlighting
|
|
209
|
+
// plugin's palette, the native-widget rules in the core sheet -- have no way
|
|
210
|
+
// to know what `midnight` means, and hard-coding a list of skin names into
|
|
211
|
+
// them is precisely the internal coupling skins exist to avoid.
|
|
212
|
+
if (skin.scheme)
|
|
213
|
+
host.setAttribute('data-ol-scheme', skin.scheme);
|
|
214
|
+
else
|
|
215
|
+
host.removeAttribute('data-ol-scheme');
|
|
216
|
+
}
|
|
217
|
+
export function applyColourScheme(host, scheme) {
|
|
218
|
+
if (scheme === 'auto') {
|
|
219
|
+
// Removing the attribute is what re-enables the prefers-color-scheme rules;
|
|
220
|
+
// there is no `data-ol-theme="auto"` for them to match.
|
|
221
|
+
host.removeAttribute('data-ol-theme');
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
host.setAttribute('data-ol-theme', scheme);
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=skins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skins.js","sourceRoot":"","sources":["../src/skins.ts"],"names":[],"mappings":"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"}
|
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Toolbar styles, and the two ways they can reach the page.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this is harder than it should be
|
|
5
|
+
*
|
|
6
|
+
* OpenLeaf deliberately does not use Shadow DOM: the *content* area must
|
|
7
|
+
* inherit the host site's typography for editing to be WYSIWYG against their
|
|
8
|
+
* theme. The price is that these rules share a cascade with a stylesheet we
|
|
9
|
+
* have never seen -- Bootstrap, Tailwind preflight, a 2009 WordPress theme, a
|
|
10
|
+
* Drupal admin theme. So every property a host `button {}` rule or reset might
|
|
11
|
+
* touch is set explicitly below, even where the browser default would do.
|
|
12
|
+
*
|
|
13
|
+
* `all: unset` is NOT used. It looks like the obvious answer and it is a trap:
|
|
14
|
+
* it destroys the inheritance we want (font, colour) and wipes the default
|
|
15
|
+
* focus behaviour we are obliged to keep.
|
|
16
|
+
*
|
|
17
|
+
* No `!important` either. It wins today and makes the toolbar unthemeable
|
|
18
|
+
* tomorrow, which defeats the point of the custom-property API.
|
|
19
|
+
*
|
|
20
|
+
* ## Delivery and CSP
|
|
21
|
+
*
|
|
22
|
+
* Government and enterprise integrators -- the users who most need a free
|
|
23
|
+
* editor -- commonly run `style-src 'self'` with no `'unsafe-inline'`, which
|
|
24
|
+
* blocks an injected `<style>` element. So there are exactly two paths:
|
|
25
|
+
*
|
|
26
|
+
* 1. A constructable `CSSStyleSheet` added to `document.adoptedStyleSheets`.
|
|
27
|
+
* CSP gates resources *parsed as style*; a CSSOM object attached this way
|
|
28
|
+
* never passes through that gate, by design rather than by loophole.
|
|
29
|
+
* 2. The integrator links `@openleaf-editor/ui/openleaf.css` themselves and calls
|
|
30
|
+
* `markStylesExternal()`.
|
|
31
|
+
*
|
|
32
|
+
* There is deliberately NO `<style>` injection fallback. It reads as a safety
|
|
33
|
+
* net and is the opposite: it is blocked by exactly the strict-CSP setups that
|
|
34
|
+
* would need it, and it fails *silently* -- an unstyled toolbar with no signal
|
|
35
|
+
* an integrator can act on. A console warning naming the stylesheet is more
|
|
36
|
+
* useful than a mechanism that quietly does nothing.
|
|
37
|
+
*/
|
|
38
|
+
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 --ol-accent: var(--openleaf-color-accent, #0550ae);\n --ol-focus: var(--openleaf-color-focus, #0969da);\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 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-accent: var(--openleaf-color-accent, #79c0ff);\n --ol-focus: var(--openleaf-color-focus, #79c0ff);\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-accent: var(--openleaf-color-accent, #79c0ff);\n --ol-focus: var(--openleaf-color-focus, #79c0ff);\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-accent: var(--openleaf-color-accent, #79c0ff);\n --ol-focus: var(--openleaf-color-focus, #79c0ff);\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);\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.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.4;\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);\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: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);\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.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.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/* 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);\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/* 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}\n";
|
|
39
|
+
/**
|
|
40
|
+
* Declare that the integrator has linked `openleaf.css` themselves, so no
|
|
41
|
+
* injection is attempted. Call before the first editor is created.
|
|
42
|
+
*/
|
|
43
|
+
export declare function markStylesExternal(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Attach a stylesheet through the CSP-safe path.
|
|
46
|
+
*
|
|
47
|
+
* Public because plugins need it. The highlighting plugin previously
|
|
48
|
+
* hand-rolled this -- the same constructable-stylesheet dance, the same
|
|
49
|
+
* fallback, the same warning -- which meant the CSP reasoning lived in two
|
|
50
|
+
* places and only one of them would get fixed.
|
|
51
|
+
*
|
|
52
|
+
* Deduplicated per document by the CSS text itself, so calling it twice from a
|
|
53
|
+
* bundle loaded twice is harmless.
|
|
54
|
+
*/
|
|
55
|
+
export declare function registerStyles(css: string, target?: Document): 'adopted' | 'unavailable' | 'already';
|
|
56
|
+
/**
|
|
57
|
+
* Ensure the editor's own stylesheet is present. Safe to call repeatedly.
|
|
58
|
+
*
|
|
59
|
+
* There is deliberately **no `<style>` injection fallback**. It looks like a
|
|
60
|
+
* safety net and is the opposite: it fails under exactly the strict-CSP
|
|
61
|
+
* configurations it would be needed for, and it fails *silently* -- a blocked
|
|
62
|
+
* injection leaves an unstyled toolbar and no signal an integrator can act on.
|
|
63
|
+
*/
|
|
64
|
+
export declare function ensureStyles(doc: Document): 'external' | 'adopted' | 'unavailable' | 'already';
|
|
65
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAqBH,eAAO,MAAM,GAAG,4xdAgZf,CAAA;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAoCpG;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAM9F"}
|