fika-editor 3.3.1 → 3.4.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.
@@ -4,14 +4,14 @@ export declare const loadLocaleAsync: (locale: Locales) => Promise<void>;
4
4
  export declare const loadAllLocalesAsync: () => Promise<void[]>;
5
5
  export declare const loadFormatters: (locale: Locales) => void;
6
6
  export declare const importNamespaceAsync: <Namespace extends Namespaces>(locale: Locales, namespace: Namespace) => Promise<{
7
- screen: import("./i18n-types").NamespaceScreenTranslation;
8
- myna: import("./i18n-types").NamespaceMynaTranslation;
9
7
  export: import("./i18n-types").NamespaceExportTranslation;
10
- editor: import("./i18n-types").NamespaceEditorTranslation;
8
+ components: import("./i18n-types").NamespaceComponentsTranslation;
9
+ myna: import("./i18n-types").NamespaceMynaTranslation;
11
10
  mobile: import("./i18n-types").NamespaceMobileTranslation;
11
+ screen: import("./i18n-types").NamespaceScreenTranslation;
12
+ common: import("./i18n-types").NamespaceCommonTranslation;
13
+ editor: import("./i18n-types").NamespaceEditorTranslation;
12
14
  configs: import("./i18n-types").NamespaceConfigsTranslation;
13
15
  canvas: import("./i18n-types").NamespaceCanvasTranslation;
14
- common: import("./i18n-types").NamespaceCommonTranslation;
15
- components: import("./i18n-types").NamespaceComponentsTranslation;
16
16
  }[Namespace]>;
17
17
  export declare const loadNamespaceAsync: <Namespace extends Namespaces>(locale: Locales, namespace: Namespace) => Promise<void>;
@@ -9,15 +9,15 @@ export declare const isNamespace: (namespace: string) => namespace is Namespaces
9
9
  export declare const loadedLocales: Record<Locales, Translations>;
10
10
  export declare const loadedFormatters: Record<Locales, Formatters>;
11
11
  export declare const extendDictionary: <Base extends import("typesafe-i18n").BaseTranslation | {
12
- screen: import("./i18n-types").NamespaceScreenTranslation;
13
- myna: import("./i18n-types").NamespaceMynaTranslation;
14
12
  export: import("./i18n-types").NamespaceExportTranslation;
15
- editor: import("./i18n-types").NamespaceEditorTranslation;
13
+ components: import("./i18n-types").NamespaceComponentsTranslation;
14
+ myna: import("./i18n-types").NamespaceMynaTranslation;
16
15
  mobile: import("./i18n-types").NamespaceMobileTranslation;
16
+ screen: import("./i18n-types").NamespaceScreenTranslation;
17
+ common: import("./i18n-types").NamespaceCommonTranslation;
18
+ editor: import("./i18n-types").NamespaceEditorTranslation;
17
19
  configs: import("./i18n-types").NamespaceConfigsTranslation;
18
20
  canvas: import("./i18n-types").NamespaceCanvasTranslation;
19
- common: import("./i18n-types").NamespaceCommonTranslation;
20
- components: import("./i18n-types").NamespaceComponentsTranslation;
21
21
  }, Translation extends Base>(base: Base, part: (Translation extends string ? string : Translation extends import("typesafe-i18n").BaseTranslation ? { [P in keyof Translation]?: Translation[P] extends infer T ? T extends Translation[P] ? T extends string ? string : T extends import("typesafe-i18n").BaseTranslation ? { [P_1 in keyof T]?: T[P_1] extends infer T_1 ? T_1 extends T[P_1] ? T_1 extends string ? string : T_1 extends import("typesafe-i18n").BaseTranslation ? { [P_2 in keyof T_1]?: T_1[P_2] extends infer T_2 ? T_2 extends T_1[P_2] ? T_2 extends string ? string : T_2 extends import("typesafe-i18n").BaseTranslation ? { [P_3 in keyof T_2]?: T_2[P_3] extends infer T_3 ? T_3 extends T_2[P_3] ? T_3 extends string ? string : T_3 extends import("typesafe-i18n").BaseTranslation ? { [P_4 in keyof T_3]?: T_3[P_4] extends infer T_4 ? T_4 extends T_3[P_4] ? T_4 extends string ? string : T_4 extends import("typesafe-i18n").BaseTranslation ? { [P_5 in keyof T_4]?: T_4[P_5] extends infer T_5 ? T_5 extends T_4[P_5] ? T_5 extends string ? string : T_5 extends import("typesafe-i18n").BaseTranslation ? { [P_6 in keyof T_5]?: T_5[P_6] extends infer T_6 ? T_6 extends T_5[P_6] ? T_6 extends string ? string : T_6 extends import("typesafe-i18n").BaseTranslation ? { [P_7 in keyof T_6]?: T_6[P_7] extends infer T_7 ? T_7 extends T_6[P_7] ? T_7 extends string ? string : T_7 extends import("typesafe-i18n").BaseTranslation ? { [P_8 in keyof T_7]?: T_7[P_8] extends infer T_8 ? T_8 extends T_7[P_8] ? T_8 extends string ? string : T_8 extends import("typesafe-i18n").BaseTranslation ? { [P_9 in keyof T_8]?: T_8[P_9] extends infer T_9 ? T_9 extends T_8[P_9] ? T_9 extends string ? string : T_9 extends import("typesafe-i18n").BaseTranslation ? { [P_10 in keyof T_9]?: /*elided*/ any; } : T_9 : never : never; } : T_8 : never : never; } : T_7 : never : never; } : T_6 : never : never; } : T_5 : never : never; } : T_4 : never : never; } : T_3 : never : never; } : T_2 : never : never; } : T_1 : never : never; } : T : never : never; } : Translation) extends infer T ? T extends (Translation extends string ? string : Translation extends import("typesafe-i18n").BaseTranslation ? { [P in keyof Translation]?: Translation[P] extends infer T ? T extends Translation[P] ? T extends string ? string : T extends import("typesafe-i18n").BaseTranslation ? { [P_1 in keyof T]?: T[P_1] extends infer T_1 ? T_1 extends T[P_1] ? T_1 extends string ? string : T_1 extends import("typesafe-i18n").BaseTranslation ? { [P_2 in keyof T_1]?: T_1[P_2] extends infer T_2 ? T_2 extends T_1[P_2] ? T_2 extends string ? string : T_2 extends import("typesafe-i18n").BaseTranslation ? { [P_3 in keyof T_2]?: T_2[P_3] extends infer T_3 ? T_3 extends T_2[P_3] ? T_3 extends string ? string : T_3 extends import("typesafe-i18n").BaseTranslation ? { [P_4 in keyof T_3]?: T_3[P_4] extends infer T_4 ? T_4 extends T_3[P_4] ? T_4 extends string ? string : T_4 extends import("typesafe-i18n").BaseTranslation ? { [P_5 in keyof T_4]?: T_4[P_5] extends infer T_5 ? T_5 extends T_4[P_5] ? T_5 extends string ? string : T_5 extends import("typesafe-i18n").BaseTranslation ? { [P_6 in keyof T_5]?: T_5[P_6] extends infer T_6 ? T_6 extends T_5[P_6] ? T_6 extends string ? string : T_6 extends import("typesafe-i18n").BaseTranslation ? { [P_7 in keyof T_6]?: T_6[P_7] extends infer T_7 ? T_7 extends T_6[P_7] ? T_7 extends string ? string : T_7 extends import("typesafe-i18n").BaseTranslation ? { [P_8 in keyof T_7]?: T_7[P_8] extends infer T_8 ? T_8 extends T_7[P_8] ? T_8 extends string ? string : T_8 extends import("typesafe-i18n").BaseTranslation ? { [P_9 in keyof T_8]?: T_8[P_9] extends infer T_9 ? T_9 extends T_8[P_9] ? T_9 extends string ? string : T_9 extends import("typesafe-i18n").BaseTranslation ? { [P_10 in keyof T_9]?: any; } : T_9 : never : never; } : T_8 : never : never; } : T_7 : never : never; } : T_6 : never : never; } : T_5 : never : never; } : T_4 : never : never; } : T_3 : never : never; } : T_2 : never : never; } : T_1 : never : never; } : T : never : never; } : Translation) ? T extends import("typesafe-i18n").BaseTranslation ? { [P in keyof T]?: T[P] extends infer T_1 ? T_1 extends T[P] ? T_1 extends import("typesafe-i18n").BaseTranslation ? { [P_1 in keyof T_1]?: T_1[P_1] extends infer T_2 ? T_2 extends T_1[P_1] ? T_2 extends import("typesafe-i18n").BaseTranslation ? { [P_2 in keyof T_2]?: T_2[P_2] extends infer T_3 ? T_3 extends T_2[P_2] ? T_3 extends import("typesafe-i18n").BaseTranslation ? { [P_3 in keyof T_3]?: T_3[P_3] extends infer T_4 ? T_4 extends T_3[P_3] ? T_4 extends import("typesafe-i18n").BaseTranslation ? { [P_4 in keyof T_4]?: T_4[P_4] extends infer T_5 ? T_5 extends T_4[P_4] ? T_5 extends import("typesafe-i18n").BaseTranslation ? { [P_5 in keyof T_5]?: T_5[P_5] extends infer T_6 ? T_6 extends T_5[P_5] ? T_6 extends import("typesafe-i18n").BaseTranslation ? { [P_6 in keyof T_6]?: T_6[P_6] extends infer T_7 ? T_7 extends T_6[P_6] ? T_7 extends import("typesafe-i18n").BaseTranslation ? { [P_7 in keyof T_7]?: T_7[P_7] extends infer T_8 ? T_8 extends T_7[P_7] ? T_8 extends import("typesafe-i18n").BaseTranslation ? { [P_8 in keyof T_8]?: T_8[P_8] extends infer T_9 ? T_9 extends T_8[P_8] ? T_9 extends import("typesafe-i18n").BaseTranslation ? { [P_9 in keyof T_9]?: T_9[P_9] extends infer T_10 ? T_10 extends T_9[P_9] ? T_10 extends import("typesafe-i18n").BaseTranslation ? { [P_10 in keyof T_10]?: /*elided*/ any; } : T_10 : never : never; } : T_9 : never : never; } : T_8 : never : never; } : T_7 : never : never; } : T_6 : never : never; } : T_5 : never : never; } : T_4 : never : never; } : T_3 : never : never; } : T_2 : never : never; } : T_1 : never : never; } : T : never : never) => Translation;
22
22
  export declare const i18nString: (locale: Locales) => TranslateByString;
23
23
  export declare const i18nObject: (locale: Locales) => TranslationFunctions;
@@ -1 +1 @@
1
- export type DialogForExportTypes = 'json' | 'pptx' | '';
1
+ export type DialogForExportTypes = 'json' | 'pptx' | 'pdf' | '';
@@ -2,6 +2,14 @@
2
2
  * LaTeX → MathML (MathLive) → OMML (mathml2omml-plus) for native PowerPoint equations.
3
3
  * No hand-rolled math grammar — conversion is entirely library-based.
4
4
  */
5
+ /** Drop every character that cannot appear in an XML 1.0 document. */
6
+ export declare function stripXmlIllegalChars(text: string): string;
7
+ /**
8
+ * Well-formedness check mirroring the one pptxgenjs runs on `options.omml`
9
+ * (strict XML 1.0 via `@rgrove/parse-xml` around a synthetic root). Returns
10
+ * the first problem, or null when the fragment is safe to embed.
11
+ */
12
+ export declare function validateOmmlFragment(omml: string): string | null;
5
13
  export interface OmmlRunStyle {
6
14
  /** CSS/hex color applied to every math glyph run and control (vinculum, …). */
7
15
  color?: string;
package/docs/EMBED.md CHANGED
@@ -552,3 +552,34 @@ ordinary Fika document and viewport. `createMynaDocument()` and `MYNA_FORMATS`
552
552
  are exported for hosts that need the starter or format catalog. The same
553
553
  controller, history, media uploader, read-only options, and change callbacks
554
554
  apply. See [Myna integration and capabilities](./MYNA.md).
555
+
556
+
557
+ ### Export without a mounted editor
558
+
559
+ `exportPresentationPptx(document, options)` and `exportPresentationPdf(document, options)`
560
+ return `Promise<Blob>`. They snapshot the supplied `FikaDocument`, do not open
561
+ an export dialog, and do not trigger a browser download. A saved deck can be
562
+ exported while another deck remains open and editable.
563
+
564
+ ```ts
565
+ import { exportPresentationPptx, exportPresentationPdf } from 'fika-editor/embed'
566
+
567
+ const options = { assetBaseUrl: '/fika-assets' }
568
+ const pptx = await exportPresentationPptx(document, options)
569
+ const pdf = await exportPresentationPdf(document, options)
570
+ ```
571
+
572
+ PPTX retains editable elements. PDF uses the existing slide painter with one
573
+ high-resolution PNG per page (2560 pixels wide by default), preserving slide
574
+ order and aspect ratio. PDF text is rasterized. No additional document IR is
575
+ required. Load `fika-embed.css` before PDF export so bundled fonts are available.
576
+
577
+ Options include `mediaResolver`, `watermark`, and `onProgress(completed, total)`.
578
+ Omitted resolvers use the current embed configuration. Pass `null` explicitly
579
+ to disable a resolver. PDF also accepts `width` (64 to 8192 pixels) and
580
+ `timeoutMs` (default 30000 per slide). Required watermark and PDF image failures
581
+ reject the promise. PPTX retains its existing partial-media warning behavior.
582
+
583
+ The native export dialog now offers `pptx`, `pdf`, and `json`; control their
584
+ visibility with `exportTabs`. Host exports should call these APIs directly,
585
+ without simulating export button clicks or mounting an offscreen editor.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fika-editor",
3
- "version": "3.3.1",
3
+ "version": "3.4.0",
4
4
  "description": "Fika presentation editor embed bundle with a typed agentic bridge.",
5
5
  "type": "module",
6
6
  "main": "dist/embed/fika-embed.js",
@@ -100,6 +100,7 @@
100
100
  "@dnd-kit/sortable": "^10.0.0",
101
101
  "@dnd-kit/utilities": "^3.2.2",
102
102
  "@karibash/pixel-units": "^2.3.0",
103
+ "@rgrove/parse-xml": "^4.2.3",
103
104
  "@tanstack/react-virtual": "^3.14.10",
104
105
  "@use-gesture/react": "^10.3.1",
105
106
  "@use-gesture/vanilla": "^10.3.1",
@@ -135,8 +136,9 @@
135
136
  "number-precision": "^1.6.0",
136
137
  "overlayscrollbars": "^2.16.0",
137
138
  "parse5": "^8.0.1",
139
+ "pdf-lib": "^1.17.1",
138
140
  "perfect-freehand": "^1.2.3",
139
- "pptxgenjs-plus": "^4.3.3",
141
+ "pptxgenjs-plus": "^4.3.4",
140
142
  "pptxtojson": "npm:@lofcz/pptxtojson@^2.2.9",
141
143
  "prosemirror-commands": "^1.7.2",
142
144
  "prosemirror-dropcursor": "^1.8.3",