Fix Zotero 8+ compatibility: file picker crash and ChromeUtils.import errors - #41
Conversation
Firefox 128+ (Zotero 8) changed nsIFilePicker.init() to take a BrowsingContext instead of a window, so the raw nsIFilePicker code in promptSavePath() threw NS_ERROR_XPC_BAD_CONVERT_JS on Zotero 8/9 and the markdown .zip export never showed a save dialog. Route the dialog through the toolkit's FilePickerHelper, which delegates to Zotero's own FilePicker module (chrome://zotero/content/modules/ filePicker.mjs). Zotero's wrapper passes window.browsingContext on new platforms and keeps working on Zotero 7, so the plugin no longer touches the changing XPCOM signature directly. Fixes max3925vats#39 https://claude.ai/code/session_01KUFXvTTsWqrPNDJ8Vi1oPL
…it patch zotero-plugin-toolkit (through at least 5.1.2) detects the legacy JSM loader with `typeof ChromeUtils.import === "undefined"`. On Zotero 8+ (Firefox 140) ChromeUtils.import still exists but only throws "ChromeUtils.import() has been removed. Use importESModule()", so the toolkit rewrote Console.sys.mjs back to Console.jsm and the import threw once per helper constructed at startup — 16 console errors on every launch. Add an esbuild plugin that patches the bundled toolkit's _importESModule to try ChromeUtils.importESModule first (available since Firefox 106, so on every supported Zotero) and keep the legacy loader as a fallback for Zotero 7. The patch is an exact-match string replacement that fails the build loudly if the toolkit source changes, so a future toolkit upgrade cannot silently un-apply it; once the toolkit fixes its feature detection upstream, the plugin block can simply be deleted. Fixes max3925vats#40 https://claude.ai/code/session_01KUFXvTTsWqrPNDJ8Vi1oPL
Getting-started editing pass aimed at first-time users: - Add a Quick start section that spells out the two-part setup (local docling-serve + plugin) and walks the happy path end to end, with a heads-up about the first-run model download. - Link installation guides for uv and pipx, and point readers without Python tooling at the container option. - Add a browser-based sanity check (the /ui playground) alongside curl. - Turn plugin installation into numbered steps, drop the stale "(when available)" hedge, and warn about Firefox auto-installing the .xpi. - Mark the from-source path as development-oriented (Node 20+) and scope the macOS .env note to the npm start workflow. - Fix the "within seconds" promise that contradicted the 2-10 minute first-run download, and de-emoji the model-weights heading so section anchors stay stable. https://claude.ai/code/session_01KUFXvTTsWqrPNDJ8Vi1oPL
Fix Zotero 8+ compatibility: file picker crash and ChromeUtils.import errors
docling-serve defaults image_export_mode to "embedded", which inlines
every figure as a base64 data URI and can grow a paper's .md by tens of
megabytes. A new opt-in "Exclude images" checkbox in Settings → Output
sends image_export_mode=placeholder instead, so each image becomes a
tiny <!-- image --> comment and the markdown keeps only text and tables.
The plugin now always sends image_export_mode explicitly ("embedded"
when the box is unticked — identical to the previous server-default
behavior), and the advancedJson escape hatch still overrides it for
users who want "referenced" or other modes. Wired through prefs.js
defaults, generated pref typings, the preferences pane (+ en-US
strings), reset-to-defaults, buildConvertForm and its unit tests, and
the README feature list.
https://claude.ai/code/session_01KUFXvTTsWqrPNDJ8Vi1oPL
Add an Exclude images option for text-and-tables-only markdown
|
Add an Exclude images option for text-and-tables-only markdown docling-serve defaults image_export_mode to "embedded", which inlines every figure as a base64 data URI and can grow a paper's .md by tens of megabytes. A new opt-in "Exclude images" checkbox in Settings → Output sends image_export_mode=placeholder instead, so each image becomes a tiny comment and the markdown keeps only text and tables. The plugin now always sends image_export_mode explicitly ("embedded" when the box is unticked — identical to the previous server-default behavior), and the advancedJson escape hatch still overrides it for users who want "referenced" or other modes. Wired through prefs.js defaults, generated pref typings, the preferences pane (+ en-US strings), reset-to-defaults, buildConvertForm and its unit tests, and the README feature list. |
Markdown converted before the Exclude-images option (or with it off) carries every figure as an embedded base64 data URI, so a single paper's .md can be tens of megabytes. This adds a retroactive cleanup: select items and right-click "Remove images from markdown" (or Tools → Docling: Remove images from markdown…) to rewrite their .md attachments in place, replacing each markdown image or raw <img> tag with the same <!-- image --> placeholder docling emits in image_export_mode=placeholder. The pure transform lives in utils/stripImages.ts: line-based so fenced code blocks are skipped (image syntax shown in a code sample isn't an image), inline-safe so images inside table cells keep the table shape, and idempotent. The orchestrator in modules/removeImages.ts resolves selections the same way the zip export does (md attachments directly, PDFs via their matching .md sibling, parents via their PDF children), guards the destructive rewrite behind a confirm dialog, refuses to run while a conversion batch is in flight, and reports replaced-image count and bytes saved (new formatBytes helper) in the completion toast. Covered by unit tests for the transform (embedded/table/HTML/fence/ idempotence cases plus fast-check properties) and formatBytes. https://claude.ai/code/session_01KUFXvTTsWqrPNDJ8Vi1oPL
Add a Remove-images utility for existing docling markdown
|
🚀 This ticket has been resolved in v0.3.2. See Release v0.3.2 for release notes. |
Fixes two Zotero 8+/9 (Firefox 128/140) compatibility bugs, plus a README getting-started editing pass. One commit per concern. Branch:
brianckeegan:claude/wizardly-bohr-hk6j7u, based onmainat 43f910e (v0.3.1).1.
nsIFilePicker.initcrash — BrowsingContext requiredFixes #39
Firefox 128+ (Zotero 8) changed
nsIFilePicker.init()to take aBrowsingContextinstead of a window, so the raw XPCOM file picker inpromptSavePath()(src/modules/markdownZipExport.ts) threwNS_ERROR_XPC_BAD_CONVERT_JSon Zotero 8/9 — this is exactly thefp.initcall at line 7021 of the built bundle named in the issue title.Implemented the issue's recommended Option B: the dialog now goes through the toolkit's
FilePickerHelper, which delegates to Zotero's ownFilePickermodule (chrome://zotero/content/modules/filePicker.mjs). Zotero's wrapper passeswindow.browsingContexton new platforms and still works on Zotero 7, so the plugin no longer touches the changing XPCOM signature. Behavior is preserved: same title/filter/default name,nullon cancel,.zipextension forced.2.
ChromeUtils.import()removed — 16 console errors at startupFixes #40
The legacy import doesn't come from this plugin's code — it's in the bundled
zotero-plugin-toolkit, and the bug is still present in the latest toolkit release (5.1.2), so upgrading the dependency can't fix it. The toolkit feature-detects the legacy loader withtypeof ChromeUtils.import === "undefined"; on Firefox 140ChromeUtils.importstill exists but only throws "has been removed. Use importESModule()", so the toolkit rewritesConsole.sys.mjsback toConsole.jsmand the import throws once per helper constructed at startup (~16 errors).Added an esbuild plugin in
zotero-plugin.config.tsthat patches the bundled toolkit's_importESModuleto tryChromeUtils.importESModulefirst (available since Firefox 106, i.e. on every supported Zotero) with the legacy loader kept as a Zotero 7 fallback. The patch is an exact-match replacement that fails the build loudly if the toolkit source stops matching, so a future toolkit upgrade can't silently un-apply it — once the toolkit fixes its detection upstream, the patch block just gets deleted.3. README: novice-friendly getting-started pass
uv/pipx, a browser-based sanity check (/ui), numbered plugin-install steps, a warning about Firefox auto-installing the.xpi, and the from-source path marked as development-oriented.Verification
npm run build(esbuild bundle +tsc --noEmit) passes; the built bundle's_importESModulenow prefersimportESModule, and no rawnsIFilePickerusage remains in the bundle.npm run lint:check(prettier + eslint) passes.https://claude.ai/code/session_01KUFXvTTsWqrPNDJ8Vi1oPL