1 /* 2 * DesktopWebPage.hpp 3 * 4 * Copyright (C) 2021 by RStudio, PBC 5 * 6 * Unless you have received this program directly from RStudio pursuant 7 * to the terms of a commercial license agreement with RStudio, then 8 * this program is licensed to you under the terms of version 3 of the 9 * GNU Affero General Public License. This program is distributed WITHOUT 10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. 13 * 14 */ 15 16 #ifndef DESKTOP_WEB_PAGE_HPP 17 #define DESKTOP_WEB_PAGE_HPP 18 19 #include <queue> 20 21 #include <QtGui> 22 #include <QWebEnginePage> 23 #include <QWebEngineUrlRequestInfo> 24 25 #include "DesktopWebProfile.hpp" 26 #include "DesktopUtils.hpp" 27 28 namespace rstudio { 29 namespace desktop { 30 31 class MainWindow; 32 33 struct PendingWindow 34 { PendingWindowrstudio::desktop::PendingWindow35 PendingWindow() 36 : name(), pMainWindow(nullptr), x(-1), y(-1), width(-1), height(-1), 37 isSatellite(false), allowExternalNavigate(false), showToolbar(false) 38 { 39 } 40 41 PendingWindow(QString name, 42 MainWindow* pMainWindow, 43 int screenX, 44 int screenY, 45 int width, 46 int height); 47 PendingWindowrstudio::desktop::PendingWindow48 PendingWindow(QString name, bool allowExternalNavigation, 49 bool showDesktopToolbar) 50 : name(name), pMainWindow(nullptr), isSatellite(false), 51 allowExternalNavigate(allowExternalNavigation), 52 showToolbar(showDesktopToolbar) 53 { 54 } 55 isEmptyrstudio::desktop::PendingWindow56 bool isEmpty() const { return name.isEmpty(); } 57 58 QString name; 59 60 MainWindow* pMainWindow; 61 62 int x = 0; 63 int y = 0; 64 int width = 0; 65 int height = 0; 66 bool isSatellite; 67 bool allowExternalNavigate; 68 bool showToolbar; 69 }; 70 71 72 class WebPage : public QWebEnginePage 73 { 74 Q_OBJECT 75 76 public: 77 explicit WebPage(QUrl baseUrl = QUrl(), 78 QWidget *parent = nullptr, 79 bool allowExternalNavigate = false); 80 81 explicit WebPage(QWebEngineProfile *profile, 82 QUrl baseUrl = QUrl(), 83 QWidget *parent = nullptr, 84 bool allowExternalNavigate = false); 85 86 void setBaseUrl(const QUrl& baseUrl); 87 void setTutorialUrl(const QString& tutorialUrl); 88 void setViewerUrl(const QString& viewerUrl); 89 void setShinyDialogUrl(const QString& shinyDialogUrl); 90 void prepareExternalNavigate(const QString& externalUrl); 91 92 void activateWindow(QString name); 93 void prepareForWindow(const PendingWindow& pendingWnd); 94 void closeWindow(QString name); 95 96 void triggerAction(QWebEnginePage::WebAction action, bool checked = false) override; 97 profile()98 inline WebProfile* profile() { return static_cast<WebProfile*>(QWebEnginePage::profile()); } 99 100 public Q_SLOTS: 101 bool shouldInterruptJavaScript(); 102 void closeRequested(); 103 void onUrlIntercepted(const QUrl& url, int type); 104 105 protected: 106 QWebEnginePage* createWindow(QWebEnginePage::WebWindowType type) override; 107 void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, 108 int lineNumber, const QString& sourceID) override; 109 QString userAgentForUrl(const QUrl &url) const; 110 bool acceptNavigationRequest(const QUrl &url, NavigationType, bool isMainFrame) override; 111 112 QString tutorialUrl(); 113 QString viewerUrl(); 114 115 private: 116 void init(); 117 void handleBase64Download(QUrl url); 118 119 private: 120 QUrl baseUrl_; 121 QString tutorialUrl_; 122 QString viewerUrl_; 123 QString shinyDialogUrl_; 124 bool allowExternalNav_; 125 std::queue<PendingWindow> pendingWindows_; 126 QDir defaultSaveDir_; 127 }; 128 129 } // namespace desktop 130 } // namespace rstudio 131 132 #endif // DESKTOP_WEB_PAGE_HPP 133