@openpresentation/opf-editor 0.15.0 → 0.17.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/README.md +42 -14
- package/dist/canvas.js +14 -2
- package/dist/catalog-control.js +21 -0
- package/dist/design-controls.js +88 -27
- package/dist/design-options.d.ts +22 -9
- package/dist/design-options.js +77 -18
- package/dist/export.d.ts +6 -1
- package/dist/export.js +6 -1
- package/dist/find-replace.js +10 -1
- package/dist/font-gate.js +0 -11
- package/dist/index.d.ts +2 -0
- package/dist/index.js +24 -9
- package/dist/json-options.js +7 -6
- package/dist/layout-handles.js +13 -0
- package/dist/layout-placeholders.js +15 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.js +5 -1
- package/dist/slide-manager.js +3 -1
- package/dist/svelte.d.ts +1 -0
- package/dist/svelte.js +3 -2
- package/dist/switches.js +3 -2
- package/dist/table-options.d.ts +6 -1
- package/dist/table-options.js +43 -0
- package/dist/template-panel.js +6 -4
- package/dist/templates.d.ts +3 -1
- package/dist/templates.js +1 -1
- package/package.json +18 -9
package/dist/table-options.js
CHANGED
|
@@ -394,6 +394,44 @@ export function readTableStyleOfTable(table) {
|
|
|
394
394
|
// Table structure (RR-24): insert, delete, move and sort rows and columns, the header row, cell values.
|
|
395
395
|
export * from "./table-structure.js";
|
|
396
396
|
|
|
397
|
+
// --- text alternative (FA-27) -----------------------------------------------------------------
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* The table's text alternative as form state, like a chart's: `alt` is the text (empty when absent or decorative) and `decorative`
|
|
401
|
+
* is the empty alt, a reviewed choice and not a missing one.
|
|
402
|
+
*/
|
|
403
|
+
export function readTableAlt(table) {
|
|
404
|
+
return { alt: typeof table?.alt === "string" ? table.alt : "", decorative: table?.alt === "" };
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Compute the patch that changes the table's text alternative. `change` is `{ alt?, decorative? }`: `alt` is trimmed and an empty string
|
|
409
|
+
* or `null` removes it, `decorative: true` writes the empty alt (and wins over `alt`), `decorative: false` removes an empty alt. It works
|
|
410
|
+
* on an inline table and on a table that shows a shared dataset, because `alt` belongs to the table and not to its data. The document
|
|
411
|
+
* is not modified.
|
|
412
|
+
*/
|
|
413
|
+
export function prepareTableAlt(presentation, tablePath, change) {
|
|
414
|
+
const before = checkFormat(presentation);
|
|
415
|
+
const parts = splitOpfPath(tablePath);
|
|
416
|
+
const table = getValueAtPath(presentation, parts);
|
|
417
|
+
if (!isObject(table) || (!Array.isArray(table.rows) && typeof table.dataset !== "string")) throw fail("table-not-found", "Choose a table (a path ending in .table).", { tablePath });
|
|
418
|
+
if (!isObject(change)) throw fail("invalid-table-option", "A table alt change is { alt?, decorative? }.", { change });
|
|
419
|
+
let wanted;
|
|
420
|
+
if (change.decorative === true) wanted = "";
|
|
421
|
+
else if (change.alt !== undefined) wanted = typeof change.alt === "string" && change.alt.trim() ? change.alt.trim() : undefined;
|
|
422
|
+
else if (change.decorative === false && table.alt === "") wanted = undefined;
|
|
423
|
+
else wanted = table.alt;
|
|
424
|
+
const pointer = opfPathToJsonPointer([...parts, "alt"]);
|
|
425
|
+
const present = Object.hasOwn(table, "alt");
|
|
426
|
+
const patches = [];
|
|
427
|
+
if (wanted === undefined) {
|
|
428
|
+
if (present) patches.push({ op: "remove", path: pointer });
|
|
429
|
+
} else if (!present) patches.push({ op: "add", path: pointer, value: wanted });
|
|
430
|
+
else if (table.alt !== wanted) patches.push({ op: "replace", path: pointer, value: wanted });
|
|
431
|
+
const next = checkedDocument(presentation, patches, before);
|
|
432
|
+
return { action: "table-alt", tablePath: parts.join("."), changed: patches.length > 0, patches, presentation: clone(next) };
|
|
433
|
+
}
|
|
434
|
+
|
|
397
435
|
// --- session forms ----------------------------------------------------------------------------
|
|
398
436
|
|
|
399
437
|
function commit(editor, prepared, meta = {}) {
|
|
@@ -423,6 +461,11 @@ export function setTableCellStyle(editor, tablePath, cells, style, meta = {}) {
|
|
|
423
461
|
checkEditor(editor);
|
|
424
462
|
return commit(editor, prepareTableCellStyle(editor.presentation, tablePath, cells, style), meta);
|
|
425
463
|
}
|
|
464
|
+
/** Change the table's text alternative as one undoable transaction. See {@link prepareTableAlt}. */
|
|
465
|
+
export function setTableAlt(editor, tablePath, change, meta = {}) {
|
|
466
|
+
checkEditor(editor);
|
|
467
|
+
return commit(editor, prepareTableAlt(editor.presentation, tablePath, change), meta);
|
|
468
|
+
}
|
|
426
469
|
/** Apply a table style as one undoable transaction. See {@link prepareTableStyle}. */
|
|
427
470
|
export function setTableStyle(editor, tablePath, preset, meta = {}) {
|
|
428
471
|
checkEditor(editor);
|
package/dist/template-panel.js
CHANGED
|
@@ -67,7 +67,7 @@ export function createTemplatePanel(container, options) {
|
|
|
67
67
|
const builtinList = h(doc, "ul", { class: "opf-template-builtin-list" });
|
|
68
68
|
const builtinSection = h(doc, "details", { class: "opf-template-builtins", "data-opf-component": "template-builtins" },
|
|
69
69
|
h(doc, "summary", { text: "Built-in variables" }),
|
|
70
|
-
h(doc, "p", { class: "opf-template-help", text: "Read from the presentation's own speaker, organization and deck fields; edit those fields to change them. Use them like any variable: {{speaker.name}} inside text, or var:speaker.photo as a whole image field." }),
|
|
70
|
+
h(doc, "p", { class: "opf-template-help", text: "Read from the presentation's own speaker, organization and deck fields; edit those fields to change them. Use them like any variable: {{speaker.name}} inside text, or var:speaker.photo as a whole image field. Slide number, section and slide count vary per slide: write them as {{slide.number}}, {{slide.section}} and {{deck.slideCount}} inside any text, not as a whole var: field." }),
|
|
71
71
|
builtinList);
|
|
72
72
|
const live = h(doc, "p", { class: "opf-template-live", role: "status", "aria-live": "polite" });
|
|
73
73
|
const applyButton = h(doc, "button", { type: "button", class: "opf-template-apply primary", text: "Fill the presentation" });
|
|
@@ -234,10 +234,12 @@ export function createTemplatePanel(container, options) {
|
|
|
234
234
|
);
|
|
235
235
|
builtinSection.hidden = !builtins.length;
|
|
236
236
|
builtinList.replaceChildren(...builtins.map((entry) => {
|
|
237
|
-
const shown = builtinValueText(entry);
|
|
238
237
|
const uses = entry.uses.length;
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
// A slide-scoped built-in has no single value: each slide gets its own when it is drawn or exported (FA-31).
|
|
239
|
+
const slideScoped = entry.scope === "slide";
|
|
240
|
+
const shown = slideScoped ? h(doc, "em", { text: "varies per slide" }) : entry.available ? builtinValueText(entry) : h(doc, "em", { text: "not set" });
|
|
241
|
+
return h(doc, "li", { "data-builtin": entry.name, "data-kind": entry.kind, "data-scope": entry.scope, "data-available": entry.available ? "true" : "false" },
|
|
242
|
+
h(doc, "code", { text: `{{${entry.name}}}` }), ` ${entry.label}: `, shown, slideScoped && !entry.available ? " (no slide has one yet)" : "", uses ? ` (used ${uses} time${uses === 1 ? "" : "s"})` : "");
|
|
241
243
|
}));
|
|
242
244
|
slideSelect.replaceChildren(...(editor.presentation.slides ?? []).map((slide, index) => h(doc, "option", { value: String(index), text: `${index + 1}. ${slideTitle(slide) || "Untitled"}` })));
|
|
243
245
|
previewSlide = Math.min(previewSlide, Math.max(0, (editor.presentation.slides?.length ?? 1) - 1));
|
package/dist/templates.d.ts
CHANGED
|
@@ -109,7 +109,9 @@ export interface BuiltinInfo {
|
|
|
109
109
|
name: string;
|
|
110
110
|
kind: "text" | "image" | "list";
|
|
111
111
|
label: string;
|
|
112
|
-
/**
|
|
112
|
+
/** `deck` for a value read once from the document; `slide` for `slide.number`, `slide.section` and `deck.slideCount`, which vary per slide. */
|
|
113
|
+
scope: "deck" | "slide";
|
|
114
|
+
/** The source value, when the document has one. Never set for a slide-scoped built-in. */
|
|
113
115
|
value?: unknown;
|
|
114
116
|
available: boolean;
|
|
115
117
|
uses: { id: string; path: string; form: "token" | "reference" }[];
|
package/dist/templates.js
CHANGED
|
@@ -8,7 +8,7 @@ import { OPFEditorError, getValueAtPath, opfPathToJsonPointer } from "./index.js
|
|
|
8
8
|
|
|
9
9
|
const VARIABLE_ID = /^[a-z][a-z0-9-]*$/;
|
|
10
10
|
// A built-in variable name (core FA-04): `speakers`, or deck/speaker/organization plus one or two dotted segments.
|
|
11
|
-
const BUILTIN_NAME = /^(?:speakers|(?:deck|speaker|organization)(
|
|
11
|
+
const BUILTIN_NAME = /^(?:speakers|(?:deck|slide|speaker|organization)(?:\.[A-Za-z0-9_-]+){1,2})$/;
|
|
12
12
|
const KINDS = ["color", "text", "number", "date", "image", "url", "list"];
|
|
13
13
|
|
|
14
14
|
/** The form control each variable kind uses. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openpresentation/opf-editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Embeddable local OPF editor primitives built on the deterministic renderer.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -226,6 +226,7 @@
|
|
|
226
226
|
"test:code-browser": "node test/code-browser.mjs",
|
|
227
227
|
"test:selection-browser": "node test/selection-browser.mjs",
|
|
228
228
|
"test:click-entry-browser": "node test/click-entry-browser.mjs",
|
|
229
|
+
"test:canvas-a11y-browser": "node test/canvas-a11y-browser.mjs",
|
|
229
230
|
"test:metric-browser": "node test/metric-browser.mjs",
|
|
230
231
|
"test:rich-input-browser": "node test/rich-input-browser.mjs",
|
|
231
232
|
"test:json": "npm run build && node test/json-source.mjs && node test/json-options.mjs",
|
|
@@ -257,11 +258,11 @@
|
|
|
257
258
|
"@codemirror/state": "6.7.6",
|
|
258
259
|
"@codemirror/view": "6.43.13",
|
|
259
260
|
"@lezer/highlight": "1.2.4",
|
|
260
|
-
"@openpresentation/opf": "^0.
|
|
261
|
+
"@openpresentation/opf": "^0.17.0",
|
|
261
262
|
"jsonc-parser": "3.3.1"
|
|
262
263
|
},
|
|
263
264
|
"peerDependencies": {
|
|
264
|
-
"@openpresentation/opf-render": "^0.
|
|
265
|
+
"@openpresentation/opf-render": "^0.17.0"
|
|
265
266
|
},
|
|
266
267
|
"peerDependenciesMeta": {
|
|
267
268
|
"@openpresentation/opf-render": {
|
|
@@ -269,6 +270,12 @@
|
|
|
269
270
|
}
|
|
270
271
|
},
|
|
271
272
|
"devDependencies": {
|
|
273
|
+
"@expo-google-fonts/arimo": "0.4.3",
|
|
274
|
+
"@expo-google-fonts/caladea": "0.4.2",
|
|
275
|
+
"@expo-google-fonts/cousine": "0.4.3",
|
|
276
|
+
"@expo-google-fonts/gelasio": "0.4.1",
|
|
277
|
+
"@expo-google-fonts/noto-color-emoji": "0.4.6",
|
|
278
|
+
"@expo-google-fonts/noto-emoji": "0.4.7",
|
|
272
279
|
"@expo-google-fonts/noto-naskh-arabic": "0.4.5",
|
|
273
280
|
"@expo-google-fonts/noto-nastaliq-urdu": "0.4.2",
|
|
274
281
|
"@expo-google-fonts/noto-sans": "0.4.2",
|
|
@@ -303,15 +310,17 @@
|
|
|
303
310
|
"@expo-google-fonts/noto-sans-thai": "0.4.2",
|
|
304
311
|
"@expo-google-fonts/noto-serif-hebrew": "0.4.2",
|
|
305
312
|
"@expo-google-fonts/noto-serif-tibetan": "0.4.2",
|
|
306
|
-
"@
|
|
307
|
-
"@
|
|
313
|
+
"@expo-google-fonts/roboto": "0.4.3",
|
|
314
|
+
"@expo-google-fonts/roboto-mono": "0.4.2",
|
|
315
|
+
"@expo-google-fonts/stix-two-math": "0.4.0",
|
|
316
|
+
"@expo-google-fonts/tinos": "0.4.2",
|
|
317
|
+
"@openpresentation/opf-pptx": "^0.17.0",
|
|
318
|
+
"@openpresentation/opf-render": "^0.17.0",
|
|
308
319
|
"axe-core": "4.13.0",
|
|
309
320
|
"esbuild": "0.28.2",
|
|
310
321
|
"jszip": "3.10.2",
|
|
322
|
+
"pdf-lib": "1.17.1",
|
|
311
323
|
"pdfjs-dist": "6.3.289",
|
|
312
|
-
"playwright": "1.63.0"
|
|
313
|
-
"@expo-google-fonts/noto-color-emoji": "0.4.6",
|
|
314
|
-
"@expo-google-fonts/noto-emoji": "0.4.7",
|
|
315
|
-
"@expo-google-fonts/stix-two-math": "0.4.0"
|
|
324
|
+
"playwright": "1.63.0"
|
|
316
325
|
}
|
|
317
326
|
}
|