diff --git a/src/lib/plugins/qml/api/tabs/qmltab.cpp b/src/lib/plugins/qml/api/tabs/qmltab.cpp index 5f50a630a..677f517d1 100644 --- a/src/lib/plugins/qml/api/tabs/qmltab.cpp +++ b/src/lib/plugins/qml/api/tabs/qmltab.cpp @@ -18,6 +18,7 @@ #include "qmltab.h" #include "loadrequest.h" #include "tabbedwebview.h" +#include "webpage.h" #include #include @@ -26,35 +27,15 @@ Q_GLOBAL_STATIC(QmlWindowData, windowData) QmlTab::QmlTab(WebTab *webTab, QObject *parent) : QObject(parent) , m_webTab(webTab) + , m_webPage(nullptr) { QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); - connect(m_webTab, &WebTab::titleChanged, this, [this](const QString &title){ - emit titleChanged(title); - }); + if (!m_webTab) { + return; + } - connect(m_webTab, &WebTab::pinnedChanged, this, [this](bool pinned){ - emit pinnedChanged(pinned); - }); - - connect(m_webTab, &WebTab::loadingChanged, this, [this](bool loading){ - emit loadingChanged(loading); - }); - - connect(m_webTab, &WebTab::mutedChanged, this, [this](bool muted){ - emit mutedChanged(muted); - }); - - connect(m_webTab, &WebTab::restoredChanged, this, [this](bool restored){ - emit restoredChanged(restored); - }); - - connect(m_webTab, &WebTab::playingChanged, this, [this](bool playing){ - emit playingChanged(playing); - }); - - connect(m_webTab->webView(), &TabbedWebView::zoomLevelChanged, this, &QmlTab::zoomLevelChanged); - connect(m_webTab->webView(), &TabbedWebView::backgroundActivityChanged, this, &QmlTab::backgroundActivityChanged); + createConnections(); } /** @@ -277,6 +258,41 @@ void QmlTab::sendPageByMail() m_webTab->webView()->sendPageByMail(); } +/** + * @brief execute JavaScript function in a page + * @param value, representing JavaScript function + * @return QVariant, the return value of executed javascript + */ +QVariant QmlTab::execJavaScript(const QJSValue &value) +{ + if (!m_webPage && !m_webTab) { + return QVariant(); + } + WebPage *webPage = m_webPage; + if (!m_webPage) { + webPage = m_webTab->webView()->page(); + } + return webPage->execJavaScript(value.toString()); +} + +/** + * @brief Gets result of web hit test at a given point + * @param point + * @return result of web hit test + */ +QmlWebHitTestResult *QmlTab::hitTestContent(const QPoint &point) +{ + if (!m_webPage && !m_webTab) { + return nullptr; + } + WebPage *webPage = m_webPage; + if (!m_webPage) { + webPage = m_webTab->webView()->page(); + } + WebHitTestResult result = webPage->hitTestContent(point); + return new QmlWebHitTestResult(result); +} + QString QmlTab::url() const { if (!m_webTab) { @@ -413,6 +429,50 @@ bool QmlTab::canGoForward() const return m_webTab->webView()->history()->canGoForward(); } +void QmlTab::setWebPage(WebPage *webPage) +{ + m_webPage = webPage; + TabbedWebView *tabbedWebView = qobject_cast(m_webPage->view()); + m_webTab = tabbedWebView->webTab(); + if (m_webTab) { + createConnections(); + } +} + +void QmlTab::createConnections() +{ + connect(m_webTab, &WebTab::titleChanged, this, [this](const QString &title){ + emit titleChanged(title); + }); + + connect(m_webTab, &WebTab::pinnedChanged, this, [this](bool pinned){ + emit pinnedChanged(pinned); + }); + + connect(m_webTab, &WebTab::loadingChanged, this, [this](bool loading){ + emit loadingChanged(loading); + }); + + connect(m_webTab, &WebTab::mutedChanged, this, [this](bool muted){ + emit mutedChanged(muted); + }); + + connect(m_webTab, &WebTab::restoredChanged, this, [this](bool restored){ + emit restoredChanged(restored); + }); + + connect(m_webTab, &WebTab::playingChanged, this, [this](bool playing){ + emit playingChanged(playing); + }); + + connect(m_webTab->webView(), &TabbedWebView::zoomLevelChanged, this, &QmlTab::zoomLevelChanged); + connect(m_webTab->webView(), &TabbedWebView::backgroundActivityChanged, this, &QmlTab::backgroundActivityChanged); + + if (m_webPage) { + connect(m_webPage, &WebPage::navigationRequestAccepted, this, &QmlTab::navigationRequestAccepted); + } +} + QmlTabData::QmlTabData() { } diff --git a/src/lib/plugins/qml/api/tabs/qmltab.h b/src/lib/plugins/qml/api/tabs/qmltab.h index c9045b1a0..47401819e 100644 --- a/src/lib/plugins/qml/api/tabs/qmltab.h +++ b/src/lib/plugins/qml/api/tabs/qmltab.h @@ -20,6 +20,9 @@ #include #include "webtab.h" #include "../windows/qmlwindow.h" +#include +#include "qml/api/menus/qmlwebhittestresult.h" +#include /** * @brief The class exposing a browser tab to QML @@ -148,6 +151,10 @@ public: Q_INVOKABLE void printPage(); Q_INVOKABLE void showSource(); Q_INVOKABLE void sendPageByMail(); + Q_INVOKABLE QVariant execJavaScript(const QJSValue &value); + Q_INVOKABLE QmlWebHitTestResult *hitTestContent(const QPoint &point); + + void setWebPage(WebPage *webPage); Q_SIGNALS: /** @@ -197,8 +204,18 @@ Q_SIGNALS: * @param Bool representing if there is background activity attached to the tab */ void backgroundActivityChanged(int backgroundActivityChanged); + + /** + * @brief The signal emitted when navigation request is accepted + * @param url, representing requested url + * @param type of navigation + * @param isMainFrame, represents if navigation is requested for a top level page. + */ + void navigationRequestAccepted(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame); + private: WebTab *m_webTab; + WebPage *m_webPage; QString url() const; QString title() const; @@ -215,6 +232,8 @@ private: bool backgroundActivity() const; bool canGoBack() const; bool canGoForward() const; + + void createConnections(); }; class QmlTabData diff --git a/src/lib/plugins/qml/qmlplugininterface.cpp b/src/lib/plugins/qml/qmlplugininterface.cpp index caae0fd6a..cf4bef857 100644 --- a/src/lib/plugins/qml/qmlplugininterface.cpp +++ b/src/lib/plugins/qml/qmlplugininterface.cpp @@ -28,6 +28,8 @@ #include "api/events/qmlmouseevent.h" #include "api/events/qmlwheelevent.h" #include "api/events/qmlkeyevent.h" +#include "api/tabs/qmltab.h" +#include "webpage.h" #include #include #include @@ -245,6 +247,21 @@ bool QmlPluginInterface::keyRelease(Qz::ObjectName type, QObject *obj, QKeyEvent return false; } +bool QmlPluginInterface::acceptNavigationRequest(WebPage *page, const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) +{ + if (!m_acceptNavigationRequest.isCallable()) { + return true; + } + QmlTab *qmlTab = new QmlTab(); + qmlTab->setWebPage(page); + QJSValueList args; + args.append(m_engine->newQObject(qmlTab)); + args.append(QString::fromUtf8(url.toEncoded())); + args.append(type); + args.append(isMainFrame); + return m_acceptNavigationRequest.call(args).toBool(); +} + QJSValue QmlPluginInterface::readInit() const { return m_init; @@ -402,6 +419,16 @@ void QmlPluginInterface::setKeyRelease(const QJSValue &keyRelease) mApp->plugins()->registerAppEventHandler(PluginProxy::KeyReleaseHandler, this); } +QJSValue QmlPluginInterface::readAcceptNavigationRequest() const +{ + return m_acceptNavigationRequest; +} + +void QmlPluginInterface::setAcceptNavigationRequest(const QJSValue &acceptNavigationRequest) +{ + m_acceptNavigationRequest = acceptNavigationRequest; +} + QQmlListProperty QmlPluginInterface::childItems() { return QQmlListProperty(this, m_childItems); diff --git a/src/lib/plugins/qml/qmlplugininterface.h b/src/lib/plugins/qml/qmlplugininterface.h index 7b36b60b8..9304c1e1d 100644 --- a/src/lib/plugins/qml/qmlplugininterface.h +++ b/src/lib/plugins/qml/qmlplugininterface.h @@ -44,6 +44,7 @@ class QmlPluginInterface : public QObject, public PluginInterface Q_PROPERTY(QJSValue wheelEvent READ readWheelEvent WRITE setWheelEvent) Q_PROPERTY(QJSValue keyPress READ readKeyPress WRITE setKeyPress) Q_PROPERTY(QJSValue keyRelease READ readKeyRelease WRITE setKeyRelease) + Q_PROPERTY(QJSValue acceptNavigationRequest READ readAcceptNavigationRequest WRITE setAcceptNavigationRequest) Q_PROPERTY(QQmlListProperty childItems READ childItems) Q_CLASSINFO("DefaultProperty", "childItems") @@ -68,6 +69,8 @@ public: bool keyPress(Qz::ObjectName type, QObject *obj, QKeyEvent *event) override; bool keyRelease(Qz::ObjectName type, QObject *obj, QKeyEvent *event) override; + bool acceptNavigationRequest(WebPage *page, const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) override; + Q_SIGNALS: void qmlPluginUnloaded(); @@ -88,6 +91,7 @@ private: QJSValue m_wheelEvent; QJSValue m_keyPress; QJSValue m_keyRelease; + QJSValue m_acceptNavigationRequest; QList m_childItems; QJSValue readInit() const; @@ -118,6 +122,8 @@ private: void setKeyPress(const QJSValue &keyPress); QJSValue readKeyRelease() const; void setKeyRelease(const QJSValue &keyRelease); + QJSValue readAcceptNavigationRequest() const; + void setAcceptNavigationRequest(const QJSValue &acceptNavigationRequest); QQmlListProperty childItems(); void addButton(BrowserWindow *window);