Improved the QtWebEngine based HTML previewer variant by including JavaScript to save and restore the current scrollbar positions.

Sun, 27 Dec 2015 13:14:00 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 27 Dec 2015 13:14:00 +0100
changeset 4625
ac72a3d8f89e
parent 4624
aebdbffe02b6
child 4626
c891c7ad6b60

Improved the QtWebEngine based HTML previewer variant by including JavaScript to save and restore the current scrollbar positions.

APIs/Python3/eric6.api file | annotate | diff | comparison | revisions
Documentation/Help/source.qch file | annotate | diff | comparison | revisions
Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
Documentation/Source/eric6.UI.Previewers.PreviewerHTML.html file | annotate | diff | comparison | revisions
UI/Previewers/PreviewerHTML.py file | annotate | diff | comparison | revisions
--- a/APIs/Python3/eric6.api	Fri Dec 25 17:44:36 2015 +0100
+++ b/APIs/Python3/eric6.api	Sun Dec 27 13:14:00 2015 +0100
@@ -8559,6 +8559,7 @@
 eric6.UI.Previewers.PreviewerHTML.PreviewerHTML.on_previewView_titleChanged?4(title)
 eric6.UI.Previewers.PreviewerHTML.PreviewerHTML.on_ssiCheckBox_clicked?4(checked)
 eric6.UI.Previewers.PreviewerHTML.PreviewerHTML.processEditor?4(editor=None)
+eric6.UI.Previewers.PreviewerHTML.PreviewerHTML.resultCallback?4(resDict=resultDict)
 eric6.UI.Previewers.PreviewerHTML.PreviewerHTML.shutdown?4()
 eric6.UI.Previewers.PreviewerHTML.PreviewerHTML?1(parent=None)
 eric6.UI.Previewers.PreviewerHTML._StrikeThroughExtension.DEL_RE?7
Binary file Documentation/Help/source.qch has changed
--- a/Documentation/Help/source.qhp	Fri Dec 25 17:44:36 2015 +0100
+++ b/Documentation/Help/source.qhp	Sun Dec 27 13:14:00 2015 +0100
@@ -8872,6 +8872,7 @@
       <keyword name="PreviewerHTML" id="PreviewerHTML" ref="eric6.UI.Previewers.PreviewerHTML.html#PreviewerHTML" />
       <keyword name="PreviewerHTML (Constructor)" id="PreviewerHTML (Constructor)" ref="eric6.UI.Previewers.PreviewerHTML.html#PreviewerHTML.__init__" />
       <keyword name="PreviewerHTML (Module)" id="PreviewerHTML (Module)" ref="eric6.UI.Previewers.PreviewerHTML.html" />
+      <keyword name="PreviewerHTML.__execJavaScript" id="PreviewerHTML.__execJavaScript" ref="eric6.UI.Previewers.PreviewerHTML.html#PreviewerHTML.__execJavaScript" />
       <keyword name="PreviewerHTML.__restoreScrollBarPositions" id="PreviewerHTML.__restoreScrollBarPositions" ref="eric6.UI.Previewers.PreviewerHTML.html#PreviewerHTML.__restoreScrollBarPositions" />
       <keyword name="PreviewerHTML.__saveScrollBarPositions" id="PreviewerHTML.__saveScrollBarPositions" ref="eric6.UI.Previewers.PreviewerHTML.html#PreviewerHTML.__saveScrollBarPositions" />
       <keyword name="PreviewerHTML.__setHtml" id="PreviewerHTML.__setHtml" ref="eric6.UI.Previewers.PreviewerHTML.html#PreviewerHTML.__setHtml" />
@@ -8881,6 +8882,7 @@
       <keyword name="PreviewerHTML.on_previewView_titleChanged" id="PreviewerHTML.on_previewView_titleChanged" ref="eric6.UI.Previewers.PreviewerHTML.html#PreviewerHTML.on_previewView_titleChanged" />
       <keyword name="PreviewerHTML.on_ssiCheckBox_clicked" id="PreviewerHTML.on_ssiCheckBox_clicked" ref="eric6.UI.Previewers.PreviewerHTML.html#PreviewerHTML.on_ssiCheckBox_clicked" />
       <keyword name="PreviewerHTML.processEditor" id="PreviewerHTML.processEditor" ref="eric6.UI.Previewers.PreviewerHTML.html#PreviewerHTML.processEditor" />
+      <keyword name="PreviewerHTML.resultCallback" id="PreviewerHTML.resultCallback" ref="eric6.UI.Previewers.PreviewerHTML.html#PreviewerHTML.resultCallback" />
       <keyword name="PreviewerHTML.shutdown" id="PreviewerHTML.shutdown" ref="eric6.UI.Previewers.PreviewerHTML.html#PreviewerHTML.shutdown" />
       <keyword name="PreviewerQSS" id="PreviewerQSS" ref="eric6.UI.Previewers.PreviewerQSS.html#PreviewerQSS" />
       <keyword name="PreviewerQSS (Constructor)" id="PreviewerQSS (Constructor)" ref="eric6.UI.Previewers.PreviewerQSS.html#PreviewerQSS.__init__" />
--- a/Documentation/Source/eric6.UI.Previewers.PreviewerHTML.html	Fri Dec 25 17:44:36 2015 +0100
+++ b/Documentation/Source/eric6.UI.Previewers.PreviewerHTML.html	Sun Dec 27 13:14:00 2015 +0100
@@ -296,6 +296,9 @@
 <td><a href="#PreviewerHTML.__init__">PreviewerHTML</a></td>
 <td>Constructor</td>
 </tr><tr>
+<td><a href="#PreviewerHTML.__execJavaScript">__execJavaScript</a></td>
+<td>Private function to execute a JavaScript function Synchroneously.</td>
+</tr><tr>
 <td><a href="#PreviewerHTML.__restoreScrollBarPositions">__restoreScrollBarPositions</a></td>
 <td>Private method to restore scroll bar positions for a previewed editor.</td>
 </tr><tr>
@@ -323,6 +326,9 @@
 <td><a href="#PreviewerHTML.processEditor">processEditor</a></td>
 <td>Public slot to process an editor's text.</td>
 </tr><tr>
+<td><a href="#PreviewerHTML.resultCallback">resultCallback</a></td>
+<td></td>
+</tr><tr>
 <td><a href="#PreviewerHTML.shutdown">shutdown</a></td>
 <td>Public method to perform shutdown actions.</td>
 </tr>
@@ -341,6 +347,26 @@
 <dd>
 reference to the parent widget (QWidget)
 </dd>
+</dl><a NAME="PreviewerHTML.__execJavaScript" ID="PreviewerHTML.__execJavaScript"></a>
+<h4>PreviewerHTML.__execJavaScript</h4>
+<b>__execJavaScript</b>(<i>script</i>)
+<p>
+        Private function to execute a JavaScript function Synchroneously.
+</p><dl>
+<dt><i>script</i> (str)</dt>
+<dd>
+JavaScript script source to be executed
+</dd>
+</dl><dl>
+<dt>Returns:</dt>
+<dd>
+result of the script
+</dd>
+</dl><dl>
+<dt>Return Type:</dt>
+<dd>
+depending upon script result
+</dd>
 </dl><a NAME="PreviewerHTML.__restoreScrollBarPositions" ID="PreviewerHTML.__restoreScrollBarPositions"></a>
 <h4>PreviewerHTML.__restoreScrollBarPositions</h4>
 <b>__restoreScrollBarPositions</b>(<i></i>)
@@ -425,7 +451,10 @@
 <dd>
 editor to be processed (Editor)
 </dd>
-</dl><a NAME="PreviewerHTML.shutdown" ID="PreviewerHTML.shutdown"></a>
+</dl><a NAME="PreviewerHTML.resultCallback" ID="PreviewerHTML.resultCallback"></a>
+<h4>PreviewerHTML.resultCallback</h4>
+<b>resultCallback</b>(<i>resDict=resultDict</i>)
+<a NAME="PreviewerHTML.shutdown" ID="PreviewerHTML.shutdown"></a>
 <h4>PreviewerHTML.shutdown</h4>
 <b>shutdown</b>(<i></i>)
 <p>
--- a/UI/Previewers/PreviewerHTML.py	Fri Dec 25 17:44:36 2015 +0100
+++ b/UI/Previewers/PreviewerHTML.py	Sun Dec 27 13:14:00 2015 +0100
@@ -51,15 +51,15 @@
         self.__layout.addWidget(self.titleLabel)
         
         try:
+            from PyQt5.QtWebEngineWidgets import QWebEngineView
+            self.previewView = QWebEngineView(self)
+            self.__usesWebKit = False
+        except ImportError:
             from PyQt5.QtWebKitWidgets import QWebPage, QWebView
             self.previewView = QWebView(self)
             self.previewView.page().setLinkDelegationPolicy(
                 QWebPage.DelegateAllLinks)
             self.__usesWebKit = True
-        except ImportError:
-            from PyQt5.QtWebEngineWidgets import QWebEngineView
-            self.previewView = QWebEngineView(self)
-            self.__usesWebKit = False
         
         sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
         sizePolicy.setHorizontalStretch(0)
@@ -200,10 +200,13 @@
         """
         self.__previewedPath = Utilities.normcasepath(
             Utilities.fromNativeSeparators(filePath))
+        self.__saveScrollBarPositions()
         if self.__usesWebKit:
-            self.__saveScrollBarPositions()
             self.previewView.page().mainFrame().contentsSizeChanged.connect(
                 self.__restoreScrollBarPositions)
+        else:
+            self.previewView.page().loadFinished.connect(
+                self.__restoreScrollBarPositions)
         self.previewView.setHtml(html, baseUrl=QUrl.fromLocalFile(filePath))
     
     @pyqtSlot(str)
@@ -233,6 +236,23 @@
                 frame.scrollBarMaximum(Qt.Horizontal) == pos.x()
             self.__vScrollBarAtEnd[self.__previewedPath] = \
                 frame.scrollBarMaximum(Qt.Vertical) == pos.y()
+        else:
+            from PyQt5.QtCore import QPoint
+            pos = self.__execJavaScript(
+                "(function() {"
+                "var res = {"
+                "    x: 0,"
+                "    y: 0,"
+                "};"
+                "res.x = window.scrollX;"
+                "res.y = window.scrollY;"
+                "return res;"
+                "})()"
+            )
+            pos = QPoint(pos["x"], pos["y"])
+            self.__scrollBarPositions[self.__previewedPath] = pos
+            self.__hScrollBarAtEnd[self.__previewedPath] = False
+            self.__vScrollBarAtEnd[self.__previewedPath] = False
 
     def __restoreScrollBarPositions(self):
         """
@@ -260,6 +280,13 @@
             if self.__vScrollBarAtEnd[self.__previewedPath]:
                 frame.setScrollBarValue(
                     Qt.Vertical, frame.scrollBarMaximum(Qt.Vertical))
+        else:
+            if self.__previewedPath not in self.__scrollBarPositions:
+                return
+            
+            pos = self.__scrollBarPositions[self.__previewedPath]
+            self.previewView.page().runJavaScript(
+                "window.scrollTo({0}, {1});".format(pos.x(), pos.y()))
     
     @pyqtSlot(QUrl)
     def on_previewView_linkClicked(self, url):
@@ -269,6 +296,30 @@
         @param url url of the clicked link (QUrl)
         """
         e5App().getObject("UserInterface").launchHelpViewer(url.toString())
+    
+    def __execJavaScript(self, script):
+        """
+        Private function to execute a JavaScript function Synchroneously.
+        
+        @param script JavaScript script source to be executed
+        @type str
+        @return result of the script
+        @rtype depending upon script result
+        """
+        from PyQt5.QtCore import QEventLoop
+        loop = QEventLoop()
+        resultDict = {"res": None}
+        
+        def resultCallback(res, resDict=resultDict):
+            if loop and loop.isRunning():
+                resDict["res"] = res
+                loop.quit()
+        
+        self.previewView.page().runJavaScript(
+            script, resultCallback)
+        
+        loop.exec_()
+        return resultDict["res"]
 
 
 class PreviewProcessingThread(QThread):

eric ide

mercurial