49 @signal navigationRequestAccepted(url, navigation type, main frame) emitted |
54 @signal navigationRequestAccepted(url, navigation type, main frame) emitted |
50 to signal an accepted navigation request |
55 to signal an accepted navigation request |
51 @signal sslConfigurationChanged() emitted to indicate a change of the |
56 @signal sslConfigurationChanged() emitted to indicate a change of the |
52 stored SSL configuration data |
57 stored SSL configuration data |
53 """ |
58 """ |
|
59 |
54 SafeJsWorld = QWebEngineScript.ScriptWorldId.ApplicationWorld |
60 SafeJsWorld = QWebEngineScript.ScriptWorldId.ApplicationWorld |
55 UnsafeJsWorld = QWebEngineScript.ScriptWorldId.MainWorld |
61 UnsafeJsWorld = QWebEngineScript.ScriptWorldId.MainWorld |
56 |
62 |
57 safeBrowsingAbort = pyqtSignal() |
63 safeBrowsingAbort = pyqtSignal() |
58 safeBrowsingBad = pyqtSignal(str, str) |
64 safeBrowsingBad = pyqtSignal(str, str) |
59 |
65 |
60 printPageRequested = pyqtSignal() |
66 printPageRequested = pyqtSignal() |
61 navigationRequestAccepted = pyqtSignal(QUrl, QWebEnginePage.NavigationType, |
67 navigationRequestAccepted = pyqtSignal(QUrl, QWebEnginePage.NavigationType, bool) |
62 bool) |
68 |
63 |
|
64 sslConfigurationChanged = pyqtSignal() |
69 sslConfigurationChanged = pyqtSignal() |
65 |
70 |
66 def __init__(self, view, parent=None): |
71 def __init__(self, view, parent=None): |
67 """ |
72 """ |
68 Constructor |
73 Constructor |
69 |
74 |
70 @param view reference to the WebBrowserView associated with the page |
75 @param view reference to the WebBrowserView associated with the page |
71 @type WebBrowserView |
76 @type WebBrowserView |
72 @param parent reference to the parent widget (defaults to None) |
77 @param parent reference to the parent widget (defaults to None) |
73 @type QWidget (optional) |
78 @type QWidget (optional) |
74 """ |
79 """ |
75 super().__init__( |
80 super().__init__(WebBrowserWindow.webProfile(), parent) |
76 WebBrowserWindow.webProfile(), parent) |
81 |
77 |
|
78 self.__printer = None |
82 self.__printer = None |
79 self.__badSite = False |
83 self.__badSite = False |
80 self.__registerProtocolHandlerRequest = None |
84 self.__registerProtocolHandlerRequest = None |
81 |
85 |
82 self.__view = view |
86 self.__view = view |
83 |
87 |
84 self.featurePermissionRequested.connect( |
88 self.featurePermissionRequested.connect(self.__featurePermissionRequested) |
85 self.__featurePermissionRequested) |
|
86 self.authenticationRequired.connect( |
89 self.authenticationRequired.connect( |
87 lambda url, auth: WebBrowserWindow.networkManager().authentication( |
90 lambda url, auth: WebBrowserWindow.networkManager().authentication( |
88 url, auth, self)) |
91 url, auth, self |
|
92 ) |
|
93 ) |
89 self.proxyAuthenticationRequired.connect( |
94 self.proxyAuthenticationRequired.connect( |
90 WebBrowserWindow.networkManager().proxyAuthentication) |
95 WebBrowserWindow.networkManager().proxyAuthentication |
|
96 ) |
91 self.fullScreenRequested.connect(self.__fullScreenRequested) |
97 self.fullScreenRequested.connect(self.__fullScreenRequested) |
92 self.urlChanged.connect(self.__urlChanged) |
98 self.urlChanged.connect(self.__urlChanged) |
93 self.contentsSizeChanged.connect(self.__contentsSizeChanged) |
99 self.contentsSizeChanged.connect(self.__contentsSizeChanged) |
94 self.registerProtocolHandlerRequested.connect( |
100 self.registerProtocolHandlerRequested.connect( |
95 self.__registerProtocolHandlerRequested) |
101 self.__registerProtocolHandlerRequested |
96 |
102 ) |
|
103 |
97 self.__sslConfiguration = None |
104 self.__sslConfiguration = None |
98 |
105 |
99 # Workaround for changing webchannel world inside |
106 # Workaround for changing webchannel world inside |
100 # acceptNavigationRequest not working |
107 # acceptNavigationRequest not working |
101 self.__channelUrl = QUrl() |
108 self.__channelUrl = QUrl() |
102 self.__channelWorldId = -1 |
109 self.__channelWorldId = -1 |
103 self.__setupChannelTimer = QTimer(self) |
110 self.__setupChannelTimer = QTimer(self) |
104 self.__setupChannelTimer.setSingleShot(True) |
111 self.__setupChannelTimer.setSingleShot(True) |
105 self.__setupChannelTimer.setInterval(100) |
112 self.__setupChannelTimer.setInterval(100) |
106 self.__setupChannelTimer.timeout.connect(self.__setupChannelTimeout) |
113 self.__setupChannelTimer.timeout.connect(self.__setupChannelTimeout) |
107 |
114 |
108 def view(self): |
115 def view(self): |
109 """ |
116 """ |
110 Public method to get a reference to the WebBrowserView associated with |
117 Public method to get a reference to the WebBrowserView associated with |
111 the page. |
118 the page. |
112 |
119 |
113 @return reference to the WebBrowserView associated with the page |
120 @return reference to the WebBrowserView associated with the page |
114 r@type WebBrowserView |
121 r@type WebBrowserView |
115 """ |
122 """ |
116 return self.__view |
123 return self.__view |
117 |
124 |
118 @pyqtSlot() |
125 @pyqtSlot() |
119 def __setupChannelTimeout(self): |
126 def __setupChannelTimeout(self): |
120 """ |
127 """ |
121 Private slot to initiate the setup of the web channel. |
128 Private slot to initiate the setup of the web channel. |
122 """ |
129 """ |
123 self.__setupWebChannelForUrl(self.__channelUrl) |
130 self.__setupWebChannelForUrl(self.__channelUrl) |
124 |
131 |
125 def acceptNavigationRequest(self, url, type_, isMainFrame): |
132 def acceptNavigationRequest(self, url, type_, isMainFrame): |
126 """ |
133 """ |
127 Public method to determine, if a request may be accepted. |
134 Public method to determine, if a request may be accepted. |
128 |
135 |
129 @param url URL to navigate to |
136 @param url URL to navigate to |
130 @type QUrl |
137 @type QUrl |
131 @param type_ type of the navigation request |
138 @param type_ type of the navigation request |
132 @type QWebEnginePage.NavigationType |
139 @type QWebEnginePage.NavigationType |
133 @param isMainFrame flag indicating, that the request originated from |
140 @param isMainFrame flag indicating, that the request originated from |
138 """ |
145 """ |
139 scheme = url.scheme() |
146 scheme = url.scheme() |
140 if scheme == "mailto": |
147 if scheme == "mailto": |
141 QDesktopServices.openUrl(url) |
148 QDesktopServices.openUrl(url) |
142 return False |
149 return False |
143 |
150 |
144 # AdBlock |
151 # AdBlock |
145 if ( |
152 if ( |
146 url.scheme() == "abp" and |
153 url.scheme() == "abp" |
147 WebBrowserWindow.adBlockManager().addSubscriptionFromUrl(url) |
154 and WebBrowserWindow.adBlockManager().addSubscriptionFromUrl(url) |
148 ): |
155 ): |
149 return False |
156 return False |
150 |
157 |
151 # GreaseMonkey |
158 # GreaseMonkey |
152 navigationType = type_ in ( |
159 navigationType = type_ in ( |
153 QWebEnginePage.NavigationType.NavigationTypeLinkClicked, |
160 QWebEnginePage.NavigationType.NavigationTypeLinkClicked, |
154 QWebEnginePage.NavigationType.NavigationTypeRedirect |
161 QWebEnginePage.NavigationType.NavigationTypeRedirect, |
155 ) |
162 ) |
156 if navigationType and url.toString().endswith(".user.js"): |
163 if navigationType and url.toString().endswith(".user.js"): |
157 WebBrowserWindow.greaseMonkeyManager().downloadScript(url) |
164 WebBrowserWindow.greaseMonkeyManager().downloadScript(url) |
158 return False |
165 return False |
159 |
166 |
160 if url.scheme() == "eric": |
167 if url.scheme() == "eric": |
161 if url.path() == "AddSearchProvider": |
168 if url.path() == "AddSearchProvider": |
162 query = QUrlQuery(url) |
169 query = QUrlQuery(url) |
163 self.__view.mainWindow().openSearchManager().addEngine( |
170 self.__view.mainWindow().openSearchManager().addEngine( |
164 QUrl(query.queryItemValue("url"))) |
171 QUrl(query.queryItemValue("url")) |
|
172 ) |
165 return False |
173 return False |
166 elif url.path() == "PrintPage": |
174 elif url.path() == "PrintPage": |
167 self.printPageRequested.emit() |
175 self.printPageRequested.emit() |
168 return False |
176 return False |
169 |
177 |
170 # Safe Browsing |
178 # Safe Browsing |
171 self.__badSite = False |
179 self.__badSite = False |
172 from WebBrowser.SafeBrowsing.SafeBrowsingManager import ( |
180 from WebBrowser.SafeBrowsing.SafeBrowsingManager import SafeBrowsingManager |
173 SafeBrowsingManager |
181 |
174 ) |
|
175 if ( |
182 if ( |
176 SafeBrowsingManager.isEnabled() and |
183 SafeBrowsingManager.isEnabled() |
177 url.scheme() not in SafeBrowsingManager.getIgnoreSchemes() |
184 and url.scheme() not in SafeBrowsingManager.getIgnoreSchemes() |
178 ): |
185 ): |
179 threatLists = ( |
186 threatLists = WebBrowserWindow.safeBrowsingManager().lookupUrl(url)[0] |
180 WebBrowserWindow.safeBrowsingManager().lookupUrl(url)[0] |
|
181 ) |
|
182 if threatLists: |
187 if threatLists: |
183 threatMessages = ( |
188 threatMessages = ( |
184 WebBrowserWindow.safeBrowsingManager() |
189 WebBrowserWindow.safeBrowsingManager().getThreatMessages( |
185 .getThreatMessages(threatLists) |
190 threatLists |
|
191 ) |
186 ) |
192 ) |
187 res = EricMessageBox.warning( |
193 res = EricMessageBox.warning( |
188 WebBrowserWindow.getWindow(), |
194 WebBrowserWindow.getWindow(), |
189 self.tr("Suspicuous URL detected"), |
195 self.tr("Suspicuous URL detected"), |
190 self.tr("<p>The URL <b>{0}</b> was found in the Safe" |
196 self.tr( |
191 " Browsing database.</p>{1}").format( |
197 "<p>The URL <b>{0}</b> was found in the Safe" |
192 url.toString(), "".join(threatMessages)), |
198 " Browsing database.</p>{1}" |
|
199 ).format(url.toString(), "".join(threatMessages)), |
193 EricMessageBox.Abort | EricMessageBox.Ignore, |
200 EricMessageBox.Abort | EricMessageBox.Ignore, |
194 EricMessageBox.Abort) |
201 EricMessageBox.Abort, |
|
202 ) |
195 if res == EricMessageBox.Abort: |
203 if res == EricMessageBox.Abort: |
196 self.safeBrowsingAbort.emit() |
204 self.safeBrowsingAbort.emit() |
197 return False |
205 return False |
198 |
206 |
199 self.__badSite = True |
207 self.__badSite = True |
200 threatType = ( |
208 threatType = WebBrowserWindow.safeBrowsingManager().getThreatType( |
201 WebBrowserWindow.safeBrowsingManager() |
209 threatLists[0] |
202 .getThreatType(threatLists[0]) |
|
203 ) |
210 ) |
204 self.safeBrowsingBad.emit(threatType, "".join(threatMessages)) |
211 self.safeBrowsingBad.emit(threatType, "".join(threatMessages)) |
205 |
212 |
206 result = QWebEnginePage.acceptNavigationRequest( |
213 result = QWebEnginePage.acceptNavigationRequest(self, url, type_, isMainFrame) |
207 self, url, type_, isMainFrame) |
214 |
208 |
|
209 if result: |
215 if result: |
210 if isMainFrame: |
216 if isMainFrame: |
211 isWeb = url.scheme() in ("http", "https", "ftp", "ftps", |
217 isWeb = url.scheme() in ("http", "https", "ftp", "ftps", "file") |
212 "file") |
|
213 globalJsEnabled = WebBrowserWindow.webSettings().testAttribute( |
218 globalJsEnabled = WebBrowserWindow.webSettings().testAttribute( |
214 QWebEngineSettings.WebAttribute.JavascriptEnabled) |
219 QWebEngineSettings.WebAttribute.JavascriptEnabled |
|
220 ) |
215 if isWeb: |
221 if isWeb: |
216 enable = globalJsEnabled |
222 enable = globalJsEnabled |
217 else: |
223 else: |
218 enable = True |
224 enable = True |
219 self.settings().setAttribute( |
225 self.settings().setAttribute( |
220 QWebEngineSettings.WebAttribute.JavascriptEnabled, enable) |
226 QWebEngineSettings.WebAttribute.JavascriptEnabled, enable |
221 |
227 ) |
|
228 |
222 self.__channelUrl = url |
229 self.__channelUrl = url |
223 self.__setupChannelTimer.start() |
230 self.__setupChannelTimer.start() |
224 self.navigationRequestAccepted.emit(url, type_, isMainFrame) |
231 self.navigationRequestAccepted.emit(url, type_, isMainFrame) |
225 |
232 |
226 return result |
233 return result |
227 |
234 |
228 @pyqtSlot(QUrl) |
235 @pyqtSlot(QUrl) |
229 def __urlChanged(self, url): |
236 def __urlChanged(self, url): |
230 """ |
237 """ |
231 Private slot to handle changes of the URL. |
238 Private slot to handle changes of the URL. |
232 |
239 |
233 @param url new URL |
240 @param url new URL |
234 @type QUrl |
241 @type QUrl |
235 """ |
242 """ |
236 if ( |
243 if ( |
237 not url.isEmpty() and |
244 not url.isEmpty() |
238 url.scheme() == "eric" and |
245 and url.scheme() == "eric" |
239 not self.isJavaScriptEnabled() |
246 and not self.isJavaScriptEnabled() |
240 ): |
247 ): |
241 self.settings().setAttribute( |
248 self.settings().setAttribute( |
242 QWebEngineSettings.WebAttribute.JavascriptEnabled, True) |
249 QWebEngineSettings.WebAttribute.JavascriptEnabled, True |
|
250 ) |
243 self.triggerAction(QWebEnginePage.WebAction.Reload) |
251 self.triggerAction(QWebEnginePage.WebAction.Reload) |
244 |
252 |
245 @classmethod |
253 @classmethod |
246 def userAgent(cls, resolveEmpty=False): |
254 def userAgent(cls, resolveEmpty=False): |
247 """ |
255 """ |
248 Class method to get the global user agent setting. |
256 Class method to get the global user agent setting. |
249 |
257 |
250 @param resolveEmpty flag indicating to resolve an empty |
258 @param resolveEmpty flag indicating to resolve an empty |
251 user agent (boolean) |
259 user agent (boolean) |
252 @return user agent string (string) |
260 @return user agent string (string) |
253 """ |
261 """ |
254 agent = Preferences.getWebBrowser("UserAgent") |
262 agent = Preferences.getWebBrowser("UserAgent") |
255 if agent == "" and resolveEmpty: |
263 if agent == "" and resolveEmpty: |
256 agent = cls.userAgentForUrl(QUrl()) |
264 agent = cls.userAgentForUrl(QUrl()) |
257 return agent |
265 return agent |
258 |
266 |
259 @classmethod |
267 @classmethod |
260 def setUserAgent(cls, agent): |
268 def setUserAgent(cls, agent): |
261 """ |
269 """ |
262 Class method to set the global user agent string. |
270 Class method to set the global user agent string. |
263 |
271 |
264 @param agent new current user agent string (string) |
272 @param agent new current user agent string (string) |
265 """ |
273 """ |
266 Preferences.setWebBrowser("UserAgent", agent) |
274 Preferences.setWebBrowser("UserAgent", agent) |
267 |
275 |
268 @classmethod |
276 @classmethod |
269 def userAgentForUrl(cls, url): |
277 def userAgentForUrl(cls, url): |
270 """ |
278 """ |
271 Class method to determine the user agent for the given URL. |
279 Class method to determine the user agent for the given URL. |
272 |
280 |
273 @param url URL to determine user agent for (QUrl) |
281 @param url URL to determine user agent for (QUrl) |
274 @return user agent string (string) |
282 @return user agent string (string) |
275 """ |
283 """ |
276 agent = WebBrowserWindow.userAgentsManager().userAgentForUrl(url) |
284 agent = WebBrowserWindow.userAgentsManager().userAgentForUrl(url) |
277 if agent == "": |
285 if agent == "": |
343 else: |
351 else: |
344 if callback is None: |
352 if callback is None: |
345 QWebEnginePage.runJavaScript(self, script) |
353 QWebEnginePage.runJavaScript(self, script) |
346 else: |
354 else: |
347 QWebEnginePage.runJavaScript(self, script, callback) |
355 QWebEnginePage.runJavaScript(self, script, callback) |
348 |
356 |
349 def isJavaScriptEnabled(self): |
357 def isJavaScriptEnabled(self): |
350 """ |
358 """ |
351 Public method to test, if JavaScript is enabled. |
359 Public method to test, if JavaScript is enabled. |
352 |
360 |
353 @return flag indicating the state of the JavaScript support |
361 @return flag indicating the state of the JavaScript support |
354 @rtype bool |
362 @rtype bool |
355 """ |
363 """ |
356 return self.settings().testAttribute( |
364 return self.settings().testAttribute( |
357 QWebEngineSettings.WebAttribute.JavascriptEnabled) |
365 QWebEngineSettings.WebAttribute.JavascriptEnabled |
358 |
366 ) |
|
367 |
359 def scroll(self, x, y): |
368 def scroll(self, x, y): |
360 """ |
369 """ |
361 Public method to scroll by the given amount of pixels. |
370 Public method to scroll by the given amount of pixels. |
362 |
371 |
363 @param x horizontal scroll value |
372 @param x horizontal scroll value |
364 @type int |
373 @type int |
365 @param y vertical scroll value |
374 @param y vertical scroll value |
366 @type int |
375 @type int |
367 """ |
376 """ |
368 self.runJavaScript( |
377 self.runJavaScript( |
369 "window.scrollTo(window.scrollX + {0}, window.scrollY + {1})" |
378 "window.scrollTo(window.scrollX + {0}, window.scrollY + {1})".format(x, y), |
370 .format(x, y), |
379 WebBrowserPage.SafeJsWorld, |
371 WebBrowserPage.SafeJsWorld |
380 ) |
372 ) |
381 |
373 |
|
374 def scrollTo(self, pos): |
382 def scrollTo(self, pos): |
375 """ |
383 """ |
376 Public method to scroll to the given position. |
384 Public method to scroll to the given position. |
377 |
385 |
378 @param pos position to scroll to |
386 @param pos position to scroll to |
379 @type QPointF |
387 @type QPointF |
380 """ |
388 """ |
381 self.runJavaScript( |
389 self.runJavaScript( |
382 "window.scrollTo({0}, {1});".format(pos.x(), pos.y()), |
390 "window.scrollTo({0}, {1});".format(pos.x(), pos.y()), |
383 WebBrowserPage.SafeJsWorld |
391 WebBrowserPage.SafeJsWorld, |
384 ) |
392 ) |
385 |
393 |
386 def mapToViewport(self, pos): |
394 def mapToViewport(self, pos): |
387 """ |
395 """ |
388 Public method to map a position to the viewport. |
396 Public method to map a position to the viewport. |
389 |
397 |
390 @param pos position to be mapped |
398 @param pos position to be mapped |
391 @type QPoint |
399 @type QPoint |
392 @return viewport position |
400 @return viewport position |
393 @rtype QPoint |
401 @rtype QPoint |
394 """ |
402 """ |
395 return QPoint(int(pos.x() // self.zoomFactor()), |
403 return QPoint( |
396 int(pos.y() // self.zoomFactor())) |
404 int(pos.x() // self.zoomFactor()), int(pos.y() // self.zoomFactor()) |
397 |
405 ) |
|
406 |
398 def hitTestContent(self, pos): |
407 def hitTestContent(self, pos): |
399 """ |
408 """ |
400 Public method to test the content at a specified position. |
409 Public method to test the content at a specified position. |
401 |
410 |
402 @param pos position to execute the test at |
411 @param pos position to execute the test at |
403 @type QPoint |
412 @type QPoint |
404 @return test result object |
413 @return test result object |
405 @rtype WebHitTestResult |
414 @rtype WebHitTestResult |
406 """ |
415 """ |
407 return WebHitTestResult(self, pos) |
416 return WebHitTestResult(self, pos) |
408 |
417 |
409 def __setupWebChannelForUrl(self, url): |
418 def __setupWebChannelForUrl(self, url): |
410 """ |
419 """ |
411 Private method to setup a web channel to our external object. |
420 Private method to setup a web channel to our external object. |
412 |
421 |
413 @param url URL for which to setup the web channel |
422 @param url URL for which to setup the web channel |
414 @type QUrl |
423 @type QUrl |
415 """ |
424 """ |
416 channel = self.webChannel() |
425 channel = self.webChannel() |
417 if channel is None: |
426 if channel is None: |
418 channel = QWebChannel(self) |
427 channel = QWebChannel(self) |
419 ExternalJsObject.setupWebChannel(channel, self) |
428 ExternalJsObject.setupWebChannel(channel, self) |
420 |
429 |
421 worldId = -1 |
430 worldId = -1 |
422 worldId = ( |
431 worldId = ( |
423 self.UnsafeJsWorld |
432 self.UnsafeJsWorld |
424 if url.scheme() in ("eric", "qthelp") else |
433 if url.scheme() in ("eric", "qthelp") |
425 self.SafeJsWorld |
434 else self.SafeJsWorld |
426 ) |
435 ) |
427 if worldId != self.__channelWorldId: |
436 if worldId != self.__channelWorldId: |
428 self.__channelWorldId = worldId |
437 self.__channelWorldId = worldId |
429 self.setWebChannel(channel, self.__channelWorldId) |
438 self.setWebChannel(channel, self.__channelWorldId) |
430 |
439 |
431 def certificateError(self, error): |
440 def certificateError(self, error): |
432 """ |
441 """ |
433 Public method to handle SSL certificate errors. |
442 Public method to handle SSL certificate errors. |
434 |
443 |
435 @param error object containing the certificate error information |
444 @param error object containing the certificate error information |
436 @type QWebEngineCertificateError |
445 @type QWebEngineCertificateError |
437 @return flag indicating to ignore this error |
446 @return flag indicating to ignore this error |
438 @rtype bool |
447 @rtype bool |
439 """ |
448 """ |
440 return WebBrowserWindow.networkManager().certificateError( |
449 return WebBrowserWindow.networkManager().certificateError(error, self.__view) |
441 error, self.__view) |
450 |
442 |
|
443 def __fullScreenRequested(self, request): |
451 def __fullScreenRequested(self, request): |
444 """ |
452 """ |
445 Private slot handling a full screen request. |
453 Private slot handling a full screen request. |
446 |
454 |
447 @param request reference to the full screen request |
455 @param request reference to the full screen request |
448 @type QWebEngineFullScreenRequest |
456 @type QWebEngineFullScreenRequest |
449 """ |
457 """ |
450 self.__view.requestFullScreen(request.toggleOn()) |
458 self.__view.requestFullScreen(request.toggleOn()) |
451 |
459 |
452 accepted = request.toggleOn() == self.__view.isFullScreen() |
460 accepted = request.toggleOn() == self.__view.isFullScreen() |
453 |
461 |
454 if accepted: |
462 if accepted: |
455 request.accept() |
463 request.accept() |
456 else: |
464 else: |
457 request.reject() |
465 request.reject() |
458 |
466 |
459 def execPrintPage(self, printer, timeout=1000): |
467 def execPrintPage(self, printer, timeout=1000): |
460 """ |
468 """ |
461 Public method to execute a synchronous print. |
469 Public method to execute a synchronous print. |
462 |
470 |
463 @param printer reference to the printer object |
471 @param printer reference to the printer object |
464 @type QPrinter |
472 @type QPrinter |
465 @param timeout timeout value in milliseconds |
473 @param timeout timeout value in milliseconds |
466 @type int |
474 @type int |
467 @return flag indicating a successful print job |
475 @return flag indicating a successful print job |
468 @rtype bool |
476 @rtype bool |
469 """ |
477 """ |
470 loop = QEventLoop() |
478 loop = QEventLoop() |
471 resultDict = {"res": None} |
479 resultDict = {"res": None} |
472 QTimer.singleShot(timeout, loop.quit) |
480 QTimer.singleShot(timeout, loop.quit) |
473 |
481 |
474 def printCallback(res, resDict=resultDict): |
482 def printCallback(res, resDict=resultDict): |
475 if loop and loop.isRunning(): |
483 if loop and loop.isRunning(): |
476 resDict["res"] = res |
484 resDict["res"] = res |
477 loop.quit() |
485 loop.quit() |
478 |
486 |
479 self.print(printer, printCallback) |
487 self.print(printer, printCallback) |
480 |
488 |
481 loop.exec() |
489 loop.exec() |
482 return resultDict["res"] |
490 return resultDict["res"] |
483 |
491 |
484 def __contentsSizeChanged(self, size): |
492 def __contentsSizeChanged(self, size): |
485 """ |
493 """ |
486 Private slot to work around QWebEnginePage not scrolling to anchors |
494 Private slot to work around QWebEnginePage not scrolling to anchors |
487 when opened in a background tab. |
495 when opened in a background tab. |
488 |
496 |
489 @param size changed contents size (unused) |
497 @param size changed contents size (unused) |
490 @type QSize |
498 @type QSize |
491 """ |
499 """ |
492 fragment = self.url().fragment() |
500 fragment = self.url().fragment() |
493 self.runJavaScript(Scripts.scrollToAnchor(fragment)) |
501 self.runJavaScript(Scripts.scrollToAnchor(fragment)) |
494 |
502 |
495 ############################################## |
503 ############################################## |
496 ## Methods below deal with JavaScript messages |
504 ## Methods below deal with JavaScript messages |
497 ############################################## |
505 ############################################## |
498 |
506 |
499 def javaScriptConsoleMessage(self, level, message, lineNumber, sourceId): |
507 def javaScriptConsoleMessage(self, level, message, lineNumber, sourceId): |
500 """ |
508 """ |
501 Public method to show a console message. |
509 Public method to show a console message. |
502 |
510 |
503 @param level severity |
511 @param level severity |
504 @type QWebEnginePage.JavaScriptConsoleMessageLevel |
512 @type QWebEnginePage.JavaScriptConsoleMessageLevel |
505 @param message message to be shown |
513 @param message message to be shown |
506 @type str |
514 @type str |
507 @param lineNumber line number of an error |
515 @param lineNumber line number of an error |
508 @type int |
516 @type int |
509 @param sourceId source URL causing the error |
517 @param sourceId source URL causing the error |
510 @type str |
518 @type str |
511 """ |
519 """ |
512 self.__view.mainWindow().javascriptConsole().javaScriptConsoleMessage( |
520 self.__view.mainWindow().javascriptConsole().javaScriptConsoleMessage( |
513 level, message, lineNumber, sourceId) |
521 level, message, lineNumber, sourceId |
514 |
522 ) |
|
523 |
515 ########################################################################### |
524 ########################################################################### |
516 ## Methods below implement safe browsing related functions |
525 ## Methods below implement safe browsing related functions |
517 ########################################################################### |
526 ########################################################################### |
518 |
527 |
519 def getSafeBrowsingStatus(self): |
528 def getSafeBrowsingStatus(self): |
520 """ |
529 """ |
521 Public method to get the safe browsing status of the current page. |
530 Public method to get the safe browsing status of the current page. |
522 |
531 |
523 @return flag indicating a safe site |
532 @return flag indicating a safe site |
524 @rtype bool |
533 @rtype bool |
525 """ |
534 """ |
526 return not self.__badSite |
535 return not self.__badSite |
527 |
536 |
528 ############################################################# |
537 ############################################################# |
529 ## Methods below implement protocol handler related functions |
538 ## Methods below implement protocol handler related functions |
530 ############################################################# |
539 ############################################################# |
531 |
540 |
532 @pyqtSlot("QWebEngineRegisterProtocolHandlerRequest") |
541 @pyqtSlot("QWebEngineRegisterProtocolHandlerRequest") |
533 def __registerProtocolHandlerRequested(self, request): |
542 def __registerProtocolHandlerRequested(self, request): |
534 """ |
543 """ |
535 Private slot to handle the registration of a custom protocol |
544 Private slot to handle the registration of a custom protocol |
536 handler. |
545 handler. |
537 |
546 |
538 @param request reference to the registration request |
547 @param request reference to the registration request |
539 @type QWebEngineRegisterProtocolHandlerRequest |
548 @type QWebEngineRegisterProtocolHandlerRequest |
540 """ |
549 """ |
541 from PyQt6.QtWebEngineCore import ( |
550 from PyQt6.QtWebEngineCore import QWebEngineRegisterProtocolHandlerRequest |
542 QWebEngineRegisterProtocolHandlerRequest |
551 |
543 ) |
|
544 |
|
545 if self.__registerProtocolHandlerRequest: |
552 if self.__registerProtocolHandlerRequest: |
546 del self.__registerProtocolHandlerRequest |
553 del self.__registerProtocolHandlerRequest |
547 self.__registerProtocolHandlerRequest = None |
554 self.__registerProtocolHandlerRequest = None |
548 self.__registerProtocolHandlerRequest = ( |
555 self.__registerProtocolHandlerRequest = ( |
549 QWebEngineRegisterProtocolHandlerRequest(request) |
556 QWebEngineRegisterProtocolHandlerRequest(request) |
550 ) |
557 ) |
551 |
558 |
552 def registerProtocolHandlerRequestUrl(self): |
559 def registerProtocolHandlerRequestUrl(self): |
553 """ |
560 """ |
554 Public method to get the registered protocol handler request URL. |
561 Public method to get the registered protocol handler request URL. |
555 |
562 |
556 @return registered protocol handler request URL |
563 @return registered protocol handler request URL |
557 @rtype QUrl |
564 @rtype QUrl |
558 """ |
565 """ |
559 if ( |
566 if self.__registerProtocolHandlerRequest and ( |
560 self.__registerProtocolHandlerRequest and |
567 self.url().host() == self.__registerProtocolHandlerRequest.origin().host() |
561 (self.url().host() == |
|
562 self.__registerProtocolHandlerRequest.origin().host()) |
|
563 ): |
568 ): |
564 return self.__registerProtocolHandlerRequest.origin() |
569 return self.__registerProtocolHandlerRequest.origin() |
565 else: |
570 else: |
566 return QUrl() |
571 return QUrl() |
567 |
572 |
568 def registerProtocolHandlerRequestScheme(self): |
573 def registerProtocolHandlerRequestScheme(self): |
569 """ |
574 """ |
570 Public method to get the registered protocol handler request scheme. |
575 Public method to get the registered protocol handler request scheme. |
571 |
576 |
572 @return registered protocol handler request scheme |
577 @return registered protocol handler request scheme |
573 @rtype str |
578 @rtype str |
574 """ |
579 """ |
575 if ( |
580 if self.__registerProtocolHandlerRequest and ( |
576 self.__registerProtocolHandlerRequest and |
581 self.url().host() == self.__registerProtocolHandlerRequest.origin().host() |
577 (self.url().host() == |
|
578 self.__registerProtocolHandlerRequest.origin().host()) |
|
579 ): |
582 ): |
580 return self.__registerProtocolHandlerRequest.scheme() |
583 return self.__registerProtocolHandlerRequest.scheme() |
581 else: |
584 else: |
582 return "" |
585 return "" |
583 |
586 |
584 ############################################################# |
587 ############################################################# |
585 ## SSL configuration handling below |
588 ## SSL configuration handling below |
586 ############################################################# |
589 ############################################################# |
587 |
590 |
588 def setSslConfiguration(self, sslConfiguration): |
591 def setSslConfiguration(self, sslConfiguration): |
589 """ |
592 """ |
590 Public slot to set the SSL configuration data of the page. |
593 Public slot to set the SSL configuration data of the page. |
591 |
594 |
592 @param sslConfiguration SSL configuration to be set |
595 @param sslConfiguration SSL configuration to be set |
593 @type QSslConfiguration |
596 @type QSslConfiguration |
594 """ |
597 """ |
595 self.__sslConfiguration = QSslConfiguration(sslConfiguration) |
598 self.__sslConfiguration = QSslConfiguration(sslConfiguration) |
596 self.__sslConfiguration.url = self.url() |
599 self.__sslConfiguration.url = self.url() |
597 self.sslConfigurationChanged.emit() |
600 self.sslConfigurationChanged.emit() |
598 |
601 |
599 def getSslConfiguration(self): |
602 def getSslConfiguration(self): |
600 """ |
603 """ |
601 Public method to return a reference to the current SSL configuration. |
604 Public method to return a reference to the current SSL configuration. |
602 |
605 |
603 @return reference to the SSL configuration in use |
606 @return reference to the SSL configuration in use |
604 @rtype QSslConfiguration |
607 @rtype QSslConfiguration |
605 """ |
608 """ |
606 return self.__sslConfiguration |
609 return self.__sslConfiguration |
607 |
610 |
608 def clearSslConfiguration(self): |
611 def clearSslConfiguration(self): |
609 """ |
612 """ |
610 Public slot to clear the stored SSL configuration data. |
613 Public slot to clear the stored SSL configuration data. |
611 """ |
614 """ |
612 self.__sslConfiguration = None |
615 self.__sslConfiguration = None |
613 self.sslConfigurationChanged.emit() |
616 self.sslConfigurationChanged.emit() |
614 |
617 |
615 def getSslCertificate(self): |
618 def getSslCertificate(self): |
616 """ |
619 """ |
617 Public method to get a reference to the SSL certificate. |
620 Public method to get a reference to the SSL certificate. |
618 |
621 |
619 @return amended SSL certificate |
622 @return amended SSL certificate |
620 @rtype QSslCertificate |
623 @rtype QSslCertificate |
621 """ |
624 """ |
622 if self.__sslConfiguration is None: |
625 if self.__sslConfiguration is None: |
623 return None |
626 return None |
624 |
627 |
625 sslCertificate = self.__sslConfiguration.peerCertificate() |
628 sslCertificate = self.__sslConfiguration.peerCertificate() |
626 sslCertificate.url = QUrl(self.__sslConfiguration.url) |
629 sslCertificate.url = QUrl(self.__sslConfiguration.url) |
627 return sslCertificate |
630 return sslCertificate |
628 |
631 |
629 def getSslCertificateChain(self): |
632 def getSslCertificateChain(self): |
630 """ |
633 """ |
631 Public method to get a reference to the SSL certificate chain. |
634 Public method to get a reference to the SSL certificate chain. |
632 |
635 |
633 @return SSL certificate chain |
636 @return SSL certificate chain |
634 @rtype list of QSslCertificate |
637 @rtype list of QSslCertificate |
635 """ |
638 """ |
636 if self.__sslConfiguration is None: |
639 if self.__sslConfiguration is None: |
637 return [] |
640 return [] |
638 |
641 |
639 chain = self.__sslConfiguration.peerCertificateChain() |
642 chain = self.__sslConfiguration.peerCertificateChain() |
640 return chain |
643 return chain |
641 |
644 |
642 def showSslInfo(self, pos): |
645 def showSslInfo(self, pos): |
643 """ |
646 """ |
644 Public slot to show some SSL information for the loaded page. |
647 Public slot to show some SSL information for the loaded page. |
645 |
648 |
646 @param pos position to show the info at |
649 @param pos position to show the info at |
647 @type QPoint |
650 @type QPoint |
648 """ |
651 """ |
649 if SSL_AVAILABLE and self.__sslConfiguration is not None: |
652 if SSL_AVAILABLE and self.__sslConfiguration is not None: |
650 from EricNetwork.EricSslInfoWidget import EricSslInfoWidget |
653 from EricNetwork.EricSslInfoWidget import EricSslInfoWidget |
651 widget = EricSslInfoWidget(self.url(), self.__sslConfiguration, |
654 |
652 self.__view) |
655 widget = EricSslInfoWidget(self.url(), self.__sslConfiguration, self.__view) |
653 widget.showAt(pos) |
656 widget.showAt(pos) |
654 else: |
657 else: |
655 EricMessageBox.warning( |
658 EricMessageBox.warning( |
656 self.__view, |
659 self.__view, |
657 self.tr("SSL Info"), |
660 self.tr("SSL Info"), |
658 self.tr("""This site does not contain SSL information.""")) |
661 self.tr("""This site does not contain SSL information."""), |
659 |
662 ) |
|
663 |
660 def hasValidSslInfo(self): |
664 def hasValidSslInfo(self): |
661 """ |
665 """ |
662 Public method to check, if the page has a valid SSL certificate. |
666 Public method to check, if the page has a valid SSL certificate. |
663 |
667 |
664 @return flag indicating a valid SSL certificate |
668 @return flag indicating a valid SSL certificate |
665 @rtype bool |
669 @rtype bool |
666 """ |
670 """ |
667 if self.__sslConfiguration is None: |
671 if self.__sslConfiguration is None: |
668 return False |
672 return False |
669 |
673 |
670 certList = self.__sslConfiguration.peerCertificateChain() |
674 certList = self.__sslConfiguration.peerCertificateChain() |
671 if not certList: |
675 if not certList: |
672 return False |
676 return False |
673 |
677 |
674 certificateDict = Globals.toDict( |
678 certificateDict = Globals.toDict( |
675 Preferences.getSettings().value("Ssl/CaCertificatesDict")) |
679 Preferences.getSettings().value("Ssl/CaCertificatesDict") |
|
680 ) |
676 for server in certificateDict: |
681 for server in certificateDict: |
677 localCAList = QSslCertificate.fromData(certificateDict[server]) |
682 localCAList = QSslCertificate.fromData(certificateDict[server]) |
678 if any(cert in localCAList for cert in certList): |
683 if any(cert in localCAList for cert in certList): |
679 return True |
684 return True |
680 |
685 |
681 return all(not cert.isBlacklisted() for cert in certList) |
686 return all(not cert.isBlacklisted() for cert in certList) |