The default bug view has changed. See this FAQ.

Enable Greasemonkey to be a WebExtension

(NeedInfo from)



WebExtensions: Compatibility
2 months ago
19 days ago


(Reporter: andym, Unassigned, NeedInfo)


Firefox Tracking Flags

(Not tracked)


(Whiteboard: triaged[awe:{e4a8a97b-f2ed-450b-b12d-ee082ba24781}])



2 months ago
Greasemonkey does quite a lot of things and this is to track those things.


2 months ago
Depends on: 1215065


2 months ago
Last Resolved: 2 months ago
Resolution: --- → DUPLICATE
Duplicate of bug: 1232177

Comment 2

2 months ago
Please don't duplicate, this is a tracker to help the Greasemonkey author track their move to a WebExtension.
Resolution: DUPLICATE → ---

Comment 3

2 months ago
OK, but I don't see why we need two bugs for that.

Comment 4

2 months ago
I'm going to dump a quick summary of things here for now, let me know if you'd like individual bugs for separate topics.  That said, Greasemonkey has a 10+ year history of accumulated features, and users accustomed to those features.  My goal would be to keep as many of them as possible.

One related group:

1) The ability to download and store "files" including arbitrary content (some will be text, some will be e.g. images).
2) The ability to load those "files" contents (i.e. load the user script's source, for evaluation).
3) A way to efficiently serve these "files" by URL, this means things like using a <style> or <img> tag that content can then load like any other.  (Today, we implement a nsIProtocolHandler for this.)
4) The ability to launch an editor, to change the content of (at least one of) these files.  This is IMO one of Greasemonkey's points over Tampermonkey today: Tampermonkey's inbuilt editor is unpleasant in a variety of ways, but with Greasemonkey users are free to select whatever text editor they prefer.  (Also: some sort of embeddable Scratchpad with it's JS editing capabilities would be nice.)

Part 1 and 2 are probably easy with something like the File API, but parts 3 and 4 are not so obviously accomplishable.

Comment 5

2 months ago
For 1) and 2) it doesn't sound like you need to have the files actually touch the file system, but rather have an efficient place to store and load blobs from. Something like storage.local won't work for that, but we've been investigating using indexedDB. 

There's more details in bug 1323414 and then bug 1331618 for storing up 20gb at a time.

And an example for that here:

Comment 6

2 months ago
Turns out point 4 from comment #4 is ~identical to `extension.getURL()` except, for a user script installed into Greasemonkey, rather than for a part of its own XPI.

I'm also starting to look into the details of the sandbox environment.  Greasemonkey has two paths: one simply injects a script, with no special nature, directly into content -- by requesting a Cu.Sandbox with the content principal and wantXrays=false.  The other uses an _expanded_ principal, wrapping the content, and wantXrays=true.  This mode also injects some number of privileged APIs.

It looks like content scripts give us exportFunction and cloneInto and wrappedJSObject, which gets us most of the way to those features, but we won't be able to control which mode (xrays or not? expanded principal or not?) we're in?

Comment 7

2 months ago
Kris should be able to help on comment #6
Flags: needinfo?(kmaglione+bmo)

Comment 8

2 months ago
Whoops, above I said "point four from comment #4" and meant "point 3".  Point four is still something I'm very interested in, but worried that WebExtensions by design completely prevents any kind of file system interaction, so I could never use the editor I'm already familiar and comfortable with for authoring (installed and active) user scripts.

Two other interesting areas have to do with detecting/intercepting normal browser events.

For injection: We use an observer on document-element-inserted to run user scripts before any content.  Two examples are for redirections (e.g. http->https) or for influencing the behavior of inline scripts (be it fixing compatibility or otherwise) before they execute.  We also want the document to exist (e.g. inject styles now, to prevent flicker), but nothing else.  IOW we want exactly document-element-inserted.

Similarly the "Intercept HTTP requests" talks about observing and canceling, but is there any way to resume a canceled request?  We do this today if:
1) Observe and cancel the request because it ends in .user.js
2) Re-start it internally, discover that the response is actually HTML (not a user script), cancel this
3) Resume the original request (and the browser's navigation to that page)

We mostly migrated away from our nsIContentPolicy implementation for e10s, but found that it was the only way to detect loading of file:// -- no amount of intercepting HTTP requests works when loading a local file (e.g. I saved this old version of this user script, because I don't like the change made in a more recent update).

Implements a get and set, but no list of previously set keys?

This is also suboptimal for storage.sync; Ideally we'd have one key per sync-able object, and be able to observe appearance during sync.  As is we'll be forced to on every (even minor) change load and serialize all the possible data into one value.. and I still don't know how to observe (besides polling?) when that value has changed.  Oh!
But Firefox doesn't even support storage.sync, only Chrome does?

We expose GM_setClipboard(String), but WebExtensions seems to have only "trigger the copy command", over the current selection.

For execution:
It seems either I have to write some executes-everywhere content script which coordinates many calls to eval(), or there's also tabs.executeScript().  But I can't tell how I'd inject our special API methods to either.  If I figure that out though, we'll also (AFAICT) be executing the user script in the full privileged "content script" scope... so how do I isolate user scripts from each other?


Comment 9

2 months ago

I've started a design doc and a discussion in GM's developer group for this topic.

Also, via other channels, it's been explained to me that storage.sync is coming in Firefox 52 (stable is 51.0.1 now), so the docs are "out of date" when they say Firefox does not support it.  And I noticed that

Does exist.  Still no `list()` call though?
You need to log in before you can comment on or make changes to this bug.