Continued porting the web browser. QtWebEngine

Sat, 05 Mar 2016 18:40:16 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 05 Mar 2016 18:40:16 +0100
branch
QtWebEngine
changeset 4809
4daf93888029
parent 4808
328e613165fe
child 4810
f68d0446609e

Continued porting the web browser.

- modified GreaseMonkey to get rid of the meta data
- modified GreaseMonkey to match the include and exclude patterns in JavaScript.

WebBrowser/GreaseMonkey/GreaseMonkeyScript.py file | annotate | diff | comparison | revisions
WebBrowser/GreaseMonkey/GreaseMonkeyUrlMatcher.py file | annotate | diff | comparison | revisions
eric6.e4p file | annotate | diff | comparison | revisions
--- a/WebBrowser/GreaseMonkey/GreaseMonkeyScript.py	Sat Mar 05 17:24:44 2016 +0100
+++ b/WebBrowser/GreaseMonkey/GreaseMonkeyScript.py	Sat Mar 05 18:40:16 2016 +0100
@@ -13,7 +13,6 @@
     QByteArray,  QCryptographicHash
 from PyQt5.QtWebEngineWidgets import QWebEngineScript
 
-from .GreaseMonkeyUrlMatcher import GreaseMonkeyUrlMatcher
 from .GreaseMonkeyJavaScript import bootstrap_js, values_js
 
 from ..Tools.DelayedFileWatcher import DelayedFileWatcher
@@ -25,6 +24,7 @@
     """
     DocumentStart = 0
     DocumentEnd = 1
+    DocumentIdle = 2
     
     scriptChanged = pyqtSignal()
     
@@ -56,7 +56,6 @@
         self.__fileName = path
         self.__enabled = True
         self.__valid = False
-        self.__metaData = ""
         self.__noFrames = False
         
         self.__parseScript()
@@ -167,10 +166,7 @@
         
         @return list of included URLs (list of strings)
         """
-        list = []
-        for matcher in self.__include:
-            list.append(matcher.pattern())
-        return list
+        return self.__include[:]
     
     def exclude(self):
         """
@@ -178,10 +174,7 @@
         
         @return list of excluded URLs (list of strings)
         """
-        list = []
-        for matcher in self.__exclude:
-            list.append(matcher.pattern())
-        return list
+        return self.__exclude[:]
     
     def script(self):
         """
@@ -191,15 +184,6 @@
         """
         return self.__script
     
-    def metaData(self):
-        """
-        Public method to get the script meta information.
-        
-        @return script meta information
-        @rtype str
-        """
-        return self.__metaData
-    
     def fileName(self):
         """
         Public method to get the path of the Javascript file.
@@ -208,26 +192,6 @@
         """
         return self.__fileName
     
-    def match(self, urlString):
-        """
-        Public method to check, if the script matches the given URL.
-        
-        @param urlString URL (string)
-        @return flag indicating a match (boolean)
-        """
-        if not self.isEnabled():
-            return False
-        
-        for matcher in self.__exclude:
-            if matcher.match(urlString):
-                return False
-        
-        for matcher in self.__include:
-            if matcher.match(urlString):
-                return True
-        
-        return False
-    
     @pyqtSlot(str)
     def __watchedFileChanged(self, fileName):
         """
@@ -266,7 +230,6 @@
         self.__script = ""
         self.__enabled = True
         self.__valid = False
-        self.__metaData = ""
         self.__noFrames = False
         
         try:
@@ -325,10 +288,10 @@
 ##                self.__downloadUrl = QUrl(value)
 ##            
             elif key in ["@include", "@match"]:
-                self.__include.append(GreaseMonkeyUrlMatcher(value))
+                self.__include.append(value)
             
             elif key in ["@exclude", "@exclude_match"]:
-                self.__exclude.append(GreaseMonkeyUrlMatcher(value))
+                self.__exclude.append(value)
             
             elif key == "@require":
                 requireList.append(value)
@@ -338,6 +301,8 @@
                     self.__startAt = GreaseMonkeyScript.DocumentEnd
                 elif value == "document-start":
                     self.__startAt = GreaseMonkeyScript.DocumentStart
+                elif value == "document-idle":
+                    self.__startAt = GreaseMonkeyScript.DocumentIdle
             
             elif key == "@downloadURL" and self.__downloadUrl.isEmpty():
                 self.__downloadUrl = QUrl(value)
@@ -346,19 +311,37 @@
                 self.__updateUrl = QUrl(value)
         
         if not self.__include:
-            self.__include.append(GreaseMonkeyUrlMatcher("*"))
-        
-        marker = "// ==/UserScript=="
-        index = fileData.find(marker) + len(marker)
-        self.__metaData = fileData[:index]
-        script = fileData[index:].strip()
+            self.__include.append("*")
         
         nspace = bytes(QCryptographicHash.hash(
             QByteArray(self.fullName().encode("utf-8")),
             QCryptographicHash.Md4).toHex()).decode("ascii")
         valuesScript = values_js.format(nspace)
-        self.__script = "(function(){{{0}\n{1}\n{2}\n}})();".format(
-            valuesScript, self.__manager.requireScripts(requireList), script
+        runCheck = """
+            for (var value of {0}) {{
+                var re = new RegExp(value);
+                if (re.test(window.location.href)) {{
+                    return;
+                }}
+            }}
+            __eric_includes = false;
+            for (var value of {1}) {{
+                var re = new RegExp(value);
+                if (re.test(window.location.href)) {{
+                    __eric_includes = true;
+                    break;
+                }}
+            }}
+            if (!__eric_includes) {{
+                return;
+            }}
+            delete __eric_includes;""".format(
+                self.__toJavaScriptList(self.__exclude[:]),
+                self.__toJavaScriptList(self.__include[:])
+            )
+        self.__script = "(function(){{{0}\n{1}\n{2}\n{3}\n}})();".format(
+            runCheck, valuesScript,
+            self.__manager.requireScripts(requireList), fileData
         )
         self.__valid = True
     
@@ -369,15 +352,44 @@
         @return prepared script object
         @rtype QWebEngineScript
         """
+        if self.startAt() == GreaseMonkeyScript.DocumentStart:
+            injectionPoint = QWebEngineScript.DocumentCreation
+        elif self.startAt() == GreaseMonkeyScript.DocumentEnd:
+            injectionPoint = QWebEngineScript.DocumentReady
+        elif self.startAt() == GreaseMonkeyScript.DocumentIdle:
+            injectionPoint = QWebEngineScript.Deferred
+        else:
+            raise ValueError("Wrong script start point.")
+        
         script = QWebEngineScript()
         script.setName(self.fullName())
-        if self.startAt() == GreaseMonkeyScript.DocumentStart:
-            script.setInjectionPoint(QWebEngineScript.DocumentCreation)
-        else:
-            script.setInjectionPoint(QWebEngineScript.DocumentReady)
+        script.setInjectionPoint(injectionPoint)
         script.setWorldId(QWebEngineScript.MainWorld)
         script.setRunsOnSubFrames(not self.__noFrames)
-        script.setSourceCode("{0}\n{1}\n{2}".format(
-            self.__metaData, bootstrap_js, self.__script
+        script.setSourceCode("{0}\n{1}".format(
+            bootstrap_js, self.__script
         ))
         return script
+    
+    def __toJavaScriptList(self, patterns):
+        """
+        Private method to convert a list of str to a string containing a valid
+        JavaScript list definition.
+        
+        @param patterns list of match patterns
+        @type list of str
+        @return JavaScript script containing the list
+        @rtype str
+        """
+        patternList = []
+        for pattern in patterns:
+            if pattern.startswith("/") and pattern.endswith("/") and \
+                    len(pattern) > 1:
+                pattern = pattern[1:-1]
+            else:
+                pattern = pattern.replace(".", "\\.").replace("*", ".*")
+            pattern = "'{0}'".format(pattern)
+            patternList.append(pattern)
+        
+        script = "[{0}]".format(",".join(patternList))
+        return script
--- a/WebBrowser/GreaseMonkey/GreaseMonkeyUrlMatcher.py	Sat Mar 05 17:24:44 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2012 - 2016 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the GreaseMonkey URL matcher.
-"""
-
-from __future__ import unicode_literals
-
-import re
-
-from PyQt5.QtCore import Qt, QRegExp
-
-
-def wildcardMatch(string, pattern):
-    """
-    Module function implementing a special wildcard matcher.
-    
-    @param string string to match (string)
-    @param pattern pattern to be used (string)
-    @return flag indicating a successful match (boolean)
-    """
-    stringSize = len(string)
-    
-    startsWithWildcard = pattern.startswith("*")
-    endsWithWildcard = pattern.endswith("*")
-    
-    parts = pattern.split("*")
-    pos = 0
-    
-    if startsWithWildcard:
-        pos = string.find(parts[1])
-        if pos == -1:
-            return False
-    
-    for part in parts:
-        pos = string.find(part, pos)
-        if pos == -1:
-            return False
-    
-    if not endsWithWildcard and stringSize - pos != len(parts[-1]):
-        return False
-    
-    return True
-
-
-class GreaseMonkeyUrlMatcher(object):
-    """
-    Class implementing the GreaseMonkey URL matcher.
-    """
-    def __init__(self, pattern):
-        """
-        Constructor
-        
-        @param pattern pattern to be used for the matching (string)
-        """
-        self.__pattern = pattern
-        self.__matchString = ""
-        self.__regExp = QRegExp()
-        self.__useRegExp = False
-        
-        self.__parsePattern(self.__pattern)
-    
-    def pattern(self):
-        """
-        Public method to get the match pattern.
-        
-        @return match pattern (string)
-        """
-        return self.__pattern
-    
-    def match(self, urlString):
-        """
-        Public method to match the given URL.
-        
-        @param urlString URL to match (string)
-        @return flag indicating a successful match (boolean)
-        """
-        if self.__useRegExp:
-            return self.__regExp.indexIn(urlString) != -1
-        else:
-            return wildcardMatch(urlString, self.__matchString)
-    
-    def __parsePattern(self, pattern):
-        """
-        Private method to parse the match pattern.
-        
-        @param pattern match pattern to be used (string)
-        """
-        if pattern.startswith("/") and pattern.endswith("/"):
-            pattern = pattern[1:-1]
-            
-            self.__regExp = QRegExp(pattern, Qt.CaseInsensitive)
-            self.__useRegExp = True
-        elif ".tld" in pattern:
-            # escape special symbols
-            pattern = re.sub(r"(\W)", r"\\\1", pattern)
-            # remove multiple wildcards
-            pattern = re.sub(r"\*+", "*", pattern)
-            # process anchor at expression start
-            pattern = re.sub(r"^\\\|", "^", pattern)
-            # process anchor at expression end
-            pattern = re.sub(r"\\\|$", "$", pattern)
-            # replace wildcards by .*
-            pattern = re.sub(r"\\\*", ".*", pattern)
-            # replace domain pattern
-            pattern = re.sub(r"\.tld", r"\.[a-z.]{2,6}")
-            
-            self.__useRegExp = True
-            self.__regExp = QRegExp(pattern, Qt.CaseInsensitive)
-        else:
-            self.__matchString = pattern
--- a/eric6.e4p	Sat Mar 05 17:24:44 2016 +0100
+++ b/eric6.e4p	Sat Mar 05 18:40:16 2016 +0100
@@ -1323,7 +1323,6 @@
     <Source>WebBrowser/GreaseMonkey/GreaseMonkeyManager.py</Source>
     <Source>WebBrowser/GreaseMonkey/GreaseMonkeyScript.py</Source>
     <Source>WebBrowser/GreaseMonkey/GreaseMonkeyUrlInterceptor.py</Source>
-    <Source>WebBrowser/GreaseMonkey/GreaseMonkeyUrlMatcher.py</Source>
     <Source>WebBrowser/GreaseMonkey/__init__.py</Source>
     <Source>WebBrowser/History/HistoryCompleter.py</Source>
     <Source>WebBrowser/History/HistoryDialog.py</Source>

eric ide

mercurial