Merge ~osomon/oxide:autofill-profiles-management into oxide:master

Proposed by Olivier Tilloy
Status: Needs review
Proposed branch: ~osomon/oxide:autofill-profiles-management
Merge into: oxide:master
Prerequisite: ~osomon/oxide:autofill
Diff against target: 1095 lines (+773/-7)
15 files modified
qt/core/browser/oxide_qt_web_context.cc (+144/-1)
qt/core/browser/oxide_qt_web_context.h (+13/-1)
qt/core/glue/oxide_qt_web_context_proxy.h (+8/-0)
qt/core/glue/oxide_qt_web_context_proxy_client.h (+3/-1)
qt/qmlplugin/oxide.qmltypes (+32/-0)
qt/qmlplugin/oxide_qml_plugin.cc (+4/-0)
qt/quick/CMakeLists.txt (+2/-1)
qt/quick/api/oxideqquickautofillprofiles.cc (+193/-0)
qt/quick/api/oxideqquickautofillprofiles.h (+68/-0)
qt/quick/api/oxideqquickautofillprofiles_p.h (+80/-0)
qt/quick/api/oxideqquickwebcontext.cc (+21/-2)
qt/quick/api/oxideqquickwebcontext.h (+4/-0)
qt/quick/api/oxideqquickwebcontext_p.h (+7/-1)
qt/tests/qmltests/api/tst_WebContext_autofillProfiles.qml (+141/-0)
qt/tests/qmltests/ubuntu_ui/tst_WebViewAutofillPopup_autofill_profiles.qml (+53/-0)
Reviewer Review Type Date Requested Status
Oxide Developers Pending
Review via email: mp+319257@code.launchpad.net

Commit message

New API on WebContext for autofill profiles management.

To post a comment you must log in.
2861ed9... by Olivier Tilloy

Ensure that the autofill profiles have been loaded before accessing them.

f4c0d6a... by Olivier Tilloy

Reduce the height of the autofill entries.

ef4fb16... by Olivier Tilloy

Preview autofill entry under mouse cursor.

f943678... by Olivier Tilloy

Highlight currently selected suggestion.

06c7bad... by Olivier Tilloy

Simplify focus handling.

818af21... by Olivier Tilloy

Fix FTBFS.

c60a7e8... by Olivier Tilloy

Handle validation when no suggestion is selected.

daa6b3b... by Olivier Tilloy

Add a unit test for autofill popup destruction.

5859240... by Olivier Tilloy

Ensure unit tests are locale-independent.

1c3531f... by Olivier Tilloy

Fix build errors when rebased on latest master.

67d903b... by Olivier Tilloy

Always use an InMemoryPrefStore.

Persisting the value of OxideQQuickWebContext::autofillEnabled would be
inconsistent with every other setting exposed by the API
(eg, we don't persist popupBlockerEnabled or doNotTrackEnabled).

a508ed9... by Olivier Tilloy

Move CreateAutofillPopup to WebContentsClient.

d9ff4e9... by Olivier Tilloy

Bump version for new WebContext API to 1.23.

bfac2c5... by Olivier Tilloy

Drop default case as there's already a branch for every value.

8d05925... by Olivier Tilloy

Do not modify oxide::ContentClient to access the application locale.

Instead, expose the application locale as a new method on BrowserPlatformIntegration.

d613e81... by Olivier Tilloy

Marked a private helper private.

e6dde29... by Olivier Tilloy

Ensure that autofill works in incognito mode, as expected.

559bd23... by Olivier Tilloy

Add tests for autofill in incognito webviews.

cb4b1d5... by Olivier Tilloy

Make WebAutofillPopupHost::Init not return anything, for consistency.

d4ec246... by Olivier Tilloy

Remove redundant std::move().

9b8a3c0... by Olivier Tilloy

Rename methods to start with an uppercase letter, for consistency with newly-written code.

7b47f20... by Olivier Tilloy

Take timeout into account.

75307e9... by Olivier Tilloy

Do not depend on the omnibox component in release builds.

f85f34f... by Olivier Tilloy

Rename files for consistency with newly-added code.

ea88035... by Olivier Tilloy

Remove unused references to gfx::NativeView (always null) in AutofillPopupController.

0c5a23f... by Olivier Tilloy

Remove unused method.

867131f... by Olivier Tilloy

Make ownership of AutofillPopupController explicit.

becd872... by Olivier Tilloy

Updated test.

3f0f3aa... by Olivier Tilloy

Fork WebDataServiceWrapper to remove bits that oxide doesn't need.

2283d7f... by Olivier Tilloy

New FilteredPrefStore class that stores all preferences in memory except for a selected set which are persisted on disk.

370bace... by Olivier Tilloy

Updated oxide.qmltypes.

Unmerged commits

370bace... by Olivier Tilloy

Updated oxide.qmltypes.

becd872... by Olivier Tilloy

Updated test.

2861ed9... by Olivier Tilloy

Ensure that the autofill profiles have been loaded before accessing them.

1925106... by Olivier Tilloy

New API on WebContext for autofill profiles management.

2283d7f... by Olivier Tilloy

New FilteredPrefStore class that stores all preferences in memory except for a selected set which are persisted on disk.

3f0f3aa... by Olivier Tilloy

Fork WebDataServiceWrapper to remove bits that oxide doesn't need.

867131f... by Olivier Tilloy

Make ownership of AutofillPopupController explicit.

0c5a23f... by Olivier Tilloy

Remove unused method.

ea88035... by Olivier Tilloy

Remove unused references to gfx::NativeView (always null) in AutofillPopupController.

f85f34f... by Olivier Tilloy

Rename files for consistency with newly-added code.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/qt/core/browser/oxide_qt_web_context.cc b/qt/core/browser/oxide_qt_web_context.cc
index fc1492f..678ec86 100644
--- a/qt/core/browser/oxide_qt_web_context.cc
+++ b/qt/core/browser/oxide_qt_web_context.cc
@@ -20,7 +20,6 @@
20#include <vector>20#include <vector>
2121
22#include <QDateTime>22#include <QDateTime>
23#include <QDebug>
24#include <QMetaMethod>23#include <QMetaMethod>
25#include <QNetworkCookie>24#include <QNetworkCookie>
26#include <QObject>25#include <QObject>
@@ -30,10 +29,13 @@
3029
31#include "base/auto_reset.h"30#include "base/auto_reset.h"
32#include "base/files/file_path.h"31#include "base/files/file_path.h"
32#include "base/guid.h"
33#include "base/logging.h"33#include "base/logging.h"
34#include "base/strings/string_util.h"34#include "base/strings/string_util.h"
35#include "base/strings/utf_string_conversions.h"
35#include "base/synchronization/lock.h"36#include "base/synchronization/lock.h"
36#include "base/threading/thread_task_runner_handle.h"37#include "base/threading/thread_task_runner_handle.h"
38#include "components/autofill/core/browser/personal_data_manager.h"
37#include "content/public/browser/browser_thread.h"39#include "content/public/browser/browser_thread.h"
38#include "content/public/browser/cookie_store_factory.h"40#include "content/public/browser/cookie_store_factory.h"
39#include "content/public/browser/resource_request_info.h"41#include "content/public/browser/resource_request_info.h"
@@ -59,6 +61,7 @@
59#include "shared/browser/oxide_user_agent_settings.h"61#include "shared/browser/oxide_user_agent_settings.h"
60#include "shared/browser/oxide_user_script_master.h"62#include "shared/browser/oxide_user_script_master.h"
61#include "shared/browser/permissions/oxide_temporary_saved_permission_context.h"63#include "shared/browser/permissions/oxide_temporary_saved_permission_context.h"
64#include "shared/browser/personal_data_manager_factory.h"
6265
63#include "oxide_qt_browser_startup.h"66#include "oxide_qt_browser_startup.h"
6467
@@ -85,6 +88,28 @@ int GetNextCookieRequestId() {
85 return id++;88 return id++;
86}89}
8790
91const char kAutofillOrigin[] = "oxide autofill";
92
93void PopulateAutofillProfileFromVariant(autofill::AutofillProfile* profile,
94 const QVariantMap& map) {
95#define SET_PROFILE_FIELD(field, key) \
96 profile->SetRawInfo(autofill::field, base::UTF8ToUTF16( \
97 map.value(QStringLiteral(key)).toString().toStdString()))
98 SET_PROFILE_FIELD(NAME_FIRST, "firstName");
99 SET_PROFILE_FIELD(NAME_MIDDLE, "middleName");
100 SET_PROFILE_FIELD(NAME_LAST, "lastName");
101 SET_PROFILE_FIELD(NAME_FULL, "fullName");
102 SET_PROFILE_FIELD(COMPANY_NAME, "companyName");
103 SET_PROFILE_FIELD(ADDRESS_HOME_STREET_ADDRESS, "address");
104 SET_PROFILE_FIELD(ADDRESS_HOME_CITY, "city");
105 SET_PROFILE_FIELD(ADDRESS_HOME_STATE, "state");
106 SET_PROFILE_FIELD(ADDRESS_HOME_ZIP, "zip");
107 SET_PROFILE_FIELD(ADDRESS_HOME_COUNTRY, "country");
108 SET_PROFILE_FIELD(PHONE_HOME_WHOLE_NUMBER, "phone");
109 SET_PROFILE_FIELD(EMAIL_ADDRESS, "email");
110#undef SET_PROFILE_FIELD
111}
112
88}113}
89114
90class WebContext::BrowserContextDelegate115class WebContext::BrowserContextDelegate
@@ -453,7 +478,13 @@ WebContext::WebContext(WebContextProxyClient* client,
453WebContext::~WebContext() {478WebContext::~WebContext() {
454 if (context_.get()) {479 if (context_.get()) {
455 context_->SetDelegate(nullptr);480 context_->SetDelegate(nullptr);
481
456 MediaCaptureDevicesContext::Get(context_.get())->set_client(nullptr);482 MediaCaptureDevicesContext::Get(context_.get())->set_client(nullptr);
483
484 autofill::PersonalDataManager* manager =
485 PersonalDataManagerFactory::GetForContext(context_.get());
486 DCHECK(manager);
487 manager->RemoveObserver(this);
457 }488 }
458}489}
459490
@@ -538,6 +569,12 @@ BrowserContext* WebContext::GetContext() {
538569
539 UpdateUserScripts();570 UpdateUserScripts();
540571
572 autofill::PersonalDataManager* manager =
573 PersonalDataManagerFactory::GetForContext(context_.get());
574 DCHECK(manager);
575 manager->AddObserver(this);
576 client_->AutofillProfilesChanged();
577
541 return context_.get();578 return context_.get();
542}579}
543580
@@ -1001,6 +1038,10 @@ void WebContext::DefaultVideoDeviceChanged() {
1001 client_->DefaultVideoCaptureDeviceChanged();1038 client_->DefaultVideoCaptureDeviceChanged();
1002}1039}
10031040
1041void WebContext::OnPersonalDataChanged() {
1042 client_->AutofillProfilesChanged();
1043}
1044
1004bool WebContext::doNotTrack() const {1045bool WebContext::doNotTrack() const {
1005 if (IsInitialized()) {1046 if (IsInitialized()) {
1006 return UserAgentSettings::Get(context_.get())->GetDoNotTrack();1047 return UserAgentSettings::Get(context_.get())->GetDoNotTrack();
@@ -1033,5 +1074,107 @@ void WebContext::setAutofillEnabled(bool enabled) {
1033 }1074 }
1034}1075}
10351076
1077bool WebContext::autofillProfilesLoaded() const {
1078 if (!IsInitialized()) {
1079 return false;
1080 }
1081
1082 autofill::PersonalDataManager* manager =
1083 PersonalDataManagerFactory::GetForContext(context_.get());
1084 DCHECK(manager);
1085 return manager->IsDataLoaded();
1086}
1087
1088QStringList WebContext::getAutofillProfiles() const {
1089 if (!autofillProfilesLoaded()) {
1090 return QStringList();
1091 }
1092
1093 autofill::PersonalDataManager* manager =
1094 PersonalDataManagerFactory::GetForContext(context_.get());
1095 QStringList rv;
1096 for (auto profile : manager->GetProfiles()) {
1097 rv.append(QString::fromStdString(profile->guid()));
1098 }
1099 return rv;
1100}
1101
1102QVariant WebContext::getAutofillProfile(const QString& guid) const {
1103 if (!autofillProfilesLoaded()) {
1104 return QVariant();
1105 }
1106
1107 autofill::PersonalDataManager* manager =
1108 PersonalDataManagerFactory::GetForContext(context_.get());
1109 autofill::AutofillProfile* profile =
1110 manager->GetProfileByGUID(guid.toStdString());
1111 if (!profile) {
1112 return QVariant();
1113 }
1114
1115 QVariantMap rv;
1116 const std::string& locale = manager->app_locale();
1117 rv[QStringLiteral("guid")] = QString::fromStdString(profile->guid());
1118 rv[QStringLiteral("origin")] = QString::fromStdString(profile->origin());
1119#define GET_PROFILE_FIELD(key, field) \
1120 rv[QStringLiteral(key)] = QString::fromStdString(base::UTF16ToUTF8( \
1121 profile->GetInfo(autofill::AutofillType(autofill::field), locale)))
1122 GET_PROFILE_FIELD("firstName", NAME_FIRST);
1123 GET_PROFILE_FIELD("middleName", NAME_MIDDLE);
1124 GET_PROFILE_FIELD("lastName", NAME_LAST);
1125 GET_PROFILE_FIELD("fullName", NAME_FULL);
1126 GET_PROFILE_FIELD("companyName", COMPANY_NAME);
1127 GET_PROFILE_FIELD("address", ADDRESS_HOME_STREET_ADDRESS);
1128 GET_PROFILE_FIELD("city", ADDRESS_HOME_CITY);
1129 GET_PROFILE_FIELD("state", ADDRESS_HOME_STATE);
1130 GET_PROFILE_FIELD("zip", ADDRESS_HOME_ZIP);
1131 GET_PROFILE_FIELD("country", ADDRESS_HOME_COUNTRY);
1132 GET_PROFILE_FIELD("phone", PHONE_HOME_WHOLE_NUMBER);
1133 GET_PROFILE_FIELD("email", EMAIL_ADDRESS);
1134#undef GET_PROFILE_FIELD
1135 return rv;
1136}
1137
1138void WebContext::addAutofillProfile(const QVariant& profile) {
1139 if (!autofillProfilesLoaded()) {
1140 return;
1141 }
1142
1143 autofill::PersonalDataManager* manager =
1144 PersonalDataManagerFactory::GetForContext(context_.get());
1145 autofill::AutofillProfile ap(base::GenerateGUID(), kAutofillOrigin);
1146 PopulateAutofillProfileFromVariant(&ap, profile.toMap());
1147 manager->AddProfile(ap);
1148}
1149
1150void WebContext::removeAutofillProfile(const QString& guid) {
1151 if (!autofillProfilesLoaded()) {
1152 return;
1153 }
1154
1155 autofill::PersonalDataManager* manager =
1156 PersonalDataManagerFactory::GetForContext(context_.get());
1157 manager->RemoveByGUID(guid.toStdString());
1158}
1159
1160void WebContext::updateAutofillProfile(const QVariant& profile) {
1161 if (!autofillProfilesLoaded()) {
1162 return;
1163 }
1164
1165 QVariantMap map = profile.toMap();
1166 if (!map.contains(QStringLiteral("guid"))) {
1167 return;
1168 }
1169
1170 autofill::PersonalDataManager* manager =
1171 PersonalDataManagerFactory::GetForContext(context_.get());
1172 autofill::AutofillProfile ap(
1173 map.value(QStringLiteral("guid")).toString().toStdString(),
1174 map.value(QStringLiteral("origin")).toString().toStdString());
1175 PopulateAutofillProfileFromVariant(&ap, profile.toMap());
1176 manager->UpdateProfile(ap);
1177}
1178
1036} // namespace qt1179} // namespace qt
1037} // namespace oxide1180} // namespace oxide
diff --git a/qt/core/browser/oxide_qt_web_context.h b/qt/core/browser/oxide_qt_web_context.h
index 1dd4134..ef5817c 100644
--- a/qt/core/browser/oxide_qt_web_context.h
+++ b/qt/core/browser/oxide_qt_web_context.h
@@ -29,6 +29,7 @@
29#include "base/macros.h"29#include "base/macros.h"
30#include "base/memory/ref_counted.h"30#include "base/memory/ref_counted.h"
31#include "base/memory/weak_ptr.h"31#include "base/memory/weak_ptr.h"
32#include "components/autofill/core/browser/personal_data_manager_observer.h"
32#include "net/cookies/canonical_cookie.h"33#include "net/cookies/canonical_cookie.h"
3334
34#include "qt/core/glue/oxide_qt_web_context_proxy.h"35#include "qt/core/glue/oxide_qt_web_context_proxy.h"
@@ -67,7 +68,8 @@ class WebContextGetter : public base::RefCountedThreadSafe<WebContextGetter> {
67};68};
6869
69class WebContext : public WebContextProxy,70class WebContext : public WebContextProxy,
70 public oxide::MediaCaptureDevicesContextClient {71 public oxide::MediaCaptureDevicesContextClient,
72 public autofill::PersonalDataManagerObserver {
71 public:73 public:
72 WebContext(WebContextProxyClient* client, QObject* handle);74 WebContext(WebContextProxyClient* client, QObject* handle);
73 ~WebContext();75 ~WebContext();
@@ -147,10 +149,20 @@ class WebContext : public WebContextProxy,
147 bool autofillEnabled() const override;149 bool autofillEnabled() const override;
148 void setAutofillEnabled(bool enabled) override;150 void setAutofillEnabled(bool enabled) override;
149151
152 bool autofillProfilesLoaded() const override;
153 QStringList getAutofillProfiles() const override;
154 QVariant getAutofillProfile(const QString& guid) const override;
155 void addAutofillProfile(const QVariant& profile) override;
156 void removeAutofillProfile(const QString& guid) override;
157 void updateAutofillProfile(const QVariant& profile) override;
158
150 // oxide::MediaCaptureDevicesContextClient implementation159 // oxide::MediaCaptureDevicesContextClient implementation
151 void DefaultAudioDeviceChanged() override;160 void DefaultAudioDeviceChanged() override;
152 void DefaultVideoDeviceChanged() override;161 void DefaultVideoDeviceChanged() override;
153162
163 // autofill::PersonalDataManagerObserver implementation
164 void OnPersonalDataChanged() override;
165
154 WebContextProxyClient* client_;166 WebContextProxyClient* client_;
155167
156 BrowserContext::UniquePtr context_;168 BrowserContext::UniquePtr context_;
diff --git a/qt/core/glue/oxide_qt_web_context_proxy.h b/qt/core/glue/oxide_qt_web_context_proxy.h
index 49f0180..59b9b6b 100644
--- a/qt/core/glue/oxide_qt_web_context_proxy.h
+++ b/qt/core/glue/oxide_qt_web_context_proxy.h
@@ -23,6 +23,7 @@
23#include <QStringList>23#include <QStringList>
24#include <QtGlobal>24#include <QtGlobal>
25#include <QUrl>25#include <QUrl>
26#include <QVariant>
26#include <QWeakPointer>27#include <QWeakPointer>
2728
28#include "qt/core/api/oxideqglobal.h"29#include "qt/core/api/oxideqglobal.h"
@@ -140,6 +141,13 @@ class OXIDE_QTCORE_EXPORT WebContextProxy : public ProxyBase<WebContext> {
140141
141 virtual bool autofillEnabled() const = 0;142 virtual bool autofillEnabled() const = 0;
142 virtual void setAutofillEnabled(bool enabled) = 0;143 virtual void setAutofillEnabled(bool enabled) = 0;
144
145 virtual bool autofillProfilesLoaded() const = 0;
146 virtual QStringList getAutofillProfiles() const = 0;
147 virtual QVariant getAutofillProfile(const QString& guid) const = 0;
148 virtual void addAutofillProfile(const QVariant& profile) = 0;
149 virtual void removeAutofillProfile(const QString& guid) = 0;
150 virtual void updateAutofillProfile(const QVariant& profile) = 0;
143};151};
144152
145} // namespace qt153} // namespace qt
diff --git a/qt/core/glue/oxide_qt_web_context_proxy_client.h b/qt/core/glue/oxide_qt_web_context_proxy_client.h
index a449c60..9c710d9 100644
--- a/qt/core/glue/oxide_qt_web_context_proxy_client.h
+++ b/qt/core/glue/oxide_qt_web_context_proxy_client.h
@@ -1,5 +1,5 @@
1// vim:expandtab:shiftwidth=2:tabstop=2:1// vim:expandtab:shiftwidth=2:tabstop=2:
2// Copyright (C) 2013-2015 Canonical Ltd.2// Copyright (C) 2013-2017 Canonical Ltd.
33
4// This library is free software; you can redistribute it and/or4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public5// modify it under the terms of the GNU Lesser General Public
@@ -51,6 +51,8 @@ class WebContextProxyClient {
5151
52 virtual void DefaultVideoCaptureDeviceChanged() = 0;52 virtual void DefaultVideoCaptureDeviceChanged() = 0;
5353
54 virtual void AutofillProfilesChanged() = 0;
55
54 class IOClient {56 class IOClient {
55 public:57 public:
56 virtual ~IOClient() {}58 virtual ~IOClient() {}
diff --git a/qt/qmlplugin/oxide.qmltypes b/qt/qmlplugin/oxide.qmltypes
index 1d7d164..2adbde8 100644
--- a/qt/qmlplugin/oxide.qmltypes
+++ b/qt/qmlplugin/oxide.qmltypes
@@ -186,6 +186,31 @@ Module {
186 Method { name: "deny" }186 Method { name: "deny" }
187 }187 }
188 Component {188 Component {
189 name: "OxideQQuickAutofillProfiles"
190 prototype: "QAbstractListModel"
191 exports: ["AutofillProfiles 1.22"]
192 isCreatable: false
193 exportMetaObjectRevisions: [0]
194 Property { name: "ready"; type: "bool"; isReadonly: true }
195 Method {
196 name: "get"
197 type: "QVariant"
198 Parameter { name: "guid"; type: "string" }
199 }
200 Method {
201 name: "add"
202 Parameter { name: "profile"; type: "QVariant" }
203 }
204 Method {
205 name: "remove"
206 Parameter { name: "guid"; type: "string" }
207 }
208 Method {
209 name: "update"
210 Parameter { name: "profile"; type: "QVariant" }
211 }
212 }
213 Component {
189 name: "OxideQQuickCookieManager"214 name: "OxideQQuickCookieManager"
190 prototype: "QObject"215 prototype: "QObject"
191 exports: ["CookieManager 1.0", "CookieManager 1.3"]216 exports: ["CookieManager 1.0", "CookieManager 1.3"]
@@ -477,6 +502,13 @@ Module {
477 Property { name: "userAgentOverrides"; revision: 3; type: "QVariantList" }502 Property { name: "userAgentOverrides"; revision: 3; type: "QVariantList" }
478 Property { name: "doNotTrackEnabled"; revision: 3; type: "bool" }503 Property { name: "doNotTrackEnabled"; revision: 3; type: "bool" }
479 Property { name: "autofillEnabled"; revision: 4; type: "bool" }504 Property { name: "autofillEnabled"; revision: 4; type: "bool" }
505 Property {
506 name: "autofillProfiles"
507 revision: 4
508 type: "OxideQQuickAutofillProfiles"
509 isReadonly: true
510 isPointer: true
511 }
480 Signal { name: "devtoolsBindIpChanged" }512 Signal { name: "devtoolsBindIpChanged" }
481 Signal { name: "hostMappingRulesChanged"; revision: 1 }513 Signal { name: "hostMappingRulesChanged"; revision: 1 }
482 Signal { name: "allowedExtraUrlSchemesChanged"; revision: 1 }514 Signal { name: "allowedExtraUrlSchemesChanged"; revision: 1 }
diff --git a/qt/qmlplugin/oxide_qml_plugin.cc b/qt/qmlplugin/oxide_qml_plugin.cc
index cf2e41c..749d66f 100644
--- a/qt/qmlplugin/oxide_qml_plugin.cc
+++ b/qt/qmlplugin/oxide_qml_plugin.cc
@@ -34,6 +34,7 @@
34#include "qt/core/api/oxideqsecuritystatus.h"34#include "qt/core/api/oxideqsecuritystatus.h"
35#include "qt/core/api/oxideqsslcertificate.h"35#include "qt/core/api/oxideqsslcertificate.h"
36#include "qt/core/api/oxideqwebpreferences.h"36#include "qt/core/api/oxideqwebpreferences.h"
37#include "qt/quick/api/oxideqquickautofillprofiles.h"
37#include "qt/quick/api/oxideqquickcookiemanager_p.h"38#include "qt/quick/api/oxideqquickcookiemanager_p.h"
38#include "qt/quick/api/oxideqquickglobal_p.h"39#include "qt/quick/api/oxideqquickglobal_p.h"
39#include "qt/quick/api/oxideqquicklocationbarcontroller.h"40#include "qt/quick/api/oxideqquicklocationbarcontroller.h"
@@ -217,6 +218,9 @@ class OxideQmlPlugin : public QQmlExtensionPlugin {
217 "NavigationHistory is accessed via WebView.navigationHistory");218 "NavigationHistory is accessed via WebView.navigationHistory");
218219
219 qmlRegisterType<OxideQQuickWebContext, 4>(uri, 1, 22, "WebContext");220 qmlRegisterType<OxideQQuickWebContext, 4>(uri, 1, 22, "WebContext");
221 qmlRegisterUncreatableType<OxideQQuickAutofillProfiles>(
222 uri, 1, 22, "AutofillProfiles",
223 "AutofillProfiles is accessed via WebContext.autofillProfiles");
220 }224 }
221};225};
222226
diff --git a/qt/quick/CMakeLists.txt b/qt/quick/CMakeLists.txt
index 3737b68..416a7ce 100644
--- a/qt/quick/CMakeLists.txt
+++ b/qt/quick/CMakeLists.txt
@@ -1,6 +1,6 @@
1# vim:expandtab:shiftwidth=2:tabstop=2:1# vim:expandtab:shiftwidth=2:tabstop=2:
22
3# Copyright (C) 2014-2016 Canonical Ltd.3# Copyright (C) 2014-2017 Canonical Ltd.
44
5# This library is free software; you can redistribute it and/or5# This library is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public6# modify it under the terms of the GNU Lesser General Public
@@ -20,6 +20,7 @@ qt5_wrap_cpp(MOC_EXTRA
20 api/oxideqquickwebcontextdelegateworker_p_p.h)20 api/oxideqquickwebcontextdelegateworker_p_p.h)
2121
22set(OXIDE_QUICKLIB_SRCS22set(OXIDE_QUICKLIB_SRCS
23 api/oxideqquickautofillprofiles.cc
23 api/oxideqquickcookiemanager.cc24 api/oxideqquickcookiemanager.cc
24 api/oxideqquickglobal.cc25 api/oxideqquickglobal.cc
25 api/oxideqquicklocationbarcontroller.cc26 api/oxideqquicklocationbarcontroller.cc
diff --git a/qt/quick/api/oxideqquickautofillprofiles.cc b/qt/quick/api/oxideqquickautofillprofiles.cc
26new file mode 10064427new file mode 100644
index 0000000..835984c
--- /dev/null
+++ b/qt/quick/api/oxideqquickautofillprofiles.cc
@@ -0,0 +1,193 @@
1// vim:expandtab:shiftwidth=2:tabstop=2:
2// Copyright (C) 2017 Canonical Ltd.
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18#include "oxideqquickautofillprofiles.h"
19#include "oxideqquickautofillprofiles_p.h"
20
21#include <QString>
22
23#include "qt/core/glue/oxide_qt_web_context_proxy.h"
24
25OxideQQuickAutofillProfilesPrivate::OxideQQuickAutofillProfilesPrivate(
26 OxideQQuickAutofillProfiles* q)
27 : q_ptr(q),
28 model_items_need_rebuilding_(true) {}
29
30void OxideQQuickAutofillProfilesPrivate::ensureModelItemsAreBuilt() {
31 if (!model_items_need_rebuilding_) {
32 return;
33 }
34
35 Q_ASSERT(model_items_.isEmpty());
36 model_items_need_rebuilding_ = false;
37
38 QStringList guids = web_context_proxy_->getAutofillProfiles();
39 for (const auto& guid : guids) {
40 model_items_.append(web_context_proxy_->getAutofillProfile(guid));
41 }
42}
43
44void OxideQQuickAutofillProfilesPrivate::AutofillProfilesChanged() {
45 Q_Q(OxideQQuickAutofillProfiles);
46
47 model_items_need_rebuilding_ = false;
48 q->beginResetModel();
49 model_items_need_rebuilding_ = true;
50 model_items_.clear();
51 q->endResetModel();
52
53 Q_EMIT q->readyChanged();
54}
55
56OxideQQuickAutofillProfilesPrivate
57 ::~OxideQQuickAutofillProfilesPrivate() = default;
58
59// static
60OxideQQuickAutofillProfilesPrivate* OxideQQuickAutofillProfilesPrivate::get(
61 OxideQQuickAutofillProfiles* q) {
62 return q->d_func();
63}
64
65// static
66std::unique_ptr<OxideQQuickAutofillProfiles>
67OxideQQuickAutofillProfilesPrivate::Create() {
68 return std::unique_ptr<OxideQQuickAutofillProfiles>(
69 new OxideQQuickAutofillProfiles());
70}
71
72void OxideQQuickAutofillProfilesPrivate::SetWebContextProxy(
73 oxide::qt::WebContextProxy* proxy) {
74 web_context_proxy_ = proxy;
75}
76
77OxideQQuickAutofillProfiles::OxideQQuickAutofillProfiles()
78 : d_ptr(new OxideQQuickAutofillProfilesPrivate(this)) {}
79
80bool OxideQQuickAutofillProfiles::ready() const {
81 Q_D(const OxideQQuickAutofillProfiles);
82
83 return d->web_context_proxy_->autofillProfilesLoaded();
84}
85
86QHash<int, QByteArray> OxideQQuickAutofillProfiles::roleNames() const {
87 static QHash<int, QByteArray> roles;
88 if (roles.isEmpty()) {
89 roles[OxideQQuickAutofillProfilesPrivate::Guid] = "guid";
90 roles[OxideQQuickAutofillProfilesPrivate::Origin] = "origin";
91 roles[OxideQQuickAutofillProfilesPrivate::FirstName] = "firstName";
92 roles[OxideQQuickAutofillProfilesPrivate::MiddleName] = "middleName";
93 roles[OxideQQuickAutofillProfilesPrivate::LastName] = "lastName";
94 roles[OxideQQuickAutofillProfilesPrivate::FullName] = "fullName";
95 roles[OxideQQuickAutofillProfilesPrivate::CompanyName] = "companyName";
96 roles[OxideQQuickAutofillProfilesPrivate::Address] = "address";
97 roles[OxideQQuickAutofillProfilesPrivate::City] = "city";
98 roles[OxideQQuickAutofillProfilesPrivate::State] = "state";
99 roles[OxideQQuickAutofillProfilesPrivate::Zip] = "zip";
100 roles[OxideQQuickAutofillProfilesPrivate::Country] = "country";
101 roles[OxideQQuickAutofillProfilesPrivate::Phone] = "phone";
102 roles[OxideQQuickAutofillProfilesPrivate::Email] = "email";
103 }
104 return roles;
105}
106
107int OxideQQuickAutofillProfiles::rowCount(const QModelIndex& parent) const {
108 Q_UNUSED(parent);
109 Q_D(const OxideQQuickAutofillProfiles);
110
111 const_cast<OxideQQuickAutofillProfiles*>(this)
112 ->d_func()->ensureModelItemsAreBuilt();
113
114 return d->model_items_.size();
115}
116
117QVariant OxideQQuickAutofillProfiles::data(const QModelIndex& index,
118 int role) const {
119 Q_D(const OxideQQuickAutofillProfiles);
120
121 const_cast<OxideQQuickAutofillProfiles*>(this)
122 ->d_func()->ensureModelItemsAreBuilt();
123
124 if (!index.isValid()) {
125 return QVariant();
126 }
127
128 int row = index.row();
129 if ((row < 0) || (row >= d->model_items_.size())) {
130 return QVariant();
131 }
132
133 const QVariantMap& item = d->model_items_[row].toMap();
134
135 switch (role) {
136 case OxideQQuickAutofillProfilesPrivate::Guid:
137 return item.value(QStringLiteral("guid"));
138 case OxideQQuickAutofillProfilesPrivate::Origin:
139 return item.value(QStringLiteral("origin"));
140 case OxideQQuickAutofillProfilesPrivate::FirstName:
141 return item.value(QStringLiteral("firstName"));
142 case OxideQQuickAutofillProfilesPrivate::MiddleName:
143 return item.value(QStringLiteral("middleName"));
144 case OxideQQuickAutofillProfilesPrivate::LastName:
145 return item.value(QStringLiteral("lastName"));
146 case OxideQQuickAutofillProfilesPrivate::FullName:
147 return item.value(QStringLiteral("fullName"));
148 case OxideQQuickAutofillProfilesPrivate::CompanyName:
149 return item.value(QStringLiteral("companyName"));
150 case OxideQQuickAutofillProfilesPrivate::Address:
151 return item.value(QStringLiteral("address"));
152 case OxideQQuickAutofillProfilesPrivate::City:
153 return item.value(QStringLiteral("city"));
154 case OxideQQuickAutofillProfilesPrivate::State:
155 return item.value(QStringLiteral("state"));
156 case OxideQQuickAutofillProfilesPrivate::Zip:
157 return item.value(QStringLiteral("zip"));
158 case OxideQQuickAutofillProfilesPrivate::Country:
159 return item.value(QStringLiteral("country"));
160 case OxideQQuickAutofillProfilesPrivate::Phone:
161 return item.value(QStringLiteral("phone"));
162 case OxideQQuickAutofillProfilesPrivate::Email:
163 return item.value(QStringLiteral("email"));
164 default:
165 return QVariant();
166 }
167}
168
169OxideQQuickAutofillProfiles::~OxideQQuickAutofillProfiles() = default;
170
171QVariant OxideQQuickAutofillProfiles::get(const QString& guid) const {
172 Q_D(const OxideQQuickAutofillProfiles);
173
174 return d->web_context_proxy_->getAutofillProfile(guid);
175}
176
177void OxideQQuickAutofillProfiles::add(const QVariant& profile) {
178 Q_D(OxideQQuickAutofillProfiles);
179
180 d->web_context_proxy_->addAutofillProfile(profile);
181}
182
183void OxideQQuickAutofillProfiles::remove(const QString& guid) {
184 Q_D(OxideQQuickAutofillProfiles);
185
186 d->web_context_proxy_->removeAutofillProfile(guid);
187}
188
189void OxideQQuickAutofillProfiles::update(const QVariant& profile) {
190 Q_D(OxideQQuickAutofillProfiles);
191
192 d->web_context_proxy_->updateAutofillProfile(profile);
193}
diff --git a/qt/quick/api/oxideqquickautofillprofiles.h b/qt/quick/api/oxideqquickautofillprofiles.h
0new file mode 100644194new file mode 100644
index 0000000..7022037
--- /dev/null
+++ b/qt/quick/api/oxideqquickautofillprofiles.h
@@ -0,0 +1,68 @@
1// vim:expandtab:shiftwidth=2:tabstop=2:
2// Copyright (C) 2017 Canonical Ltd.
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18#ifndef OXIDE_QTQUICK_AUTOFILL_PROFILES
19#define OXIDE_QTQUICK_AUTOFILL_PROFILES
20
21#include <QtCore/QAbstractListModel>
22#include <QtCore/QScopedPointer>
23#include <QtCore/QVariant>
24#include <QtQml/QtQml>
25
26#include <OxideQtQuick/oxideqquickglobal.h>
27
28class QString;
29
30class OxideQQuickAutofillProfilesPrivate;
31
32class OXIDE_QTQUICK_EXPORT OxideQQuickAutofillProfiles
33 : public QAbstractListModel {
34 Q_OBJECT
35
36 Q_PROPERTY(bool ready READ ready NOTIFY readyChanged)
37
38 Q_DECLARE_PRIVATE(OxideQQuickAutofillProfiles)
39 Q_DISABLE_COPY(OxideQQuickAutofillProfiles)
40
41 public:
42 ~OxideQQuickAutofillProfiles() Q_DECL_OVERRIDE;
43
44 bool ready() const;
45
46 public Q_SLOTS:
47 QVariant get(const QString& guid) const;
48 void add(const QVariant& profile);
49 void remove(const QString& guid);
50 void update(const QVariant& profile);
51
52 Q_SIGNALS:
53 void readyChanged();
54
55 private:
56 OxideQQuickAutofillProfiles();
57
58 // reimplemented from QAbstractListModel
59 QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
60 int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
61 QVariant data(const QModelIndex& index, int role) const Q_DECL_OVERRIDE;
62
63 QScopedPointer<OxideQQuickAutofillProfilesPrivate> d_ptr;
64};
65
66QML_DECLARE_TYPE(OxideQQuickAutofillProfiles)
67
68#endif // OXIDE_QTQUICK_AUTOFILL_PROFILES
diff --git a/qt/quick/api/oxideqquickautofillprofiles_p.h b/qt/quick/api/oxideqquickautofillprofiles_p.h
0new file mode 10064469new file mode 100644
index 0000000..d47b60b
--- /dev/null
+++ b/qt/quick/api/oxideqquickautofillprofiles_p.h
@@ -0,0 +1,80 @@
1// vim:expandtab:shiftwidth=2:tabstop=2:
2// Copyright (C) 2017 Canonical Ltd.
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18#ifndef _OXIDE_QT_QUICK_API_AUTOFILL_PROFILES_P_H_
19#define _OXIDE_QT_QUICK_API_AUTOFILL_PROFILES_P_H_
20
21#include <memory>
22
23#include <QtGlobal>
24#include <QVariantList>
25
26namespace oxide {
27namespace qt {
28class WebContextProxy;
29}
30}
31
32class OxideQQuickAutofillProfiles;
33
34class OxideQQuickAutofillProfilesPrivate {
35 Q_DECLARE_PUBLIC(OxideQQuickAutofillProfiles)
36 Q_DISABLE_COPY(OxideQQuickAutofillProfilesPrivate)
37
38 public:
39 ~OxideQQuickAutofillProfilesPrivate();
40
41 static OxideQQuickAutofillProfilesPrivate* get(
42 OxideQQuickAutofillProfiles* q);
43
44 static std::unique_ptr<OxideQQuickAutofillProfiles> Create();
45
46 void SetWebContextProxy(oxide::qt::WebContextProxy* proxy);
47
48 void AutofillProfilesChanged();
49
50 private:
51 OxideQQuickAutofillProfilesPrivate(OxideQQuickAutofillProfiles* q);
52
53 void ensureModelItemsAreBuilt();
54
55 enum Roles {
56 Guid = Qt::UserRole + 1,
57 Origin,
58 FirstName,
59 MiddleName,
60 LastName,
61 FullName,
62 CompanyName,
63 Address,
64 City,
65 State,
66 Zip,
67 Country,
68 Phone,
69 Email
70 };
71
72 OxideQQuickAutofillProfiles* q_ptr;
73
74 oxide::qt::WebContextProxy* web_context_proxy_;
75
76 bool model_items_need_rebuilding_;
77 QVariantList model_items_;
78};
79
80#endif // _OXIDE_QT_QUICK_API_AUTOFILL_PROFILES_P_H_
diff --git a/qt/quick/api/oxideqquickwebcontext.cc b/qt/quick/api/oxideqquickwebcontext.cc
index 1946af0..92b99ee 100644
--- a/qt/quick/api/oxideqquickwebcontext.cc
+++ b/qt/quick/api/oxideqquickwebcontext.cc
@@ -1,5 +1,5 @@
1// vim:expandtab:shiftwidth=2:tabstop=2:1// vim:expandtab:shiftwidth=2:tabstop=2:
2// Copyright (C) 2013-2016 Canonical Ltd.2// Copyright (C) 2013-2017 Canonical Ltd.
33
4// This library is free software; you can redistribute it and/or4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public5// modify it under the terms of the GNU Lesser General Public
@@ -35,6 +35,8 @@
35#include "qt/core/glue/oxide_qt_web_context_proxy.h"35#include "qt/core/glue/oxide_qt_web_context_proxy.h"
36#include "qt/quick/oxide_qquick_init.h"36#include "qt/quick/oxide_qquick_init.h"
3737
38#include "oxideqquickautofillprofiles.h"
39#include "oxideqquickautofillprofiles_p.h"
38#include "oxideqquickcookiemanager_p.h"40#include "oxideqquickcookiemanager_p.h"
39#include "oxideqquickuserscript.h"41#include "oxideqquickuserscript.h"
40#include "oxideqquickuserscript_p.h"42#include "oxideqquickuserscript_p.h"
@@ -213,7 +215,11 @@ OxideQQuickWebContextPrivate::OxideQQuickWebContextPrivate(
213 proxy_(WebContextProxy::create(this, q)),215 proxy_(WebContextProxy::create(this, q)),
214 constructed_(false),216 constructed_(false),
215 io_(new oxide::qquick::WebContextIODelegate()),217 io_(new oxide::qquick::WebContextIODelegate()),
216 cookie_manager_(nullptr) {}218 cookie_manager_(nullptr),
219 autofill_profiles_(OxideQQuickAutofillProfilesPrivate::Create()) {
220 OxideQQuickAutofillProfilesPrivate::get(autofill_profiles_.get())
221 ->SetWebContextProxy(proxy_.data());
222}
217223
218void OxideQQuickWebContextPrivate::userScriptUpdated() {224void OxideQQuickWebContextPrivate::userScriptUpdated() {
219 proxy_->updateUserScripts();225 proxy_->updateUserScripts();
@@ -391,6 +397,13 @@ void OxideQQuickWebContextPrivate::DefaultVideoCaptureDeviceChanged() {
391 emit q->defaultVideoCaptureDeviceIdChanged();397 emit q->defaultVideoCaptureDeviceIdChanged();
392}398}
393399
400void OxideQQuickWebContextPrivate::AutofillProfilesChanged() {
401 Q_Q(OxideQQuickWebContext);
402
403 OxideQQuickAutofillProfilesPrivate::get(autofill_profiles_.get())
404 ->AutofillProfilesChanged();
405}
406
394OxideQQuickWebContextPrivate::~OxideQQuickWebContextPrivate() {}407OxideQQuickWebContextPrivate::~OxideQQuickWebContextPrivate() {}
395408
396void OxideQQuickWebContextPrivate::delegateWorkerDestroyed(409void OxideQQuickWebContextPrivate::delegateWorkerDestroyed(
@@ -1592,4 +1605,10 @@ void OxideQQuickWebContext::setAutofillEnabled(bool enabled) {
1592 emit autofillEnabledChanged();1605 emit autofillEnabledChanged();
1593}1606}
15941607
1608OxideQQuickAutofillProfiles* OxideQQuickWebContext::autofillProfiles() const {
1609 Q_D(const OxideQQuickWebContext);
1610
1611 return d->autofill_profiles_.get();
1612}
1613
1595#include "moc_oxideqquickwebcontext.cpp"1614#include "moc_oxideqquickwebcontext.cpp"
diff --git a/qt/quick/api/oxideqquickwebcontext.h b/qt/quick/api/oxideqquickwebcontext.h
index f8ca6fa..85c1773 100644
--- a/qt/quick/api/oxideqquickwebcontext.h
+++ b/qt/quick/api/oxideqquickwebcontext.h
@@ -30,6 +30,7 @@
3030
31#include <OxideQtQuick/oxideqquickglobal.h>31#include <OxideQtQuick/oxideqquickglobal.h>
3232
33class OxideQQuickAutofillProfiles;
33class OxideQQuickCookieManager;34class OxideQQuickCookieManager;
34class OxideQQuickWebContextDelegateWorker;35class OxideQQuickWebContextDelegateWorker;
35class OxideQQuickUserScript;36class OxideQQuickUserScript;
@@ -78,6 +79,7 @@ class OXIDE_QTQUICK_EXPORT OxideQQuickWebContext : public QObject,
78 Q_PROPERTY(bool doNotTrackEnabled READ doNotTrack WRITE setDoNotTrack NOTIFY doNotTrackEnabledChanged REVISION 3)79 Q_PROPERTY(bool doNotTrackEnabled READ doNotTrack WRITE setDoNotTrack NOTIFY doNotTrackEnabledChanged REVISION 3)
7980
80 Q_PROPERTY(bool autofillEnabled READ autofillEnabled WRITE setAutofillEnabled NOTIFY autofillEnabledChanged REVISION 4)81 Q_PROPERTY(bool autofillEnabled READ autofillEnabled WRITE setAutofillEnabled NOTIFY autofillEnabledChanged REVISION 4)
82 Q_PROPERTY(OxideQQuickAutofillProfiles* autofillProfiles READ autofillProfiles CONSTANT REVISION 4)
8183
82 Q_ENUMS(CookiePolicy)84 Q_ENUMS(CookiePolicy)
83 Q_ENUMS(SessionCookieMode)85 Q_ENUMS(SessionCookieMode)
@@ -178,6 +180,8 @@ class OXIDE_QTQUICK_EXPORT OxideQQuickWebContext : public QObject,
178 bool autofillEnabled() const;180 bool autofillEnabled() const;
179 void setAutofillEnabled(bool enabled);181 void setAutofillEnabled(bool enabled);
180182
183 OxideQQuickAutofillProfiles* autofillProfiles() const;
184
181 Q_SIGNALS:185 Q_SIGNALS:
182 void productChanged();186 void productChanged();
183 void userAgentChanged();187 void userAgentChanged();
diff --git a/qt/quick/api/oxideqquickwebcontext_p.h b/qt/quick/api/oxideqquickwebcontext_p.h
index 262e132..4e9f34a 100644
--- a/qt/quick/api/oxideqquickwebcontext_p.h
+++ b/qt/quick/api/oxideqquickwebcontext_p.h
@@ -1,5 +1,5 @@
1// vim:expandtab:shiftwidth=2:tabstop=2:1// vim:expandtab:shiftwidth=2:tabstop=2:
2// Copyright (C) 2013-2016 Canonical Ltd.2// Copyright (C) 2013-2017 Canonical Ltd.
33
4// This library is free software; you can redistribute it and/or4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public5// modify it under the terms of the GNU Lesser General Public
@@ -25,10 +25,13 @@
25#include <QStringList>25#include <QStringList>
26#include <QtGlobal>26#include <QtGlobal>
2727
28#include <memory>
29
28#include "qt/core/glue/oxide_qt_web_context_proxy_client.h"30#include "qt/core/glue/oxide_qt_web_context_proxy_client.h"
2931
30#include "qt/quick/api/oxideqquickwebcontext.h"32#include "qt/quick/api/oxideqquickwebcontext.h"
3133
34class OxideQQuickAutofillProfiles;
32class OxideQQuickWebContextDelegateWorker;35class OxideQQuickWebContextDelegateWorker;
33class OxideQQuickUserScript;36class OxideQQuickUserScript;
3437
@@ -108,6 +111,7 @@ class Q_DECL_EXPORT OxideQQuickWebContextPrivate
108 QNetworkAccessManager* GetCustomNetworkAccessManager() override;111 QNetworkAccessManager* GetCustomNetworkAccessManager() override;
109 void DefaultAudioCaptureDeviceChanged() override;112 void DefaultAudioCaptureDeviceChanged() override;
110 void DefaultVideoCaptureDeviceChanged() override;113 void DefaultVideoCaptureDeviceChanged() override;
114 void AutofillProfilesChanged() override;
111115
112 OxideQQuickWebContext* q_ptr;116 OxideQQuickWebContext* q_ptr;
113117
@@ -125,6 +129,8 @@ class Q_DECL_EXPORT OxideQQuickWebContextPrivate
125129
126 QStringList allowed_extra_url_schemes_;130 QStringList allowed_extra_url_schemes_;
127131
132 std::unique_ptr<OxideQQuickAutofillProfiles> autofill_profiles_;
133
128 Q_DISABLE_COPY(OxideQQuickWebContextPrivate);134 Q_DISABLE_COPY(OxideQQuickWebContextPrivate);
129};135};
130136
diff --git a/qt/tests/qmltests/api/tst_WebContext_autofillProfiles.qml b/qt/tests/qmltests/api/tst_WebContext_autofillProfiles.qml
131new file mode 100644137new file mode 100644
index 0000000..3c38ec2
--- /dev/null
+++ b/qt/tests/qmltests/api/tst_WebContext_autofillProfiles.qml
@@ -0,0 +1,141 @@
1import QtQuick 2.0
2import QtTest 1.0
3import com.canonical.Oxide 1.22
4import Oxide.testsupport 1.0
5import Ubuntu.Components 1.3
6
7TestWebView {
8 id: webView
9
10 ListView {
11 id: listView
12 anchors.fill: parent
13 model: SortFilterModel {
14 model: webView.context ? webView.context.autofillProfiles: null
15 sort.property: "fullName"
16 }
17 delegate: Item {
18 objectName: "profile_delegate_%1".arg(index)
19 readonly property string guid: model.guid
20 readonly property string fullName: model.fullName
21 }
22 }
23
24 TestCase {
25 name: "WebContext_autofillProfiles"
26 when: windowShown
27
28 function makeProfile(firstName, lastName, companyName, address,
29 city, zip, country, phone, email) {
30 var profile = new Object;
31 profile.firstName = firstName;
32 profile.lastName = lastName;
33 profile.companyName = companyName;
34 profile.address = address;
35 profile.city = city;
36 profile.zip = zip;
37 profile.country = country;
38 profile.phone = phone;
39 profile.email = email;
40 return profile;
41 }
42
43 function compareProfile(profile, fullName, firstName, lastName, companyName,
44 address, city, zip, phone, email) {
45 compare(profile.fullName, fullName);
46 compare(profile.firstName, firstName);
47 compare(profile.lastName, lastName);
48 compare(profile.companyName, companyName);
49 compare(profile.address, address);
50 compare(profile.city, city);
51 compare(profile.zip, zip);
52 compare(profile.phone, phone);
53 compare(profile.email, email);
54 }
55
56 function getDelegate(index) {
57 return TestSupport.findItemInScene(listView,
58 "profile_delegate_%1".arg(index));
59 }
60
61 function initTestCase() {
62 webView.context.autofillEnabled = true;
63 tryCompare(webView.context.autofillProfiles, "ready", true);
64 }
65
66 function init() {
67 compare(listView.count, 0);
68 }
69
70 function test_WebContext_autofillProfiles_get_nonexistent_profile() {
71 compare(webView.context.autofillProfiles.get("I-DONT-EXIST"), undefined);
72 }
73
74 function test_WebContext_autofillProfiles_add_and_remove_profiles() {
75 var p1 = makeProfile("John", "Lennon", "Apple Records",
76 "Beaconsfield Road", "Liverpool", "L25 6DA",
77 "England", "+440151234567", "john@thebeatles.com");
78 webView.context.autofillProfiles.add(p1);
79 tryCompare(listView, "count", 1);
80 compare(getDelegate(0).fullName, "John Lennon");
81
82 var p2 = makeProfile("John", "Doe", "", "Park Avenue", "NYC", "NY 10016",
83 "USA", "", "john.doe@nospam.org");
84 webView.context.autofillProfiles.add(p2);
85 tryCompare(listView, "count", 2);
86 verify(TestUtils.waitFor(function() {
87 return (getDelegate(0).fullName == "John Doe"); }));
88 compare(getDelegate(1).fullName, "John Lennon");
89
90 var guid0 = getDelegate(0).guid;
91 var guid1 = getDelegate(1).guid;
92 compareProfile(webView.context.autofillProfiles.get(guid0),
93 "John Doe", "John", "Doe", "", "Park Avenue", "NYC",
94 "NY 10016", "", "john.doe@nospam.org");
95 compareProfile(webView.context.autofillProfiles.get(guid1),
96 "John Lennon", "John", "Lennon", "Apple Records",
97 "Beaconsfield Road", "Liverpool", "L25 6DA",
98 "+440151234567", "john@thebeatles.com");
99
100 webView.context.autofillProfiles.remove("I-DONT-EXIST");
101 compare(listView.count, 2);
102
103 webView.context.autofillProfiles.remove(guid1);
104 tryCompare(listView, "count", 1);
105 webView.context.autofillProfiles.remove(guid0);
106 tryCompare(listView, "count", 0);
107 }
108
109 function test_WebContext_autofillProfiles_update_profile() {
110 var p = makeProfile("John", "Lennon", "Apple Records",
111 "Beaconsfield Road", "Liverpool", "L25 6DA",
112 "England", "+440151234567", "john@thebeatles.com");
113 webView.context.autofillProfiles.add(p);
114 tryCompare(listView, "count", 1);
115 var delegate = getDelegate(0);
116 compare(delegate.fullName, "John Lennon");
117 var guid = delegate.guid;
118
119 // Try updating without specifying the GUID, nothing should happen
120 p.firstName = "Paul";
121 compare(p.guid, undefined);
122 webView.context.autofillProfiles.update(p);
123 compare(webView.context.autofillProfiles.get(guid).firstName, "John");
124
125 // Try updating with an invalid GUID, nothing should happen
126 p.guid = "I-DONT-EXIST";
127 webView.context.autofillProfiles.update(p);
128 compare(webView.context.autofillProfiles.get(guid).firstName, "John");
129
130 // Update the profile with its GUID
131 p.lastName = "McCartney";
132 p.guid = guid;
133 webView.context.autofillProfiles.update(p);
134 verify(TestUtils.waitFor(function() {
135 return (getDelegate(0).fullName == "Paul McCartney"); }));
136
137 webView.context.autofillProfiles.remove(guid);
138 tryCompare(listView, "count", 0);
139 }
140 }
141}
diff --git a/qt/tests/qmltests/ubuntu_ui/tst_WebViewAutofillPopup_autofill_profiles.qml b/qt/tests/qmltests/ubuntu_ui/tst_WebViewAutofillPopup_autofill_profiles.qml
index 8001673..e1954b0 100644
--- a/qt/tests/qmltests/ubuntu_ui/tst_WebViewAutofillPopup_autofill_profiles.qml
+++ b/qt/tests/qmltests/ubuntu_ui/tst_WebViewAutofillPopup_autofill_profiles.qml
@@ -14,6 +14,21 @@ UbuntuTestWebView {
1414
15 focus: true15 focus: true
1616
17 Component {
18 id: profilesViewFactory
19
20 ListView {
21 anchors.fill: parent
22 model: SortFilterModel {
23 model: webView.context ? webView.context.autofillProfiles: null
24 }
25 delegate: Item {
26 objectName: "profile_delegate_%1".arg(index)
27 readonly property string guid: model.guid
28 }
29 }
30 }
31
17 TestCase {32 TestCase {
18 name: "WebViewAutofillPopup_autofill_profiles"33 name: "WebViewAutofillPopup_autofill_profiles"
19 when: windowShown34 when: windowShown
@@ -224,5 +239,43 @@ UbuntuTestWebView {
224 tryCompare(popup, "count", 1);239 tryCompare(popup, "count", 1);
225 compare(getSuggestion(0).label, "Beaconsfield Road");240 compare(getSuggestion(0).label, "Beaconsfield Road");
226 }241 }
242
243 function test_use_profile_added_from_settings() {
244 // Add a new profile
245 tryCompare(webView.context.autofillProfiles, "ready", true);
246 var profile = new Object;
247 profile.firstName = "Paul";
248 profile.lastName = "McCartney";
249 profile.address = "Penny Lane";
250 profile.city = "Liverpool";
251 profile.zip = "L18 1DE";
252 profile.email = "paul@thebeatles.com";
253 webView.context.autofillProfiles.add(profile);
254
255 typeStringInField("p", "firstname");
256 var popup = getAutofillPopup();
257 compare(popup.count, 1);
258 compare(getSuggestion(0).value, "Paul");
259 var item = getSuggestion(0);
260 mouseClick(item);
261 verify(waitForAutofillPopupToClose());
262 compare_field_value("firstname", "Paul");
263 compare_field_value("lastname", "McCartney");
264 compare_field_value("email", "paul@thebeatles.com");
265 compare_field_value("zipcode", "L18 1DE");
266 compare_field_value("city", "Liverpool");
267 compare_field_value("street", "Penny Lane");
268
269 // Remove the profile
270 var profilesView = profilesViewFactory.createObject(webView);
271 profilesView.model.filter.property = "firstName";
272 profilesView.model.filter.pattern = /^Paul$/;
273 tryCompare(profilesView, "count", 1);
274 var delegate = TestSupport.findItemInScene(profilesView,
275 "profile_delegate_0");
276 webView.context.autofillProfiles.remove(delegate.guid);
277 tryCompare(profilesView, "count", 0);
278 profilesView.destroy();
279 }
227 }280 }
228}281}

Subscribers

People subscribed via source and target branches