@fiduswriter/editor 0.2.6 → 0.2.7

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.
Files changed (43) hide show
  1. package/dist/copyright_dialog/templates.d.ts.map +1 -1
  2. package/dist/copyright_dialog/templates.js +11 -31
  3. package/dist/copyright_dialog/templates.js.map +1 -1
  4. package/dist/dialogs/epub_export.d.ts +15 -0
  5. package/dist/dialogs/epub_export.d.ts.map +1 -0
  6. package/dist/dialogs/epub_export.js +43 -0
  7. package/dist/dialogs/epub_export.js.map +1 -0
  8. package/dist/dialogs/html_export.d.ts +3 -0
  9. package/dist/dialogs/html_export.d.ts.map +1 -1
  10. package/dist/dialogs/html_export.js +4 -3
  11. package/dist/dialogs/html_export.js.map +1 -1
  12. package/dist/dialogs/index.d.ts +2 -0
  13. package/dist/dialogs/index.d.ts.map +1 -1
  14. package/dist/dialogs/index.js +2 -0
  15. package/dist/dialogs/index.js.map +1 -1
  16. package/dist/dialogs/template_export.d.ts +13 -0
  17. package/dist/dialogs/template_export.d.ts.map +1 -0
  18. package/dist/dialogs/template_export.js +46 -0
  19. package/dist/dialogs/template_export.js.map +1 -0
  20. package/dist/dialogs/templates.d.ts +9 -0
  21. package/dist/dialogs/templates.d.ts.map +1 -1
  22. package/dist/dialogs/templates.js +54 -12
  23. package/dist/dialogs/templates.js.map +1 -1
  24. package/dist/document_template/index.d.ts.map +1 -1
  25. package/dist/document_template/index.js +23 -4
  26. package/dist/document_template/index.js.map +1 -1
  27. package/dist/menus/headerbar/model.d.ts +1 -1
  28. package/dist/menus/headerbar/model.d.ts.map +1 -1
  29. package/dist/menus/headerbar/model.js +31 -10
  30. package/dist/menus/headerbar/model.js.map +1 -1
  31. package/dist/menus/toolbar/model.d.ts +7 -7
  32. package/dist/menus/toolbar/model.d.ts.map +1 -1
  33. package/locale/en/messages.json +18 -1
  34. package/locale/en_US/messages.json +18 -1
  35. package/package.json +5 -5
  36. package/src/copyright_dialog/templates.ts +35 -31
  37. package/src/dialogs/epub_export.ts +66 -0
  38. package/src/dialogs/html_export.ts +11 -3
  39. package/src/dialogs/index.ts +2 -0
  40. package/src/dialogs/template_export.ts +66 -0
  41. package/src/dialogs/templates.ts +117 -14
  42. package/src/document_template/index.ts +23 -4
  43. package/src/menus/headerbar/model.ts +39 -10
@@ -0,0 +1,66 @@
1
+ import {Dialog} from "fwtoolkit"
2
+ import {
3
+ exportTrackChangesTemplate,
4
+ getExportTrackChangesValue
5
+ } from "./templates.js"
6
+
7
+ export interface TemplateExportDialogResult {
8
+ /** Resolve all tracked changes (accept all) before exporting. When false,
9
+ the tracked changes are kept and rendered in the exported file. */
10
+ resolveTrackChanges: boolean
11
+ }
12
+
13
+ /** Ask how tracked changes should be handled before a DOCX/ODT template export. */
14
+ export class TemplateExportDialog {
15
+ dialog: Dialog | false
16
+
17
+ constructor() {
18
+ this.dialog = false
19
+ }
20
+
21
+ init(fileType: "docx" | "odt"): Promise<TemplateExportDialogResult | false> {
22
+ const title =
23
+ fileType === "docx"
24
+ ? gettext("DOCX export options")
25
+ : gettext("ODT export options")
26
+ const buttons: Array<Record<string, unknown>> = []
27
+ const dialogDonePromise = new Promise<TemplateExportDialogResult | false>(
28
+ resolve => {
29
+ buttons.push({
30
+ text: gettext("Export"),
31
+ classes: "fw-dark",
32
+ click: () => {
33
+ const dialogEl = (this.dialog as Dialog).dialogEl
34
+ const resolveTrackChanges =
35
+ getExportTrackChangesValue(
36
+ dialogEl,
37
+ "template-track-changes"
38
+ ) !== "include"
39
+ ;(this.dialog as Dialog).close()
40
+ return resolve({resolveTrackChanges})
41
+ }
42
+ })
43
+
44
+ buttons.push({
45
+ type: "cancel" as const,
46
+ click: () => {
47
+ ;(this.dialog as Dialog).close()
48
+ resolve(false)
49
+ }
50
+ })
51
+ }
52
+ )
53
+
54
+ this.dialog = new Dialog({
55
+ title,
56
+ body: exportTrackChangesTemplate("template-track-changes"),
57
+ height: 220,
58
+ width: 420,
59
+ buttons,
60
+ restoreActiveElement: false
61
+ })
62
+ this.dialog.open()
63
+
64
+ return dialogDonePromise
65
+ }
66
+ }
@@ -1,5 +1,5 @@
1
1
  import {CATS} from "@fiduswriter/document/schema/i18n"
2
- import {escapeText} from "fwtoolkit"
2
+ import {escapeText, infoTooltip} from "fwtoolkit"
3
3
 
4
4
  interface InternalTarget {
5
5
  id: string
@@ -96,40 +96,143 @@ export const revisionDialogTemplate = ({dir}: {dir: string}): string =>
96
96
  export const pdfExportDialogTemplate = (): string => `
97
97
  <h4>${gettext("Tracked changes")}</h4>
98
98
  <div class="fw-radio">
99
- <input type="radio" name="pdf-track-changes" value="resolve" class="pdf-track-resolve" checked="">
99
+ <input type="radio" name="pdf-track-changes" value="resolve" class="pdf-track-resolve" checked="" aria-describedby="pdf-track-resolve-help">
100
100
  <label class="pdf-track-resolve-label">${gettext("Resolve tracked changes (accept all)")}</label>
101
+ ${infoTooltip(
102
+ gettext(
103
+ "Applies all tracked changes so the PDF shows the document as if every change had already been accepted."
104
+ ),
105
+ "pdf-track-resolve-help"
106
+ )}
101
107
  </div>
102
108
  <div class="fw-radio">
103
- <input type="radio" name="pdf-track-changes" value="include" class="pdf-track-include">
109
+ <input type="radio" name="pdf-track-changes" value="include" class="pdf-track-include" aria-describedby="pdf-track-include-help">
104
110
  <label class="pdf-track-include-label">${gettext("Include tracked changes in the PDF")}</label>
111
+ ${infoTooltip(
112
+ gettext(
113
+ "Prints the tracked changes so reviewers can see what was added, removed or altered."
114
+ ),
115
+ "pdf-track-include-help"
116
+ )}
105
117
  </div>
106
118
  <p>
107
119
  <label>
108
- <input type="checkbox" class="pdf-embed-fidus">
120
+ <input type="checkbox" class="pdf-embed-fidus" aria-describedby="pdf-embed-fidus-help">
109
121
  ${gettext("Embed a Fidus Writer file of this document in the PDF")}
110
122
  </label>
123
+ ${infoTooltip(
124
+ gettext(
125
+ "Embeds the editable Fidus Writer document inside the PDF so it can be reopened for editing."
126
+ ),
127
+ "pdf-embed-fidus-help"
128
+ )}
111
129
  </p>
112
130
  <h4>${gettext("Print production")}</h4>
113
131
  <p>
114
- <label><input type="checkbox" class="pdf-crop-marks"> ${gettext("Crop marks")}</label><br>
115
- <label><input type="checkbox" class="pdf-trim-box"> ${gettext("Trim box")}</label><br>
116
- <label><input type="checkbox" class="pdf-bleed-box"> ${gettext("Bleed box")}</label><br>
117
- <label>${gettext("Bleed")}: <input type="number" class="pdf-bleed-mm" value="3" min="0" step="0.5"> ${gettext("mm")}</label><br>
118
- <label><input type="checkbox" class="pdf-link-borders"> ${gettext("Show link annotation borders")}</label><br>
119
- <label><input type="checkbox" class="pdf-rasterize-svgs"> ${gettext("Rasterize SVG images")}</label>
132
+ <label><input type="checkbox" class="pdf-crop-marks" aria-describedby="pdf-crop-marks-help"> ${gettext("Crop marks")}</label>
133
+ ${infoTooltip(
134
+ gettext("Small lines at the corners of the page that show printers where to cut the paper."),
135
+ "pdf-crop-marks-help"
136
+ )}<br>
137
+ <label><input type="checkbox" class="pdf-trim-box" aria-describedby="pdf-trim-box-help"> ${gettext("Trim box")}</label>
138
+ ${infoTooltip(
139
+ gettext("Marks the final size of the page after it has been cut."),
140
+ "pdf-trim-box-help"
141
+ )}<br>
142
+ <label><input type="checkbox" class="pdf-bleed-box" aria-describedby="pdf-bleed-box-help"> ${gettext("Bleed box")}</label>
143
+ ${infoTooltip(
144
+ gettext("Marks the area beyond the final page size where images and colors must extend so no white edges appear after cutting."),
145
+ "pdf-bleed-box-help"
146
+ )}<br>
147
+ <label>${gettext("Bleed")}: <input type="number" class="pdf-bleed-mm" value="3" min="0" step="0.5" aria-describedby="pdf-bleed-mm-help"> ${gettext("mm")}</label>
148
+ ${infoTooltip(
149
+ gettext("How far, in millimeters, images and colors extend beyond the edge of the page."),
150
+ "pdf-bleed-mm-help"
151
+ )}<br>
152
+ <label><input type="checkbox" class="pdf-link-borders" aria-describedby="pdf-link-borders-help"> ${gettext("Show link annotation borders")}</label>
153
+ ${infoTooltip(
154
+ gettext("Draws a visible border around hyperlinks in the PDF so they are easier to find."),
155
+ "pdf-link-borders-help"
156
+ )}<br>
157
+ <label><input type="checkbox" class="pdf-rasterize-svgs" aria-describedby="pdf-rasterize-svgs-help"> ${gettext("Rasterize SVG images")}</label>
158
+ ${infoTooltip(
159
+ gettext("Converts SVG images to bitmap images in the PDF, which can help when PDF viewers or printers do not render SVG images correctly."),
160
+ "pdf-rasterize-svgs-help"
161
+ )}
120
162
  </p>
121
163
  `
122
164
 
165
+ /**
166
+ * Radio group for choosing whether tracked changes are resolved (accepted) or
167
+ * kept in the exported file. `name` must be unique per dialog; the chosen value
168
+ * is read back with {@link getExportTrackChangesValue}.
169
+ */
170
+ export const exportTrackChangesTemplate = (name: string): string => `
171
+ <h4>${gettext("Tracked changes")}</h4>
172
+ <div class="fw-radio">
173
+ <input type="radio" name="${name}" value="resolve" class="export-track-resolve" checked="" aria-describedby="${name}-resolve-help">
174
+ <label class="export-track-resolve-label">${gettext("Resolve tracked changes (accept all)")}</label>
175
+ ${infoTooltip(
176
+ gettext(
177
+ "Applies all tracked changes so the exported file shows the document as if every change had already been accepted."
178
+ ),
179
+ `${name}-resolve-help`
180
+ )}
181
+ </div>
182
+ <div class="fw-radio">
183
+ <input type="radio" name="${name}" value="include" class="export-track-include" aria-describedby="${name}-include-help">
184
+ <label class="export-track-include-label">${gettext("Include tracked changes in the export")}</label>
185
+ ${infoTooltip(
186
+ gettext(
187
+ "Keeps the tracked changes so reviewers can see what was added, removed or altered."
188
+ ),
189
+ `${name}-include-help`
190
+ )}
191
+ </div>
192
+ `
193
+
194
+ /** Read the tracked-changes radio group value ("resolve" or "include"). */
195
+ export const getExportTrackChangesValue = (
196
+ dialogEl: Element,
197
+ name: string
198
+ ): string => {
199
+ return (
200
+ dialogEl.querySelector(
201
+ `input[name="${name}"]:checked`
202
+ ) as HTMLInputElement | null
203
+ )?.value || "resolve"
204
+ }
205
+
123
206
  export const htmlExportDialogTemplate = (): string => `
207
+ ${exportTrackChangesTemplate("html-track-changes")}
208
+ <p>
209
+ <label>
210
+ <input type="checkbox" class="html-svg-math" aria-describedby="html-svg-math-help">
211
+ ${gettext("Render formulas as SVG images instead of MathML")}
212
+ </label>
213
+ ${infoTooltip(
214
+ gettext(
215
+ "SVG renders consistently across browsers; MathML keeps formulas as text that can be searched and copied, but only newer browsers support it."
216
+ ),
217
+ "html-svg-math-help"
218
+ )}
219
+ </p>
220
+ `
221
+
222
+ export const epubExportDialogTemplate = (): string => `
223
+ ${exportTrackChangesTemplate("epub-track-changes")}
124
224
  <p>
125
225
  <label>
126
- <input type="checkbox" class="html-svg-math">
226
+ <input type="checkbox" class="epub-svg-math" aria-describedby="epub-svg-math-help">
127
227
  ${gettext("Render formulas as SVG images instead of MathML")}
128
228
  </label>
229
+ ${infoTooltip(
230
+ gettext(
231
+ "SVG renders consistently across browsers; MathML keeps formulas as text that can be searched and copied, but only newer browsers support it."
232
+ ),
233
+ "epub-svg-math-help"
234
+ )}
129
235
  </p>
130
- <p class="formula-note">${gettext(
131
- "SVG renders consistently across browsers and is used in PDF export; MathML keeps formulas as text that can be searched and copied, but only newer browsers support it."
132
- )}</p>
133
236
  `
134
237
 
135
238
  export const tableInsertTemplate = (): string => `
@@ -14,6 +14,7 @@ import {
14
14
 
15
15
  import type {Editor} from "../types.js"
16
16
  import {SaveCopy} from "../exporter/native/index.js"
17
+ import {TemplateExportDialog} from "../dialogs/index.js"
17
18
 
18
19
  export {serializeHelp} from "./schema.js"
19
20
 
@@ -388,8 +389,17 @@ export class ModDocumentTemplate {
388
389
  action: (editor: Editor) => {
389
390
  import(
390
391
  "@fiduswriter/document/exporter/docx/index"
391
- ).then(({DOCXExporter}: any) => {
392
- const doc = editor.getDoc() as any
392
+ ).then(async ({DOCXExporter}: any) => {
393
+ const dialog = new TemplateExportDialog()
394
+ const options = await dialog.init("docx")
395
+ if (!options) {
396
+ return
397
+ }
398
+ const doc = editor.getDoc({
399
+ changes: options.resolveTrackChanges
400
+ ? "acceptAllNoInsertions"
401
+ : undefined
402
+ }) as any
393
403
  const title = shortFileTitle(
394
404
  doc.title,
395
405
  doc.path || ""
@@ -426,8 +436,17 @@ export class ModDocumentTemplate {
426
436
  ),
427
437
  action: (editor: Editor) => {
428
438
  import("@fiduswriter/document/exporter/odt/index").then(
429
- ({ODTExporter}: any) => {
430
- const doc = editor.getDoc() as any
439
+ async ({ODTExporter}: any) => {
440
+ const dialog = new TemplateExportDialog()
441
+ const options = await dialog.init("odt")
442
+ if (!options) {
443
+ return
444
+ }
445
+ const doc = editor.getDoc({
446
+ changes: options.resolveTrackChanges
447
+ ? "acceptAllNoInsertions"
448
+ : undefined
449
+ }) as any
431
450
  const title = shortFileTitle(
432
451
  doc.title,
433
452
  doc.path || ""
@@ -14,7 +14,8 @@ import {
14
14
  LanguageDialog,
15
15
  PdfExportDialog,
16
16
  RevisionDialog,
17
- HtmlExportDialog
17
+ HtmlExportDialog,
18
+ EpubExportDialog
18
19
  } from "../../dialogs/index.js"
19
20
  import {E2EEKeyManager} from "fwtoolkit/e2ee/key-manager"
20
21
  import {PassphraseManager} from "fwtoolkit/e2ee/passphrase-manager"
@@ -639,9 +640,20 @@ export const headerbarModel = () => ({
639
640
  if (!options) {
640
641
  return
641
642
  }
642
- const doc = getExportDoc(editor, {
643
- changes: "acceptAllNoInsertions"
644
- })
643
+ const doc = getExportDoc(
644
+ editor,
645
+ options.resolveTrackChanges
646
+ ? {changes: "acceptAllNoInsertions"}
647
+ : undefined
648
+ )
649
+ const converterOptions: Record<string, unknown> = {}
650
+ if (options.svgMath) {
651
+ converterOptions.mathOutput = "svg"
652
+ }
653
+ if (!options.resolveTrackChanges) {
654
+ // Keep the marks and render them in the output.
655
+ converterOptions.trackChanges = true
656
+ }
645
657
  const exporter = new HTMLExporter(
646
658
  doc,
647
659
  db.bibDB,
@@ -649,7 +661,7 @@ export const headerbarModel = () => ({
649
661
  editor.app.csl,
650
662
  editor.docInfo.updated as Date,
651
663
  getDocumentTemplate(editor).documentStyles,
652
- options.svgMath ? {mathOutput: "svg"} : {}
664
+ converterOptions
653
665
  )
654
666
  exporter.progressCallback = exportProgress(doc)
655
667
  exporter.init()
@@ -732,18 +744,35 @@ export const headerbarModel = () => ({
732
744
  action: (editor: Editor) => {
733
745
  import(
734
746
  "@fiduswriter/document/exporter/epub/index"
735
- ).then(({EpubExporter}) => {
747
+ ).then(async ({EpubExporter}) => {
736
748
  const db = getDB(editor)
737
- const doc = getExportDoc(editor, {
738
- changes: "acceptAllNoInsertions"
739
- })
749
+ const dialog = new EpubExportDialog()
750
+ const options = await dialog.init()
751
+ if (!options) {
752
+ return
753
+ }
754
+ const doc = getExportDoc(
755
+ editor,
756
+ options.resolveTrackChanges
757
+ ? {changes: "acceptAllNoInsertions"}
758
+ : undefined
759
+ )
760
+ const converterOptions: Record<string, unknown> = {}
761
+ if (options.svgMath) {
762
+ converterOptions.mathOutput = "svg"
763
+ }
764
+ if (!options.resolveTrackChanges) {
765
+ // Keep the marks and render them in the output.
766
+ converterOptions.trackChanges = true
767
+ }
740
768
  const exporter = new EpubExporter(
741
769
  doc,
742
770
  db.bibDB,
743
771
  db.imageDB,
744
772
  editor.app.csl,
745
773
  editor.docInfo.updated as Date,
746
- getDocumentTemplate(editor).documentStyles
774
+ getDocumentTemplate(editor).documentStyles,
775
+ converterOptions
747
776
  )
748
777
  exporter.progressCallback = exportProgress(doc)
749
778
  exporter.init()