Greasemonkey: Support QTWebEngine versions < 5.8
QTWebEngine 5.8 added support for parsing greasemonkey metadata blocks and scripts added to the QWebEngineScriptCollection of a page or its profile and then deciding what urls to run those scripts on and at what point in the load process to run them. For earlier versions we must do that work ourselves. But with the additional handicap of the less rich qtwebengine api. We have acceptNavigationRequest, loadStarted, loadProgress, loadFinished, urlChanged to choose from regarding points at which to register scripts for the current page. Adding scripts on acceptNavigation loadStarted and loadFinished causes scripts to run too early or too late (eg on the pages being navigated from/to) and not run on the desired page at the time they are inserted. We could maybe do some more sophisticated stuff with loadProgress but it didn't have any better behaviour in the brief testing I gave it. Registering scripts on the urlChanged event seems to work fine. Even if it seems like there could be problems with the signal firing too often, due to not necessarily being tied to the page load progress, that doesn't seem to have an effect in practice. The event is fired when, for example, the url fragment changes and even if we add a new script to the collection (or remove an existing one) it doesn't have an effect on what is running on the page. I suspect all of those timing issues is due to the signals being forwarded fairly directly from the underlying chomium/blink code but the webengine script stuff only being pushed back to the implementation on certain events. Anyway, using urlChanged seems to work fine due to some quirk(s) of the implementation. That might change with later development but this codepath is only ever going to be used for version 5.7. There are other potential optimizations like not removing and then re-adding scripts for the current page. But they probably wouldn't do anything anyway, or at least anything that you would expect.
This commit is contained in:
parent
209e43e0ba
commit
efde31aa57
@ -23,12 +23,14 @@ import functools
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, PYQT_VERSION
|
||||
from PyQt5.QtGui import QPalette
|
||||
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
|
||||
from PyQt5.QtWebEngineWidgets import (QWebEngineView, QWebEnginePage,
|
||||
QWebEngineScript)
|
||||
|
||||
from qutebrowser.browser import shared
|
||||
from qutebrowser.browser.webengine import certificateerror, webenginesettings
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import log, debug, usertypes, jinja, urlutils, message
|
||||
from qutebrowser.utils import (log, debug, usertypes, jinja, urlutils, message,
|
||||
objreg, qtutils)
|
||||
|
||||
|
||||
class WebEngineView(QWebEngineView):
|
||||
@ -135,6 +137,7 @@ class WebEnginePage(QWebEnginePage):
|
||||
self._theme_color = theme_color
|
||||
self._set_bg_color()
|
||||
config.instance.changed.connect(self._set_bg_color)
|
||||
self.urlChanged.connect(self._inject_userjs)
|
||||
|
||||
@config.change_filter('colors.webpage.bg')
|
||||
def _set_bg_color(self):
|
||||
@ -300,3 +303,41 @@ class WebEnginePage(QWebEnginePage):
|
||||
message.error(msg)
|
||||
return False
|
||||
return True
|
||||
|
||||
@pyqtSlot('QUrl')
|
||||
def _inject_userjs(self, url):
|
||||
"""Inject userscripts registered for `url` into the current page."""
|
||||
if qtutils.version_check('5.8'):
|
||||
# Handled in webenginetab with the builtin greasemonkey
|
||||
# support.
|
||||
return
|
||||
|
||||
# Using QWebEnginePage.scripts() to hold the user scripts means
|
||||
# we don't have to worry ourselves about where to inject the
|
||||
# page but also means scripts hang around for the tab lifecycle.
|
||||
# So clear them here.
|
||||
scripts = self.scripts()
|
||||
for script in scripts.toList():
|
||||
if script.name().startswith("GM-"):
|
||||
really_removed = scripts.remove(script)
|
||||
log.greasemonkey.debug("Removing ({}) script: {}"
|
||||
.format(really_removed, script.name()))
|
||||
|
||||
def _add_script(script, injection_point):
|
||||
new_script = QWebEngineScript()
|
||||
new_script.setInjectionPoint(injection_point)
|
||||
new_script.setWorldId(QWebEngineScript.MainWorld)
|
||||
new_script.setSourceCode(script.code())
|
||||
new_script.setName("GM-{}".format(script.name))
|
||||
log.greasemonkey.debug("Adding script: {}"
|
||||
.format(new_script.name()))
|
||||
scripts.insert(new_script)
|
||||
|
||||
greasemonkey = objreg.get('greasemonkey')
|
||||
matching_scripts = greasemonkey.scripts_for(url)
|
||||
for script in matching_scripts.start:
|
||||
_add_script(script, QWebEngineScript.DocumentCreation)
|
||||
for script in matching_scripts.end:
|
||||
_add_script(script, QWebEngineScript.DocumentReady)
|
||||
for script in matching_scripts.idle:
|
||||
_add_script(script, QWebEngineScript.Deferred)
|
||||
|
Loading…
Reference in New Issue
Block a user