Skip to content

Commit c034a4f

Browse files
committed
doc: rework @inject-into, add wrappedJSObject
1 parent fde45a9 commit c034a4f

1 file changed

Lines changed: 19 additions & 63 deletions

File tree

content/posts/inject-into-context.md

Lines changed: 19 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ redirect_from:
88
- /2018/11/23/inject-into-context/
99
---
1010

11-
Since Violentmonkey v2.10.0, a new type of metadata named [`@inject-into`](/api/metadata-block/#inject-into) is introduced. With its help, **scripts can be injected into CSP restricted pages in Firefox now!**
11+
Violentmonkey v2.10.0 and newer supports [`// @inject-into`](/api/metadata-block/#inject-into) metadata comment so that **the script can be injected into CSP restricted pages in Firefox without suppressing CSP and lowering website security**, although if the scripts accesses global variables of the webpage it will have to add a few tricks as described in [`content`](#mode-content) section below.
12+
13+
The default mode is [`auto`](#mode-auto), you can change it in Violentmonkey's settings. The actual mode can be seen by a userscript in [GM_info.injectInto](/api/#gm_info). The popup also shows a `@` mark since Violentmonkey v2.38.0 for scripts in `content` mode.
1214

1315
## Contexts
1416

15-
As we know, there are two types of context for a script to execute in:
17+
Violentmonkey supports 2 types of context for a script to execute in:
1618

1719
- context of a web page
1820

@@ -24,77 +26,31 @@ As we know, there are two types of context for a script to execute in:
2426

2527
## Injection Modes
2628

27-
In earlier versions of Violentmonkey, all scripts will be injected into the *page context*.
28-
29-
This works well at most times in Chrome. However, Firefox works differently. All scripts will be blocked in websites with CSP rules blocking inline scripts, like [GitHub](https://github.com). See issue [#173](https://github.com/violentmonkey/violentmonkey/issues/173), [#408](https://github.com/violentmonkey/violentmonkey/issues/408).
30-
31-
By introducing `@inject-into`, userscripts can be injected in Firefox now. In pages with CSP restrictions, we can inject userscripts into the *content context*.
29+
In earlier versions of Violentmonkey, all scripts were injected into the *page context*. This works well in Chrome and usually in Firefox except for websites with strict CSP that blocks inline scripts created by a WebExtension, like [GitHub](https://github.com). As a workaround, Violentmonkey can inject userscripts into the *content context*.
3230

3331
### Mode: `page`
3432

35-
This is the default mode, as the behavior in Violentmonkey v2.9.x.
36-
37-
`unsafeWindow` refers to `window` of the web page.
38-
39-
**Example usage:**
40-
41-
```js
42-
// ==UserScript==
43-
// ...
44-
// @inject-into page
45-
// ==/UserScript==
46-
47-
// `@inject-into` should be set to `page` since we need to access `window` of page context.
48-
49-
// Accessing objects attached to `window` of page
50-
alert('Hi, ' + unsafeWindow.context.user);
51-
```
33+
Same behavior as in older Violentmonkey. Injection fails in Firefox on sites with strict CSP that forbids inline scripts.
5234

5335
### Mode: `content`
5436

55-
```js
56-
// ==UserScript==
57-
// @inject-into content
58-
// ==/UserScript==
59-
```
60-
61-
In this mode, scripts will be injected into the *content context*.
37+
Scripts run in the *content context*, a secure "isolated world".
6238

63-
The *content context* is an isolated world, scripts in this context have no access to JavaScript objects from *page context*. But they can communicate with DOM APIs such as `addEventListener`.
39+
Content userscripts can't access JavaScript objects of the webpage in Chrome and by default in Firefox, but the latter allows you to use `wrappedJSObject`, optionally `cloneInto` and `exportFunction` (see [MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts)).
6440

65-
`unsafeWindow` refers to the `global` object of *content context*.
41+
* Universal workaround: DOM messaging via `CustomEvent` (synchronous) or `window.postMessage` (asynchronous).
6642

67-
**Scripts requiring access to JavaScript objects in the web page will not work in this mode.** For example, `unsafeWindow.jQuery` becomes inaccessible even if jQuery is introduced in the page.
43+
* Firefox-only workaround:
6844

45+
```js
46+
if (typeof exportFunction === 'function') {
47+
const wnd = typeof unsafeWindow === 'object' ? unsafeWindow : window;
48+
wnd.wrappedJSObject.foo = 1;
49+
wnd.wrappedJSObject.bar = exportFunction(function myFancyApi(x) {
50+
return cloneInto({ test: () => x }, wnd, { cloneFunctions: true });
51+
});
52+
}
53+
```
6954
### Mode: `auto`
7055

71-
```js
72-
// ==UserScript==
73-
// @inject-into auto
74-
// ==/UserScript==
75-
```
76-
7756
In this mode, scripts will be injected into the *page context* if possible. If blocked by CSP, they will be injected into the *content context*. It is the script author's job to check the environments.
78-
79-
**Example usage:**
80-
81-
```js
82-
// ==UserScript==
83-
// ...
84-
// @inject-into auto
85-
// ==/UserScript==
86-
87-
// `@inject-into` can be set to `auto` if we don't need to access any JavaScript object from page context.
88-
89-
// Accessing JavaScript objects shared in both contexts
90-
alert('The current page link is ' + window.location.href);
91-
92-
// Accessing DOM
93-
document.body.style = 'background: orange';
94-
```
95-
96-
## Violentmonkey Settings
97-
98-
By default, a script will try to execute in the *page context*. In Firefox, this may fail in CSP restricted pages.
99-
100-
You can change the default behavior in the settings tab of Violentmonkey. By changing the *default injection mode* to `auto`, scripts that do not depend on traditional `unsafeWindow` will work again in Firefox.

0 commit comments

Comments
 (0)