@openpresentation/opf-editor 0.26.6 → 0.26.8
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/dist/json-editor.js +2 -0
- package/dist/layout-editor.js +6 -2
- package/dist/source-pane.js +3 -2
- package/dist/source-wrap.js +97 -0
- package/dist/styles.css +279 -4
- package/package.json +7 -7
package/dist/json-editor.js
CHANGED
|
@@ -17,6 +17,7 @@ import { forEachDiagnostic } from "@codemirror/lint";
|
|
|
17
17
|
import {createDiagnostics,editsTransaction} from './source-diagnostics.js';
|
|
18
18
|
import { createKeymap, domKeymap, strokeText } from './source-keymap.js';
|
|
19
19
|
import { fold, foldEverything, foldGutterExtension, foldLevel, foldRecursively, toggleFoldHere, unfold, unfoldEverything, unfoldRecursively } from './source-folding.js';
|
|
20
|
+
import { hangingIndent } from './source-wrap.js';
|
|
20
21
|
import {languageDataFor,markdownBackspace,markdownEnter,markdownFolding,markdownTab,markdownToggleComment,markdownWrapSelection,yamlEnter} from './source-editing.js';
|
|
21
22
|
const external = Annotation.define();
|
|
22
23
|
const hoverField = StateEffect.define();
|
|
@@ -551,6 +552,7 @@ function mountJsonCodeEditor(parent, options) {
|
|
|
551
552
|
attributes.of(contentAttributes()),
|
|
552
553
|
options.lineNumbers ? lineNumbers() : [],
|
|
553
554
|
EditorView.lineWrapping,
|
|
555
|
+
hangingIndent,
|
|
554
556
|
keydownKeys,
|
|
555
557
|
mainKeymap,
|
|
556
558
|
EditorView.domEventHandlers({
|
package/dist/layout-editor.js
CHANGED
|
@@ -140,9 +140,13 @@ export function createLayoutEditor(container, options = {}) {
|
|
|
140
140
|
paint();
|
|
141
141
|
|
|
142
142
|
// The container's width decides the layout: wide shows the palette, canvas and side panels; narrow stacks them with tabs.
|
|
143
|
-
const measure = () => {
|
|
143
|
+
const measure = () => {
|
|
144
|
+
const compact = String((container.clientWidth || root.clientWidth || COMPACT_WIDTH) < COMPACT_WIDTH);
|
|
145
|
+
if (root.dataset.compact !== compact) root.dataset.compact = compact;
|
|
146
|
+
};
|
|
147
|
+
// The switch changes the editor's own height, so a host whose height follows it would loop inside the observer: the change is made a frame later.
|
|
144
148
|
let observer = null;
|
|
145
|
-
if (typeof win.ResizeObserver === "function") { observer = new win.ResizeObserver(measure); observer.observe(container); }
|
|
149
|
+
if (typeof win.ResizeObserver === "function") { observer = new win.ResizeObserver(() => win.requestAnimationFrame(measure)); observer.observe(container); }
|
|
146
150
|
measure();
|
|
147
151
|
|
|
148
152
|
root.addEventListener("keydown", (event) => { handleGlobalShortcut(event, model); });
|
package/dist/source-pane.js
CHANGED
|
@@ -403,8 +403,9 @@ export function createSourcePane(container, options = {}) {
|
|
|
403
403
|
if (token !== syntaxToken) return;
|
|
404
404
|
syntaxBusy = false;
|
|
405
405
|
showBusy();
|
|
406
|
-
// The applied
|
|
407
|
-
|
|
406
|
+
// A null answer means the worker dropped the request. The text may equal the applied one: a quick fix and Undo bring the broken text
|
|
407
|
+
// back while `baseline` still holds it, and its syntax problem must show again at once (checkSyntax has no such guard either).
|
|
408
|
+
if (found === null || destroyed || format !== "json" || control.api.getValue() !== text) return;
|
|
408
409
|
showSyntax(found);
|
|
409
410
|
}, () => {
|
|
410
411
|
if (token !== syntaxToken) return;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { RangeSetBuilder, StateEffect, countColumn } from "@codemirror/state";
|
|
2
|
+
import { Decoration, ViewPlugin } from "@codemirror/view";
|
|
3
|
+
|
|
4
|
+
// A wrapped line continues under its own indentation, as VS Code's `wrappingIndent: "indent"` does (JSON, YAML and Markdown).
|
|
5
|
+
// Each line carries a class `opf-hang-<n>`; the stylesheet (panels.css) turns n columns into a left padding and the same negative
|
|
6
|
+
// text-indent, so the first line starts where it always did and every continuation line starts n columns in. n is the line's leading
|
|
7
|
+
// whitespace (a tab counts as the editor's tab size) plus the width of a list marker ("- ", "1. ") when the line starts one, so wrapped
|
|
8
|
+
// list items line up under their text, or plus two columns (one indent step) for any other line, so a continuation never looks like a new line.
|
|
9
|
+
// The hang is capped at 40% of the line's width, so a deeply nested line still leaves room for text on a phone. The cap is worked out here, in
|
|
10
|
+
// columns, from the measured width, and not in the stylesheet: a percentage in `padding-left` makes the style and layout of every line depend on
|
|
11
|
+
// its containing block, and replacing the text of a long document then took about 15 times as long (0.26.7).
|
|
12
|
+
|
|
13
|
+
/** The most columns a line can hang. The stylesheet defines `opf-hang-0` through `opf-hang-${MAX_HANG}`. */
|
|
14
|
+
export const MAX_HANG = 32;
|
|
15
|
+
/** The share of the line's width a hang can take. */
|
|
16
|
+
export const HANG_SHARE = 0.4;
|
|
17
|
+
const LIST_MARKER = /^([-*+]|\d{1,9}[.)])[ \t]+/;
|
|
18
|
+
const OFFSET = 2;
|
|
19
|
+
|
|
20
|
+
/** How many columns the continuation lines of `text` are indented. */
|
|
21
|
+
export function hangColumns(text, tabSize = 4) {
|
|
22
|
+
let at = 0;
|
|
23
|
+
while (at < text.length && (text[at] === " " || text[at] === "\t")) at++;
|
|
24
|
+
const indent = countColumn(text.slice(0, at), tabSize);
|
|
25
|
+
const marker = LIST_MARKER.exec(text.slice(at));
|
|
26
|
+
const columns = marker ? indent + countColumn(marker[0], tabSize) : indent + OFFSET;
|
|
27
|
+
return Math.min(columns, MAX_HANG);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The most columns a line can hang in a line `width` pixels wide whose columns are `columnWidth` pixels wide: 40% of the width, in whole
|
|
32
|
+
* columns, never above MAX_HANG. `MAX_HANG` when either size is unknown (zero, negative or not a number), for example while the editor is hidden.
|
|
33
|
+
*/
|
|
34
|
+
export function hangCap(width, columnWidth) {
|
|
35
|
+
if (!(width > 0) || !(columnWidth > 0)) return MAX_HANG;
|
|
36
|
+
return Math.max(0, Math.min(MAX_HANG, Math.floor((width * HANG_SHARE) / columnWidth)));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const decorations = Array.from({ length: MAX_HANG + 1 }, (_, columns) => Decoration.line({ class: `opf-hang-${columns}` }));
|
|
40
|
+
|
|
41
|
+
function build(view, cap) {
|
|
42
|
+
const builder = new RangeSetBuilder();
|
|
43
|
+
const { doc, tabSize } = view.state;
|
|
44
|
+
let last = -1;
|
|
45
|
+
for (const { from, to } of view.visibleRanges) {
|
|
46
|
+
for (let position = from; position <= to;) {
|
|
47
|
+
const line = doc.lineAt(position);
|
|
48
|
+
if (line.from > last) {
|
|
49
|
+
builder.add(line.from, line.from, decorations[Math.min(hangColumns(line.text, tabSize), cap)]);
|
|
50
|
+
last = line.from;
|
|
51
|
+
}
|
|
52
|
+
position = line.to + 1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return builder.finish();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const setCap = StateEffect.define();
|
|
59
|
+
|
|
60
|
+
/** The width of the text area of a line, in pixels: the content box of the editor's content element, which is what a percentage would have resolved against. */
|
|
61
|
+
function lineWidth(view) {
|
|
62
|
+
const content = view.contentDOM, style = getComputedStyle(content);
|
|
63
|
+
return content.clientWidth - (parseFloat(style.paddingLeft) || 0) - (parseFloat(style.paddingRight) || 0);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The extension: line decorations for the visible lines (a line is decorated again when the document, the viewport, the tab size or the cap
|
|
68
|
+
* changes). The cap is measured in CodeMirror's measure cycle whenever the geometry changes, and the lines are decorated again only when it differs.
|
|
69
|
+
*/
|
|
70
|
+
export const hangingIndent = ViewPlugin.fromClass(
|
|
71
|
+
class {
|
|
72
|
+
constructor(view) {
|
|
73
|
+
this.cap = MAX_HANG;
|
|
74
|
+
this.decorations = build(view, this.cap);
|
|
75
|
+
this.measure = {
|
|
76
|
+
key: this,
|
|
77
|
+
read: (target) => hangCap(lineWidth(target), target.defaultCharacterWidth),
|
|
78
|
+
write: (cap, target) => {
|
|
79
|
+
if (cap === this.cap) return;
|
|
80
|
+
// The measure cycle is an update in progress: the new cap is dispatched right after it, before the browser paints.
|
|
81
|
+
queueMicrotask(() => { if (!this.destroyed) target.dispatch({ effects: setCap.of(cap) }); });
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
view.requestMeasure(this.measure);
|
|
85
|
+
}
|
|
86
|
+
update(update) {
|
|
87
|
+
let capped = false;
|
|
88
|
+
for (const transaction of update.transactions) for (const effect of transaction.effects) if (effect.is(setCap)) { this.cap = effect.value; capped = true; }
|
|
89
|
+
if (update.geometryChanged || update.viewportChanged) update.view.requestMeasure(this.measure);
|
|
90
|
+
if (capped || update.docChanged || update.viewportChanged || update.startState.tabSize !== update.state.tabSize) this.decorations = build(update.view, this.cap);
|
|
91
|
+
}
|
|
92
|
+
destroy() {
|
|
93
|
+
this.destroyed = true;
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{ decorations: (plugin) => plugin.decorations },
|
|
97
|
+
);
|
package/dist/styles.css
CHANGED
|
@@ -72,6 +72,17 @@
|
|
|
72
72
|
--opf-ui-control-h: 40px;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/* A coarse pointer (a finger) gets 44px controls, whatever the density: every control built from --opf-ui-control-h grows with it, and
|
|
76
|
+
src/styles/touch.css lifts the ones that size themselves. Comes after the density rule so it wins at equal specificity. */
|
|
77
|
+
@media (pointer: coarse) {
|
|
78
|
+
:root,
|
|
79
|
+
.opf-ui,
|
|
80
|
+
.opf-ui[data-density="touch"],
|
|
81
|
+
[data-density="touch"] .opf-ui {
|
|
82
|
+
--opf-ui-control-h: 44px;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
75
86
|
/* Base rules for a mounted component or a whole editor surface. */
|
|
76
87
|
.opf-ui {
|
|
77
88
|
font-family: var(--opf-ui-font);
|
|
@@ -695,7 +706,7 @@
|
|
|
695
706
|
.opf-lx[data-compact="true"] { min-height: 0; height: auto; }
|
|
696
707
|
.opf-lx[data-compact="true"] .opf-lx-main { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto auto; }
|
|
697
708
|
.opf-lx[data-compact="true"] .opf-lx-palette-host { overflow-x: auto; border-bottom: 1px solid var(--opf-ui-border); }
|
|
698
|
-
.opf-lx[data-compact="true"] .opf-lx-palette { flex-direction: row; flex: 1; padding: 4px 8px; border-right: 0; }
|
|
709
|
+
.opf-lx[data-compact="true"] .opf-lx-palette { flex-direction: row; flex-wrap: wrap; justify-content: center; flex: 1; padding: 4px 8px; border-right: 0; }
|
|
699
710
|
.opf-lx[data-compact="true"] .opf-lx-tool-gap { width: 1px; height: auto; margin: 4px; }
|
|
700
711
|
.opf-lx[data-compact="true"] .opf-lx-viewport { min-height: 220px; }
|
|
701
712
|
.opf-lx[data-compact="true"] .opf-lx-side { border-left: 0; border-top: 1px solid var(--opf-ui-border); }
|
|
@@ -3542,6 +3553,54 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
|
|
|
3542
3553
|
border-right: 1px solid var(--opf-ui-code-border);
|
|
3543
3554
|
}
|
|
3544
3555
|
|
|
3556
|
+
/* A wrapped line continues under its own indentation (src/source-wrap.js, VS Code's wrappingIndent "indent"): `opf-hang-<n>` says how many
|
|
3557
|
+
columns, the first line keeps its place (a negative text-indent of the same width) and every continuation line starts n columns in.
|
|
3558
|
+
The hang is capped at 40% of the line so a deeply nested line still leaves room for text at 320px; the cap is applied to n in source-wrap.js,
|
|
3559
|
+
from the measured width, because a percentage here makes style and layout of every line very slow (replacing the text of an 848-line
|
|
3560
|
+
document took 8.5 s instead of 0.56 s). Text inside an inline widget does not inherit the negative indent. `--opf-line-start` is the line's own
|
|
3561
|
+
left padding (the source pane sets it to 2px). */
|
|
3562
|
+
.cm-line.opf-hang-0 { --opf-hang: 0; }
|
|
3563
|
+
.cm-line.opf-hang-1 { --opf-hang: 1; }
|
|
3564
|
+
.cm-line.opf-hang-2 { --opf-hang: 2; }
|
|
3565
|
+
.cm-line.opf-hang-3 { --opf-hang: 3; }
|
|
3566
|
+
.cm-line.opf-hang-4 { --opf-hang: 4; }
|
|
3567
|
+
.cm-line.opf-hang-5 { --opf-hang: 5; }
|
|
3568
|
+
.cm-line.opf-hang-6 { --opf-hang: 6; }
|
|
3569
|
+
.cm-line.opf-hang-7 { --opf-hang: 7; }
|
|
3570
|
+
.cm-line.opf-hang-8 { --opf-hang: 8; }
|
|
3571
|
+
.cm-line.opf-hang-9 { --opf-hang: 9; }
|
|
3572
|
+
.cm-line.opf-hang-10 { --opf-hang: 10; }
|
|
3573
|
+
.cm-line.opf-hang-11 { --opf-hang: 11; }
|
|
3574
|
+
.cm-line.opf-hang-12 { --opf-hang: 12; }
|
|
3575
|
+
.cm-line.opf-hang-13 { --opf-hang: 13; }
|
|
3576
|
+
.cm-line.opf-hang-14 { --opf-hang: 14; }
|
|
3577
|
+
.cm-line.opf-hang-15 { --opf-hang: 15; }
|
|
3578
|
+
.cm-line.opf-hang-16 { --opf-hang: 16; }
|
|
3579
|
+
.cm-line.opf-hang-17 { --opf-hang: 17; }
|
|
3580
|
+
.cm-line.opf-hang-18 { --opf-hang: 18; }
|
|
3581
|
+
.cm-line.opf-hang-19 { --opf-hang: 19; }
|
|
3582
|
+
.cm-line.opf-hang-20 { --opf-hang: 20; }
|
|
3583
|
+
.cm-line.opf-hang-21 { --opf-hang: 21; }
|
|
3584
|
+
.cm-line.opf-hang-22 { --opf-hang: 22; }
|
|
3585
|
+
.cm-line.opf-hang-23 { --opf-hang: 23; }
|
|
3586
|
+
.cm-line.opf-hang-24 { --opf-hang: 24; }
|
|
3587
|
+
.cm-line.opf-hang-25 { --opf-hang: 25; }
|
|
3588
|
+
.cm-line.opf-hang-26 { --opf-hang: 26; }
|
|
3589
|
+
.cm-line.opf-hang-27 { --opf-hang: 27; }
|
|
3590
|
+
.cm-line.opf-hang-28 { --opf-hang: 28; }
|
|
3591
|
+
.cm-line.opf-hang-29 { --opf-hang: 29; }
|
|
3592
|
+
.cm-line.opf-hang-30 { --opf-hang: 30; }
|
|
3593
|
+
.cm-line.opf-hang-31 { --opf-hang: 31; }
|
|
3594
|
+
.cm-line.opf-hang-32 { --opf-hang: 32; }
|
|
3595
|
+
:is(.opf-ui, .opf-json, .opf-code) .cm-line {
|
|
3596
|
+
padding-left: calc(var(--opf-line-start, 6px) + var(--opf-hang, 0) * 1ch);
|
|
3597
|
+
text-indent: calc(-1 * var(--opf-hang, 0) * 1ch);
|
|
3598
|
+
}
|
|
3599
|
+
|
|
3600
|
+
:is(.opf-ui, .opf-json, .opf-code) .cm-line > * {
|
|
3601
|
+
text-indent: 0;
|
|
3602
|
+
}
|
|
3603
|
+
|
|
3545
3604
|
:is(.opf-ui, .opf-json, .opf-code) .cm-activeLine,
|
|
3546
3605
|
:is(.opf-ui, .opf-json, .opf-code) .cm-line.is-hover {
|
|
3547
3606
|
background: color-mix(in srgb, var(--opf-ui-accent) 8%, transparent);
|
|
@@ -4256,11 +4315,13 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
|
|
|
4256
4315
|
.opf-source [hidden] { display: none !important; }
|
|
4257
4316
|
.opf-source button { font: inherit; color: inherit; }
|
|
4258
4317
|
|
|
4259
|
-
/* Bar: file name, format menu, actions
|
|
4318
|
+
/* Bar: file name, format menu, actions. It wraps: where the name, the format and the actions do not fit on one row (a narrow pane, or 44px
|
|
4319
|
+
buttons under a coarse pointer), the actions drop to their own row on the right instead of squeezing the name. */
|
|
4260
4320
|
.opf-source-bar {
|
|
4261
4321
|
display: flex;
|
|
4322
|
+
flex-wrap: wrap;
|
|
4262
4323
|
align-items: center;
|
|
4263
|
-
gap: 14px;
|
|
4324
|
+
gap: 0 14px;
|
|
4264
4325
|
flex: none;
|
|
4265
4326
|
min-height: var(--_bar);
|
|
4266
4327
|
padding: 0 8px 0 14px;
|
|
@@ -4391,7 +4452,7 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
|
|
|
4391
4452
|
.opf-source-code .cm-scroller { overflow: auto; font: 400 13.5px/22px var(--opf-ui-mono); }
|
|
4392
4453
|
.opf-source[data-density="touch"] .opf-source-code .cm-scroller { font-size: 13px; line-height: 21px; }
|
|
4393
4454
|
.opf-source-code .cm-content { padding: 16px 16px 16px 4px; caret-color: var(--opf-ui-fg); }
|
|
4394
|
-
.opf-source-code .cm-line { padding: 0 2px; }
|
|
4455
|
+
.opf-source-code .cm-line { --opf-line-start: 2px; padding-top: 0; padding-right: 2px; padding-bottom: 0; }
|
|
4395
4456
|
.opf-source-code .cm-gutters { border: 0; background: transparent; color: color-mix(in srgb, var(--opf-ui-muted-fg) 60%, transparent); }
|
|
4396
4457
|
.opf-source-code .cm-lineNumbers .cm-gutterElement { min-width: 30px; padding: 0 12px 0 0; text-align: right; font-size: 11px; }
|
|
4397
4458
|
.opf-source-code .cm-activeLine { background: transparent; }
|
|
@@ -4741,3 +4802,217 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
|
|
|
4741
4802
|
transition: none;
|
|
4742
4803
|
}
|
|
4743
4804
|
}
|
|
4805
|
+
|
|
4806
|
+
/* touch.css */
|
|
4807
|
+
/*
|
|
4808
|
+
* Touch: a coarse pointer (a finger) gets a 44px hit area on every control, and the text in a field is 16px so iOS Safari does not
|
|
4809
|
+
* zoom the page when the field gets focus. tokens.css already raises --opf-ui-control-h to 44px under `(pointer: coarse)`, which lifts every
|
|
4810
|
+
* control that is sized by it; this file lifts the ones that size themselves (compact buttons, rows, menu items, completion items) and
|
|
4811
|
+
* keeps the visual look: the padding grows, the type does not. The code in an editor stays at its own size: it is not a field.
|
|
4812
|
+
* Tokens only, no color literals (test/styles.mjs).
|
|
4813
|
+
*/
|
|
4814
|
+
@media (pointer: coarse) {
|
|
4815
|
+
/* ---- fields: 16px, 44px ------------------------------------------------------------------------------------------------------ */
|
|
4816
|
+
:is(.opf-ui, .opf-source, .opf-json, .opf-code, .opf-shortcuts, .opf-quickpick, .opf-sym)
|
|
4817
|
+
:is(input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="color"], [type="button"], [type="submit"], [type="reset"], [type="image"]), select, textarea):not(.opf-inline-input, .opf-rich-input) {
|
|
4818
|
+
font-size: 16px;
|
|
4819
|
+
}
|
|
4820
|
+
:is(.opf-ui, .opf-source, .opf-json, .opf-code, .opf-shortcuts, .opf-quickpick, .opf-sym)
|
|
4821
|
+
:is(input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="color"], [type="button"], [type="submit"], [type="reset"], [type="image"]), select):not(.opf-inline-input, .opf-rich-input) {
|
|
4822
|
+
min-height: 44px;
|
|
4823
|
+
}
|
|
4824
|
+
/* WebKit sizes a native select by its text unless the height is set. */
|
|
4825
|
+
:is(.opf-ui, .opf-source, .opf-json, .opf-code) select {
|
|
4826
|
+
height: 44px;
|
|
4827
|
+
}
|
|
4828
|
+
.opf-ui input[type="file"] {
|
|
4829
|
+
min-height: 44px;
|
|
4830
|
+
}
|
|
4831
|
+
|
|
4832
|
+
/* ---- the source pane ---------------------------------------------------------------------------------------------------------- */
|
|
4833
|
+
.opf-source,
|
|
4834
|
+
.opf-source[data-density="touch"] {
|
|
4835
|
+
--_h: 44px;
|
|
4836
|
+
--_bar: 52px;
|
|
4837
|
+
}
|
|
4838
|
+
.opf-source-name,
|
|
4839
|
+
.opf-source-format {
|
|
4840
|
+
min-height: var(--_h);
|
|
4841
|
+
}
|
|
4842
|
+
.opf-source-name {
|
|
4843
|
+
min-width: 44px;
|
|
4844
|
+
}
|
|
4845
|
+
.opf-source-finding {
|
|
4846
|
+
min-height: var(--_h);
|
|
4847
|
+
}
|
|
4848
|
+
.opf-source-finding-fix,
|
|
4849
|
+
.opf-source-finding-details {
|
|
4850
|
+
min-height: var(--_h);
|
|
4851
|
+
padding: 0 12px;
|
|
4852
|
+
}
|
|
4853
|
+
.opf-source-finding-fixes {
|
|
4854
|
+
gap: 6px;
|
|
4855
|
+
}
|
|
4856
|
+
.opf-source-outline-item {
|
|
4857
|
+
min-height: var(--_h);
|
|
4858
|
+
}
|
|
4859
|
+
.opf-source-finding-explain-link {
|
|
4860
|
+
display: inline-flex;
|
|
4861
|
+
align-items: center;
|
|
4862
|
+
min-height: 44px;
|
|
4863
|
+
}
|
|
4864
|
+
.opf-sym-close {
|
|
4865
|
+
min-width: 44px;
|
|
4866
|
+
min-height: 44px;
|
|
4867
|
+
}
|
|
4868
|
+
.opf-sym-ref {
|
|
4869
|
+
min-height: 44px;
|
|
4870
|
+
align-items: center;
|
|
4871
|
+
}
|
|
4872
|
+
.opf-shortcuts .opf-shortcuts-close {
|
|
4873
|
+
width: 44px;
|
|
4874
|
+
height: 44px;
|
|
4875
|
+
}
|
|
4876
|
+
.opf-shortcuts .opf-shortcuts-search,
|
|
4877
|
+
.opf-quickpick-input {
|
|
4878
|
+
min-height: 44px;
|
|
4879
|
+
}
|
|
4880
|
+
.opf-quickpick-item {
|
|
4881
|
+
min-height: 44px;
|
|
4882
|
+
align-items: center;
|
|
4883
|
+
}
|
|
4884
|
+
|
|
4885
|
+
/* ---- CodeMirror's lists and panels (completions, problems, quick fixes, search) ---------------------------------------------- */
|
|
4886
|
+
:root :is(.opf-ui, .opf-source, .opf-json, .opf-code) .cm-tooltip.cm-tooltip-autocomplete > ul > li {
|
|
4887
|
+
display: flex;
|
|
4888
|
+
align-items: center;
|
|
4889
|
+
gap: 4px;
|
|
4890
|
+
min-height: 44px;
|
|
4891
|
+
padding: 2px 12px;
|
|
4892
|
+
}
|
|
4893
|
+
:root :is(.opf-ui, .opf-source, .opf-json, .opf-code) .cm-tooltip-autocomplete .cm-completionLabel {
|
|
4894
|
+
min-width: 0;
|
|
4895
|
+
overflow: hidden;
|
|
4896
|
+
text-overflow: ellipsis;
|
|
4897
|
+
}
|
|
4898
|
+
.cm-tooltip .opf-fix {
|
|
4899
|
+
display: flex;
|
|
4900
|
+
align-items: center;
|
|
4901
|
+
min-height: 44px;
|
|
4902
|
+
padding: 3px 12px;
|
|
4903
|
+
}
|
|
4904
|
+
.cm-tooltip-lint .cm-diagnosticAction {
|
|
4905
|
+
min-height: 44px;
|
|
4906
|
+
padding: 0 14px;
|
|
4907
|
+
}
|
|
4908
|
+
:root .cm-panels .cm-panel.cm-search :is(input, button, label) {
|
|
4909
|
+
min-height: 44px;
|
|
4910
|
+
}
|
|
4911
|
+
:root .cm-panels .cm-panel.cm-search :is(input[type="text"], input:not([type])) {
|
|
4912
|
+
font-size: 16px;
|
|
4913
|
+
}
|
|
4914
|
+
/* The find and replace fields take a row of their own each, the buttons and options wrap beneath, the close button stays in the corner. */
|
|
4915
|
+
:root .cm-panels .cm-panel.cm-search {
|
|
4916
|
+
display: flex;
|
|
4917
|
+
flex-wrap: wrap;
|
|
4918
|
+
align-items: center;
|
|
4919
|
+
gap: 6px;
|
|
4920
|
+
padding: 6px 52px 6px 8px;
|
|
4921
|
+
}
|
|
4922
|
+
:root .cm-panels .cm-panel.cm-search br {
|
|
4923
|
+
display: none;
|
|
4924
|
+
}
|
|
4925
|
+
:root .cm-panels .cm-panel.cm-search input[type="text"],
|
|
4926
|
+
:root .cm-panels .cm-panel.cm-search input:not([type]) {
|
|
4927
|
+
flex: 1 1 100%;
|
|
4928
|
+
min-width: 0;
|
|
4929
|
+
margin: 0;
|
|
4930
|
+
}
|
|
4931
|
+
:root .cm-panels .cm-panel.cm-search button,
|
|
4932
|
+
:root .cm-panels .cm-panel.cm-search label {
|
|
4933
|
+
margin: 0;
|
|
4934
|
+
}
|
|
4935
|
+
:root .cm-panels .cm-panel.cm-search label {
|
|
4936
|
+
display: inline-flex;
|
|
4937
|
+
align-items: center;
|
|
4938
|
+
gap: 6px;
|
|
4939
|
+
}
|
|
4940
|
+
:root .cm-panels .cm-panel.cm-search button {
|
|
4941
|
+
min-width: 44px;
|
|
4942
|
+
}
|
|
4943
|
+
:root .cm-panels .cm-panel.cm-search button[name="close"] {
|
|
4944
|
+
top: 0;
|
|
4945
|
+
right: 4px;
|
|
4946
|
+
}
|
|
4947
|
+
|
|
4948
|
+
/* ---- menus, dialogs and the compact controls of the panels --------------------------------------------------------------------- */
|
|
4949
|
+
.opf-export .opf-export-close {
|
|
4950
|
+
width: 44px;
|
|
4951
|
+
height: 44px;
|
|
4952
|
+
}
|
|
4953
|
+
.opf-export[data-density="touch"] .opf-export-trigger,
|
|
4954
|
+
.opf-export[data-density="touch"] .opf-export-item,
|
|
4955
|
+
.opf-export .opf-export-item {
|
|
4956
|
+
min-height: 44px;
|
|
4957
|
+
}
|
|
4958
|
+
.opf-export .opf-export-status-action {
|
|
4959
|
+
height: 44px;
|
|
4960
|
+
}
|
|
4961
|
+
.opf-handoff[data-density="touch"] .opf-handoff-button,
|
|
4962
|
+
.opf-handoff .opf-handoff-button {
|
|
4963
|
+
height: 44px;
|
|
4964
|
+
}
|
|
4965
|
+
.opf-handoff[data-density="touch"] .opf-handoff-target,
|
|
4966
|
+
.opf-handoff .opf-handoff-target {
|
|
4967
|
+
height: 44px;
|
|
4968
|
+
padding: 0 14px;
|
|
4969
|
+
}
|
|
4970
|
+
.opf-handoff[data-density="touch"] .opf-handoff-x,
|
|
4971
|
+
.opf-handoff .opf-handoff-x {
|
|
4972
|
+
width: 44px;
|
|
4973
|
+
height: 44px;
|
|
4974
|
+
}
|
|
4975
|
+
.opf-nav[data-density="touch"] .opf-nav-button,
|
|
4976
|
+
.opf-nav .opf-nav-button {
|
|
4977
|
+
width: 44px;
|
|
4978
|
+
height: 44px;
|
|
4979
|
+
}
|
|
4980
|
+
.opf-thumbs[data-density="touch"] .opf-thumbs-item,
|
|
4981
|
+
.opf-thumbs .opf-thumbs-item {
|
|
4982
|
+
min-height: 44px;
|
|
4983
|
+
}
|
|
4984
|
+
:root .opf-review-fix {
|
|
4985
|
+
min-height: 44px;
|
|
4986
|
+
padding: 0 12px;
|
|
4987
|
+
}
|
|
4988
|
+
:root .opf-find button.opf-find-close,
|
|
4989
|
+
:root .opf-find button[aria-label="Previous match"],
|
|
4990
|
+
:root .opf-find button[aria-label="Next match"] {
|
|
4991
|
+
min-width: 44px;
|
|
4992
|
+
}
|
|
4993
|
+
.opf-dc-group > summary,
|
|
4994
|
+
.opf-template-insert-section summary {
|
|
4995
|
+
min-height: 44px;
|
|
4996
|
+
padding-block: calc((44px - 1lh) / 2);
|
|
4997
|
+
}
|
|
4998
|
+
.opf-dc-check {
|
|
4999
|
+
display: flex;
|
|
5000
|
+
flex-direction: row;
|
|
5001
|
+
flex-wrap: wrap;
|
|
5002
|
+
align-items: center;
|
|
5003
|
+
column-gap: 10px;
|
|
5004
|
+
}
|
|
5005
|
+
.opf-dc-check > input {
|
|
5006
|
+
flex: none;
|
|
5007
|
+
width: 22px;
|
|
5008
|
+
height: 22px;
|
|
5009
|
+
margin: 0;
|
|
5010
|
+
}
|
|
5011
|
+
.opf-dc-check > label {
|
|
5012
|
+
display: flex;
|
|
5013
|
+
align-items: center;
|
|
5014
|
+
flex: 1 1 0;
|
|
5015
|
+
min-width: 0;
|
|
5016
|
+
min-height: 44px;
|
|
5017
|
+
}
|
|
5018
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openpresentation/opf-editor",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.8",
|
|
4
4
|
"description": "Embeddable local OPF editor primitives built on the deterministic renderer.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -287,10 +287,10 @@
|
|
|
287
287
|
"@lezer/highlight": "1.2.5",
|
|
288
288
|
"jsonc-parser": "3.3.1",
|
|
289
289
|
"yaml": "^2.9.1",
|
|
290
|
-
"@openpresentation/opf": "^0.26.
|
|
290
|
+
"@openpresentation/opf": "^0.26.8"
|
|
291
291
|
},
|
|
292
292
|
"peerDependencies": {
|
|
293
|
-
"@openpresentation/opf-render": "^0.26.
|
|
293
|
+
"@openpresentation/opf-render": "^0.26.8"
|
|
294
294
|
},
|
|
295
295
|
"peerDependenciesMeta": {
|
|
296
296
|
"@openpresentation/opf-render": {
|
|
@@ -349,9 +349,9 @@
|
|
|
349
349
|
"pdf-lib": "1.17.1",
|
|
350
350
|
"pdfjs-dist": "6.4.299",
|
|
351
351
|
"playwright": "1.64.0",
|
|
352
|
-
"@openpresentation/
|
|
353
|
-
"@openpresentation/opf-
|
|
354
|
-
"@openpresentation/
|
|
352
|
+
"@openpresentation/gallery": "0.26.8",
|
|
353
|
+
"@openpresentation/opf-pptx": "0.26.8",
|
|
354
|
+
"@openpresentation/opf-render": "0.26.8"
|
|
355
355
|
},
|
|
356
356
|
"scripts": {
|
|
357
357
|
"build": "node scripts/build.mjs",
|
|
@@ -402,5 +402,5 @@
|
|
|
402
402
|
"test:export-menu-browser": "node test/export-menu-browser.mjs",
|
|
403
403
|
"test:agent-handoff-browser": "node test/agent-handoff-browser.mjs"
|
|
404
404
|
},
|
|
405
|
-
"gitHead": "
|
|
405
|
+
"gitHead": "bb6faa40bebc1654f607bf6a434c43b5e95d0b1e"
|
|
406
406
|
}
|