generator-zotero-plugin icon indicating copy to clipboard operation
generator-zotero-plugin copied to clipboard

Zotero not defined in bootstrap.js

Open Dominic-DallOsto opened this issue 3 years ago • 13 comments

I just generated a new bootstrap plugin, but am getting the following error here that Zotero is not defined. Line 267 of bootstrap.js corresponds to line 59 of bootstrap.ts. I'm running with Zotero directly reading from the plugin's build folder, but the same happens if I install the xpi.

1641819681880	addons.xpi	WARN	Error loading bootstrap.js for [email protected]: ReferenceError: Zotero is not defined (resource://gre/modules/addons/XPIProvider.jsm -> file:///home/dominic/zotero-api-endpoint/build/bootstrap.js:267:3) JS Stack trace: install__startup__shutdown__uninstall<@bootstrap.js:267:3
@bootstrap.js:1:45
[email protected]:4299:9
[email protected]:4363:9
[email protected]:1606:13
[email protected]:3291:34
[email protected]:2196:25
[email protected]:253:12
[email protected]:728:5
[email protected]:892:9
[email protected]:2981:5
[email protected]:63:9 

Am I missing something?

[email protected] [email protected] [email protected]

Dominic-DallOsto avatar Jan 10 '22 13:01 Dominic-DallOsto

Oops, bootstrap was supposed to be behind an "experimental" flag; I haven't yet found out how bootstrap extensions can learn that Zotero is up and running.

retorquere avatar Jan 10 '22 13:01 retorquere

Ahh, all good!

Dominic-DallOsto avatar Jan 10 '22 13:01 Dominic-DallOsto

Maybe not all good, but I have not found a way to safely wait until Zotero is available. I thought cita was bootstrapped but I can't find how they do this... I can't even find their chrome.manifest currently.

retorquere avatar Jan 10 '22 13:01 retorquere

Here it is. It seems that Zutilo (and Cita I think is based off it) uses Components.utils.import to load the main script in the bootstrap

Dominic-DallOsto avatar Jan 10 '22 13:01 Dominic-DallOsto

That call to Components.utils.import brings in generic firefox infrastructure, not zotero infra. If there is a clean path to Zotero, I'll happily add it to the generator. For now, I only know how to make overlay plugins work reliably.

retorquere avatar Jan 10 '22 13:01 retorquere

Like this in Zutilo, which leads to a bunch of jumping through zutilo.js until here where the Zotero overlay is imported.

I'm testing this at the moment - just having some issues getting it to run through esbuild properly

Dominic-DallOsto avatar Jan 10 '22 13:01 Dominic-DallOsto

Let me know if you hit on something that works reliably -- I'll be happy to add that to the generator.

retorquere avatar Jan 10 '22 13:01 retorquere

I'll also gladly help with esbuild

retorquere avatar Jan 10 '22 13:01 retorquere

Ok, it's not very nice but this at least works, more or less copying and simplifying Zutilo/Cita.

The idea seems to be:

  • wait for the window called 'navigator:browser' to load - now we can access Zotero as a property of the window
  • if we load a script with Services.scriptloader.loadSubScript, it will have access to Zotero like a global variable
    • for this to work, I needed to specify it as an extra entry point in esbuild.js

I couldn't get it to work if I imported the script normally. I could pass in a reference to Zotero but it wouldn't exist globally and I couldn't manage to declare/initialise a global variable properly.

I didn't yet try waiting for the window before exporting the bootstrap functions.

Dominic-DallOsto avatar Jan 10 '22 18:01 Dominic-DallOsto

I don't think you can wait before exporting them. Those bootstrap functions need to exist from the start or the extension won't load. But this isn't so bad. The one thing I'm wondering about is this line. To my knowledge, after the first call to resolve or reject, further resolves/rejects become no-ops.

retorquere avatar Jan 10 '22 19:01 retorquere

I have some other cleanup I'm working on now that I understand your solution. One major problem with restartless addons is that the lifecycle functions (install, uninstall, startup and shutdown) are not async, and trying to do async cleanup in shutdown is most likely going to error out if you do anything of substance. Good news is that Firefox does have (separate) async shutdown listeners and I can probably pass on the work to them.

retorquere avatar Jan 10 '22 20:01 retorquere

I don't think you can wait before exporting them. Those bootstrap functions need to exist from the start or the extension won't load. But this isn't so bad. The one thing I'm wondering about is this line. To my knowledge, after the first call to resolve or reject, further resolves/rejects become no-ops.

Ahh yep. It seems the idea is that the it's only resolved once, but I don't know if it's possible to code it so that's guaranteed, or we just rely on there only ever being one window with that name.

Dominic-DallOsto avatar Jan 11 '22 15:01 Dominic-DallOsto

I'm doing cleanup based on the information you unearthed that will make things much clearer.

retorquere avatar Jan 11 '22 15:01 retorquere