Framescripts are not webpages and do not offer access to most of the global variables that jquery expects to exist, e.g. XHR, the document and window itself etc.
Even if you rigged the variables in a way that looks like a window environment this would still be highly problematic because a frame script has a lifetime that extends beyond that of a DOM windows, i.e. its existence is tied to a tab, not to individual pages of a tab. Jquery is designed to only live as long as a page does.
A third problem is security, framescripts run with chrome/system privileges and so would jquery if you ran it directly from a frame script. Jquery is not designed to be security-conscious as it is normally constrained by the same-origin policy of a website. Some complex interaction of event processing and XHRs might thus open security vulnerabilities.
So using jquery in browser-internal scripting environments is not recommended.
The two options of doing DOM manipulation from frame scripts is
a) Using standard DOM APIs directly from a frame script. Addon scripts automatically run with ES6 support enabled (e.g. destructuring, arrow functions etc.) and do not have to concern themselves with cross-browser compatibility. In other words: There's no need for jquery
b) If using jquery is absolutely necessary, e.g. because some 3rd-party library depends on it, then it's possible to create a sandbox with the current window as its prototype and using the subscript loader to inject jquery and a custom script into it.
Recommended way to create sandbox to isolate it from untrusted content and at the same time drop system privileges:
let options = {
// this is the name reported in about:memory
sandboxName: "<addon name> <purpose of sandbox>",
// ensure that jquery sees the window as global
sandboxPrototype: content,
// reduces GC overhead by having the sandbox reside in the same space as target window
sameZoneAs: content,
// don't include components object that grants access to privileged APIs
wantComponents: false,
// helper functions for interacting with untrusted content
wantExportHelpers: true,
// clean view of DOM APIs, otherwise untrusted content could override prototypes
wantXrays: true,
// addon ID, used by addon debugger and memory reporting
// sdk addons can obtain it via require("sdk/self").id, other addons define it in the install.rdf
metadata: {addonID: id}
}
// set the security principal to an extended principal covering the target window
let sandbox = Cu.Sandbox([content], options)
// structured-clone objects into the sandbox
sandbox.myData = {foo: "bar"}
loader.loadSubscript("resource://myaddon-id/libs/jquery.js", sandbox, "UTF-8")
loader.loadSubscript("resource://myaddon-id/src/mypagescript.js", sandbox, "UTF-8")
// call custom function created by mypagescript.js
sandbox.myFunc()
Note that the sandbox is only valid for the lifetime of a page, so if the frame gets navigated to a new window (content
object) you will have to create a new sandbox
The above basically is the underlying low-level API used by the SDK's page-mod and webextensions content-scripts.