A workaround to load framescripts in Nightly 57

Talk about add-ons and extension development.
Post Reply
AlexVallat
Posts: 90
Joined: September 30th, 2006, 8:53 am

A workaround to load framescripts in Nightly 57

Post by AlexVallat »

Nightly 57 is out, and as promised, it's breaking extensions all over the place. Unfortunately, WebExtensions are not sufficient to replace lost functionality, but luckily there's the extensions.legacy.enabled pref that lets us keep using it.

Only one problem, is that there's some irritating new permissions thing that prevents content scripts (or web pages) from accessing chrome manifest registered resources, neither content:// urls (even with contentaccessible=yes flag set) or resource:// urls. This naturally makes fixing up any legacy extension that loads framescripts a little tricky.

At least for the moment, though, loadFrameScript will work with moz-extension:// urls, so as long as the framescript can be placed in one of those, it can still be loaded. To do this, create a minimal embedded webextension to hold your framescript as a resource. Add <em:hasEmbeddedWebExtension>true</em:hasEmbeddedWebExtension> to your install.rdf, and create a "webextension" folder at the top level of your addon. In that, put a manifest.json:

Code: Select all

{
  "manifest_version": 2,
  "name": "Embedded Resources", 
  "version": "0.1",
  "background": {
    "scripts": ["embedded_resources.js"]
  },
  "web_accessible_resources": [
     "content/*"
  ]
}
Then in a "content" subfolder, put your framescripts.
Next to manifest.json, place "embedded_resources.js", which simply contains the line

Code: Select all

browser.runtime.sendMessage(browser.extension.getURL("content/"));
Finally, in your bootstrap.js, the code for loading your framescript should now look like:

Code: Select all

function startup(data, reason) {
    const globalMessageManager = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
    
    data.webExtension.startup().then(api => 
		api.browser.runtime.onMessage.addListener(embeddedResourceUrl => {
			globalMessageManager.loadFrameScript(embeddedResourceUrl + "framescript.js", true);
		})
	);
}
This works, but is subject to one limitation I have not yet been able to figure out. In the framescript itself, it is not possible to Cu.import other local jsm modules. System ones are fine, but local ones (belonging to the addon) can't be loaded. Even with the correct moz-extension:// url to them, it still refuses to load them. The only thing I've come up with is to pre-process them and embed them directly into the framescript.js file rather than loading them as modules, which isn't great.

Anyway, just thought I'd throw this out there in case anyone else is trying to patch up legacy addons to work under 57.
lithopsian
Posts: 3664
Joined: September 15th, 2010, 9:03 am

Re: A workaround to load framescripts in Nightly 57

Post by lithopsian »

My experience has been that loading framescripts from chrome urls works fine, but the scripts themselves do not run properly in the content process. Symptoms are not receiving messages and events that don't bubble into the frame script (and are not captured with use_capture). This started at some point during 56. I am also able to import jsms into the frame script so I can use things like Services.jsm.
AlexVallat
Posts: 90
Joined: September 30th, 2006, 8:53 am

Re: A workaround to load framescripts in Nightly 57

Post by AlexVallat »

lithopsian wrote:My experience has been that loading framescripts from chrome urls works fine
Curious... is that in 57? Are you sure they are being loaded in tabs that are showing normal content (from http:// or https://)? I did notice that the framescript would load in a file:// or in a about: page, for example.

If there's some configuration switch I can enable to let them continue to load normally in an http:// page from a chrome:// url, I'd love to be able to find it.
lithopsian
Posts: 3664
Joined: September 15th, 2010, 9:03 am

Re: A workaround to load framescripts in Nightly 57

Post by lithopsian »

It is possible that I'm only seeing an initial load in the about:blank page for each window. They don't seem to get loaded for additional tabs, so possible are never loaded at all in the content processes, as you describe. I'll see if I can find out more using your workaround.

I should probably mention that everything works fine with e10s turned off.
Post Reply