diff --git a/addon/chrome/content/docxExport.html b/addon/chrome/content/docxExport.html new file mode 100644 index 0000000..bf62478 --- /dev/null +++ b/addon/chrome/content/docxExport.html @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/package.json b/package.json index ff3ce1f..506b55a 100644 --- a/package.json +++ b/package.json @@ -46,9 +46,10 @@ "crypto-js": "^4.1.1", "diff": "^5.1.0", "hast-util-to-html": "^9.0.0", - "hast-util-to-mdast": "^10.0.0", + "hast-util-to-mdast": "^8.4.1", "hast-util-to-text": "^4.0.0", "hastscript": "^8.0.0", + "html-docx-js": "^0.3.1", "html-docx-js-typescript": "^0.1.5", "katex": "^0.16.8", "rehype-format": "^4.0.1", @@ -69,29 +70,31 @@ "zotero-plugin-toolkit": "^2.2.5" }, "devDependencies": { + "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@prettier/plugin-xml": "^3.2.0", "@types/browser-or-node": "^1.3.0", "@types/diff": "^5.0.3", - "@types/node": "^20.4.9", + "@types/html-docx-js": "^0.3.1", + "@types/node": "^20.5.6", "@types/seedrandom": "^3.0.5", "@types/yamljs": "^0.2.31", - "@typescript-eslint/eslint-plugin": "^6.3.0", - "@typescript-eslint/parser": "^6.3.0", + "@typescript-eslint/eslint-plugin": "^6.4.1", + "@typescript-eslint/parser": "^6.4.1", "chokidar-cli": "^3.0.0", - "compressing": "^1.9.1", - "concurrently": "^8.2.0", + "compressing": "^1.10.0", + "concurrently": "^8.2.1", "cross-env": "^7.0.3", "esbuild": "^0.19.2", - "eslint": "^8.46.0", + "eslint": "^8.47.0", "eslint-config-prettier": "^9.0.0", - "prettier": "^3.0.1", + "prettier": "^3.0.2", "prosemirror-model": "^1.19.3", "prosemirror-state": "^1.4.3", - "prosemirror-transform": "^1.7.4", + "prosemirror-transform": "^1.7.5", "prosemirror-view": "^1.31.7", - "release-it": "^16.1.4", + "release-it": "^16.1.5", "replace-in-file": "^7.0.1", - "typescript": "^5.1.6", - "zotero-types": "^1.2.1" + "typescript": "^5.2.2", + "zotero-types": "^1.2.2" } } diff --git a/src/addon.ts b/src/addon.ts index 385528d..be2a051 100644 --- a/src/addon.ts +++ b/src/addon.ts @@ -28,7 +28,6 @@ class Addon { }; export: { pdf: { promise?: _ZoteroTypes.PromiseObject }; - docx: { worker?: HTMLIFrameElement }; }; sync: { lock: boolean; @@ -92,7 +91,6 @@ class Addon { // ztoolkit: new ZoteroToolkit(), export: { pdf: { promise: undefined }, - docx: { worker: undefined }, }, sync: { lock: false, diff --git a/src/extras/docxWorker.ts b/src/extras/docxWorker.ts index 4557272..66387f3 100644 --- a/src/extras/docxWorker.ts +++ b/src/extras/docxWorker.ts @@ -1,16 +1,13 @@ -import { asBlob } from "html-docx-js-typescript"; +// @ts-ignore +import htmlDocx from "html-docx-js/dist/html-docx"; -// this runs in a webworker. accept input message +// this runs in a iframe. accept input message // and return output message onmessage = ({ data: { type, jobId, message } }) => { if (type === "parseDocx") { console.log("DOCX Worker", type, jobId, message); - asBlob(message) - .then((blob) => { - postMessage({ type: "parseDocxReturn", jobId, message: blob }, "*"); - }) - .catch((err) => { - console.log(err); - }); + const blob = htmlDocx.asBlob(message); + console.log("DOCX Worker", blob); + postMessage({ type: "parseDocxReturn", jobId, message: blob }, "*"); } }; diff --git a/src/modules/export/docx.ts b/src/modules/export/docx.ts index 9ecd4c5..1c19c40 100644 --- a/src/modules/export/docx.ts +++ b/src/modules/export/docx.ts @@ -1,7 +1,8 @@ import { showHintWithLink } from "../../utils/hint"; import { renderNoteHTML } from "../../utils/note"; -import { getFileContent, randomString } from "../../utils/str"; +import { randomString } from "../../utils/str"; import { waitUtilAsync } from "../../utils/wait"; +import { config } from "../../../package.json"; export async function saveDocx(filename: string, noteId: number) { const noteItem = Zotero.Items.get(noteId); @@ -39,30 +40,28 @@ async function note2docx(noteItem: Zotero.Item) { ); await lock.promise; worker.contentWindow?.removeEventListener("message", listener); + destroyWorker(worker); return blob!; } -async function getWorker() { - if (addon.data.export.docx.worker) { - return addon.data.export.docx.worker; - } - const worker = Zotero.Browser.createHiddenBrowser( - window, - ) as HTMLIFrameElement; - await waitUtilAsync(() => worker.contentDocument?.readyState === "complete"); - - const doc = worker.contentDocument; - ztoolkit.UI.appendElement( - { - tag: "script", - properties: { - innerHTML: await getFileContent( - rootURI + "chrome/content/scripts/docxWorker.js", - ), - }, +async function getWorker(): Promise { + const worker = ztoolkit.UI.createElement(document, "iframe", { + properties: { + src: `chrome://${config.addonRef}/content/docxExport.html`, }, - doc!.head, - ); - addon.data.export.docx.worker = worker; + styles: { + width: "0", + height: "0", + border: "0", + position: "absolute", + }, + }); + window.document.documentElement.appendChild(worker); + await waitUtilAsync(() => worker.contentDocument?.readyState === "complete"); return worker; } + +function destroyWorker(worker: any) { + worker.parentNode.removeChild(worker); + worker = null; +} diff --git a/tsconfig.json b/tsconfig.json index 7034702..7188846 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "target": "ES2016", "resolveJsonModule": true, "skipLibCheck": true, + "alwaysStrict": false, "strict": true }, "include": ["src", "typings", "node_modules/zotero-types"],