28 #include <QtCore/QSet>
29 #include <QtCore/QHash>
30 #include <QtCore/QFile>
31 #include <QtCore/QWeakPointer>
32 #include <QtCore/QScopedPointer>
33 #include <QtWebKit/QWebPage>
34 #include <QtWebKit/QWebFrame>
35 #include <qwindowdefs.h>
37 #define QL1S(x) QLatin1String(x)
38 #define QL1C(x) QLatin1Char(x)
41 #define FILLABLE_FORM_ELEMENT_EXTRACTOR_JS "(function (){ \
43 var formList = document.querySelectorAll('form'); \
44 if (formList.length > 0) { \
46 for (var i = 0; i < formList.length; ++i) { \
47 var inputList = formList[i].querySelectorAll('input[type=text]:not([disabled]):not([autocomplete=off]),input[type=password]:not([disabled]):not([autocomplete=off]),input:not([type]):not([disabled]):not([autocomplete=off])'); \
48 if (inputList.length < 1) { \
51 var formObject = new Object; \
52 formObject.name = formList[i].name; \
53 formObject.index = i; \
54 formObject.elements = new Array; \
55 for (var j = 0; j < inputList.length; ++j) { \
56 var element = new Object; \
57 element.name = inputList[j].name; \
58 element.value = inputList[j].value; \
59 element.type = inputList[j].type; \
60 element.readonly = inputList[j].hasAttribute('readonly'); \
61 formObject.elements.push(element); \
63 forms.push(formObject); \
76 QString key = form.
url.toString(QUrl::RemoveQuery|QUrl::RemoveFragment);
84 list << frame->childFrames();
85 QListIterator<QWebFrame*> it(frame->childFrames());
86 while (it.hasNext()) {
93 return (frame->url().isEmpty() ? frame->baseUrl().resolved(frame->url()) : frame->url());
106 QWidget* widget = (page ? page->view() : qobject_cast<
QWidget*>(page));
107 while (widget && widget->parentWidget()) {
108 widget = widget->parentWidget();
110 return (widget ? widget->window() : 0);
118 QWeakPointer<QWebFrame> frame;
125 void saveDataToCache(
const QString &key);
126 void removeDataFromCache(
const WebFormList &formList);
130 void _k_openWalletDone(
bool);
131 void _k_walletClosed();
135 QScopedPointer<KWallet::Wallet> wallet;
137 QHash<KUrl, FormsData> pendingFillRequests;
138 QHash<QString, KWebWallet::WebFormList> pendingSaveRequests;
139 QSet<KUrl> confirmSaveRequestOverwrites;
147 KWebWallet::WebFormList KWebWallet::KWebWalletPrivate::parseFormData(QWebFrame *frame,
bool fillform,
bool ignorepasswd)
153 const QVariantList results (result.toList());
155 Q_FOREACH (
const QVariant &formVariant, results) {
156 QVariantMap map = formVariant.toMap();
159 form.
name = map[
QL1S(
"name")].toString();
160 form.
index = map[
QL1S(
"index")].toString();
161 bool formHasPasswords =
false;
162 const QVariantList elements = map[
QL1S(
"elements")].toList();
163 QList<KWebWallet::WebForm::WebField> inputFields;
164 Q_FOREACH (
const QVariant &element, elements) {
165 QVariantMap elementMap (element.toMap());
167 const QString value (ignorepasswd ?
QString() : elementMap[
QL1S(
"value")].toString());
168 if (
name.isEmpty()) {
171 if (fillform && elementMap[
QL1S(
"readonly")].toBool()) {
174 if (elementMap[
QL1S(
"type")].toString().compare(
QL1S(
"password"), Qt::CaseInsensitive) == 0) {
175 if (!fillform && value.isEmpty())
177 formHasPasswords =
true;
179 inputFields.append(qMakePair(name, value));
183 if (formHasPasswords || fillform) {
184 form.
fields = inputFields;
188 if ((fillform && q->hasCachedFormData(form)) || (!fillform && !form.
fields.isEmpty()))
198 kWarning(800) <<
"Unable to retrieve form data from wallet";
204 QMutableListIterator <WebForm> formIt (formList);
206 while (formIt.hasNext()) {
209 if (key != lastKey && wallet->readMap(key, cachedValues) != 0) {
210 kWarning(800) <<
"Unable to read form data for key:" << key;
214 for (
int i = 0, count = form.
fields.count(); i < count; ++i) {
215 form.
fields[i].second = cachedValues.value(form.
fields[i].first);
221 void KWebWallet::KWebWalletPrivate::saveDataToCache(
const QString &key)
224 if (!pendingSaveRequests.contains(key)) {
228 bool success =
false;
229 const QUrl url = pendingSaveRequests.value(key).first().url;
234 QListIterator<KWebWallet::WebForm> formIt (list);
236 while (formIt.hasNext()) {
240 if (confirmSaveRequestOverwrites.contains(url)) {
241 confirmSaveRequestOverwrites.remove(url);
242 const int status = wallet->readMap(accessKey, storedValues);
243 if (status == 0 && storedValues.count()) {
244 QListIterator<KWebWallet::WebForm::WebField> fieldIt (form.
fields);
245 while (fieldIt.hasNext()) {
247 if (storedValues.contains(field.first) &&
248 storedValues.value(field.first) != field.second) {
249 emit q->saveFormDataRequested(key, url);
260 QListIterator<KWebWallet::WebForm::WebField> fieldIt (form.
fields);
261 while (fieldIt.hasNext()) {
263 values.insert(field.first, field.second);
266 if (wallet->writeMap(accessKey, values) == 0)
269 kWarning(800) <<
"Unable to write form data to wallet";
272 if (list.isEmpty() || count > 0)
275 pendingSaveRequests.remove(key);
277 kWarning(800) <<
"NULL KWallet instance!";
280 emit q->saveFormDataCompleted(url, success);
283 void KWebWallet::KWebWalletPrivate::openWallet()
285 if (!wallet.isNull()) {
292 if (wallet.isNull()) {
296 connect(wallet.data(), SIGNAL(walletOpened(
bool)), q, SLOT(_k_openWalletDone(
bool)));
297 connect(wallet.data(), SIGNAL(walletClosed()), q, SLOT(_k_walletClosed()));
301 void KWebWallet::KWebWalletPrivate::removeDataFromCache(
const WebFormList &formList)
304 kWarning(800) <<
"NULL KWallet instance!";
308 QListIterator<WebForm> formIt (formList);
309 while (formIt.hasNext())
310 wallet->removeEntry(
walletKey(formIt.next()));
313 void KWebWallet::KWebWalletPrivate::_k_openWalletDone(
bool ok)
323 if (!pendingFillRequests.isEmpty()) {
325 QMutableHashIterator<KUrl, FormsData> requestIt (pendingFillRequests);
326 while (requestIt.hasNext()) {
329 fillDataFromCache(list);
330 q->fillWebForm(requestIt.key(), list);
333 pendingFillRequests.clear();
337 if (!pendingSaveRequests.isEmpty()) {
338 QListIterator<QString> keysIt (pendingSaveRequests.keys());
339 while (keysIt.hasNext())
340 saveDataToCache(keysIt.next());
344 if (!pendingRemoveRequests.isEmpty()) {
345 removeDataFromCache(pendingRemoveRequests);
346 pendingRemoveRequests.clear();
351 delete wallet.take();
355 void KWebWallet::KWebWalletPrivate::_k_walletClosed()
358 wallet.take()->deleteLater();
360 emit q->walletClosed();
364 :
QObject(parent), d(new KWebWalletPrivate(this))
371 wid = widget->winId();
388 list << d->parseFormData(frame);
391 QList<QWebFrame*> childFrameList;
393 QListIterator <QWebFrame *> framesIt (childFrameList);
394 while (framesIt.hasNext()) {
395 list << d->parseFormData(framesIt.next());
410 if (!formsList.isEmpty()) {
412 if (d->pendingFillRequests.contains(url)) {
413 kWarning(800) <<
"Duplicate request rejected!";
415 KWebWalletPrivate::FormsData data;
416 data.frame = QWeakPointer<QWebFrame>(frame);
417 data.forms << formsList;
418 d->pendingFillRequests.insert(url, data);
424 QList<QWebFrame*> childFrameList;
426 QListIterator<QWebFrame*> frameIt (childFrameList);
427 while (frameIt.hasNext()) {
428 QWebFrame *childFrame = frameIt.next();
429 formsList = d->parseFormData(childFrame);
430 if (formsList.isEmpty())
432 const QUrl url (childFrame->url());
433 if (d->pendingFillRequests.contains(url)) {
434 kWarning(800) <<
"Duplicate request rejected!!!";
436 KWebWalletPrivate::FormsData data;
437 data.frame = QWeakPointer<QWebFrame>(childFrame);
438 data.forms << formsList;
439 d->pendingFillRequests.insert(url, data);
445 if (!urlList.isEmpty())
454 WebFormList list = d->parseFormData(frame,
false, ignorePasswordFields);
456 QList<QWebFrame*> childFrameList;
458 QListIterator<QWebFrame*> frameIt (childFrameList);
459 while (frameIt.hasNext())
460 list << d->parseFormData(frameIt.next(),
false, ignorePasswordFields);
467 const bool isAlreadyPending = d->pendingSaveRequests.contains(key);
468 d->pendingSaveRequests.insert(key, list);
470 if (isAlreadyPending)
473 for (
int i = 0 ; i < list.count(); ++i) {
478 if (list.isEmpty()) {
479 d->confirmSaveRequestOverwrites.insert(
urlForFrame(frame));
495 d->pendingRemoveRequests << forms;
506 d->pendingSaveRequests.remove(key);
511 QWeakPointer<QWebFrame> frame = d->pendingFillRequests.value(url).frame;
516 bool wasFilled =
false;
521 value.replace(QLatin1Char(
'\\'), QLatin1String(
"\\\\"));
522 script += QString::fromLatin1(
"if (document.forms[\"%1\"].elements[\"%2\"]) document.forms[\"%1\"].elements[\"%2\"].value=\"%3\";\n")
524 .arg(field.first).arg(value);
528 if (!script.isEmpty()) {
530 frame.data()->evaluateJavaScript(script);
538 return d->pendingFillRequests.value(url).forms;
543 return d->pendingSaveRequests.value(key);
556 QListIterator<KUrl> urlIt (urlList);
557 while (urlIt.hasNext()) {
558 const KUrl url = urlIt.next();
560 d->fillDataFromCache(list);
563 d->pendingFillRequests.clear();
571 d->saveDataToCache(key);
580 d->removeDataFromCache(forms);
581 d->pendingRemoveRequests.clear();
587 #include "kwebwallet.moc"