Merge lp:~uriboni/oxide/find-in-page into lp:~oxide-developers/oxide/oxide.trunk

Proposed by Ugo Riboni
Status: Merged
Merged at revision: 1088
Proposed branch: lp:~uriboni/oxide/find-in-page
Merge into: lp:~oxide-developers/oxide/oxide.trunk
Diff against target: 863 lines (+587/-1)
15 files modified
qt/core/api/oxideqfindcontroller.cc (+97/-0)
qt/core/api/oxideqfindcontroller.h (+71/-0)
qt/core/api/oxideqfindcontroller_p.h (+46/-0)
qt/core/browser/oxide_qt_web_view.cc (+16/-1)
qt/core/browser/oxide_qt_web_view.h (+7/-0)
qt/core/core.gyp (+9/-0)
qt/core/glue/oxide_qt_web_view_proxy.h (+11/-0)
qt/qmlplugin/oxide_qml_plugin.cc (+5/-0)
qt/quick/api/oxideqquickwebview.cc (+7/-0)
qt/quick/api/oxideqquickwebview_p.h (+10/-0)
qt/tests/qmltests/api/tst_WebView_findController.html (+13/-0)
qt/tests/qmltests/api/tst_WebView_findController.qml (+152/-0)
qt/tests/qmltests/api/tst_WebView_findControllerManyResults.html (+9/-0)
shared/browser/oxide_web_view.cc (+102/-0)
shared/browser/oxide_web_view.h (+32/-0)
To merge this branch: bzr merge lp:~uriboni/oxide/find-in-page
Reviewer Review Type Date Requested Status
Chris Coulson Approve
Review via email: mp+258184@code.launchpad.net

Description of the change

Adds a new API to allow searching text within a page.

To post a comment you must log in.
lp:~uriboni/oxide/find-in-page updated
1063. By Ugo Riboni

Remove unrelated changes to cmake file

1064. By Ugo Riboni

Minor code style fixes

1065. By Ugo Riboni

Make findInPage group property constant to prevent non-notifyable property warnings

1066. By Ugo Riboni

Merge changes from trunk

Revision history for this message
Olivier Tilloy (osomon) wrote :

The API looks good to me (I’ll let Chris comment on the actual implementation). Here are a few comments, most of them on the unit tests:

 - In test_case_insensitive(), the second test should be on a different string, otherwise the count might not have been updated yet.

 - In test_new_text_resets_count() and in test_navigation_does_not_reset(), next() should be called after verifying that the count is 2.

 - In test_find_on_invalid_page(), waiting for a successful load doesn’t look right. Shouldn’t you use webView.waitForLoadFailed() ?

 - In test_navigation_does_not_reset(), the comparison of text to "dolor" doesn’t need a tryCompare(), it should be a simple compare().

 - In OxideQQuickWebViewFindInPage’s constructor, the explicit initialization of text_ is useless.

 - In the implementation of WebView::findInPage() and other methods, please avoid the use of a return statement on the same line as the condition, and always use curly braces, even for one-liner if blocks.

lp:~uriboni/oxide/find-in-page updated
1067. By Ugo Riboni

Fix code style (braces, indentation)

1068. By Ugo Riboni

Improve some tests

1069. By Ugo Riboni

Remove useless initialization

1070. By Ugo Riboni

Add explanatory comment and fix indentation

1071. By Ugo Riboni

Merge changes from trunk

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Thanks for working on this. I have some general comments:

- I think I'd prefer WebView.findController and FindController for the corresponding class name in QML

- The implementation doesn't need to live in qt/quick/api - it should go in qt/core/api as OxideQFindController, as it doesn't really have any dependencies outside of the core library or QtCore and the implementation could be shared with a QWidget port - if someone ever decides it would be a good idea to write one :)

- As we want to open up the C++ API in the future, the data members on the public class should be in a private class.

I've also left some comments inline.

review: Needs Fixing
lp:~uriboni/oxide/find-in-page updated
1072. By Ugo Riboni

Refactor all the logic into an OxideQFindController class owned by oxide::qt::WebView. The QML API merely exposes it through the renamed findController property. Address other minor issues from code review.

1073. By Ugo Riboni

Merge changes from trunk

1074. By Ugo Riboni

Move all non-QT code to oxide::WebView

Revision history for this message
Ugo Riboni (uriboni) wrote :

I think all your comments should be addressed at this point, except some to which I replied inline.

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Thanks. There's a few stylistic nits (eg, 4-space indents in some places) and some other things (eg, the constructor for OxideQFindController shouldn't be exported). The API looks like it's fine now.

I'm going to approve this though, as I'm currently working on re-architecting oxide::WebView which is probably going to be quite disruptive to this branch - I've already created some merge conflicts with http://bazaar.launchpad.net/~oxide-developers/oxide/oxide.trunk/revision/1087, which I'll fix up

review: Approve
Revision history for this message
Ugo Riboni (uriboni) wrote :

> Thanks. There's a few stylistic nits (eg, 4-space indents in some places) and
> some other things (eg, the constructor for OxideQFindController shouldn't be
> exported). The API looks like it's fine now.
>
> I'm going to approve this though, as I'm currently working on re-architecting
> oxide::WebView which is probably going to be quite disruptive to this branch -
> I've already created some merge conflicts with http://bazaar.launchpad.net
> /~oxide-developers/oxide/oxide.trunk/revision/1087, which I'll fix up

Thanks Chris.
Just to be clear, is there any further action needed from me on this branch ?

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

There isn't - I'm going to clean up the merge conflicts I've created and then merge it in for you.

Thanks!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'qt/core/api/oxideqfindcontroller.cc'
2--- qt/core/api/oxideqfindcontroller.cc 1970-01-01 00:00:00 +0000
3+++ qt/core/api/oxideqfindcontroller.cc 2015-05-20 22:10:39 +0000
4@@ -0,0 +1,97 @@
5+// vim:expandtab:shiftwidth=2:tabstop=2:
6+// Copyright (C) 2015 Canonical Ltd.
7+
8+// This library is free software; you can redistribute it and/or
9+// modify it under the terms of the GNU Lesser General Public
10+// License as published by the Free Software Foundation; either
11+// version 2.1 of the License, or (at your option) any later version.
12+
13+// This library 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 GNU
16+// Lesser General Public License for more details.
17+
18+// You should have received a copy of the GNU Lesser General Public
19+// License along with this library; if not, write to the Free Software
20+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
22+#include "oxideqfindcontroller.h"
23+#include "oxideqfindcontroller_p.h"
24+
25+#include "content/browser/web_contents/web_contents_impl.h"
26+#include "qt/core/browser/oxide_qt_web_view.h"
27+#include "shared/browser/oxide_web_view.h"
28+
29+OxideQFindControllerPrivate::OxideQFindControllerPrivate(oxide::WebView* webview) :
30+ case_sensitive_(false),
31+ count_(0),
32+ current_(0),
33+ request_id_(0),
34+ webview_(webview) {}
35+
36+OxideQFindControllerPrivate::~OxideQFindControllerPrivate() {}
37+
38+OxideQFindController::OxideQFindController(oxide::WebView* webview) :
39+ QObject(nullptr),
40+ d_ptr(new OxideQFindControllerPrivate(webview)) {
41+}
42+
43+OxideQFindController::~OxideQFindController() {}
44+
45+QString OxideQFindController::text() const {
46+ Q_D(const OxideQFindController);
47+
48+ return QString::fromStdString(d->webview_->GetFindInPageText());
49+}
50+
51+void OxideQFindController::setText(const QString& newText) {
52+ Q_D(OxideQFindController);
53+
54+ if (newText == text()) {
55+ return;
56+ }
57+
58+ d->webview_->SetFindInPageText(newText.toStdString());
59+ emit textChanged();
60+}
61+
62+bool OxideQFindController::caseSensitive() const {
63+ Q_D(const OxideQFindController);
64+
65+ return d->webview_->GetFindInPageCaseSensitive();
66+}
67+
68+void OxideQFindController::setCaseSensitive(bool newCaseSensitive) {
69+ Q_D(OxideQFindController);
70+
71+ if (newCaseSensitive == caseSensitive()) {
72+ return;
73+ }
74+
75+ d->webview_->SetFindInPageCaseSensitive(newCaseSensitive);
76+ emit caseSensitiveChanged();
77+}
78+
79+int OxideQFindController::count() const {
80+ Q_D(const OxideQFindController);
81+
82+ return d->webview_->GetFindInPageCount();
83+}
84+
85+int OxideQFindController::current() const {
86+ Q_D(const OxideQFindController);
87+
88+ return d->webview_->GetFindInPageCurrent();
89+}
90+
91+void OxideQFindController::next() {
92+ Q_D(OxideQFindController);
93+
94+ d->webview_->FindInPageNext();
95+}
96+
97+void OxideQFindController::previous() {
98+ Q_D(OxideQFindController);
99+
100+ d->webview_->FindInPagePrevious();
101+}
102
103=== added file 'qt/core/api/oxideqfindcontroller.h'
104--- qt/core/api/oxideqfindcontroller.h 1970-01-01 00:00:00 +0000
105+++ qt/core/api/oxideqfindcontroller.h 2015-05-20 22:10:39 +0000
106@@ -0,0 +1,71 @@
107+// vim:expandtab:shiftwidth=2:tabstop=2:
108+// Copyright (C) 2015 Canonical Ltd.
109+
110+// This library is free software; you can redistribute it and/or
111+// modify it under the terms of the GNU Lesser General Public
112+// License as published by the Free Software Foundation; either
113+// version 2.1 of the License, or (at your option) any later version.
114+
115+// This library is distributed in the hope that it will be useful,
116+// but WITHOUT ANY WARRANTY; without even the implied warranty of
117+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
118+// Lesser General Public License for more details.
119+
120+// You should have received a copy of the GNU Lesser General Public
121+// License along with this library; if not, write to the Free Software
122+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
123+
124+#ifndef OXIDE_Q_FIND_CONTROLLER
125+#define OXIDE_Q_FIND_CONTROLLER
126+
127+#include <QObject>
128+#include <QScopedPointer>
129+#include <QString>
130+#include <QtGlobal>
131+
132+class OxideQFindControllerPrivate;
133+
134+namespace oxide {
135+ class WebView;
136+ namespace qt {
137+ class WebView;
138+ }
139+}
140+
141+class Q_DECL_EXPORT OxideQFindController : public QObject {
142+ Q_OBJECT
143+ Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
144+ Q_PROPERTY(bool caseSensitive READ caseSensitive WRITE setCaseSensitive NOTIFY caseSensitiveChanged)
145+ Q_PROPERTY(int count READ count NOTIFY countChanged)
146+ Q_PROPERTY(int current READ current NOTIFY currentChanged)
147+
148+ Q_DECLARE_PRIVATE(OxideQFindController)
149+ Q_DISABLE_COPY(OxideQFindController)
150+
151+ public:
152+ OxideQFindController(oxide::WebView* webview);
153+ ~OxideQFindController();
154+
155+ QString text() const;
156+ void setText(const QString& text);
157+ bool caseSensitive() const;
158+ void setCaseSensitive(bool caseSensitive);
159+ int count() const;
160+ int current() const;
161+
162+ Q_INVOKABLE void next();
163+ Q_INVOKABLE void previous();
164+
165+ Q_SIGNALS:
166+ void textChanged() const;
167+ void caseSensitiveChanged() const;
168+ void countChanged() const;
169+ void currentChanged() const;
170+
171+ private:
172+ QScopedPointer<OxideQFindControllerPrivate> d_ptr;
173+
174+ friend class oxide::qt::WebView;
175+};
176+
177+#endif // OXIDE_Q_FIND_CONTROLLER
178
179=== added file 'qt/core/api/oxideqfindcontroller_p.h'
180--- qt/core/api/oxideqfindcontroller_p.h 1970-01-01 00:00:00 +0000
181+++ qt/core/api/oxideqfindcontroller_p.h 2015-05-20 22:10:39 +0000
182@@ -0,0 +1,46 @@
183+// vim:expandtab:shiftwidth=2:tabstop=2:
184+// Copyright (C) 2015 Canonical Ltd.
185+
186+// This library is free software; you can redistribute it and/or
187+// modify it under the terms of the GNU Lesser General Public
188+// License as published by the Free Software Foundation; either
189+// version 2.1 of the License, or (at your option) any later version.
190+
191+// This library is distributed in the hope that it will be useful,
192+// but WITHOUT ANY WARRANTY; without even the implied warranty of
193+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
194+// Lesser General Public License for more details.
195+
196+// You should have received a copy of the GNU Lesser General Public
197+// License along with this library; if not, write to the Free Software
198+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
199+
200+#ifndef _OXIDE_QT_CORE_API_FIND_CONTROLLER_P_H_
201+#define _OXIDE_QT_CORE_API_FIND_CONTROLLER_P_H_
202+
203+#include <QtGlobal>
204+#include <QString>
205+
206+namespace oxide {
207+ class WebView;
208+}
209+
210+class OxideQFindControllerPrivate {
211+ public:
212+ virtual ~OxideQFindControllerPrivate();
213+
214+ private:
215+ OxideQFindControllerPrivate(oxide::WebView* webview);
216+
217+ QString text_;
218+ bool case_sensitive_;
219+ int count_;
220+ int current_;
221+ int request_id_;
222+ oxide::WebView* webview_;
223+
224+ friend class OxideQFindController;
225+};
226+
227+#endif // _OXIDE_QT_CORE_API_FIND_CONTROLLER_P_H_
228+
229
230=== modified file 'qt/core/browser/oxide_qt_web_view.cc'
231--- qt/core/browser/oxide_qt_web_view.cc 2015-05-11 21:23:12 +0000
232+++ qt/core/browser/oxide_qt_web_view.cc 2015-05-20 22:10:39 +0000
233@@ -67,6 +67,8 @@
234 #include "qt/core/api/oxideqcertificateerror_p.h"
235 #include "qt/core/api/oxideqsecuritystatus.h"
236 #include "qt/core/api/oxideqsecuritystatus_p.h"
237+#include "qt/core/api/oxideqfindcontroller.h"
238+#include "qt/core/api/oxideqfindcontroller_p.h"
239 #include "qt/core/api/oxideqwebpreferences.h"
240 #include "qt/core/api/oxideqwebpreferences_p.h"
241 #include "qt/core/common/oxide_qt_screen_utils.h"
242@@ -1280,6 +1282,18 @@
243 Reload();
244 }
245
246+OxideQFindController* WebView::findInPage() {
247+ return find_in_page_controller_.get();
248+}
249+
250+void WebView::OnFindInPageCountChanged() {
251+ Q_EMIT find_in_page_controller_->countChanged();
252+}
253+
254+void WebView::OnFindInPageCurrentChanged() {
255+ Q_EMIT find_in_page_controller_->currentChanged();
256+}
257+
258 void WebView::loadHtml(const QString& html, const QUrl& base_url) {
259 QByteArray encoded_data = html.toUtf8().toPercentEncoding();
260 LoadData(std::string(encoded_data.constData(), encoded_data.length()),
261@@ -1511,7 +1525,8 @@
262 client_(client),
263 has_input_method_state_(false),
264 qsecurity_status_(
265- OxideQSecurityStatusPrivate::Create(this)) {
266+ OxideQSecurityStatusPrivate::Create(this)),
267+ find_in_page_controller_(new OxideQFindController(this)) {
268 QInputMethod* im = QGuiApplication::inputMethod();
269 if (im) {
270 connect(im, SIGNAL(visibleChanged()),
271
272=== modified file 'qt/core/browser/oxide_qt_web_view.h'
273--- qt/core/browser/oxide_qt_web_view.h 2015-05-11 21:23:12 +0000
274+++ qt/core/browser/oxide_qt_web_view.h 2015-05-20 22:10:39 +0000
275@@ -41,6 +41,7 @@
276 class QWheelEvent;
277 QT_END_NAMESPACE
278
279+class OxideQFindController;
280 class OxideQSecurityStatus;
281
282 namespace oxide {
283@@ -156,6 +157,9 @@
284 const std::string& cookies,
285 const std::string& referrer) override;
286
287+ void OnFindInPageCountChanged() override;
288+ void OnFindInPageCurrentChanged() override;
289+
290 bool ShouldHandleNavigation(const GURL& url,
291 WindowOpenDisposition disposition,
292 bool user_gesture) override;
293@@ -231,6 +235,8 @@
294 void stop() override;
295 void reload() override;
296
297+ OxideQFindController* findInPage() override;
298+
299 void loadHtml(const QString& html, const QUrl& base_url) override;
300
301 QList<ScriptMessageHandlerProxyHandle*>& messageHandlers() override;
302@@ -291,6 +297,7 @@
303 UITouchEventFactory touch_event_factory_;
304
305 QSharedPointer<CompositorFrameHandle> compositor_frame_;
306+ scoped_ptr<OxideQFindController> find_in_page_controller_;
307
308 DISALLOW_IMPLICIT_CONSTRUCTORS(WebView);
309 };
310
311=== modified file 'qt/core/core.gyp'
312--- qt/core/core.gyp 2015-05-06 21:13:13 +0000
313+++ qt/core/core.gyp 2015-05-20 22:10:39 +0000
314@@ -201,6 +201,7 @@
315 '<(INTERMEDIATE_DIR)/moc_oxideqnavigationrequest.cc',
316 '<(INTERMEDIATE_DIR)/moc_oxideqnewviewrequest.cc',
317 '<(INTERMEDIATE_DIR)/moc_oxideqpermissionrequest.cc',
318+ '<(INTERMEDIATE_DIR)/moc_oxideqfindcontroller.cc',
319 '<(INTERMEDIATE_DIR)/moc_oxideqsecuritystatus.cc',
320 '<(INTERMEDIATE_DIR)/moc_oxideqsslcertificate.cc',
321 '<(INTERMEDIATE_DIR)/moc_oxideqstoragepermissionrequest.cc',
322@@ -229,6 +230,9 @@
323 'api/oxideqpermissionrequest.cc',
324 'api/oxideqpermissionrequest.h',
325 'api/oxideqpermissionrequest_p.h',
326+ 'api/oxideqfindcontroller.cc',
327+ 'api/oxideqfindcontroller.h',
328+ 'api/oxideqfindcontroller_p.h',
329 'api/oxideqsecuritystatus.cc',
330 'api/oxideqsecuritystatus.h',
331 'api/oxideqsecuritystatus_p.h',
332@@ -279,6 +283,11 @@
333 'includes': [ 'moc.gypi' ],
334 },
335 {
336+ 'action_name': 'moc_oxideqfindcontroller.cc',
337+ 'moc_input': 'api/oxideqfindcontroller.h',
338+ 'includes': [ 'moc.gypi' ],
339+ },
340+ {
341 'action_name': 'moc_oxideqsecuritystatus.cc',
342 'moc_input': 'api/oxideqsecuritystatus.h',
343 'includes': [ 'moc.gypi' ],
344
345=== modified file 'qt/core/glue/oxide_qt_web_view_proxy.h'
346--- qt/core/glue/oxide_qt_web_view_proxy.h 2015-05-06 15:05:53 +0000
347+++ qt/core/glue/oxide_qt_web_view_proxy.h 2015-05-20 22:10:39 +0000
348@@ -45,6 +45,7 @@
349 class QWheelEvent;
350 QT_END_NAMESPACE
351
352+class OxideQFindController;
353 class OxideQNewViewRequest;
354 class OxideQSecurityStatus;
355 class OxideQWebPreferences;
356@@ -101,6 +102,14 @@
357 virtual EGLImageKHR GetImageFrame() = 0;
358 };
359
360+struct FindInPageState {
361+ int request_id;
362+ QString text;
363+ bool case_sensitive;
364+ int current;
365+ int count;
366+};
367+
368 OXIDE_Q_DECL_PROXY_HANDLE(ScriptMessageHandlerProxy);
369 OXIDE_Q_DECL_PROXY_HANDLE(WebContextProxy);
370 OXIDE_Q_DECL_PROXY_HANDLE(WebFrameProxy);
371@@ -155,6 +164,8 @@
372 virtual void stop() = 0;
373 virtual void reload() = 0;
374
375+ virtual OxideQFindController* findInPage() = 0;
376+
377 virtual void loadHtml(const QString& html, const QUrl& base_url) = 0;
378
379 virtual QList<ScriptMessageHandlerProxyHandle*>& messageHandlers() = 0;
380
381=== modified file 'qt/qmlplugin/oxide_qml_plugin.cc'
382--- qt/qmlplugin/oxide_qml_plugin.cc 2015-05-11 21:23:12 +0000
383+++ qt/qmlplugin/oxide_qml_plugin.cc 2015-05-20 22:10:39 +0000
384@@ -24,6 +24,7 @@
385
386 #include "qt/core/api/oxideqcertificateerror.h"
387 #include "qt/core/api/oxideqdownloadrequest.h"
388+#include "qt/core/api/oxideqfindcontroller.h"
389 #include "qt/core/api/oxideqloadevent.h"
390 #include "qt/core/api/oxideqnavigationrequest.h"
391 #include "qt/core/api/oxideqnewviewrequest.h"
392@@ -128,8 +129,12 @@
393 qmlRegisterUncreatableType<OxideQQuickLocationBarController, 1>(uri, 1, 7, "LocationBarController",
394 "LocationBarController is accessed via WebView.locationBarController");
395
396+ qmlRegisterUncreatableType<OxideQFindController>(uri, 1, 8, "FindController",
397+ "FindInPage is accessed via WebView.findController");
398+
399 qmlRegisterUncreatableType<OxideQLoadEvent, 2>(uri, 1, 8, "LoadEvent",
400 "LoadEvent is delivered by WebView.loadEvent");
401+
402 qmlRegisterType<OxideQQuickWebView, 4>(uri, 1, 8, "WebView");
403 }
404 };
405
406=== modified file 'qt/quick/api/oxideqquickwebview.cc'
407--- qt/quick/api/oxideqquickwebview.cc 2015-05-11 15:32:11 +0000
408+++ qt/quick/api/oxideqquickwebview.cc 2015-05-20 22:10:39 +0000
409@@ -41,6 +41,7 @@
410 #include <Qt>
411
412 #include "qt/core/api/oxideqcertificateerror.h"
413+#include "qt/core/api/oxideqfindcontroller.h"
414 #include "qt/core/api/oxideqglobal.h"
415 #include "qt/core/api/oxideqloadevent.h"
416 #include "qt/core/api/oxideqnewviewrequest.h"
417@@ -1744,4 +1745,10 @@
418 d->proxy()->prepareToClose();
419 }
420
421+OxideQFindController* OxideQQuickWebView::findController() const {
422+ Q_D(const OxideQQuickWebView);
423+
424+ return d->proxy()->findInPage();
425+}
426+
427 #include "moc_oxideqquickwebview_p.cpp"
428
429=== modified file 'qt/quick/api/oxideqquickwebview_p.h'
430--- qt/quick/api/oxideqquickwebview_p.h 2015-05-11 15:32:11 +0000
431+++ qt/quick/api/oxideqquickwebview_p.h 2015-05-20 22:10:39 +0000
432@@ -32,6 +32,7 @@
433
434 QT_USE_NAMESPACE
435
436+class OxideQFindController;
437 class OxideQLoadEvent;
438 class OxideQNavigationRequest;
439 class OxideQNewViewRequest;
440@@ -45,6 +46,11 @@
441 class OxideQQuickWebViewPrivate;
442 class OxideQDownloadRequest;
443 class OxideQSecurityStatus;
444+namespace oxide {
445+ namespace qt {
446+ class WebViewProxy;
447+ }
448+}
449
450 class OxideQQuickWebViewAttached : public QObject {
451 Q_OBJECT
452@@ -107,6 +113,8 @@
453
454 Q_PROPERTY(OxideQNewViewRequest* request READ request WRITE setRequest)
455
456+ Q_PROPERTY(OxideQFindController* findController READ findController CONSTANT REVISION 4)
457+
458 // Set at construction time only
459 Q_PROPERTY(QString restoreState READ restoreState WRITE setRestoreState REVISION 2)
460 Q_PROPERTY(RestoreType restoreType READ restoreType WRITE setRestoreType REVISION 2)
461@@ -234,6 +242,8 @@
462
463 static OxideQQuickWebViewAttached* qmlAttachedProperties(QObject* object);
464
465+ OxideQFindController* findController() const;
466+
467 public Q_SLOTS:
468 void goBack();
469 void goForward();
470
471=== added file 'qt/tests/qmltests/api/tst_WebView_findController.html'
472--- qt/tests/qmltests/api/tst_WebView_findController.html 1970-01-01 00:00:00 +0000
473+++ qt/tests/qmltests/api/tst_WebView_findController.html 2015-05-20 22:10:39 +0000
474@@ -0,0 +1,13 @@
475+<html>
476+ <head>
477+ <meta charset="UTF-8">
478+ </head>
479+ <body>
480+ Lorem ipsum dolor sit Amet, consectetur adipiscing elit.
481+ Nam eu venenatis velit.
482+ Suspendisse vitae libero rutrum Amet, congue velit quis, fringilla eros.
483+ Nulla at semper purus, id scelerisque est.
484+ Fusce rhoncus placerat erat ñec ultricies amet.
485+ Curabitur mauris. Dolor, facilisis eu tellus vitae, semper iaculis tortor.
486+ </body>
487+</html>
488
489=== added file 'qt/tests/qmltests/api/tst_WebView_findController.qml'
490--- qt/tests/qmltests/api/tst_WebView_findController.qml 1970-01-01 00:00:00 +0000
491+++ qt/tests/qmltests/api/tst_WebView_findController.qml 2015-05-20 22:10:39 +0000
492@@ -0,0 +1,152 @@
493+import QtQuick 2.0
494+import QtTest 1.0
495+import com.canonical.Oxide 1.8
496+import com.canonical.Oxide.Testing 1.0
497+
498+TestWebView {
499+ id: webView
500+ focus: true
501+ width: 200
502+ height: 200
503+
504+ TestCase {
505+ name: "findController"
506+ when: windowShown
507+
508+ function init() {
509+ webView.findController.text = "";
510+ webView.findController.caseSensitive = false;
511+
512+ // load the page that will be used by most tests
513+ webView.url = "http://testsuite/tst_WebView_findController.html";
514+ verify(webView.waitForLoadSucceeded(),
515+ "Timed out waiting for successful load");
516+ }
517+
518+ function test_case_insensitive() {
519+ webView.findController.text = "suspendisse";
520+ tryCompare(webView.findController, "count", 1);
521+
522+ webView.findController.text = "aMet";
523+ tryCompare(webView.findController, "count", 3);
524+ }
525+
526+ function test_case_sensitive() {
527+ webView.findController.caseSensitive = true;
528+
529+ webView.findController.text = "Suspendisse";
530+ tryCompare(webView.findController, "count", 1);
531+
532+ webView.findController.text = "suspendisse";
533+ tryCompare(webView.findController, "count", 0);
534+ }
535+
536+ function test_change_case_sensitivity() {
537+ webView.findController.caseSensitive = true;
538+
539+ webView.findController.text = "Dolor";
540+ tryCompare(webView.findController, "count", 1);
541+
542+ webView.findController.caseSensitive = false;
543+ tryCompare(webView.findController, "count", 2);
544+ }
545+
546+ function test_movement() {
547+ webView.findController.text = "dolor";
548+ tryCompare(webView.findController, "count", 2);
549+ tryCompare(webView.findController, "current", 1);
550+
551+ webView.findController.next();
552+ tryCompare(webView.findController, "count", 2);
553+ tryCompare(webView.findController, "current", 2);
554+
555+ webView.findController.previous();
556+ tryCompare(webView.findController, "count", 2);
557+ tryCompare(webView.findController, "current", 1);
558+ }
559+
560+ function test_movement_wraps() {
561+ webView.findController.text = "dolor";
562+ tryCompare(webView.findController, "count", 2);
563+ tryCompare(webView.findController, "current", 1);
564+
565+ webView.findController.next();
566+ webView.findController.next();
567+ tryCompare(webView.findController, "current", 1);
568+
569+ webView.findController.previous();
570+ webView.findController.previous();
571+ tryCompare(webView.findController, "current", 1);
572+ }
573+
574+ function test_clear() {
575+ webView.findController.text = "dolor";
576+ tryCompare(webView.findController, "count", 2);
577+
578+ webView.findController.text = "";
579+ tryCompare(webView.findController, "count", 0);
580+ tryCompare(webView.findController, "current", 0);
581+ }
582+
583+ function test_new_text_resets_count() {
584+ webView.findController.text = "dolor";
585+ tryCompare(webView.findController, "count", 2);
586+ webView.findController.next();
587+ tryCompare(webView.findController, "current", 2);
588+
589+ webView.findController.text = "suspendisse";
590+ tryCompare(webView.findController, "count", 1);
591+ tryCompare(webView.findController, "current", 1);
592+ }
593+
594+ function test_not_found_resets_count() {
595+ webView.findController.text = "dolor";
596+ tryCompare(webView.findController, "count", 2);
597+
598+ webView.findController.text = "i_am_not_there";
599+ tryCompare(webView.findController, "count", 0);
600+ tryCompare(webView.findController, "current", 0);
601+ }
602+
603+ function test_find_non_latin() {
604+ webView.findController.text = "ñec";
605+ tryCompare(webView.findController, "count", 1);
606+ }
607+
608+ function test_find_on_invalid_page() {
609+ webView.url = "http://testsuite/tst_invalid_page.html";
610+ // verify successful load because the server returns a 404 page apparently
611+ // and that does not count as a failure
612+ verify(webView.waitForLoadSucceeded(),
613+ "Timed out waiting for successful load");
614+
615+ webView.findController.text = "hello";
616+ tryCompare(webView.findController, "count", 0);
617+ tryCompare(webView.findController, "current", 0);
618+ }
619+
620+ function test_navigation_does_not_reset() {
621+ webView.findController.text = "dolor";
622+ tryCompare(webView.findController, "count", 2);
623+ webView.findController.next();
624+ tryCompare(webView.findController, "current", 2);
625+
626+ // Verify that when navigating to another page the search does not
627+ // reset, it is the user responsibility to cancel it and restart it
628+ webView.url = "http://testsuite/tst_WebView_findControllerManyResults.html";
629+ verify(webView.waitForLoadSucceeded(),
630+ "Timed out waiting for successful load");
631+ compare(webView.findController.text, "dolor");
632+ tryCompare(webView.findController, "count", 2);
633+ tryCompare(webView.findController, "current", 2);
634+
635+ webView.findController.text = "";
636+ tryCompare(webView.findController, "count", 0);
637+ tryCompare(webView.findController, "current", 0);
638+
639+ webView.findController.text = "dolor";
640+ tryCompare(webView.findController, "count", 20);
641+ tryCompare(webView.findController, "current", 1);
642+ }
643+ }
644+}
645
646=== added file 'qt/tests/qmltests/api/tst_WebView_findControllerManyResults.html'
647--- qt/tests/qmltests/api/tst_WebView_findControllerManyResults.html 1970-01-01 00:00:00 +0000
648+++ qt/tests/qmltests/api/tst_WebView_findControllerManyResults.html 2015-05-20 22:10:39 +0000
649@@ -0,0 +1,9 @@
650+<html>
651+ <head>
652+ <meta charset="UTF-8">
653+ </head>
654+ <body>
655+ Lorem ipsum dolor dolor dolor dolor dolor dolor dolor dolor dolor dolor
656+ dolor dolor dolor dolor dolor dolor dolor dolor dolor dolor sit amet.
657+ </body>
658+</html>
659
660=== modified file 'shared/browser/oxide_web_view.cc'
661--- shared/browser/oxide_web_view.cc 2015-05-15 14:49:32 +0000
662+++ shared/browser/oxide_web_view.cc 2015-05-20 22:10:39 +0000
663@@ -76,6 +76,8 @@
664 #include "shared/common/oxide_event_utils.h"
665 #include "shared/common/oxide_messages.h"
666
667+#include "third_party/WebKit/public/web/WebFindOptions.h"
668+
669 #include "oxide_browser_context.h"
670 #include "oxide_browser_process_main.h"
671 #include "oxide_content_browser_client.h"
672@@ -753,6 +755,25 @@
673 return IsFullscreen();
674 }
675
676+void WebView::FindReply(content::WebContents* web_contents,
677+ int request_id,
678+ int number_of_matches,
679+ const gfx::Rect& selection_rect,
680+ int active_match_ordinal,
681+ bool final_update) {
682+ if (active_match_ordinal != -1 &&
683+ find_in_page_.current != active_match_ordinal) {
684+ find_in_page_.current = active_match_ordinal;
685+ OnFindInPageCurrentChanged();
686+ }
687+
688+ if (number_of_matches != -1 &&
689+ find_in_page_.count != number_of_matches) {
690+ find_in_page_.count = number_of_matches;
691+ OnFindInPageCountChanged();
692+ }
693+}
694+
695 void WebView::RequestMediaAccessPermission(
696 content::WebContents* source,
697 const content::MediaStreamRequest& request,
698@@ -1222,6 +1243,9 @@
699 void WebView::OnPrepareToCloseResponse(bool proceed) {}
700 void WebView::OnCloseRequested() {}
701
702+void WebView::OnFindInPageCountChanged() {}
703+void WebView::OnFindInPageCurrentChanged() {}
704+
705 WebView::WebView()
706 : text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
707 show_ime_if_needed_(false),
708@@ -1636,6 +1660,84 @@
709 rvh->OnWebkitPreferencesChanged();
710 }
711
712+int WebView::GetFindInPageCount() const {
713+ return find_in_page_.count;
714+}
715+
716+int WebView::GetFindInPageCurrent() const {
717+ return find_in_page_.current;
718+}
719+
720+std::string WebView::GetFindInPageText() const {
721+ return find_in_page_.text;
722+}
723+
724+bool WebView::GetFindInPageCaseSensitive() const {
725+ return find_in_page_.case_sensitive;
726+}
727+
728+void WebView::SetFindInPageText(const std::string& text) {
729+ find_in_page_.text = text;
730+ RestartFindInPage();
731+}
732+
733+void WebView::SetFindInPageCaseSensitive(bool case_sensitive) {
734+ find_in_page_.case_sensitive = case_sensitive;
735+ RestartFindInPage();
736+}
737+
738+void WebView::RestartFindInPage() {
739+ if (!web_contents_) {
740+ return;
741+ }
742+
743+ web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
744+
745+ find_in_page_.current = 0;
746+ OnFindInPageCurrentChanged();
747+ find_in_page_.count = 0;
748+ OnFindInPageCountChanged();
749+
750+ if (!find_in_page_.text.empty()) {
751+ find_in_page_.request_id++;
752+
753+ blink::WebFindOptions options;
754+ options.forward = true;
755+ options.findNext = false;
756+ options.matchCase = find_in_page_.case_sensitive;
757+
758+ web_contents_->Find(find_in_page_.request_id,
759+ base::UTF8ToUTF16(find_in_page_.text),
760+ options);
761+ }
762+}
763+
764+void WebView::FindInPageNext() {
765+ if (!web_contents_) {
766+ return;
767+ }
768+
769+ blink::WebFindOptions options;
770+ options.forward = true;
771+ options.findNext = true;
772+
773+ web_contents_->Find(find_in_page_.request_id,
774+ base::UTF8ToUTF16(find_in_page_.text), options);
775+}
776+
777+void WebView::FindInPagePrevious() {
778+ if (!web_contents_) {
779+ return;
780+ }
781+
782+ blink::WebFindOptions options;
783+ options.forward = false;
784+ options.findNext = true;
785+
786+ web_contents_->Find(find_in_page_.request_id,
787+ base::UTF8ToUTF16(find_in_page_.text), options);
788+}
789+
790 BrowserContext* WebView::GetBrowserContext() const {
791 return BrowserContext::FromContent(web_contents_->GetBrowserContext());
792 }
793
794=== modified file 'shared/browser/oxide_web_view.h'
795--- shared/browser/oxide_web_view.h 2015-05-15 14:49:32 +0000
796+++ shared/browser/oxide_web_view.h 2015-05-20 22:10:39 +0000
797@@ -201,6 +201,15 @@
798 void InputPanelVisibilityChanged();
799 void UpdateWebPreferences();
800
801+ int GetFindInPageCount() const;
802+ int GetFindInPageCurrent() const;
803+ std::string GetFindInPageText() const;
804+ void SetFindInPageText(const std::string& text);
805+ bool GetFindInPageCaseSensitive() const;
806+ void SetFindInPageCaseSensitive(bool case_sensitive);
807+ void FindInPageNext();
808+ void FindInPagePrevious();
809+
810 BrowserContext* GetBrowserContext() const;
811 content::WebContents* GetWebContents() const;
812
813@@ -355,6 +364,8 @@
814 void InitializeTopControlsForHost(content::RenderViewHost* rvh,
815 bool initial_host);
816
817+ void RestartFindInPage();
818+
819 // ScriptMessageTarget implementation
820 virtual size_t GetScriptMessageHandlerCount() const override;
821 virtual const ScriptMessageHandler* GetScriptMessageHandlerAt(
822@@ -440,6 +451,13 @@
823 const content::MediaStreamRequest& request,
824 const content::MediaResponseCallback& callback) final;
825
826+ void FindReply(content::WebContents* web_contents,
827+ int request_id,
828+ int number_of_matches,
829+ const gfx::Rect& selection_rect,
830+ int active_match_ordinal,
831+ bool final_update) final;
832+
833 // content::WebContentsObserver implementation
834 void RenderFrameCreated(content::RenderFrameHost* render_frame_host) final;
835 void RenderViewReady() final;
836@@ -577,6 +595,9 @@
837 virtual void OnPrepareToCloseResponse(bool proceed);
838 virtual void OnCloseRequested();
839
840+ virtual void OnFindInPageCurrentChanged();
841+ virtual void OnFindInPageCountChanged();
842+
843 struct WebContentsDeleter {
844 void operator()(content::WebContents* contents);
845 };
846@@ -623,6 +644,17 @@
847
848 SecurityStatus security_status_;
849
850+ struct FindInPageState {
851+ int request_id;
852+ int current;
853+ int count;
854+ bool case_sensitive;
855+ std::string text;
856+ FindInPageState() : request_id(0), current(0), count(0),
857+ case_sensitive(false) {}
858+ };
859+ FindInPageState find_in_page_;
860+
861 int location_bar_height_pix_;
862 blink::WebTopControlsState location_bar_constraints_;
863 bool location_bar_animated_;

Subscribers

People subscribed via source and target branches

to all changes: