Merge remote-tracking branch 'origin/pr/3443'

This commit is contained in:
Florian Bruhin 2018-01-24 20:36:15 +01:00
commit caca3614f8
2 changed files with 47 additions and 10 deletions

View File

@ -23,7 +23,6 @@ import re
import os import os
import json import json
import fnmatch import fnmatch
import functools
import glob import glob
import attr import attr
@ -178,10 +177,10 @@ class GreasemonkeyManager(QObject):
elif script.run_at == 'document-idle': elif script.run_at == 'document-idle':
self._run_idle.append(script) self._run_idle.append(script)
else: else:
log.greasemonkey.warning("Script {} has invalid run-at " if script.run_at:
"defined, defaulting to " log.greasemonkey.warning(
"document-end" "Script {} has invalid run-at defined, "
.format(script_path)) "defaulting to document-end".format(script_path))
# Default as per # Default as per
# https://wiki.greasespot.net/Metadata_Block#.40run-at # https://wiki.greasespot.net/Metadata_Block#.40run-at
self._run_end.append(script) self._run_end.append(script)
@ -196,11 +195,23 @@ class GreasemonkeyManager(QObject):
""" """
if url.scheme() not in self.greaseable_schemes: if url.scheme() not in self.greaseable_schemes:
return MatchingScripts(url, [], [], []) return MatchingScripts(url, [], [], [])
match = functools.partial(fnmatch.fnmatch,
url.toString(QUrl.FullyEncoded)) string_url = url.toString(QUrl.FullyEncoded)
def _match(pattern):
# For include and exclude rules if they start and end with '/' they
# should be treated as a (ecma syntax) regular expression.
if pattern.startswith('/') and pattern.endswith('/'):
matches = re.search(pattern[1:-1], string_url, flags=re.I)
return matches is not None
# Otherwise they are glob expressions.
return fnmatch.fnmatch(string_url, pattern)
tester = (lambda script: tester = (lambda script:
any(match(pat) for pat in script.includes) and any(_match(pat) for pat in script.includes) and
not any(match(pat) for pat in script.excludes)) not any(_match(pat) for pat in script.excludes))
return MatchingScripts( return MatchingScripts(
url, url,
[script for script in self._run_start if tester(script)], [script for script in self._run_start if tester(script)],

View File

@ -19,6 +19,7 @@
"""Tests for qutebrowser.browser.greasemonkey.""" """Tests for qutebrowser.browser.greasemonkey."""
import logging import logging
import textwrap
import pytest import pytest
import py.path # pylint: disable=no-name-in-module import py.path # pylint: disable=no-name-in-module
@ -26,7 +27,7 @@ from PyQt5.QtCore import QUrl
from qutebrowser.browser import greasemonkey from qutebrowser.browser import greasemonkey
test_gm_script = """ test_gm_script = r"""
// ==UserScript== // ==UserScript==
// @name qutebrowser test userscript // @name qutebrowser test userscript
// @namespace invalid.org // @namespace invalid.org
@ -75,6 +76,31 @@ def test_get_scripts_by_url(url, expected_matches):
expected_matches) expected_matches)
@pytest.mark.parametrize("url, expected_matches", [
# included
('https://github.com/qutebrowser/qutebrowser/', 1),
# neither included nor excluded
('http://aaaaaaaaaa.com/', 0),
# excluded takes priority
('http://github.com/foo', 0),
])
def test_regex_includes_scripts_for(url, expected_matches):
"""Ensure our GM @*clude support supports regular expressions."""
gh_dark_example = textwrap.dedent(r"""
// ==UserScript==
// @include /^https?://((gist|guides|help|raw|status|developer)\.)?github\.com/((?!generated_pages\/preview).)*$/
// @exclude /https?://github\.com/foo/
// @run-at document-start
// ==/UserScript==
""")
_save_script(gh_dark_example, 'test.user.js')
gm_manager = greasemonkey.GreasemonkeyManager()
scripts = gm_manager.scripts_for(QUrl(url))
assert (len(scripts.start + scripts.end + scripts.idle) ==
expected_matches)
def test_no_metadata(caplog): def test_no_metadata(caplog):
"""Run on all sites at document-end is the default.""" """Run on all sites at document-end is the default."""
_save_script("var nothing = true;\n", 'nothing.user.js') _save_script("var nothing = true;\n", 'nothing.user.js')