Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions apply-patches.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash
# Apply Zotero 8 compatibility patches to zotero-plugin-toolkit
# These patches fix deprecated ChromeUtils.import() calls

TOOLKIT_DIR="node_modules/zotero-plugin-toolkit/dist"

# Patch basic.js - fix Console.jsm import
sed -i.bak 's/if (typeof globalThis.ChromeUtils?.import !== "undefined") {/try {/' "$TOOLKIT_DIR/basic.js"
sed -i.bak 's/ChromeUtils.import("resource:\/\/gre\/modules\/Console.jsm")/ChromeUtils.importESModule("resource:\/\/gre\/modules\/Console.sys.mjs")/' "$TOOLKIT_DIR/basic.js"
sed -i.bak 's/});$/});\n } catch (e) {\n \/\/ Console not available\n }/' "$TOOLKIT_DIR/basic.js"

# Patch pluginBridge.js - fix AddonManager.jsm import
sed -i.bak 's/ChromeUtils.import("resource:\/\/gre\/modules\/AddonManager.jsm")/ChromeUtils.importESModule("resource:\/\/gre\/modules\/AddonManager.sys.mjs")/' "$TOOLKIT_DIR/utils/pluginBridge.js"

echo "Patches applied for Zotero 8 compatibility"
18 changes: 2 additions & 16 deletions bootstrap.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,19 @@
import { log } from './content/debug'

export function install() {
log.info('installed')
}
export function uninstall() {
log.info('uninstalled')
}
export function install() {}
export function uninstall() {}

let chromeHandle
export async function startup({ id, version, rootURI }) {
log.info('startup', id, version)

const aomStartup = Components.classes['@mozilla.org/addons/addon-manager-startup;1'].getService(Components.interfaces.amIAddonManagerStartup)
const manifestURI = Services.io.newURI(`${rootURI}manifest.json`)
chromeHandle = aomStartup.registerChrome(manifestURI, [
['content', 'zotero-folder-import', 'content/'],
['locale', 'zotero-folder-import', 'en-US', 'locale/en-US/'],
])

Services.scriptloader.loadSubScript(`${rootURI}content/folder-import.js`, { rootURI, Zotero })
await Zotero.FolderImport.startup()
log.info('startup', id, version, 'ready')
}

export async function shutdown() {
log.info('shutdown')
await Zotero.FolderImport.shutdown()
if (chromeHandle) {
chromeHandle.destruct()
Expand All @@ -34,12 +23,9 @@ export async function shutdown() {
}

export function onMainWindowLoad({ window }) {
log.info('onMainWindowLoad')
window.MozXULElement.insertFTLIfNeeded('folder-import.ftl')
Zotero.FolderImport?.onMainWindowLoad(window)
}

export function onMainWindowUnload({ window }) {
log.info('onMainWindowUnload')
Zotero.FolderImport?.onMainWindowUnload(window)
}
10 changes: 8 additions & 2 deletions content/debug.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { Logger } from 'zotero-plugin/logger'
// Simple logger using Zotero.debug directly (Zotero 8 compatible)
declare var Zotero: any

export const log = new Logger('folder-import')
export const log = {
info: (...args: any[]) => Zotero.debug(`[folder-import] INFO: ${args.join(' ')}`),
debug: (...args: any[]) => Zotero.debug(`[folder-import] DEBUG: ${args.join(' ')}`),
error: (...args: any[]) => Zotero.debug(`[folder-import] ERROR: ${args.join(' ')}`),
warn: (...args: any[]) => Zotero.debug(`[folder-import] WARN: ${args.join(' ')}`),
}
42 changes: 27 additions & 15 deletions content/folder-import.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
declare var Zotero: any // eslint-disable-line no-var
declare const FileUtils: any
declare const Services: any

declare const Components: any
Components.utils.import('resource://gre/modules/FileUtils.jsm')

declare const ChromeUtils: any

import { FilePickerHelper, ZoteroToolkit } from 'zotero-plugin-toolkit'
const ztoolkit = new ZoteroToolkit()

import { DebugLog as DebugLogSender } from 'zotero-plugin/debug-log'
import { log } from './debug'

declare const OS: {
Expand Down Expand Up @@ -156,10 +150,11 @@ class FolderScanner {

export class $FolderImport {
private status: { total: number; done: number }
private menuRegisteredID: string | null = null

public async startup() {
await Zotero.initializationPromise
DebugLogSender.register('Folder import', [])
log.info('startup')
for (const win of Zotero.getMainWindows()) {
if (win.ZoteroPane) this.onMainWindowLoad(win)
}
Expand All @@ -172,17 +167,34 @@ export class $FolderImport {
}

public onMainWindowLoad(win: Window) {
log.debug('onMainWindowLoad')

ztoolkit.Menu.register('menuFile', {
tag: 'menuitem',
label: 'Add Files from Folder…',
oncommand: 'Zotero.FolderImport.addAttachmentsFromFolder()',
const doc = win.document
const fileMenu = doc.getElementById('menu_FilePopup')
if (!fileMenu) return

const menuItem = doc.createXULElement('menuitem')
menuItem.id = 'folder-import-menuitem'
menuItem.setAttribute('label', 'Add Files from Folder…')
menuItem.addEventListener('command', () => {
Zotero.FolderImport.addAttachmentsFromFolder()
})

const importFromClipboard = doc.getElementById('menu_import_clipboard')
if (importFromClipboard && importFromClipboard.nextSibling) {
fileMenu.insertBefore(menuItem, importFromClipboard.nextSibling)
} else {
const exportLibrary = doc.getElementById('menu_exportLibrary')
if (exportLibrary) {
fileMenu.insertBefore(menuItem, exportLibrary)
} else {
fileMenu.appendChild(menuItem)
}
}
}

public onMainWindowUnload(win: Window) {
ztoolkit.Menu.unregisterAll()
const doc = win.document
const menuItem = doc.getElementById('folder-import-menuitem')
if (menuItem) menuItem.remove()
}

public update() {
Expand All @@ -204,7 +216,7 @@ export class $FolderImport {
const duplicates: string = PathUtils.join(Zotero.getTempDirectory().path as string, `rmlint${Zotero.Utilities.randomString()}.json`)

try {
const cmd = new FileUtils.File(rmlint)
const cmd = Zotero.File.pathToFile(rmlint)
if (!cmd.isExecutable()) return []

const proc = Components.classes['@mozilla.org/process/util;1'].createInstance(Components.interfaces.nsIProcess)
Expand Down
4 changes: 2 additions & 2 deletions esbuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const pretty = require('pretty')
rmrf.sync('gen')

require('zotero-plugin/copy-assets')
require('zotero-plugin/rdf')
require('zotero-plugin/version')
require('zotero-plugin/make-manifest')
require('zotero-plugin/make-version')

async function bundle(entry) {
const outdir = path.join('build', path.basename(path.dirname(entry)))
Expand Down
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "zotero-folder-import",
"version": "0.0.9",
"version": "0.1.0",
"description": "Import folder of attachments into a collection hierarchy",
"scripts": {
"postinstall": "patch-package || true",
"lint": "dprint fmt bootstrap.ts content/*.ts && dprint check bootstrap.ts content/*.ts",
"prebuild": "npm run lint",
"build": "rm -rf build && tsc --noEmit && node esbuild.js",
Expand All @@ -25,22 +26,23 @@
},
"homepage": "https://github.com/retorquere/zotero-folder-import",
"devDependencies": {
"dprint": "^0.50.0",
"esbuild": "^0.25.5",
"patch-package": "^8.0.0",
"pretty": "^2.0.0",
"pug": "^3.0.3",
"esbuild": "^0.25.5",
"rimraf": "^6.0.1",
"ts-node": "^10.9.2",
"typescript": "^5.8.3",
"zotero-types": "^4.0.3",
"dprint": "^0.50.0",
"zotero-plugin": "5.0.18"
"zotero-plugin": "^8.0.8",
"zotero-types": "^4.0.5"
},
"xpi": {
"name": "Folder Import for Zotero",
"updateLink": "https://github.com/retorquere/zotero-folder-import/releases/download/v{version}/zotero-auto-index-{version}.xpi",
"releaseURL": "https://github.com/retorquere/zotero-folder-import/releases/download/release/"
},
"dependencies": {
"zotero-plugin-toolkit": "^5.0.0"
"zotero-plugin-toolkit": "5.1.0-beta.13"
}
}
29 changes: 29 additions & 0 deletions patches/zotero-plugin-toolkit+5.1.0-beta.13.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--- a/node_modules/zotero-plugin-toolkit/dist/basic.js
+++ b/node_modules/zotero-plugin-toolkit/dist/basic.js
@@ -52,11 +52,12 @@
_mainWindow: undefined,
_plugin: undefined,
};
- if (typeof globalThis.ChromeUtils?.import !== "undefined") {
- const { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm");
+ try {
+ const { ConsoleAPI } = ChromeUtils.importESModule("resource://gre/modules/Console.sys.mjs");
this._console = new ConsoleAPI({
consoleID: `${this._basicOptions.api.pluginID}-${Date.now()}`,
});
+ } catch (e) {
+ // Console not available
}
this.updateOptions(data);
}
--- a/node_modules/zotero-plugin-toolkit/dist/utils/pluginBridge.js
+++ b/node_modules/zotero-plugin-toolkit/dist/utils/pluginBridge.js
@@ -26,7 +26,7 @@
}
}
initializePluginBridge() {
- const { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
+ const { AddonManager } = ChromeUtils.importESModule("resource://gre/modules/AddonManager.sys.mjs");
const Zotero = BasicTool.getZotero();
const pluginBridgeExtension = {
noContent: true,
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"importHelpers": true,
"target": "es2017",
"disableSizeLimit": true,
"module": "commonjs",
"module": "ESNext",
"moduleResolution": "bundler",
"noImplicitAny": false,
"removeComments": false,
"preserveConstEnums": false,
Expand All @@ -16,6 +17,7 @@
"types": [ "node" ],
"typeRoots": [ "./node_modules/@types" ],
"skipDefaultLibCheck": true,
"skipLibCheck": true,
},
"include": [ "bootstrap.ts", "content/folder-import.ts", "content/globals.d.ts", "node_modules/zotero-types" ],
"exclude": [
Expand Down