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