=== modified file 'qt/core/browser/oxide_qt_web_view.cc' --- qt/core/browser/oxide_qt_web_view.cc 2015-10-27 11:36:49 +0000 +++ qt/core/browser/oxide_qt_web_view.cc 2015-11-23 18:04:16 +0000 @@ -873,6 +873,10 @@ client_->CloseRequested(); } +void WebView::TargetURLChanged() { + client_->TargetURLChanged(); +} + size_t WebView::GetScriptMessageHandlerCount() const { return message_handlers_.size(); } @@ -1358,6 +1362,10 @@ } } +QUrl WebView::targetUrl() const { + return QUrl(QString::fromStdString(view_->target_url().spec())); +} + void WebView::teardownFrameTree() { DCHECK(!frame_tree_torn_down_); === modified file 'qt/core/browser/oxide_qt_web_view.h' --- qt/core/browser/oxide_qt_web_view.h 2015-10-21 19:06:54 +0000 +++ qt/core/browser/oxide_qt_web_view.h 2015-11-23 18:04:16 +0000 @@ -171,6 +171,7 @@ void ContentBlocked() override; void PrepareToCloseResponseReceived(bool proceed) override; void CloseRequested() override; + void TargetURLChanged() override; // oxide::ScriptMessageTarget implementation size_t GetScriptMessageHandlerCount() const override; @@ -285,6 +286,8 @@ void executeEditingCommand(EditingCommands command) const override; + QUrl targetUrl() const override; + void teardownFrameTree() override; // This must outlive |view_| === modified file 'qt/core/glue/oxide_qt_web_view_proxy.h' --- qt/core/glue/oxide_qt_web_view_proxy.h 2015-10-16 21:36:30 +0000 +++ qt/core/glue/oxide_qt_web_view_proxy.h 2015-11-23 18:04:16 +0000 @@ -237,6 +237,8 @@ virtual void executeEditingCommand(EditingCommands command) const = 0; + virtual QUrl targetUrl() const = 0; + virtual void teardownFrameTree() = 0; }; === modified file 'qt/core/glue/oxide_qt_web_view_proxy_client.h' --- qt/core/glue/oxide_qt_web_view_proxy_client.h 2015-10-08 15:56:22 +0000 +++ qt/core/glue/oxide_qt_web_view_proxy_client.h 2015-11-23 18:04:16 +0000 @@ -19,7 +19,6 @@ #define _OXIDE_QT_CORE_GLUE_WEB_VIEW_PROXY_CLIENT_H_ #include -#include #include #include "qt/core/glue/oxide_qt_javascript_dialog_proxy_client.h" @@ -150,6 +149,8 @@ virtual void PrepareToCloseResponse(bool proceed) = 0; virtual void CloseRequested() = 0; + + virtual void TargetURLChanged() = 0; }; } // namespace qt === modified file 'qt/qmlplugin/oxide.qmltypes' --- qt/qmlplugin/oxide.qmltypes 2015-10-19 17:27:42 +0000 +++ qt/qmlplugin/oxide.qmltypes 2015-11-23 18:04:16 +0000 @@ -4,7 +4,7 @@ // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -v -noinstantiate com.canonical.Oxide 1.11 com/canonical/Oxide' +// 'qmlplugindump -v -noinstantiate com.canonical.Oxide 1.12 com/canonical/Oxide' Module { Component { @@ -460,13 +460,14 @@ exports: [ "WebView 1.0", "WebView 1.11", + "WebView 1.12", "WebView 1.3", "WebView 1.4", "WebView 1.5", "WebView 1.8", "WebView 1.9" ] - exportMetaObjectRevisions: [0, 6, 1, 2, 3, 4, 5] + exportMetaObjectRevisions: [0, 6, 7, 1, 2, 3, 4, 5] attachedType: "OxideQQuickWebViewAttached" Enum { name: "LogMessageSeverityLevel" @@ -618,6 +619,7 @@ isPointer: true } Property { name: "webProcessStatus"; revision: 4; type: "WebProcessStatus"; isReadonly: true } + Property { name: "hoveredUrl"; type: "QUrl"; isReadonly: true } Signal { name: "loadingStateChanged"; revision: 1 } Signal { name: "loadEvent" @@ -686,6 +688,7 @@ revision: 5 Parameter { name: "request"; type: "QJSValue" } } + Signal { name: "hoveredUrlChanged"; revision: 7 } Signal { name: "loadingChanged" Parameter { name: "loadEvent"; type: "OxideQLoadEvent" } === modified file 'qt/qmlplugin/oxide_qml_plugin.cc' --- qt/qmlplugin/oxide_qml_plugin.cc 2015-09-25 22:35:33 +0000 +++ qt/qmlplugin/oxide_qml_plugin.cc 2015-11-23 18:04:16 +0000 @@ -162,6 +162,8 @@ qmlRegisterType(uri, 1, 9, "WebView"); qmlRegisterType(uri, 1, 11, "WebView"); + + qmlRegisterType(uri, 1, 12, "WebView"); } }; === modified file 'qt/quick/api/oxideqquickwebview.cc' --- qt/quick/api/oxideqquickwebview.cc 2015-11-20 15:49:58 +0000 +++ qt/quick/api/oxideqquickwebview.cc 2015-11-23 18:04:16 +0000 @@ -636,6 +636,12 @@ emit q->closeRequested(); } +void OxideQQuickWebViewPrivate::TargetURLChanged() { + Q_Q(OxideQQuickWebView); + + emit q->hoveredUrlChanged(); +} + void OxideQQuickWebViewPrivate::completeConstruction() { Q_Q(OxideQQuickWebView); @@ -2068,6 +2074,16 @@ return static_cast(d->proxy()->webProcessStatus()); } +QUrl OxideQQuickWebView::hoveredUrl() const { + Q_D(const OxideQQuickWebView); + + if (!d->proxy()) { + return QUrl(); + } + + return d->proxy()->targetUrl(); +} + // static OxideQQuickWebViewAttached* OxideQQuickWebView::qmlAttachedProperties( QObject* object) { === modified file 'qt/quick/api/oxideqquickwebview_p.h' --- qt/quick/api/oxideqquickwebview_p.h 2015-09-25 22:30:19 +0000 +++ qt/quick/api/oxideqquickwebview_p.h 2015-11-23 18:04:16 +0000 @@ -131,6 +131,8 @@ Q_PROPERTY(WebProcessStatus webProcessStatus READ webProcessStatus NOTIFY webProcessStatusChanged REVISION 4) + Q_PROPERTY(QUrl hoveredUrl READ hoveredUrl NOTIFY hoveredUrlChanged) + Q_DECLARE_PRIVATE(OxideQQuickWebView) public: @@ -293,6 +295,8 @@ WebProcessStatus webProcessStatus() const; + QUrl hoveredUrl() const; + static OxideQQuickWebViewAttached* qmlAttachedProperties(QObject* object); OxideQFindController* findController() const; @@ -357,6 +361,7 @@ Q_REVISION(2) void closeRequested(); Q_REVISION(4) void webProcessStatusChanged(); Q_REVISION(5) void httpAuthenticationRequested(const QJSValue& request); + Q_REVISION(7) void hoveredUrlChanged(); // Deprecated since 1.3 void loadingChanged(const OxideQLoadEvent& loadEvent); === modified file 'qt/quick/api/oxideqquickwebview_p_p.h' --- qt/quick/api/oxideqquickwebview_p_p.h 2015-10-08 15:56:22 +0000 +++ qt/quick/api/oxideqquickwebview_p_p.h 2015-11-23 18:04:16 +0000 @@ -142,6 +142,7 @@ void ContentBlocked() override; void PrepareToCloseResponse(bool proceed) override; void CloseRequested() override; + void TargetURLChanged() override; oxide::qt::WebViewProxy* proxy() const { return oxide::qt::WebViewProxyHandle::proxy(); === added file 'qt/tests/qmltests/api/tst_WebView_hoveredUrl.html' --- qt/tests/qmltests/api/tst_WebView_hoveredUrl.html 1970-01-01 00:00:00 +0000 +++ qt/tests/qmltests/api/tst_WebView_hoveredUrl.html 2015-11-23 18:04:16 +0000 @@ -0,0 +1,7 @@ + + +

example.org

+

+

launchpad.net

+ + === added file 'qt/tests/qmltests/api/tst_WebView_hoveredUrl.qml' --- qt/tests/qmltests/api/tst_WebView_hoveredUrl.qml 1970-01-01 00:00:00 +0000 +++ qt/tests/qmltests/api/tst_WebView_hoveredUrl.qml 2015-11-23 18:04:16 +0000 @@ -0,0 +1,51 @@ +import QtQuick 2.0 +import QtTest 1.0 +import com.canonical.Oxide 1.12 +import com.canonical.Oxide.Testing 1.0 + +TestWebView { + id: webView + focus: true + width: 200 + height: 200 + + SignalSpy { + id: spy + target: webView + signalName: "hoveredUrlChanged" + } + + TestCase { + name: "WebView_hoveredUrl" + when: windowShown + + function test_hoveredUrl() { + webView.url = "http://foo.testsuite/tst_WebView_hoveredUrl.html" + verify(webView.waitForLoadSucceeded()); + spy.clear(); + + var r = webView.getTestApi().getBoundingClientRectForSelector("#link1"); + mouseMove(webView, r.x + r.width / 2, r.y + r.height / 2); + spy.wait(); + compare(webView.hoveredUrl, "http://example.org/"); + compare(spy.count, 1); + + r = webView.getTestApi().getBoundingClientRectForSelector("#button"); + mouseMove(webView, r.x + r.width / 2, r.y + r.height / 2); + spy.wait(); + compare(webView.hoveredUrl, ""); + compare(spy.count, 2); + + r = webView.getTestApi().getBoundingClientRectForSelector("#link2"); + mouseMove(webView, r.x + r.width / 2, r.y + r.height / 2); + spy.wait(); + compare(webView.hoveredUrl, "https://launchpad.net/"); + compare(spy.count, 3); + + mouseMove(webView, r.x + r.width / 2, r.y + r.height * 2); + spy.wait(); + compare(webView.hoveredUrl, ""); + compare(spy.count, 4); + } + } +} === modified file 'shared/browser/oxide_web_view.cc' --- shared/browser/oxide_web_view.cc 2015-11-16 20:03:58 +0000 +++ shared/browser/oxide_web_view.cc 2015-11-23 18:04:16 +0000 @@ -785,6 +785,15 @@ client_->CloseRequested(); } +void WebView::UpdateTargetURL(content::WebContents* source, const GURL& url) { + DCHECK_VALID_SOURCE_CONTENTS + + if (url != target_url_) { + target_url_ = url; + client_->TargetURLChanged(); + } +} + bool WebView::AddMessageToConsole(content::WebContents* source, int32 level, const base::string16& message, === modified file 'shared/browser/oxide_web_view.h' --- shared/browser/oxide_web_view.h 2015-11-11 21:20:30 +0000 +++ shared/browser/oxide_web_view.h 2015-11-23 18:04:16 +0000 @@ -288,6 +288,8 @@ bool CanCreateWindows() const; + const GURL& target_url() const { return target_url_; } + private: WebView(WebViewClient* client); @@ -390,6 +392,7 @@ bool* was_blocked) final; void LoadProgressChanged(content::WebContents* source, double progress) final; void CloseContents(content::WebContents* source) final; + void UpdateTargetURL(content::WebContents* source, const GURL& url) final; bool AddMessageToConsole(content::WebContents* source, int32 level, const base::string16& message, @@ -511,6 +514,8 @@ RenderWidgetHostID interstitial_rwh_id_; + GURL target_url_; + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(WebView); === modified file 'shared/browser/oxide_web_view_client.cc' --- shared/browser/oxide_web_view_client.cc 2015-10-21 19:06:54 +0000 +++ shared/browser/oxide_web_view_client.cc 2015-11-23 18:04:16 +0000 @@ -147,6 +147,8 @@ void WebViewClient::CloseRequested() {} +void WebViewClient::TargetURLChanged() {} + void WebViewClient::HttpAuthenticationRequested( ResourceDispatcherHostLoginDelegate* login_delegate) {} === modified file 'shared/browser/oxide_web_view_client.h' --- shared/browser/oxide_web_view_client.h 2015-10-21 19:06:54 +0000 +++ shared/browser/oxide_web_view_client.h 2015-11-23 18:04:16 +0000 @@ -183,6 +183,8 @@ virtual void CloseRequested(); + virtual void TargetURLChanged(); + virtual void HttpAuthenticationRequested( ResourceDispatcherHostLoginDelegate* login_delegate); };