Continued porting the web browser. QtWebEngine

Wed, 10 Feb 2016 20:00:09 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 10 Feb 2016 20:00:09 +0100
branch
QtWebEngine
changeset 4731
67d861d9e492
parent 4729
fc8d00860717
child 4732
5ac4fc1dfc20

Continued porting the web browser.

- did some more context menu stuff

WebBrowser/Tools/Scripts.py file | annotate | diff | comparison | revisions
WebBrowser/WebBrowserView.py file | annotate | diff | comparison | revisions
WebBrowser/WebBrowserWindow.py file | annotate | diff | comparison | revisions
--- a/WebBrowser/Tools/Scripts.py	Tue Feb 09 20:29:26 2016 +0100
+++ b/WebBrowser/Tools/Scripts.py	Wed Feb 10 20:00:09 2016 +0100
@@ -96,7 +96,7 @@
                 e.play();
             else
                 e.pause();
-            }})()"""
+        }})()"""
     return source.format(pos.x(), pos.y())
 
 
@@ -115,5 +115,42 @@
             if (!e)
                 return;
             e.muted = !e.muted;
-            }})()"""
+        }})()"""
     return source.format(pos.x(), pos.y())
+
+
+def getFormData(pos):
+    """
+    Function generating a script to extract data for a form element.
+    
+    @param pos position to extract data at
+    @type QPoint
+    @return script to extract form data
+    @rtype str
+    """
+    source = """
+        (function() {{
+            var e = document.elementFromPoint({0}, {1});
+            if (!e || e.tagName != 'INPUT')
+                return;
+            var fe = e.parentElement;
+            while (fe) {{
+                if (fe.tagName == 'FORM')
+                    break;
+                fe = fe.parentElement;
+            }}
+            if (!fe)
+                return;
+            var res = {{
+                method: fe.method.toLowerCase(),
+                action: fe.action,
+                inputName: e.name,
+                inputs: [],
+            }};
+            for (var i = 0; i < fe.length; ++i) {{
+                var input = fe.elements[i];
+                res.inputs.push([input.name, input.value]);
+            }}
+            return res;
+        }})()"""
+    return source.format(pos.x(), pos.y())
--- a/WebBrowser/WebBrowserView.py	Tue Feb 09 20:29:26 2016 +0100
+++ b/WebBrowser/WebBrowserView.py	Wed Feb 10 20:00:09 2016 +0100
@@ -83,7 +83,8 @@
         
         self.__rwhvqt = None
         self.installEventFilter(self)
-##        
+        
+        # TODO: Speeddial
 ##        import Helpviewer.HelpWindow
 ##        self.__speedDial = Helpviewer.HelpWindow.HelpWindow.speedDial()
         
@@ -369,8 +370,6 @@
         """
         Public slot to move to the first page loaded.
         """
-##        homeUrl = QUrl("http://localhost")
-##        # TODO: eric: scheme or Configuration page
         homeUrl = QUrl(Preferences.getWebBrowser("HomePage"))
         self.setSource(homeUrl)
         self.__urlChanged(self.history().currentItem().url())
@@ -546,16 +545,6 @@
         else:
             self.findText(txt, findFlags, callback)
     
-    # TODO: WebBrowserWebElement
-##    def __isMediaElement(self, element):
-##        """
-##        Private method to check, if the given element is a media element.
-##        
-##        @param element element to be checked (QWebElement)
-##        @return flag indicating a media element (boolean)
-##        """
-##        return element.tagName().lower() in ["video", "audio"]
-    
     def contextMenuEvent(self, evt):
         """
         Public method called to create a context menu.
@@ -573,7 +562,6 @@
         # needs to be done this way because contextMenuEvent is blocking
         # the main loop
     
-    # TODO: re-arrange the menu creation stuff to better adjust to the current situation
     def _contextMenuEvent(self, evt):
         """
         Protected method called to create a context menu.
@@ -633,11 +621,11 @@
 ##            menu.addSeparator()
 ##            self.__mw.personalInformationManager().createSubMenu(menu, self, hit)
             
-            # TODO: complete this context menu action
-##            if hitTest.tagName() == "input":
-##                act = menu.addAction("")
-##                act.setVisible(False)
-##                self.__checkForForm(act, hitTest.pos())
+            if hitTest.tagName() == "input":
+                menu.addSeparator()
+                act = menu.addAction("")
+                act.setVisible(False)
+                self.__checkForForm(act, hitTest.pos())
         
         if self.selectedText():
             self.__createSelectedTextContextMenu(menu, hitTest)
@@ -892,16 +880,47 @@
         menu.addAction(self.__mw.selectAllAct)
         menu.addSeparator()
         menu.addAction(self.__mw.findAct)
+        menu.addSeparator()
+        menu.addAction(self.__mw.pageSourceAct)
+        # TODO: Site Info
+##        menu.addSeparator()
+##        menu.addAction(self.__mw.siteInfoAct)
         
-        # TODO: OpenSearch
-##        
-##        element = hit.element()
-##        if not element.isNull() and \
-##           element.tagName().lower() == "input" and \
-##           element.attribute("type", "text") == "text":
-##            menu.addAction(self.tr("Add to web search toolbar"),
-##                           self.__addSearchEngine).setData(element)
-##            menu.addSeparator()
+    def __checkForForm(self, act, pos):
+        """
+        Private method to check the given position for an open search form.
+        
+        @param act reference to the action to be populated upon success
+        @type QAction
+        @param pos position to be tested
+        @type QPoint
+        """
+        self.__clickedPos = pos
+        
+        from .Tools import Scripts
+        script = Scripts.getFormData(pos)
+        self.page().runJavaScript(
+            script, lambda res: self.__checkForFormCallback(res, act))
+    
+    def __checkForFormCallback(self, res, act):
+        """
+        Private method handling the __checkForForm result.
+        
+        @param res result dictionary generated by JavaScript
+        @type dict
+        @param act reference to the action to be populated upon success
+        @type QAction
+        """
+        if act is None or not bool(res):
+            return
+        
+        url = QUrl(res["action"])
+        method = res["method"]
+        
+        if not url.isEmpty() and method in ["get", "post"]:
+            act.setVisible(True)
+            act.setText(self.tr("Add to web search toolbar"))
+            act.triggered.connect(self.__addSearchEngine)
     
     def __isUrlValid(self, url):
         """
@@ -1051,128 +1070,18 @@
 ##        if engineName:
 ##            engine = self.__mw.openSearchManager().engine(engineName)
 ##            self.search.emit(engine.searchUrl(searchText))
-##    
-##    def __addSearchEngine(self):
-##        """
-##        Private slot to add a new search engine.
-##        """
-##        act = self.sender()
-##        if act is None:
-##            return
-##        
-##        element = act.data()
-##        elementName = element.attribute("name")
-##        formElement = QWebElement(element)
-##        while formElement.tagName().lower() != "form":
-##            formElement = formElement.parent()
-##        
-##        if formElement.isNull() or \
-##           formElement.attribute("action") == "":
-##            return
-##        
-##        method = formElement.attribute("method", "get").lower()
-##        if method != "get":
-##            E5MessageBox.warning(
-##                self,
-##                self.tr("Method not supported"),
-##                self.tr(
-##                    """{0} method is not supported.""").format(method.upper()))
-##            return
-##        
-##        searchUrl = QUrl(self.page().mainFrame().baseUrl().resolved(
-##            QUrl(formElement.attribute("action"))))
-##        if searchUrl.scheme() != "http":
-##            return
-##        
-##        if qVersion() >= "5.0.0":
-##            from PyQt5.QtCore import QUrlQuery
-##            searchUrlQuery = QUrlQuery(searchUrl)
-##        searchEngines = {}
-##        inputFields = formElement.findAll("input")
-##        for inputField in inputFields.toList():
-##            type_ = inputField.attribute("type", "text")
-##            name = inputField.attribute("name")
-##            value = inputField.evaluateJavaScript("this.value")
-##            
-##            if type_ == "submit":
-##                searchEngines[value] = name
-##            elif type_ == "text":
-##                if inputField == element:
-##                    value = "{searchTerms}"
-##                if qVersion() >= "5.0.0":
-##                    searchUrlQuery.addQueryItem(name, value)
-##                else:
-##                    searchUrl.addQueryItem(name, value)
-##            elif type_ == "checkbox" or type_ == "radio":
-##                if inputField.evaluateJavaScript("this.checked"):
-##                    if qVersion() >= "5.0.0":
-##                        searchUrlQuery.addQueryItem(name, value)
-##                    else:
-##                        searchUrl.addQueryItem(name, value)
-##            elif type_ == "hidden":
-##                if qVersion() >= "5.0.0":
-##                    searchUrlQuery.addQueryItem(name, value)
-##                else:
-##                    searchUrl.addQueryItem(name, value)
-##        
-##        selectFields = formElement.findAll("select")
-##        for selectField in selectFields.toList():
-##            name = selectField.attribute("name")
-##            selectedIndex = selectField.evaluateJavaScript(
-##                "this.selectedIndex")
-##            if selectedIndex == -1:
-##                continue
-##            
-##            options = selectField.findAll("option")
-##            value = options.at(selectedIndex).toPlainText()
-##            if qVersion() >= "5.0.0":
-##                searchUrlQuery.addQueryItem(name, value)
-##            else:
-##                searchUrl.addQueryItem(name, value)
-##        
-##        ok = True
-##        if len(searchEngines) > 1:
-##            searchEngine, ok = QInputDialog.getItem(
-##                self,
-##                self.tr("Search engine"),
-##                self.tr("Choose the desired search engine"),
-##                sorted(searchEngines.keys()), 0, False)
-##            
-##            if not ok:
-##                return
-##            
-##            if searchEngines[searchEngine] != "":
-##                if qVersion() >= "5.0.0":
-##                    searchUrlQuery.addQueryItem(
-##                        searchEngines[searchEngine], searchEngine)
-##                else:
-##                    searchUrl.addQueryItem(
-##                        searchEngines[searchEngine], searchEngine)
-##        engineName = ""
-##        labels = formElement.findAll('label[for="{0}"]'.format(elementName))
-##        if labels.count() > 0:
-##            engineName = labels.at(0).toPlainText()
-##        
-##        engineName, ok = QInputDialog.getText(
-##            self,
-##            self.tr("Engine name"),
-##            self.tr("Enter a name for the engine"),
-##            QLineEdit.Normal,
-##            engineName)
-##        if not ok:
-##            return
-##        
-##        if qVersion() >= "5.0.0":
-##            searchUrl.setQuery(searchUrlQuery)
-##        
-##        from .OpenSearch.OpenSearchEngine import OpenSearchEngine
-##        engine = OpenSearchEngine()
-##        engine.setName(engineName)
-##        engine.setDescription(engineName)
-##        engine.setSearchUrlTemplate(searchUrl.toString())
-##        engine.setImage(self.icon().pixmap(16, 16).toImage())
-##        
-##        self.__mw.openSearchManager().addEngine(engine)
+    
+    def __addSearchEngine(self):
+        """
+        Private slot to add a new search engine.
+        """
+        from .Tools import Scripts
+        script = Scripts.getFormData(self.__clickedPos)
+        # TODO: OpenSearch: add ew method
+##        self.page().runJavaScript(
+##            script,
+##            lambda res: self.__mw.openSearchManager().addEngineFromForm(
+##                res, self))
     
     # TODO: WebInspector
 ##    def __webInspector(self):
@@ -1371,7 +1280,7 @@
         
         super(WebBrowserView, self).focusOutEvent(evt)
     
-    # TODO: Obsoleted by eventFilter() (?)
+    # TODO: Gestures: Obsoleted by eventFilter() (?)
 ##    def event(self, evt):
 ##        """
 ##        Public method handling events.
@@ -1571,6 +1480,8 @@
         
         if ok:
             pass
+            # TODO: History
+##            self.__mw.historyManager().addHistoryEntry(self.url())
             # TODO: AdBlock
 ##            self.__mw.adBlockManager().page().hideBlockedPageEntries(self.page())
             # TODO: Password Manager
--- a/WebBrowser/WebBrowserWindow.py	Tue Feb 09 20:29:26 2016 +0100
+++ b/WebBrowser/WebBrowserWindow.py	Wed Feb 10 20:00:09 2016 +0100
@@ -540,6 +540,8 @@
             self.newAct.triggered.connect(self.newWindow)
         self.__actions.append(self.newAct)
         
+        # TODO: Private Window
+        
         self.openAct = E5Action(
             self.tr('Open File'),
             UI.PixmapCache.getIcon("open.png"),
@@ -2173,6 +2175,8 @@
                              self.__fromEric)
         h.show()
     
+    # TODO: Private Window
+    
     # TODO: check if this is still needed
     def previewer(self):
         """
@@ -2564,6 +2568,7 @@
 ##            QWebSettings.ZoomTextOnly, textOnly)
 ##        self.zoomTextOnlyChanged.emit(textOnly)
 ##    
+    # TODO: Full Screen
 ##    def __viewFullScreen(self):
 ##        """
 ##        Private slot called to toggle fullscreen mode.

eric ide

mercurial