summaryrefslogtreecommitdiff
path: root/qutebrowser/browser/webengine/webenginetab.py
diff options
context:
space:
mode:
Diffstat (limited to 'qutebrowser/browser/webengine/webenginetab.py')
-rw-r--r--qutebrowser/browser/webengine/webenginetab.py203
1 files changed, 3 insertions, 200 deletions
diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py
index 6f0ea82f3..23933cf7f 100644
--- a/qutebrowser/browser/webengine/webenginetab.py
+++ b/qutebrowser/browser/webengine/webenginetab.py
@@ -24,7 +24,7 @@ import functools
import dataclasses
import re
import html as html_utils
-from typing import cast, Union, Optional
+from typing import cast, Union
from qutebrowser.qt.core import (pyqtSignal, pyqtSlot, Qt, QPoint, QPointF, QTimer, QUrl,
QObject)
@@ -33,13 +33,13 @@ from qutebrowser.qt.webenginewidgets import QWebEngineView
from qutebrowser.qt.webenginecore import QWebEnginePage, QWebEngineScript, QWebEngineHistory
from qutebrowser.config import config
-from qutebrowser.browser import browsertab, eventfilter, shared, webelem, greasemonkey
+from qutebrowser.browser import browsertab, eventfilter, shared, webelem
from qutebrowser.browser.webengine import (webview, webengineelem, tabhistory,
webenginesettings, certificateerror,
webengineinspector)
from qutebrowser.utils import (usertypes, qtutils, log, javascript, utils,
- resources, message, jinja, debug, version)
+ message, jinja, debug, version)
from qutebrowser.qt import sip, machinery
from qutebrowser.misc import objects, miscwidgets
@@ -1001,21 +1001,6 @@ class _WebEnginePermissions(QObject):
blocking=True)
-@dataclasses.dataclass
-class _Quirk:
-
- filename: str
- injection_point: QWebEngineScript.InjectionPoint = (
- QWebEngineScript.InjectionPoint.DocumentCreation)
- world: QWebEngineScript.ScriptWorldId = QWebEngineScript.ScriptWorldId.MainWorld
- predicate: bool = True
- name: Optional[str] = None
-
- def __post_init__(self):
- if self.name is None:
- self.name = f"js-{self.filename.replace('_', '-')}"
-
-
class _WebEngineScripts(QObject):
_widget: webview.WebEngineView
@@ -1024,7 +1009,6 @@ class _WebEngineScripts(QObject):
super().__init__(parent)
self._tab = tab
self._widget = cast(webview.WebEngineView, None)
- self._greasemonkey = greasemonkey.gm_manager
def connect_signals(self):
"""Connect signals to our private slots."""
@@ -1037,7 +1021,6 @@ class _WebEngineScripts(QObject):
@pyqtSlot(str)
def _on_config_changed(self, option):
if option in ['scrolling.bar', 'content.user_stylesheets']:
- self._init_stylesheet()
self._update_stylesheet()
@pyqtSlot(bool)
@@ -1047,185 +1030,6 @@ class _WebEngineScripts(QObject):
code = javascript.assemble('stylesheet', 'set_css', css)
self._tab.run_js_async(code)
- def _inject_js(self, name, js_code, *,
- world=QWebEngineScript.ScriptWorldId.ApplicationWorld,
- injection_point=QWebEngineScript.InjectionPoint.DocumentCreation,
- subframes=False):
- """Inject the given script to run early on a page load."""
- script = QWebEngineScript()
- script.setInjectionPoint(injection_point)
- script.setSourceCode(js_code)
- script.setWorldId(world)
- script.setRunsOnSubFrames(subframes)
- script.setName(f'_qute_{name}')
- self._widget.page().scripts().insert(script)
-
- def _remove_js(self, name):
- """Remove an early QWebEngineScript."""
- scripts = self._widget.page().scripts()
- if machinery.IS_QT6:
- for script in scripts.find(f'_qute_{name}'):
- scripts.remove(script)
- else: # Qt 5
- script = scripts.findScript(f'_qute_{name}')
- if not script.isNull():
- scripts.remove(script)
-
- def init(self):
- """Initialize global qutebrowser JavaScript."""
- js_code = javascript.wrap_global(
- 'scripts',
- resources.read_file('javascript/scroll.js'),
- resources.read_file('javascript/webelem.js'),
- resources.read_file('javascript/caret.js'),
- )
- # FIXME:qtwebengine what about subframes=True?
- self._inject_js('js', js_code, subframes=True)
- self._init_stylesheet()
-
- self._greasemonkey.scripts_reloaded.connect(
- self._inject_all_greasemonkey_scripts)
- self._inject_all_greasemonkey_scripts()
- self._inject_site_specific_quirks()
-
- def _init_stylesheet(self):
- """Initialize custom stylesheets.
-
- Partially inspired by QupZilla:
- https://github.com/QupZilla/qupzilla/blob/v2.0/src/lib/app/mainapplication.cpp#L1063-L1101
- """
- self._remove_js('stylesheet')
- css = shared.get_user_stylesheet()
- js_code = javascript.wrap_global(
- 'stylesheet',
- resources.read_file('javascript/stylesheet.js'),
- javascript.assemble('stylesheet', 'set_css', css),
- )
- self._inject_js('stylesheet', js_code, subframes=True)
-
- @pyqtSlot()
- def _inject_all_greasemonkey_scripts(self):
- scripts = self._greasemonkey.all_scripts()
- self._inject_greasemonkey_scripts(scripts)
-
- def _remove_all_greasemonkey_scripts(self):
- page_scripts = self._widget.page().scripts()
- for script in page_scripts.toList():
- if script.name().startswith("GM-"):
- log.greasemonkey.debug('Removing script: {}'
- .format(script.name()))
- removed = page_scripts.remove(script)
- assert removed, script.name()
-
- def _inject_greasemonkey_scripts(self, scripts):
- """Register user JavaScript files with the current tab.
-
- Args:
- scripts: A list of GreasemonkeyScripts.
- """
- if sip.isdeleted(self._widget):
- return
-
- # Since we are inserting scripts into a per-tab collection,
- # rather than just injecting scripts on page load, we need to
- # make sure we replace existing scripts, not just add new ones.
- # While, taking care not to remove any other scripts that might
- # have been added elsewhere, like the one for stylesheets.
- page_scripts = self._widget.page().scripts()
- self._remove_all_greasemonkey_scripts()
-
- seen_names = set()
- for script in scripts:
- while script.full_name() in seen_names:
- script.dedup_suffix += 1
- seen_names.add(script.full_name())
-
- new_script = QWebEngineScript()
-
- try:
- world = int(script.jsworld)
- if not 0 <= world <= qtutils.MAX_WORLD_ID:
- log.greasemonkey.error(
- f"script {script.name} has invalid value for '@qute-js-world'"
- f": {script.jsworld}, should be between 0 and "
- f"{qtutils.MAX_WORLD_ID}")
- continue
- except ValueError:
- try:
- world = _JS_WORLD_MAP[usertypes.JsWorld[script.jsworld.lower()]]
- except KeyError:
- log.greasemonkey.error(
- f"script {script.name} has invalid value for '@qute-js-world'"
- f": {script.jsworld}")
- continue
- new_script.setWorldId(world)
-
- # Corresponds to "@run-at document-end" which is the default according to
- # https://wiki.greasespot.net/Metadata_Block#.40run-at - however,
- # QtWebEngine uses QWebEngineScript.InjectionPoint.Deferred (@run-at document-idle) as
- # default.
- #
- # NOTE that this needs to be done before setSourceCode, so that
- # QtWebEngine's parsing of GreaseMonkey tags will override it if there is a
- # @run-at comment.
- new_script.setInjectionPoint(QWebEngineScript.InjectionPoint.DocumentReady)
-
- new_script.setSourceCode(script.code())
- new_script.setName(script.full_name())
- new_script.setRunsOnSubFrames(script.runs_on_sub_frames)
-
- if script.needs_document_end_workaround():
- log.greasemonkey.debug(
- f"Forcing @run-at document-end for {script.name}")
- new_script.setInjectionPoint(QWebEngineScript.InjectionPoint.DocumentReady)
-
- log.greasemonkey.debug(f'adding script: {new_script.name()}')
- page_scripts.insert(new_script)
-
- def _get_quirks(self):
- """Get a list of all available JS quirks."""
- versions = version.qtwebengine_versions()
- return [
- # FIXME:qt6 Double check which of those are still required
- _Quirk(
- 'whatsapp_web',
- injection_point=QWebEngineScript.InjectionPoint.DocumentReady,
- world=QWebEngineScript.ScriptWorldId.ApplicationWorld,
- ),
- _Quirk('discord'),
- _Quirk(
- 'googledocs',
- # will be an UA quirk once we set the JS UA as well
- name='ua-googledocs',
- ),
-
- _Quirk(
- 'string_replaceall',
- predicate=versions.webengine < utils.VersionNumber(5, 15, 3),
- ),
- _Quirk(
- 'array_at',
- predicate=versions.webengine < utils.VersionNumber(6, 3),
- ),
- ]
-
- def _inject_site_specific_quirks(self):
- """Add site-specific quirk scripts."""
- if not config.val.content.site_specific_quirks.enabled:
- return
-
- for quirk in self._get_quirks():
- if not quirk.predicate:
- continue
- src = resources.read_file(f'javascript/quirks/{quirk.filename}.user.js')
- if quirk.name not in config.val.content.site_specific_quirks.skip:
- self._inject_js(
- f'quirk_{quirk.filename}',
- src,
- world=quirk.world,
- injection_point=quirk.injection_point,
- )
-
class WebEngineTabPrivate(browsertab.AbstractTabPrivate):
@@ -1301,7 +1105,6 @@ class WebEngineTab(browsertab.AbstractTab):
self.backend = usertypes.Backend.QtWebEngine
self._child_event_filter = None
self._saved_zoom = None
- self._scripts.init()
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-65223
self._needs_qtbug65223_workaround = (
version.qtwebengine_versions().webengine < utils.VersionNumber(5, 15, 5))