WebBrowser/Tools/WebHitTestResult.py

branch
QtWebEngine
changeset 4728
0367675d783d
child 4917
682750cc7bd5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/Tools/WebHitTestResult.py	Mon Feb 08 20:56:16 2016 +0100
@@ -0,0 +1,255 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2016 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing an object for testing certain aspects of a web page.
+"""
+
+#
+# This code was ported from QupZilla.
+# Copyright (C) David Rosca <nowrep@gmail.com>
+#
+
+from __future__ import unicode_literals
+
+from PyQt5.QtCore import QPoint, QRect, QUrl
+
+class WebHitTestResult(object):
+    """
+    Class implementing an object for testing certain aspects of a web page.
+    """
+    def __init__(self, page, pos):
+        """
+        Constructor
+        
+        @param page reference to the web page
+        @type WebBrowserPage
+        @param pos position to be tested
+        @type QPoint
+        """
+        self.__isNull = True
+        self.__isContentEditable = False
+        self.__isContentSelected = False
+        self.__isMediaPaused = False
+        self.__isMediaMuted = False
+        self.__pos = QPoint(pos)
+        self.__alternateText = ""
+        self.__boundingRect = QRect()
+        self.__imageUrl = QUrl()
+        self.__linkTitle = ""
+        self.__linkUrl = QUrl()
+        self.__mediaUrl = QUrl()
+        self.__tagName = ""
+    
+        script = """
+            (function() {{
+                var e = document.elementFromPoint({0}, {1});
+                if (!e)
+                    return;
+                function isMediaElement(e) {{
+                    return e.tagName == 'AUDIO' || e.tagName == 'VIDEO';
+                }}
+                function isEditableElement(e) {{
+                    if (e.isContentEditable)
+                        return true;
+                    if (e.tagName == 'INPUT' || e.tagName == 'TEXTAREA')
+                        return e.getAttribute('readonly') != 'readonly';
+                    return false;
+                }}
+                function isSelected(e) {{
+                    var selection = window.getSelection();
+                    if (selection.type != 'Range')
+                        return false;
+                    return window.getSelection().containsNode(e, true);
+                }}
+                var res = {{
+                    alternateText: e.getAttribute('alt'),
+                    boundingRect: '',
+                    imageUrl: '',
+                    contentEditable: isEditableElement(e),
+                    contentSelected: isSelected(e),
+                    linkTitle: '',
+                    linkUrl: '',
+                    mediaUrl: '',
+                    mediaPaused: false,
+                    mediaMuted: false,
+                    tagName: e.tagName.toLowerCase()
+                }};
+                var r = e.getBoundingClientRect();
+                res.boundingRect = [r.top, r.left, r.width, r.height];
+                if (e.tagName == 'IMG')
+                    res.imageUrl = e.getAttribute('src');
+                if (e.tagName == 'A') {{
+                    res.linkTitle = e.text;
+                    res.linkUrl = e.getAttribute('href');
+                }}
+                while (e) {{
+                    if (res.linkTitle == '' && e.tagName == 'A')
+                        res.linkTitle = e.text;
+                    if (res.linkUrl == '' && e.tagName == 'A')
+                        res.linkUrl = e.getAttribute('href');
+                    if (res.mediaUrl == '' && isMediaElement(e)) {{
+                        res.mediaUrl = e.currentSrc;
+                        res.mediaPaused = e.paused;
+                        res.mediaMuted = e.muted;
+                    }}
+                    e = e.parentElement;
+                }}
+                return res;
+            }})()
+        """.format(pos.x(), pos.y())
+        self.__populate(page.url(), page.execJavaScript(script))
+    
+    def alternateText(self):
+        """
+        Public method to get the alternate text.
+        
+        @return alternate text
+        @rtype str
+        """
+        return self.__alternateText
+    
+    def boundingRect(self):
+        """
+        Public method to get the bounding rectangle.
+        
+        @return bounding rectangle
+        @rtype QRect
+        """
+        return QRect(self.__boundingRect)
+    
+    def imageUrl(self):
+        """
+        Public method to get the URL of an image.
+        
+        @return image URL
+        @rtype QUrl
+        """
+        return self.__imageUrl
+    
+    def isContentEditable(self):
+        """
+        Public method to check for editable content.
+        
+        @return flag indicating editable content
+        @rtype bool
+        """
+        return self.__isContentEditable
+    
+    def isContentSelected(self):
+        """
+        Public method to check for selected content.
+        
+        @return flag indicating selected content
+        @rtype bool
+        """
+        return self.__isContentSelected
+    
+    def isNull(self):
+        """
+        Public method to test, if the hit test is empty.
+        
+        @return flag indicating an empty object
+        @rtype bool
+        """
+        return self.__isNull
+    
+    def linkTitle(self):
+        """
+        Public method to get the title for a link element.
+        
+        @return title for a link element
+        @rtype str
+        """
+        return self.__linkTitle
+    
+    def linkUrl(self):
+        """
+        Public method to get the URL for a link element.
+        
+        @return URL for a link element
+        @rtype QUrl
+        """
+        return self.__linkUrl
+    
+    def mediaUrl(self):
+        """
+        Public method to get the URL for a media element.
+        
+        @return URL for a media element
+        @rtype QUrl
+        """
+        return self.__mediaUrl
+    
+    def mediaPaused(self):
+        """
+        Public method to check, if a media element is paused.
+        
+        @return flag indicating a paused media element
+        @rtype bool
+        """
+        return self.__isMediaPaused
+    
+    def mediaMuted(self):
+        """
+        Public method to check, if a media element is muted.
+        
+        @return flag indicating a muted media element
+        @rtype bool
+        """
+        return self.__isMediaMuted
+    
+    def pos(self):
+        """
+        Public method to get the position of the hit test.
+        
+        @return position of hit test
+        @rtype QPoint
+        """
+        return QPoint(self.__pos)
+    
+    def tagName(self):
+        """
+        Public method to get the name of the tested tag.
+        
+        @return name of the tested tag
+        @rtype str
+        """
+        return self.__tagName
+    
+    def __populate(self, url, res):
+        """
+        Private method to populate the object.
+        
+        @param url URL of the tested page
+        @type QUrl
+        @param res dictionary with result data from JavaScript
+        @type dict
+        """
+        if not res:
+            return
+        
+        self.__alternateText = res["alternateText"]
+        self.__imageUrl = QUrl(res["imageUrl"])
+        self.__isContentEditable = res["contentEditable"]
+        self.__isContentSelected = res["contentSelected"]
+        self.__linkTitle = res["linkTitle"]
+        self.__linkUrl = QUrl(res["linkUrl"])
+        self.__mediaUrl = QUrl(res["mediaUrl"])
+        self.__isMediaPaused = res["mediaPaused"]
+        self.__isMediaMuted = res["mediaMuted"]
+        self.__tagName = res["tagName"]
+        
+        rect = res["boundingRect"]
+        if len(rect) == 4:
+            self.__boundingRect = QRect(int(rect[0]), int(rect[1]),
+                                        int(rect[2]), int(rect[3]))
+        
+        if not self.__imageUrl.isEmpty():
+            self.__imageUrl = url.resolved(self.__imageUrl)
+        if not self.__linkUrl.isEmpty():
+            self.__linkUrl = url.resolved(self.__linkUrl)
+        if not self.__mediaUrl.isEmpty():
+            self.__mediaUrl = url.resolved(self.__mediaUrl)

eric ide

mercurial