summaryrefslogtreecommitdiff
path: root/qutebrowser/browser/greasemonkey.py
diff options
context:
space:
mode:
authorJimmy <jimmy@spalge.com>2018-06-25 14:28:28 +1200
committerJimmy <jimmy@spalge.com>2018-06-26 15:00:35 +1200
commit54ca9b34e529e7d0fc84c77c16cff21ce302381e (patch)
treea7c3e579ba2752c8c7f07b97c217615833bea728 /qutebrowser/browser/greasemonkey.py
parent1bc3d444b6c0e25cc754c34e2b40476cd5ba0464 (diff)
downloadqutebrowser-54ca9b34e529e7d0fc84c77c16cff21ce302381e.tar.gz
qutebrowser-54ca9b34e529e7d0fc84c77c16cff21ce302381e.zip
greasemonkey: enable running in isolated js worlds
QtWebEngine (via chromium) has the ability to run injected scripts in isolated "worlds". What is isolated is just the javascript environment, so variables and functions defined by the page and the script won't clobber each other, or be able to interact (including variables saved to the global `window` object). The DOM is still accessible from "isolated" scripts. This is NOT a security measure. You cannot put untrusted scripts in one of these isolated worlds and expect it to not be able to do whatever page js can do, it is just for namespacing convenience. See https://stackoverflow.com/questions/9515704/insert-code-into-the-page-context-using-a-content-script for some examples of how to inject scripts into the page scope using DOM elements. Now you can specify the world ID in a `@qute-js-world` directive like: ``` // ==UserScript== // @name Do thing // @match *://some.site/* // @qute-js-world 1234 // ==/UserScript== document.body.innerHTML = "<strong>overwritten</strong>" ``` The QtWebEngine docs say worldid is a `quint32` so you can put whatever number (positive, whole, real) you want there. I have chosen to allow the `qutebrowser.utils.usertypes` enum as aliases for IDs that are predefined in `qutebrowser.browser.webengine.webenginetab._JS_WORLD_MAP`. So you can pass `main`, `application`, `user` or `jseval` in there too. `main` (0) is the default one and is the only one in which JS disabled when `content.javascript.enabled` is set to `false`. All others are still enabled. I'm not sure whether using any of those already-named worlds makes sense, apart from `main`. We could stop people from using them I suppose. Another option is to allow people to pass in `*` as a value to have scripts put into their own little worlds, probably backed by a counter in the GreaseMonkeyManager class. Chrome docs: https://developer.chrome.com/extensions/content_scripts#execution-environment Webengine docs: https://doc.qt.io/qt-5/qwebenginescript.html#details
Diffstat (limited to 'qutebrowser/browser/greasemonkey.py')
-rw-r--r--qutebrowser/browser/greasemonkey.py3
1 files changed, 3 insertions, 0 deletions
diff --git a/qutebrowser/browser/greasemonkey.py b/qutebrowser/browser/greasemonkey.py
index db8246bab..cff45f3ac 100644
--- a/qutebrowser/browser/greasemonkey.py
+++ b/qutebrowser/browser/greasemonkey.py
@@ -58,6 +58,7 @@ class GreasemonkeyScript:
self.run_at = None
self.script_meta = None
self.runs_on_sub_frames = True
+ self.jsworld = "main"
for name, value in properties:
if name == 'name':
self.name = value
@@ -77,6 +78,8 @@ class GreasemonkeyScript:
self.runs_on_sub_frames = False
elif name == 'require':
self.requires.append(value)
+ elif name == 'qute-js-world':
+ self.jsworld = value
HEADER_REGEX = r'// ==UserScript==|\n+// ==/UserScript==\n'
PROPS_REGEX = r'// @(?P<prop>[^\s]+)\s*(?P<val>.*)'