1 /**************************************************************************
2 * Otter Browser: Web browser controlled by the user, not vice-versa.
3 * Copyright (C) 2013 - 2018 Michal Dutkiewicz aka Emdek <michal@emdek.pl>
4 * Copyright (C) 2015 Piotr Wójcik <chocimier@tlen.pl>
5 * Copyright (C) 2015 Jan Bajer aka bajasoft <jbajer@gmail.com>
6 * Copyright (C) 2017 Piktas Zuikis <piktas.zuikis@inbox.lt>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 **************************************************************************/
22 
23 #ifndef OTTER_WEBWIDGET_H
24 #define OTTER_WEBWIDGET_H
25 
26 #include "../core/ActionExecutor.h"
27 #include "../core/NetworkManager.h"
28 #include "../core/PasswordsManager.h"
29 #include "../core/SessionsManager.h"
30 #include "../core/SpellCheckManager.h"
31 
32 #include <QtGui/QHelpEvent>
33 #include <QtNetwork/QSslCertificate>
34 #include <QtNetwork/QSslCipher>
35 #include <QtNetwork/QSslError>
36 #include <QtPrintSupport/QPrinter>
37 #include <QtWidgets/QWidget>
38 
39 namespace Otter
40 {
41 
42 class ContentsDialog;
43 class ContentsWidget;
44 class Transfer;
45 class WebBackend;
46 
47 class WebWidget : public QWidget, public ActionExecutor
48 {
49 	Q_OBJECT
50 
51 public:
52 	enum ChangeWatcher
53 	{
54 		UnknownWatcher = 0,
55 		FeedsWatcher,
56 		LinksWatcher,
57 		MetaDataWatcher,
58 		SearchEnginesWatcher,
59 		StylesheetsWatcher
60 	};
61 
62 	enum ContentState
63 	{
64 		UnknownContentState = 0,
65 		ApplicationContentState = 1,
66 		LocalContentState = 2,
67 		RemoteContentState = 4,
68 		SecureContentState = 8,
69 		TrustedContentState = 16,
70 		MixedContentState = 32,
71 		FraudContentState = 64
72 	};
73 
74 	Q_DECLARE_FLAGS(ContentStates, ContentState)
75 
76 	enum LoadingState
77 	{
78 		DeferredLoadingState = 0,
79 		OngoingLoadingState,
80 		FinishedLoadingState,
81 		CrashedLoadingState
82 	};
83 
84 	enum FeaturePermission
85 	{
86 		UnknownFeature = 0,
87 		FullScreenFeature,
88 		GeolocationFeature,
89 		NotificationsFeature,
90 		PointerLockFeature,
91 		CaptureAudioFeature,
92 		CaptureVideoFeature,
93 		CaptureAudioVideoFeature,
94 		PlaybackAudioFeature
95 	};
96 
97 	enum PermissionPolicy
98 	{
99 		DeniedPermission = 0,
100 		GrantedPermission,
101 		KeepAskingPermission
102 	};
103 
104 	Q_DECLARE_FLAGS(PermissionPolicies, PermissionPolicy)
105 
106 	enum FindFlag
107 	{
108 		NoFlagsFind = 0,
109 		BackwardFind = 1,
110 		CaseSensitiveFind = 2,
111 		ExactMatchFind = 4,
112 		HighlightAllFind = 8
113 	};
114 
115 	Q_DECLARE_FLAGS(FindFlags, FindFlag)
116 
117 	enum SaveFormat
118 	{
119 		UnknownSaveFormat = 0,
120 		CompletePageSaveFormat,
121 		MhtmlSaveFormat,
122 		PdfSaveFormat,
123 		SingleFileSaveFormat
124 	};
125 
126 	enum PageInformation
127 	{
128 		UnknownInformation = 0,
129 		DocumentBytesReceivedInformation,
130 		DocumentBytesTotalInformation,
131 		DocumentLoadingProgressInformation,
132 		DocumentMimeTypeInformation,
133 		TotalBytesReceivedInformation,
134 		TotalBytesTotalInformation,
135 		TotalLoadingProgressInformation,
136 		RequestsBlockedInformation,
137 		RequestsFinishedInformation,
138 		RequestsStartedInformation,
139 		LoadingSpeedInformation,
140 		LoadingFinishedInformation,
141 		LoadingTimeInformation,
142 		LoadingMessageInformation
143 	};
144 
145 	struct HitTestResult
146 	{
147 		enum HitTestFlag
148 		{
149 			NoTest = 0,
150 			IsContentEditableTest = 1,
151 			IsEmptyTest = 2,
152 			IsFormTest = 4,
153 			IsLinkFromSelectionTest = 8,
154 			IsSelectedTest = 16,
155 			IsSpellCheckEnabled = 32,
156 			MediaHasControlsTest = 64,
157 			MediaIsLoopedTest = 128,
158 			MediaIsMutedTest = 256,
159 			MediaIsPausedTest = 512
160 		};
161 
162 		Q_DECLARE_FLAGS(HitTestFlags, HitTestFlag)
163 
164 		QString title;
165 		QString tagName;
166 		QString alternateText;
167 		QString longDescription;
168 		QUrl formUrl;
169 		QUrl frameUrl;
170 		QUrl imageUrl;
171 		QUrl linkUrl;
172 		QUrl mediaUrl;
173 		QPoint hitPosition;
174 		QRect elementGeometry;
175 		qreal playbackRate = 1;
176 		HitTestFlags flags = NoTest;
177 	};
178 
179 	struct LinkUrl final
180 	{
181 		QString title;
182 		QString mimeType;
183 		QUrl url;
184 	};
185 
186 	struct SslInformation final
187 	{
188 		struct SslError final
189 		{
190 			QSslError error;
191 			QUrl url;
192 		};
193 
194 		QSslCipher cipher;
195 		QVector<QSslCertificate> certificates;
196 		QVector<SslError> errors;
197 	};
198 
199 	virtual void search(const QString &query, const QString &searchEngine);
200 	virtual void print(QPrinter *printer) = 0;
201 	void startWatchingChanges(QObject *object, ChangeWatcher watcher);
202 	void stopWatchingChanges(QObject *object, ChangeWatcher watcher);
203 	void showDialog(ContentsDialog *dialog, bool lockEventLoop = true);
204 	void setParent(QWidget *parent);
205 	virtual void setOptions(const QHash<int, QVariant> &options, const QStringList &excludedOptions = {});
206 	void setWindowIdentifier(quint64 identifier);
207 	virtual WebWidget* clone(bool cloneHistory = true, bool isPrivate = false, const QStringList &excludedOptions = {}) const = 0;
208 	virtual QWidget* getInspector();
209 	virtual QWidget* getViewport();
210 	WebBackend* getBackend() const;
211 	virtual QString getTitle() const = 0;
212 	virtual QString getDescription() const;
213 	virtual QString getActiveStyleSheet() const;
214 	virtual QString getCharacterEncoding() const;
215 	virtual QString getSelectedText() const;
216 	QString getStatusMessage() const;
217 	QVariant getOption(int identifier, const QUrl &url = {}) const;
218 	virtual QVariant getPageInformation(PageInformation key) const;
219 	virtual QUrl getUrl() const = 0;
220 	QUrl getRequestedUrl() const;
221 	virtual QIcon getIcon() const = 0;
222 	virtual QPixmap createThumbnail(const QSize &size = {});
223 	QPoint getClickPosition() const;
224 	virtual QPoint getScrollPosition() const = 0;
225 	virtual QRect getGeometry(bool excludeScrollBars = false) const;
226 	ActionsManager::ActionDefinition::State getActionState(int identifier, const QVariantMap &parameters = {}) const override;
227 	virtual LinkUrl getActiveFrame() const;
228 	virtual LinkUrl getActiveImage() const;
229 	virtual LinkUrl getActiveLink() const;
230 	virtual LinkUrl getActiveMedia() const;
231 	virtual SslInformation getSslInformation() const;
232 	virtual WindowHistoryInformation getHistory() const = 0;
233 	virtual HitTestResult getHitTestResult(const QPoint &position);
234 	virtual QStringList getStyleSheets() const;
235 	virtual QVector<SpellCheckManager::DictionaryInformation> getDictionaries() const;
236 	virtual QVector<LinkUrl> getFeeds() const;
237 	virtual QVector<LinkUrl> getLinks() const;
238 	virtual QVector<LinkUrl> getSearchEngines() const;
239 	virtual QVector<NetworkManager::ResourceInformation> getBlockedRequests() const;
240 	QHash<int, QVariant> getOptions() const;
241 	virtual QMap<QByteArray, QByteArray> getHeaders() const;
242 	virtual QMultiMap<QString, QString> getMetaData() const;
243 	virtual WebWidget::ContentStates getContentState() const;
244 	virtual WebWidget::LoadingState getLoadingState() const = 0;
245 	quint64 getWindowIdentifier() const;
246 	virtual int getZoom() const = 0;
247 	virtual int findInPage(const QString &text, FindFlags flags = NoFlagsFind) = 0;
248 	bool hasOption(int identifier) const;
249 	virtual bool hasSelection() const;
250 	virtual bool hasWatchedChanges(ChangeWatcher watcher) const;
251 	virtual bool isAudible() const;
252 	virtual bool isAudioMuted() const;
253 	virtual bool isFullScreen() const;
254 	virtual bool isPrivate() const = 0;
255 	bool isWatchingChanges(ChangeWatcher watcher) const;
256 
257 public slots:
258 	virtual void triggerAction(int identifier, const QVariantMap &parameters = {}, ActionsManager::TriggerType trigger = ActionsManager::UnknownTrigger) override;
259 	virtual void clearOptions();
260 	virtual void fillPassword(const PasswordsManager::PasswordInformation &password);
261 	virtual void showContextMenu(const QPoint &position = {});
262 	virtual void setActiveStyleSheet(const QString &styleSheet);
263 	virtual void setPermission(FeaturePermission feature, const QUrl &url, PermissionPolicies policies);
264 	virtual void setOption(int identifier, const QVariant &value);
265 	virtual void setScrollPosition(const QPoint &position) = 0;
266 	virtual void setHistory(const WindowHistoryInformation &history) = 0;
267 	virtual void setZoom(int zoom) = 0;
268 	virtual void setUrl(const QUrl &url, bool isTyped = true) = 0;
269 	void setRequestedUrl(const QUrl &url, bool isTyped = true, bool onlyUpdate = false);
270 
271 protected:
272 	explicit WebWidget(const QVariantMap &parameters, WebBackend *backend, ContentsWidget *parent = nullptr);
273 
274 	void timerEvent(QTimerEvent *event) override;
275 	void openUrl(const QUrl &url, SessionsManager::OpenHints hints);
276 	void startReloadTimer();
277 	void startTransfer(Transfer *transfer);
278 	void handleToolTipEvent(QHelpEvent *event, QWidget *widget);
279 	void updateHitTestResult(const QPoint &position);
280 	virtual void updateWatchedData(ChangeWatcher watcher);
281 	void setClickPosition(const QPoint &position);
282 	QString suggestSaveFileName(const QString &extension) const;
283 	QString suggestSaveFileName(SaveFormat format) const;
284 	QString getSavePath(const QVector<SaveFormat> &allowedFormats, SaveFormat *selectedFormat) const;
285 	QString getOpenActionText(SessionsManager::OpenHints hints) const;
286 	static QString getFastForwardScript(bool isSelectingTheBestLink);
287 	HitTestResult getCurrentHitTestResult() const;
288 	PermissionPolicy getPermission(FeaturePermission feature, const QUrl &url) const;
289 	virtual int getAmountOfDeferredPlugins() const;
290 	virtual bool canGoBack() const;
291 	virtual bool canGoForward() const;
292 	virtual bool canFastForward() const;
293 	virtual bool canInspect() const;
294 	virtual bool canTakeScreenshot() const;
295 	virtual bool canRedo() const;
296 	virtual bool canUndo() const;
297 	virtual bool canShowContextMenu(const QPoint &position) const;
298 	virtual bool canViewSource() const;
299 	virtual bool isInspecting() const;
300 	virtual bool isPopup() const;
301 	virtual bool isScrollBar(const QPoint &position) const;
302 
303 protected slots:
304 	void handleLoadingStateChange(WebWidget::LoadingState state);
305 	void handleWindowCloseRequest();
306 	void notifyRedoActionStateChanged();
307 	void notifyUndoActionStateChanged();
308 	void setStatusMessage(const QString &message);
309 	void setStatusMessageOverride(const QString &message);
310 
311 private:
312 	ContentsWidget *m_parent;
313 	WebBackend *m_backend;
314 	QUrl m_requestedUrl;
315 	QString m_statusMessage;
316 	QString m_statusMessageOverride;
317 	QPoint m_clickPosition;
318 	QHash<int, QVariant> m_options;
319 	QHash<ChangeWatcher, QVector<QObject*> > m_changeWatchers;
320 	HitTestResult m_hitResult;
321 	quint64 m_windowIdentifier;
322 	int m_loadingTime;
323 	int m_loadingTimer;
324 	int m_reloadTimer;
325 
326 	static QString m_fastForwardScript;
327 
328 signals:
329 	void aboutToNavigate();
330 	void aboutToReload();
331 	void needsAttention();
332 	void requestedCloseWindow();
333 	void requestedNewWindow(WebWidget *widget, SessionsManager::OpenHints hints, const QVariantMap &parameters);
334 	void requestedPopupWindow(const QUrl &parentUrl, const QUrl &popupUrl);
335 	void requestedPermission(WebWidget::FeaturePermission feature, const QUrl &url, bool isCancellation);
336 	void requestedSavePassword(const PasswordsManager::PasswordInformation &password, bool isUpdate);
337 	void requestedGeometryChange(const QRect &geometry);
338 	void requestedInspectorVisibilityChange(bool isVisible);
339 	void geometryChanged();
340 	void statusMessageChanged(const QString &message);
341 	void titleChanged(const QString &title);
342 	void urlChanged(const QUrl &url);
343 	void iconChanged(const QIcon &icon);
344 	void requestBlocked(const NetworkManager::ResourceInformation &request);
345 	void arbitraryActionsStateChanged(const QVector<int> &identifiers);
346 	void categorizedActionsStateChanged(const QVector<int> &categories);
347 	void contentStateChanged(WebWidget::ContentStates state);
348 	void loadingStateChanged(WebWidget::LoadingState state);
349 	void pageInformationChanged(WebWidget::PageInformation, const QVariant &value);
350 	void optionChanged(int identifier, const QVariant &value);
351 	void watchedDataChanged(ChangeWatcher watcher);
352 	void zoomChanged(int zoom);
353 	void isAudibleChanged(bool isAudible);
354 	void isFullScreenChanged(bool isFullScreen);
355 };
356 
357 }
358 
359 Q_DECLARE_OPERATORS_FOR_FLAGS(Otter::WebWidget::ContentStates)
360 Q_DECLARE_OPERATORS_FOR_FLAGS(Otter::WebWidget::PermissionPolicies)
361 
362 #endif
363