[BlackBerry] CredentialBackingStore implement encryptString() and decryptString()
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / qt / qquickwebview.cpp
1 /*
2  * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This program 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this program; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #include "config.h"
22 #include "qquickwebview_p.h"
23
24 #include "DownloadProxy.h"
25 #include "DrawingAreaProxyImpl.h"
26 #include "QtDownloadManager.h"
27 #include "QtWebContext.h"
28 #include "QtWebIconDatabaseClient.h"
29 #include "QtWebPageEventHandler.h"
30 #include "UtilsQt.h"
31 #include "WebBackForwardList.h"
32 #include "WebPageGroup.h"
33 #include "WebPreferences.h"
34
35 #include "qquicknetworkreply_p.h"
36 #include "qquicknetworkrequest_p.h"
37 #include "qquickwebpage_p_p.h"
38 #include "qquickwebview_p_p.h"
39 #include "qwebdownloaditem_p_p.h"
40 #include "qwebloadrequest_p.h"
41 #include "qwebnavigationhistory_p.h"
42 #include "qwebnavigationhistory_p_p.h"
43 #include "qwebpreferences_p.h"
44 #include "qwebpreferences_p_p.h"
45 #include "qwebviewportinfo_p.h"
46
47 #include <private/qquickflickable_p.h>
48 #include <JavaScriptCore/InitializeThreading.h>
49 #include <QDeclarativeEngine>
50 #include <QtQuick/QQuickCanvas>
51 #include <WebCore/IntPoint.h>
52 #include <WebCore/IntRect.h>
53 #include <WKOpenPanelResultListener.h>
54 #include <wtf/Assertions.h>
55 #include <wtf/text/WTFString.h>
56
57 using namespace WebCore;
58
59 static bool s_flickableViewportEnabled = true;
60
61 static QQuickWebViewPrivate* createPrivateObject(QQuickWebView* publicObject)
62 {
63     if (s_flickableViewportEnabled)
64         return new QQuickWebViewFlickablePrivate(publicObject);
65     return new QQuickWebViewLegacyPrivate(publicObject);
66 }
67
68 QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport)
69     : q_ptr(viewport)
70     , flickProvider(0)
71     , alertDialog(0)
72     , confirmDialog(0)
73     , promptDialog(0)
74     , authenticationDialog(0)
75     , certificateVerificationDialog(0)
76     , itemSelector(0)
77     , proxyAuthenticationDialog(0)
78     , filePicker(0)
79     , databaseQuotaDialog(0)
80     , userDidOverrideContentWidth(false)
81     , userDidOverrideContentHeight(false)
82     , m_navigatorQtObjectEnabled(false)
83     , m_renderToOffscreenBuffer(false)
84     , m_loadStartedSignalSent(false)
85     , m_dialogActive(false)
86 {
87     viewport->setFlags(QQuickItem::ItemClipsChildrenToShape);
88     QObject::connect(viewport, SIGNAL(visibleChanged()), viewport, SLOT(_q_onVisibleChanged()));
89     QObject::connect(viewport, SIGNAL(urlChanged()), viewport, SLOT(_q_onUrlChanged()));
90     pageView.reset(new QQuickWebPage(viewport));
91 }
92
93 QQuickWebViewPrivate::~QQuickWebViewPrivate()
94 {
95     webPageProxy->close();
96 }
97
98 // Note: we delay this initialization to make sure that QQuickWebView has its d-ptr in-place.
99 void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pageGroupRef)
100 {
101     RefPtr<WebPageGroup> pageGroup;
102     if (pageGroupRef)
103         pageGroup = toImpl(pageGroupRef);
104     else
105         pageGroup = WebPageGroup::create();
106
107     context = contextRef ? QtWebContext::create(toImpl(contextRef)) : QtWebContext::defaultContext();
108     webPageProxy = context->createWebPage(&pageClient, pageGroup.get());
109
110     QQuickWebPagePrivate* const pageViewPrivate = pageView.data()->d;
111     pageViewPrivate->initialize(webPageProxy.get());
112
113     pageLoadClient.reset(new QtWebPageLoadClient(toAPI(webPageProxy.get()), q_ptr));
114     pagePolicyClient.reset(new QtWebPagePolicyClient(toAPI(webPageProxy.get()), q_ptr));
115     pageUIClient.reset(new QtWebPageUIClient(toAPI(webPageProxy.get()), q_ptr));
116     navigationHistory = adoptPtr(QWebNavigationHistoryPrivate::createHistory(toAPI(webPageProxy.get())));
117
118     QtWebIconDatabaseClient* iconDatabase = context->iconDatabase();
119     QObject::connect(iconDatabase, SIGNAL(iconChangedForPageURL(QUrl, QUrl)), q_ptr, SLOT(_q_onIconChangedForPageURL(QUrl, QUrl)));
120
121     // Any page setting should preferrable be set before creating the page.
122     webPageProxy->pageGroup()->preferences()->setAcceleratedCompositingEnabled(true);
123     webPageProxy->pageGroup()->preferences()->setForceCompositingMode(true);
124     webPageProxy->pageGroup()->preferences()->setFrameFlatteningEnabled(true);
125
126     pageClient.initialize(q_ptr, pageViewPrivate->eventHandler.data(), &undoController);
127     webPageProxy->initializeWebPage();
128 }
129
130 void QQuickWebViewPrivate::setTransparentBackground(bool enable)
131 {
132     webPageProxy->setDrawsTransparentBackground(enable);
133 }
134
135 bool QQuickWebViewPrivate::transparentBackground() const
136 {
137     return webPageProxy->drawsTransparentBackground();
138 }
139
140 void QQuickWebViewPrivate::enableMouseEvents()
141 {
142     Q_Q(QQuickWebView);
143     q->setAcceptedMouseButtons(Qt::MouseButtonMask);
144     q->setAcceptHoverEvents(true);
145 }
146
147 void QQuickWebViewPrivate::disableMouseEvents()
148 {
149     Q_Q(QQuickWebView);
150     q->setAcceptedMouseButtons(Qt::NoButton);
151     q->setAcceptHoverEvents(false);
152 }
153
154 QPointF QQuickWebViewPrivate::pageItemPos()
155 {
156     ASSERT(pageView);
157     return pageView->pos();
158 }
159
160 void QQuickWebViewPrivate::loadDidSucceed()
161 {
162     Q_Q(QQuickWebView);
163     ASSERT(!q->loading());
164     QWebLoadRequest loadRequest(q->url(), QQuickWebView::LoadSucceededStatus);
165     emit q->loadingChanged(&loadRequest);
166 }
167
168 void QQuickWebViewPrivate::onComponentComplete()
169 {
170     if (m_deferedUrlToLoad.isEmpty())
171         return;
172
173     q_ptr->setUrl(m_deferedUrlToLoad);
174 }
175
176 void QQuickWebViewPrivate::setNeedsDisplay()
177 {
178     Q_Q(QQuickWebView);
179     if (renderToOffscreenBuffer()) {
180         // TODO: we can maintain a real image here and use it for pixel tests. Right now this is used only for running the rendering code-path while running tests.
181         QImage dummyImage(1, 1, QImage::Format_ARGB32);
182         QPainter painter(&dummyImage);
183         q->page()->d->paint(&painter);
184         return;
185     }
186
187     q->page()->update();
188 }
189
190 void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURL)
191 {
192     Q_Q(QQuickWebView);
193     if (q->url() != pageURL)
194         return;
195
196     setIcon(iconURL);
197 }
198
199 void QQuickWebViewPrivate::didChangeLoadingState(QWebLoadRequest* loadRequest)
200 {
201     Q_Q(QQuickWebView);
202     ASSERT(q->loading() == (loadRequest->status() == QQuickWebView::LoadStartedStatus));
203     emit q->loadingChanged(loadRequest);
204     m_loadStartedSignalSent = loadRequest->status() == QQuickWebView::LoadStartedStatus;
205 }
206
207 void QQuickWebViewPrivate::didChangeBackForwardList()
208 {
209     navigationHistory->d->reset();
210 }
211
212 void QQuickWebViewPrivate::processDidCrash()
213 {
214     pageView->eventHandler()->resetGestureRecognizers();
215     QUrl url(KURL(WebCore::ParsedURLString, webPageProxy->urlAtProcessExit()));
216     if (m_loadStartedSignalSent) {
217         QWebLoadRequest loadRequest(url, QQuickWebView::LoadFailedStatus, QLatin1String("The web process crashed."), QQuickWebView::InternalErrorDomain, 0);
218         didChangeLoadingState(&loadRequest);
219     }
220     qWarning("WARNING: The web process experienced a crash on '%s'.", qPrintable(url.toString(QUrl::RemoveUserInfo)));
221 }
222
223 void QQuickWebViewPrivate::didRelaunchProcess()
224 {
225     qWarning("WARNING: The web process has been successfully restarted.");
226     webPageProxy->drawingArea()->setSize(viewSize(), IntSize());
227 }
228
229 PassOwnPtr<DrawingAreaProxy> QQuickWebViewPrivate::createDrawingAreaProxy()
230 {
231     return DrawingAreaProxyImpl::create(webPageProxy.get());
232 }
233
234 void QQuickWebViewPrivate::handleDownloadRequest(DownloadProxy* download)
235 {
236     Q_Q(QQuickWebView);
237     // This function is responsible for hooking up a DownloadProxy to our API layer
238     // by creating a QWebDownloadItem. It will then wait for the QWebDownloadItem to be
239     // ready (filled with the ResourceResponse information) so we can pass it through to
240     // our WebViews.
241     QWebDownloadItem* downloadItem = new QWebDownloadItem();
242     downloadItem->d->downloadProxy = download;
243
244     q->connect(downloadItem->d, SIGNAL(receivedResponse(QWebDownloadItem*)), q, SLOT(_q_onReceivedResponseFromDownload(QWebDownloadItem*)));
245     context->downloadManager()->addDownload(download, downloadItem);
246 }
247
248 void QQuickWebViewPrivate::_q_onVisibleChanged()
249 {
250     webPageProxy->viewStateDidChange(WebPageProxy::ViewIsVisible);
251 }
252
253 void QQuickWebViewPrivate::_q_onUrlChanged()
254 {
255     Q_Q(QQuickWebView);
256     context->iconDatabase()->requestIconForPageURL(q->url());
257 }
258
259 void QQuickWebViewPrivate::_q_onReceivedResponseFromDownload(QWebDownloadItem* downloadItem)
260 {
261     // Now that our downloadItem has everything we need we can emit downloadRequested.
262     if (!downloadItem)
263         return;
264
265     Q_Q(QQuickWebView);
266     QDeclarativeEngine::setObjectOwnership(downloadItem, QDeclarativeEngine::JavaScriptOwnership);
267     emit q->experimental()->downloadRequested(downloadItem);
268 }
269
270 void QQuickWebViewPrivate::runJavaScriptAlert(const QString& alertText)
271 {
272     if (!alertDialog)
273         return;
274
275     Q_Q(QQuickWebView);
276     QtDialogRunner dialogRunner;
277     if (!dialogRunner.initForAlert(alertDialog, q, alertText))
278         return;
279
280     execDialogRunner(dialogRunner);
281 }
282
283 bool QQuickWebViewPrivate::runJavaScriptConfirm(const QString& message)
284 {
285     if (!confirmDialog)
286         return true;
287
288     Q_Q(QQuickWebView);
289     QtDialogRunner dialogRunner;
290     if (!dialogRunner.initForConfirm(confirmDialog, q, message))
291         return true;
292
293     execDialogRunner(dialogRunner);
294
295     return dialogRunner.wasAccepted();
296 }
297
298 QString QQuickWebViewPrivate::runJavaScriptPrompt(const QString& message, const QString& defaultValue, bool& ok)
299 {
300     if (!promptDialog) {
301         ok = true;
302         return defaultValue;
303     }
304
305     Q_Q(QQuickWebView);
306     QtDialogRunner dialogRunner;
307     if (!dialogRunner.initForPrompt(promptDialog, q, message, defaultValue)) {
308         ok = true;
309         return defaultValue;
310     }
311
312     execDialogRunner(dialogRunner);
313
314     ok = dialogRunner.wasAccepted();
315     return dialogRunner.result();
316 }
317
318 void QQuickWebViewPrivate::handleAuthenticationRequiredRequest(const QString& hostname, const QString& realm, const QString& prefilledUsername, QString& username, QString& password)
319 {
320     if (!authenticationDialog)
321         return;
322
323     Q_Q(QQuickWebView);
324     QtDialogRunner dialogRunner;
325     if (!dialogRunner.initForAuthentication(authenticationDialog, q, hostname, realm, prefilledUsername))
326         return;
327
328     execDialogRunner(dialogRunner);
329
330     username = dialogRunner.username();
331     password = dialogRunner.password();
332 }
333
334 void QQuickWebViewPrivate::handleProxyAuthenticationRequiredRequest(const QString& hostname, uint16_t port, const QString& prefilledUsername, QString& username, QString& password)
335 {
336     if (!proxyAuthenticationDialog)
337         return;
338
339     Q_Q(QQuickWebView);
340     QtDialogRunner dialogRunner;
341     if (!dialogRunner.initForProxyAuthentication(proxyAuthenticationDialog, q, hostname, port, prefilledUsername))
342         return;
343
344     execDialogRunner(dialogRunner);
345
346     username = dialogRunner.username();
347     password = dialogRunner.password();
348 }
349
350 bool QQuickWebViewPrivate::handleCertificateVerificationRequest(const QString& hostname)
351 {
352     if (!certificateVerificationDialog)
353         return false;
354
355     Q_Q(QQuickWebView);
356     QtDialogRunner dialogRunner;
357     if (!dialogRunner.initForCertificateVerification(certificateVerificationDialog, q, hostname))
358         return false;
359
360     execDialogRunner(dialogRunner);
361
362     return dialogRunner.wasAccepted();
363 }
364
365 void QQuickWebViewPrivate::execDialogRunner(QtDialogRunner& dialogRunner)
366 {
367     setViewInAttachedProperties(dialogRunner.dialog());
368
369     disableMouseEvents();
370     m_dialogActive = true;
371
372     dialogRunner.exec();
373     m_dialogActive = false;
374     enableMouseEvents();
375 }
376
377 void QQuickWebViewPrivate::chooseFiles(WKOpenPanelResultListenerRef listenerRef, const QStringList& selectedFileNames, QtWebPageUIClient::FileChooserType type)
378 {
379     Q_Q(QQuickWebView);
380
381     if (!filePicker || type == QtWebPageUIClient::MultipleFilesSelection)
382         return;
383
384     QtDialogRunner dialogRunner;
385     if (!dialogRunner.initForFilePicker(filePicker, q, selectedFileNames))
386         return;
387
388     execDialogRunner(dialogRunner);
389
390     if (dialogRunner.wasAccepted()) {
391         QStringList selectedPaths = dialogRunner.filePaths();
392
393         Vector<RefPtr<APIObject> > wkFiles(selectedPaths.size());
394         for (unsigned i = 0; i < selectedPaths.size(); ++i)
395             wkFiles[i] = WebURL::create(QUrl::fromLocalFile(selectedPaths.at(i)).toString());            
396
397         WKOpenPanelResultListenerChooseFiles(listenerRef, toAPI(ImmutableArray::adopt(wkFiles).leakRef()));
398     } else
399         WKOpenPanelResultListenerCancel(listenerRef);
400
401 }
402
403 quint64 QQuickWebViewPrivate::exceededDatabaseQuota(const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage)
404 {
405     if (!databaseQuotaDialog)
406         return 0;
407
408     Q_Q(QQuickWebView);
409     QtDialogRunner dialogRunner;
410     if (!dialogRunner.initForDatabaseQuotaDialog(databaseQuotaDialog, q, databaseName, displayName, securityOrigin, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage))
411         return 0;
412
413     execDialogRunner(dialogRunner);
414
415     return dialogRunner.wasAccepted() ? dialogRunner.databaseQuota() : 0;
416 }
417
418 void QQuickWebViewPrivate::setViewInAttachedProperties(QObject* object)
419 {
420     Q_Q(QQuickWebView);
421     QQuickWebViewAttached* attached = static_cast<QQuickWebViewAttached*>(qmlAttachedPropertiesObject<QQuickWebView>(object));
422     attached->setView(q);
423 }
424
425 void QQuickWebViewPrivate::setIcon(const QUrl& iconURL)
426 {
427     Q_Q(QQuickWebView);
428     if (m_iconURL == iconURL)
429         return;
430
431     String oldPageURL = QUrl::fromPercentEncoding(m_iconURL.encodedFragment());
432     String newPageURL = webPageProxy->mainFrame()->url();
433
434     if (oldPageURL != newPageURL) {
435         QtWebIconDatabaseClient* iconDatabase = context->iconDatabase();
436         if (!oldPageURL.isEmpty())
437             iconDatabase->releaseIconForPageURL(oldPageURL);
438
439         if (!newPageURL.isEmpty())
440             iconDatabase->retainIconForPageURL(newPageURL);
441     }
442
443     m_iconURL = iconURL;
444     emit q->iconChanged();
445 }
446
447 bool QQuickWebViewPrivate::navigatorQtObjectEnabled() const
448 {
449     return m_navigatorQtObjectEnabled;
450 }
451
452 void QQuickWebViewPrivate::setNavigatorQtObjectEnabled(bool enabled)
453 {
454     ASSERT(enabled != m_navigatorQtObjectEnabled);
455     // FIXME: Currently we have to keep this information in both processes and the setting is asynchronous.
456     m_navigatorQtObjectEnabled = enabled;
457     context->setNavigatorQtObjectEnabled(webPageProxy.get(), enabled);
458 }
459
460 QRect QQuickWebViewPrivate::visibleContentsRect() const
461 {
462     Q_Q(const QQuickWebView);
463     const QRectF visibleRect(q->boundingRect().intersected(pageView->boundingRect()));
464
465     return q->mapRectToWebContent(visibleRect).toAlignedRect();
466 }
467
468 WebCore::IntSize QQuickWebViewPrivate::viewSize() const
469 {
470     return WebCore::IntSize(pageView->width(), pageView->height());
471 }
472
473 void QQuickWebViewPrivate::didReceiveMessageFromNavigatorQtObject(const String& message)
474 {
475     QVariantMap variantMap;
476     variantMap.insert(QLatin1String("data"), QString(message));
477     variantMap.insert(QLatin1String("origin"), q_ptr->url());
478     emit q_ptr->experimental()->messageReceived(variantMap);
479 }
480
481 QQuickWebViewLegacyPrivate::QQuickWebViewLegacyPrivate(QQuickWebView* viewport)
482     : QQuickWebViewPrivate(viewport)
483 {
484 }
485
486 void QQuickWebViewLegacyPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pageGroupRef)
487 {
488     QQuickWebViewPrivate::initialize(contextRef, pageGroupRef);
489     enableMouseEvents();
490
491     // Trigger setting of correct visibility flags after everything was allocated and initialized.
492     _q_onVisibleChanged();
493 }
494
495 void QQuickWebViewLegacyPrivate::updateViewportSize()
496 {
497     Q_Q(QQuickWebView);
498     QSize viewportSize = q->boundingRect().size().toSize();
499     pageView->setContentsSize(viewportSize);
500     // The fixed layout is handled by the FrameView and the drawing area doesn't behave differently
501     // whether its fixed or not. We still need to tell the drawing area which part of it
502     // has to be rendered on tiles, and in desktop mode it's all of it.
503     webPageProxy->drawingArea()->setSize(viewportSize, IntSize());
504     webPageProxy->drawingArea()->setVisibleContentsRect(IntRect(IntPoint(), viewportSize), 1, FloatPoint());
505 }
506
507 QQuickWebViewFlickablePrivate::QQuickWebViewFlickablePrivate(QQuickWebView* viewport)
508     : QQuickWebViewPrivate(viewport)
509     , pageIsSuspended(true)
510     , loadSuccessDispatchIsPending(false)
511 {
512 }
513
514 QQuickWebViewFlickablePrivate::~QQuickWebViewFlickablePrivate()
515 {
516     interactionEngine->disconnect();
517 }
518
519 void QQuickWebViewFlickablePrivate::initialize(WKContextRef contextRef, WKPageGroupRef pageGroupRef)
520 {
521     QQuickWebViewPrivate::initialize(contextRef, pageGroupRef);
522     webPageProxy->setUseFixedLayout(true);
523 }
524
525 QPointF QQuickWebViewFlickablePrivate::pageItemPos()
526 {
527     // Flickable moves its contentItem so we need to take that position into account,
528     // as well as the potential displacement of the page on the contentItem because
529     // of additional QML items.
530     qreal xPos = flickProvider->contentItem()->x() + pageView->x();
531     qreal yPos = flickProvider->contentItem()->y() + pageView->y();
532     return QPointF(xPos, yPos);
533 }
534
535 void QQuickWebViewFlickablePrivate::updateContentsSize(const QSizeF& size)
536 {
537     ASSERT(flickProvider);
538
539     // Make sure that the contentItem is sized to the page
540     // if the user did not add other flickable items in QML.
541     // If the user adds items in QML he has to make sure to
542     // also bind the contentWidth and contentHeight accordingly.
543     // This is in accordance with normal QML Flickable behaviour.
544     if (!userDidOverrideContentWidth)
545         flickProvider->setContentWidth(size.width());
546     if (!userDidOverrideContentHeight)
547         flickProvider->setContentHeight(size.height());
548 }
549
550 void QQuickWebViewFlickablePrivate::onComponentComplete()
551 {
552     Q_Q(QQuickWebView);
553
554     ASSERT(!flickProvider);
555     flickProvider = new QtFlickProvider(q, pageView.data());
556
557     // Propagate flickable signals.
558     QQuickWebViewExperimental* experimental = q->experimental();
559     QObject::connect(flickProvider, SIGNAL(contentWidthChanged()), experimental, SIGNAL(contentWidthChanged()));
560     QObject::connect(flickProvider, SIGNAL(contentHeightChanged()), experimental, SIGNAL(contentHeightChanged()));
561     QObject::connect(flickProvider, SIGNAL(contentXChanged()), experimental, SIGNAL(contentXChanged()));
562     QObject::connect(flickProvider, SIGNAL(contentYChanged()), experimental, SIGNAL(contentYChanged()));
563
564     interactionEngine.reset(new QtViewportInteractionEngine(q, pageView.data(), flickProvider));
565     pageView->eventHandler()->setViewportInteractionEngine(interactionEngine.data());
566
567     QObject::connect(interactionEngine.data(), SIGNAL(contentSuspendRequested()), q, SLOT(_q_suspend()));
568     QObject::connect(interactionEngine.data(), SIGNAL(contentResumeRequested()), q, SLOT(_q_resume()));
569     QObject::connect(interactionEngine.data(), SIGNAL(contentViewportChanged(QPointF)), q, SLOT(_q_contentViewportChanged(QPointF)));
570
571     _q_resume();
572
573     if (loadSuccessDispatchIsPending) {
574         QQuickWebViewPrivate::loadDidSucceed();
575         loadSuccessDispatchIsPending = false;
576     }
577
578     // Trigger setting of correct visibility flags after everything was allocated and initialized.
579     _q_onVisibleChanged();
580
581     QQuickWebViewPrivate::onComponentComplete();
582
583     emit experimental->flickableChanged();
584 }
585
586 void QQuickWebViewFlickablePrivate::loadDidSucceed()
587 {
588     if (interactionEngine)
589         QQuickWebViewPrivate::loadDidSucceed();
590     else
591         loadSuccessDispatchIsPending = true;
592
593 }
594
595 void QQuickWebViewFlickablePrivate::loadDidCommit()
596 {
597     // Due to entering provisional load before committing, we
598     // might actually be suspended here.
599 }
600
601 void QQuickWebViewFlickablePrivate::didFinishFirstNonEmptyLayout()
602 {
603 }
604
605 void QQuickWebViewFlickablePrivate::didChangeViewportProperties(const WebCore::ViewportArguments& args)
606 {
607     viewportArguments = args;
608
609     // FIXME: If suspended we should do this on resume.
610     interactionEngine->applyConstraints(computeViewportConstraints());
611 }
612
613 void QQuickWebViewFlickablePrivate::updateViewportSize()
614 {
615     Q_Q(QQuickWebView);
616     QSize viewportSize = q->boundingRect().size().toSize();
617
618     if (viewportSize.isEmpty() || !interactionEngine)
619         return;
620
621     flickProvider->setViewportSize(viewportSize);
622
623     // Let the WebProcess know about the new viewport size, so that
624     // it can resize the content accordingly.
625     webPageProxy->setViewportSize(viewportSize);
626
627     interactionEngine->applyConstraints(computeViewportConstraints());
628     _q_contentViewportChanged(QPointF());
629 }
630
631 void QQuickWebViewFlickablePrivate::_q_contentViewportChanged(const QPointF& trajectoryVector)
632 {
633     Q_Q(QQuickWebView);
634     // This is only for our QML ViewportInfo debugging API.
635     q->experimental()->viewportInfo()->didUpdateCurrentScale();
636
637     DrawingAreaProxy* drawingArea = webPageProxy->drawingArea();
638     if (!drawingArea)
639         return;
640
641     const QRect visibleRect(visibleContentsRect());
642     float scale = pageView->contentsScale();
643
644     drawingArea->setVisibleContentsRect(visibleRect, scale, trajectoryVector);
645     webPageProxy->setFixedVisibleContentRect(visibleRect);
646 }
647
648 void QQuickWebViewFlickablePrivate::_q_suspend()
649 {
650     pageIsSuspended = true;
651     webPageProxy->suspendActiveDOMObjectsAndAnimations();
652 }
653
654 void QQuickWebViewFlickablePrivate::_q_resume()
655 {
656     if (!interactionEngine)
657         return;
658
659     pageIsSuspended = false;
660     webPageProxy->resumeActiveDOMObjectsAndAnimations();
661
662     _q_contentViewportChanged(QPointF());
663 }
664
665 void QQuickWebViewFlickablePrivate::pageDidRequestScroll(const QPoint& pos)
666 {
667     interactionEngine->pagePositionRequest(pos);
668 }
669
670 void QQuickWebViewFlickablePrivate::didChangeContentsSize(const QSize& newSize)
671 {
672     Q_Q(QQuickWebView);
673     pageView->setContentsSize(newSize);
674     q->experimental()->viewportInfo()->didUpdateContentsSize();
675 }
676
677 QtViewportInteractionEngine::Constraints QQuickWebViewFlickablePrivate::computeViewportConstraints()
678 {
679     Q_Q(QQuickWebView);
680
681     QtViewportInteractionEngine::Constraints newConstraints;
682     QSize availableSize = q->boundingRect().size().toSize();
683
684     // Return default values for zero sized viewport.
685     if (availableSize.isEmpty())
686         return newConstraints;
687
688     WebPreferences* wkPrefs = webPageProxy->pageGroup()->preferences();
689
690     // FIXME: Remove later; Hardcode a value for now to make sure the DPI adjustment is being tested.
691     wkPrefs->setDeviceDPI(160);
692
693     wkPrefs->setDeviceWidth(availableSize.width());
694     wkPrefs->setDeviceHeight(availableSize.height());
695
696     int minimumLayoutFallbackWidth = qMax<int>(wkPrefs->layoutFallbackWidth(), availableSize.width());
697
698     WebCore::ViewportAttributes attr = WebCore::computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, wkPrefs->deviceWidth(), wkPrefs->deviceHeight(), wkPrefs->deviceDPI(), availableSize);
699     WebCore::restrictMinimumScaleFactorToViewportSize(attr, availableSize);
700     WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attr);
701
702     newConstraints.initialScale = attr.initialScale;
703     newConstraints.minimumScale = attr.minimumScale;
704     newConstraints.maximumScale = attr.maximumScale;
705     newConstraints.devicePixelRatio = attr.devicePixelRatio;
706     newConstraints.isUserScalable = !!attr.userScalable;
707     newConstraints.layoutSize = attr.layoutSize;
708
709     q->experimental()->viewportInfo()->didUpdateViewportConstraints();
710
711     return newConstraints;
712 }
713
714 /*!
715     \qmlsignal WebView::onNavigationRequested(request)
716
717     This signal is emitted for every navigation request. The request object contains url, button and modifiers properties
718     describing the navigation action, e.g. "a middle click with shift key pressed to 'http://qt-project.org'".
719
720     The navigation will be accepted by default. To change that, one can set the action property to WebView.IgnoreRequest to reject
721     the request or WebView.DownloadRequest to trigger a download instead of navigating to the url.
722
723     The request object cannot be used after the signal handler function ends.
724 */
725
726 QQuickWebViewAttached::QQuickWebViewAttached(QObject* object)
727     : QObject(object)
728     , m_view(0)
729 {
730
731 }
732
733 void QQuickWebViewAttached::setView(QQuickWebView* view)
734 {
735     if (m_view == view)
736         return;
737     m_view = view;
738     emit viewChanged();
739 }
740
741 QQuickWebViewExperimental::QQuickWebViewExperimental(QQuickWebView *webView)
742     : QObject(webView)
743     , q_ptr(webView)
744     , d_ptr(webView->d_ptr.data())
745     , schemeParent(new QObject(this))
746     , m_viewportInfo(new QWebViewportInfo(webView->d_ptr.data(), this))
747 {
748 }
749
750 QQuickWebViewExperimental::~QQuickWebViewExperimental()
751 {
752 }
753
754 void QQuickWebViewExperimental::setRenderToOffscreenBuffer(bool enable)
755 {
756     Q_D(QQuickWebView);
757     d->setRenderToOffscreenBuffer(enable);
758 }
759
760 bool QQuickWebViewExperimental::renderToOffscreenBuffer() const
761 {
762     Q_D(const QQuickWebView);
763     return d->renderToOffscreenBuffer();
764 }
765
766 bool QQuickWebViewExperimental::transparentBackground() const
767 {
768     Q_D(const QQuickWebView);
769     return d->transparentBackground();
770 }
771 void QQuickWebViewExperimental::setTransparentBackground(bool enable)
772 {
773     Q_D(QQuickWebView);
774     d->setTransparentBackground(enable);
775 }
776
777 void QQuickWebViewExperimental::setFlickableViewportEnabled(bool enable)
778 {
779     s_flickableViewportEnabled = enable;
780 }
781
782 bool QQuickWebViewExperimental::flickableViewportEnabled()
783 {
784     return s_flickableViewportEnabled;
785 }
786
787 void QQuickWebViewExperimental::postMessage(const QString& message)
788 {
789     Q_D(QQuickWebView);
790     d->context->postMessageToNavigatorQtObject(d->webPageProxy.get(), message);
791 }
792
793 QDeclarativeComponent* QQuickWebViewExperimental::alertDialog() const
794 {
795     Q_D(const QQuickWebView);
796     return d->alertDialog;
797 }
798
799 void QQuickWebViewExperimental::setAlertDialog(QDeclarativeComponent* alertDialog)
800 {
801     Q_D(QQuickWebView);
802     if (d->alertDialog == alertDialog)
803         return;
804     d->alertDialog = alertDialog;
805     emit alertDialogChanged();
806 }
807
808 QDeclarativeComponent* QQuickWebViewExperimental::confirmDialog() const
809 {
810     Q_D(const QQuickWebView);
811     return d->confirmDialog;
812 }
813
814 void QQuickWebViewExperimental::setConfirmDialog(QDeclarativeComponent* confirmDialog)
815 {
816     Q_D(QQuickWebView);
817     if (d->confirmDialog == confirmDialog)
818         return;
819     d->confirmDialog = confirmDialog;
820     emit confirmDialogChanged();
821 }
822
823 QWebNavigationHistory* QQuickWebViewExperimental::navigationHistory() const
824 {
825     return d_ptr->navigationHistory.get();
826 }
827
828 QDeclarativeComponent* QQuickWebViewExperimental::promptDialog() const
829 {
830     Q_D(const QQuickWebView);
831     return d->promptDialog;
832 }
833
834 QWebPreferences* QQuickWebViewExperimental::preferences() const
835 {
836     QQuickWebViewPrivate* const d = d_ptr;
837     if (!d->preferences)
838         d->preferences = adoptPtr(QWebPreferencesPrivate::createPreferences(d));
839     return d->preferences.get();
840 }
841
842 void QQuickWebViewExperimental::setPromptDialog(QDeclarativeComponent* promptDialog)
843 {
844     Q_D(QQuickWebView);
845     if (d->promptDialog == promptDialog)
846         return;
847     d->promptDialog = promptDialog;
848     emit promptDialogChanged();
849 }
850
851 QDeclarativeComponent* QQuickWebViewExperimental::authenticationDialog() const
852 {
853     Q_D(const QQuickWebView);
854     return d->authenticationDialog;
855 }
856
857 void QQuickWebViewExperimental::setAuthenticationDialog(QDeclarativeComponent* authenticationDialog)
858 {
859     Q_D(QQuickWebView);
860     if (d->authenticationDialog == authenticationDialog)
861         return;
862     d->authenticationDialog = authenticationDialog;
863     emit authenticationDialogChanged();
864 }
865
866 QDeclarativeComponent* QQuickWebViewExperimental::proxyAuthenticationDialog() const
867 {
868     Q_D(const QQuickWebView);
869     return d->proxyAuthenticationDialog;
870 }
871
872 void QQuickWebViewExperimental::setProxyAuthenticationDialog(QDeclarativeComponent* proxyAuthenticationDialog)
873 {
874     Q_D(QQuickWebView);
875     if (d->proxyAuthenticationDialog == proxyAuthenticationDialog)
876         return;
877     d->proxyAuthenticationDialog = proxyAuthenticationDialog;
878     emit proxyAuthenticationDialogChanged();
879 }
880 QDeclarativeComponent* QQuickWebViewExperimental::certificateVerificationDialog() const
881 {
882     Q_D(const QQuickWebView);
883     return d->certificateVerificationDialog;
884 }
885
886 void QQuickWebViewExperimental::setCertificateVerificationDialog(QDeclarativeComponent* certificateVerificationDialog)
887 {
888     Q_D(QQuickWebView);
889     if (d->certificateVerificationDialog == certificateVerificationDialog)
890         return;
891     d->certificateVerificationDialog = certificateVerificationDialog;
892     emit certificateVerificationDialogChanged();
893 }
894
895 QDeclarativeComponent* QQuickWebViewExperimental::itemSelector() const
896 {
897     Q_D(const QQuickWebView);
898     return d->itemSelector;
899 }
900
901 void QQuickWebViewExperimental::setItemSelector(QDeclarativeComponent* itemSelector)
902 {
903     Q_D(QQuickWebView);
904     if (d->itemSelector == itemSelector)
905         return;
906     d->itemSelector = itemSelector;
907     emit itemSelectorChanged();
908 }
909
910 QDeclarativeComponent* QQuickWebViewExperimental::filePicker() const
911 {
912     Q_D(const QQuickWebView);
913     return d->filePicker;
914 }
915
916 void QQuickWebViewExperimental::setFilePicker(QDeclarativeComponent* filePicker)
917 {
918     Q_D(QQuickWebView);
919     if (d->filePicker == filePicker)
920         return;
921     d->filePicker = filePicker;
922     emit filePickerChanged();
923 }
924
925 QDeclarativeComponent* QQuickWebViewExperimental::databaseQuotaDialog() const
926 {
927     Q_D(const QQuickWebView);
928     return d->databaseQuotaDialog;
929 }
930
931 void QQuickWebViewExperimental::setDatabaseQuotaDialog(QDeclarativeComponent* databaseQuotaDialog)
932 {
933     Q_D(QQuickWebView);
934     if (d->databaseQuotaDialog == databaseQuotaDialog)
935         return;
936     d->databaseQuotaDialog = databaseQuotaDialog;
937     emit databaseQuotaDialogChanged();
938 }
939
940 QString QQuickWebViewExperimental::userAgent() const
941 {
942     Q_D(const QQuickWebView);
943     return d->webPageProxy->userAgent();
944 }
945
946 void QQuickWebViewExperimental::setUserAgent(const QString& userAgent)
947 {
948     Q_D(QQuickWebView);
949     if (userAgent == QString(d->webPageProxy->userAgent()))
950         return;
951
952     d->webPageProxy->setUserAgent(userAgent);
953     emit userAgentChanged();
954 }
955
956 QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property, int index)
957 {
958     const QObjectList children = property->object->children();
959     if (index < children.count())
960         return static_cast<QQuickUrlSchemeDelegate*>(children.at(index));
961     return 0;
962 }
963
964 void QQuickWebViewExperimental::schemeDelegates_Append(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property, QQuickUrlSchemeDelegate *scheme)
965 {
966     QObject* schemeParent = property->object;
967     scheme->setParent(schemeParent);
968     QQuickWebViewExperimental* webViewExperimental = qobject_cast<QQuickWebViewExperimental*>(property->object->parent());
969     if (!webViewExperimental)
970         return;
971     scheme->reply()->setWebViewExperimental(webViewExperimental);
972     QQuickWebViewPrivate* d = webViewExperimental->d_func();
973     d->webPageProxy->registerApplicationScheme(scheme->scheme());
974 }
975
976 int QQuickWebViewExperimental::schemeDelegates_Count(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property)
977 {
978     return property->object->children().count();
979 }
980
981 void QQuickWebViewExperimental::schemeDelegates_Clear(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property)
982 {
983     const QObjectList children = property->object->children();
984     for (int index = 0; index < children.count(); index++) {
985         QObject* child = children.at(index);
986         child->setParent(0);
987         delete child;
988     }
989 }
990
991 QDeclarativeListProperty<QQuickUrlSchemeDelegate> QQuickWebViewExperimental::schemeDelegates()
992 {
993     return QDeclarativeListProperty<QQuickUrlSchemeDelegate>(schemeParent, 0,
994             QQuickWebViewExperimental::schemeDelegates_Append,
995             QQuickWebViewExperimental::schemeDelegates_Count,
996             QQuickWebViewExperimental::schemeDelegates_At,
997             QQuickWebViewExperimental::schemeDelegates_Clear);
998 }
999
1000 void QQuickWebViewExperimental::invokeApplicationSchemeHandler(PassRefPtr<QtRefCountedNetworkRequestData> request)
1001 {
1002     RefPtr<QtRefCountedNetworkRequestData> req = request;
1003     const QObjectList children = schemeParent->children();
1004     for (int index = 0; index < children.count(); index++) {
1005         QQuickUrlSchemeDelegate* delegate = qobject_cast<QQuickUrlSchemeDelegate*>(children.at(index));
1006         if (!delegate)
1007             continue;
1008         if (!delegate->scheme().compare(QString(req->data().m_scheme), Qt::CaseInsensitive)) {
1009             delegate->request()->setNetworkRequestData(req);
1010             delegate->reply()->setNetworkRequestData(req);
1011             emit delegate->receivedRequest();
1012             return;
1013         }
1014     }
1015 }
1016
1017 void QQuickWebViewExperimental::sendApplicationSchemeReply(QQuickNetworkReply* reply)
1018 {
1019     d_ptr->webPageProxy->sendApplicationSchemeReply(reply);
1020 }
1021
1022 void QQuickWebViewExperimental::goForwardTo(int index)
1023 {
1024     d_ptr->navigationHistory->d->goForwardTo(index);
1025 }
1026
1027 void QQuickWebViewExperimental::goBackTo(int index)
1028 {
1029     d_ptr->navigationHistory->d->goBackTo(index);
1030 }
1031
1032 QWebViewportInfo* QQuickWebViewExperimental::viewportInfo()
1033 {
1034     return m_viewportInfo;
1035 }
1036
1037 QQuickWebPage* QQuickWebViewExperimental::page()
1038 {
1039     return q_ptr->page();
1040 }
1041
1042 QDeclarativeListProperty<QObject> QQuickWebViewExperimental::flickableData()
1043 {
1044     Q_D(const QQuickWebView);
1045     ASSERT(d->flickProvider);
1046     return d->flickProvider->flickableData();
1047 }
1048
1049 QQuickFlickable* QQuickWebViewExperimental::flickable()
1050 {
1051     Q_D(QQuickWebView);
1052     if (!d->flickProvider)
1053         return 0;
1054
1055     QQuickFlickable* flickableItem = qobject_cast<QQuickFlickable*>(contentItem()->parentItem());
1056
1057     ASSERT(flickableItem);
1058
1059     return flickableItem;
1060 }
1061
1062 QQuickItem* QQuickWebViewExperimental::contentItem()
1063 {
1064     Q_D(QQuickWebView);
1065     ASSERT(d->flickProvider);
1066     return d->flickProvider->contentItem();
1067 }
1068
1069 qreal QQuickWebViewExperimental::contentWidth() const
1070 {
1071     Q_D(const QQuickWebView);
1072     ASSERT(d->flickProvider);
1073     return d->flickProvider->contentWidth();
1074 }
1075
1076 void QQuickWebViewExperimental::setContentWidth(qreal width)
1077 {
1078     Q_D(QQuickWebView);
1079     ASSERT(d->flickProvider);
1080     d->userDidOverrideContentWidth = true;
1081     d->flickProvider->setContentWidth(width);
1082 }
1083
1084 qreal QQuickWebViewExperimental::contentHeight() const
1085 {
1086     Q_D(const QQuickWebView);
1087     ASSERT(d->flickProvider);
1088     return d->flickProvider->contentHeight();
1089 }
1090
1091 void QQuickWebViewExperimental::setContentHeight(qreal height)
1092 {
1093     Q_D(QQuickWebView);
1094     ASSERT(d->flickProvider);
1095     d->userDidOverrideContentHeight = true;
1096     d->flickProvider->setContentHeight(height);
1097 }
1098
1099 qreal QQuickWebViewExperimental::contentX() const
1100 {
1101     Q_D(const QQuickWebView);
1102     ASSERT(d->flickProvider);
1103     return d->flickProvider->contentX();
1104 }
1105
1106 void QQuickWebViewExperimental::setContentX(qreal x)
1107 {
1108     Q_D(QQuickWebView);
1109     ASSERT(d->flickProvider);
1110     d->flickProvider->setContentX(x);
1111 }
1112
1113 qreal QQuickWebViewExperimental::contentY() const
1114 {
1115     Q_D(const QQuickWebView);
1116     ASSERT(d->flickProvider);
1117     return d->flickProvider->contentY();
1118 }
1119
1120 void QQuickWebViewExperimental::setContentY(qreal y)
1121 {
1122     Q_D(QQuickWebView);
1123     ASSERT(d->flickProvider);
1124     d->flickProvider->setContentY(y);
1125 }
1126
1127 QQuickWebView::QQuickWebView(QQuickItem* parent)
1128     : QQuickItem(parent)
1129     , d_ptr(createPrivateObject(this))
1130     , m_experimental(new QQuickWebViewExperimental(this))
1131 {
1132     Q_D(QQuickWebView);
1133     d->initialize();
1134 }
1135
1136 QQuickWebView::QQuickWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef, QQuickItem* parent)
1137     : QQuickItem(parent)
1138     , d_ptr(createPrivateObject(this))
1139     , m_experimental(new QQuickWebViewExperimental(this))
1140 {
1141     Q_D(QQuickWebView);
1142     d->initialize(contextRef, pageGroupRef);
1143     setClip(true);
1144 }
1145
1146 QQuickWebView::~QQuickWebView()
1147 {
1148 }
1149
1150 QQuickWebPage* QQuickWebView::page()
1151 {
1152     Q_D(QQuickWebView);
1153     return d->pageView.data();
1154 }
1155
1156 void QQuickWebView::goBack()
1157 {
1158     Q_D(QQuickWebView);
1159     d->webPageProxy->goBack();
1160 }
1161
1162 void QQuickWebView::goForward()
1163 {
1164     Q_D(QQuickWebView);
1165     d->webPageProxy->goForward();
1166 }
1167
1168 void QQuickWebView::stop()
1169 {
1170     Q_D(QQuickWebView);
1171     d->webPageProxy->stopLoading();
1172 }
1173
1174 void QQuickWebView::reload()
1175 {
1176     Q_D(QQuickWebView);
1177     const bool reloadFromOrigin = true;
1178     d->webPageProxy->reload(reloadFromOrigin);
1179 }
1180
1181 QUrl QQuickWebView::url() const
1182 {
1183     Q_D(const QQuickWebView);
1184     RefPtr<WebFrameProxy> mainFrame = d->webPageProxy->mainFrame();
1185     if (!mainFrame)
1186         return QUrl();
1187     return QUrl(QString(mainFrame->url()));
1188 }
1189
1190 void QQuickWebView::setUrl(const QUrl& url)
1191 {
1192     Q_D(QQuickWebView);
1193
1194     if (url.isEmpty())
1195         return;
1196
1197     if (!isComponentComplete()) {
1198         d->m_deferedUrlToLoad = url;
1199         return;
1200     }
1201
1202     d->webPageProxy->loadURL(url.toString());
1203 }
1204
1205 QUrl QQuickWebView::icon() const
1206 {
1207     Q_D(const QQuickWebView);
1208     return d->m_iconURL;
1209 }
1210
1211 int QQuickWebView::loadProgress() const
1212 {
1213     Q_D(const QQuickWebView);
1214     return d->pageLoadClient->loadProgress();
1215 }
1216
1217 bool QQuickWebView::canGoBack() const
1218 {
1219     Q_D(const QQuickWebView);
1220     return d->webPageProxy->canGoBack();
1221 }
1222
1223 bool QQuickWebView::canGoForward() const
1224 {
1225     Q_D(const QQuickWebView);
1226     return d->webPageProxy->canGoForward();
1227 }
1228
1229 bool QQuickWebView::loading() const
1230 {
1231     Q_D(const QQuickWebView);
1232     RefPtr<WebKit::WebFrameProxy> mainFrame = d->webPageProxy->mainFrame();
1233     return mainFrame && !(WebFrameProxy::LoadStateFinished == mainFrame->loadState());
1234 }
1235
1236 QPointF QQuickWebView::mapToWebContent(const QPointF& pointInViewCoordinates) const
1237 {
1238     Q_D(const QQuickWebView);
1239     return d->pageView->transformFromItem().map(pointInViewCoordinates);
1240 }
1241
1242 QRectF QQuickWebView::mapRectToWebContent(const QRectF& rectInViewCoordinates) const
1243 {
1244     Q_D(const QQuickWebView);
1245     return d->pageView->transformFromItem().mapRect(rectInViewCoordinates);
1246 }
1247
1248 QPointF QQuickWebView::mapFromWebContent(const QPointF& pointInCSSCoordinates) const
1249 {
1250     Q_D(const QQuickWebView);
1251     return d->pageView->transformToItem().map(pointInCSSCoordinates);
1252 }
1253
1254 QRectF QQuickWebView::mapRectFromWebContent(const QRectF& rectInCSSCoordinates) const
1255 {
1256     Q_D(const QQuickWebView);
1257     return d->pageView->transformToItem().mapRect(rectInCSSCoordinates);
1258 }
1259
1260 QString QQuickWebView::title() const
1261 {
1262     Q_D(const QQuickWebView);
1263     return d->webPageProxy->pageTitle();
1264 }
1265
1266 QVariant QQuickWebView::inputMethodQuery(Qt::InputMethodQuery property) const
1267 {
1268     Q_D(const QQuickWebView);
1269     const EditorState& state = d->webPageProxy->editorState();
1270
1271     switch(property) {
1272     case Qt::ImCursorRectangle:
1273         return QRectF(state.cursorRect);
1274     case Qt::ImFont:
1275         return QVariant();
1276     case Qt::ImCursorPosition:
1277         return QVariant(static_cast<int>(state.cursorPosition));
1278     case Qt::ImAnchorPosition:
1279         return QVariant(static_cast<int>(state.anchorPosition));
1280     case Qt::ImSurroundingText:
1281         return QString(state.surroundingText);
1282     case Qt::ImCurrentSelection:
1283         return QString(state.selectedText);
1284     case Qt::ImMaximumTextLength:
1285         return QVariant(); // No limit.
1286     case Qt::ImHints:
1287         return int(Qt::InputMethodHints(state.inputMethodHints));
1288     default:
1289         // Rely on the base implementation for ImEnabled, ImHints and ImPreferredLanguage.
1290         return QQuickItem::inputMethodQuery(property);
1291     }
1292 }
1293
1294 QQuickWebViewExperimental* QQuickWebView::experimental() const
1295 {
1296     return m_experimental;
1297 }
1298
1299 QQuickWebViewAttached* QQuickWebView::qmlAttachedProperties(QObject* object)
1300 {
1301     return new QQuickWebViewAttached(object);
1302 }
1303
1304 void QQuickWebView::platformInitialize()
1305 {
1306     JSC::initializeThreading();
1307     WTF::initializeMainThread();
1308 }
1309
1310 void QQuickWebView::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry)
1311 {
1312     Q_D(QQuickWebView);
1313     QQuickItem::geometryChanged(newGeometry, oldGeometry);
1314     if (newGeometry.size() != oldGeometry.size())
1315         d->updateViewportSize();
1316 }
1317
1318 void QQuickWebView::componentComplete()
1319 {
1320     Q_D(QQuickWebView);
1321     QQuickItem::componentComplete();
1322
1323     d->onComponentComplete();
1324     d->updateViewportSize();
1325 }
1326
1327 void QQuickWebView::keyPressEvent(QKeyEvent* event)
1328 {
1329     Q_D(QQuickWebView);
1330     d->pageView->eventHandler()->handleKeyPressEvent(event);
1331 }
1332
1333 void QQuickWebView::keyReleaseEvent(QKeyEvent* event)
1334 {
1335     Q_D(QQuickWebView);
1336     d->pageView->eventHandler()->handleKeyReleaseEvent(event);
1337 }
1338
1339 void QQuickWebView::inputMethodEvent(QInputMethodEvent* event)
1340 {
1341     Q_D(QQuickWebView);
1342     d->pageView->eventHandler()->handleInputMethodEvent(event);
1343 }
1344
1345 void QQuickWebView::focusInEvent(QFocusEvent* event)
1346 {
1347     Q_D(QQuickWebView);
1348     d->pageView->eventHandler()->handleFocusInEvent(event);
1349 }
1350
1351 void QQuickWebView::focusOutEvent(QFocusEvent* event)
1352 {
1353     Q_D(QQuickWebView);
1354     d->pageView->eventHandler()->handleFocusOutEvent(event);
1355 }
1356
1357 void QQuickWebView::touchEvent(QTouchEvent* event)
1358 {
1359     Q_D(QQuickWebView);
1360     if (d->m_dialogActive) {
1361         event->ignore();
1362         return;
1363     }
1364
1365     forceActiveFocus();
1366     d->pageView->eventHandler()->handleTouchEvent(event);
1367 }
1368
1369 void QQuickWebView::mousePressEvent(QMouseEvent* event)
1370 {
1371     Q_D(QQuickWebView);
1372     forceActiveFocus();
1373     d->pageView->eventHandler()->handleMousePressEvent(event);
1374 }
1375
1376 void QQuickWebView::mouseMoveEvent(QMouseEvent* event)
1377 {
1378     Q_D(QQuickWebView);
1379     d->pageView->eventHandler()->handleMouseMoveEvent(event);
1380 }
1381
1382 void QQuickWebView::mouseReleaseEvent(QMouseEvent* event)
1383 {
1384     Q_D(QQuickWebView);
1385     d->pageView->eventHandler()->handleMouseReleaseEvent(event);
1386 }
1387
1388 void QQuickWebView::mouseDoubleClickEvent(QMouseEvent* event)
1389 {
1390     Q_D(QQuickWebView);
1391     // If a MouseButtonDblClick was received then we got a MouseButtonPress before
1392     // handleMousePressEvent will take care of double clicks.
1393     d->pageView->eventHandler()->handleMousePressEvent(event);
1394 }
1395
1396 void QQuickWebView::wheelEvent(QWheelEvent* event)
1397 {
1398     Q_D(QQuickWebView);
1399     d->pageView->eventHandler()->handleWheelEvent(event);
1400 }
1401
1402 void QQuickWebView::hoverEnterEvent(QHoverEvent* event)
1403 {
1404     Q_D(QQuickWebView);
1405     // Map HoverEnter to Move, for WebKit the distinction doesn't matter.
1406     d->pageView->eventHandler()->handleHoverMoveEvent(event);
1407 }
1408
1409 void QQuickWebView::hoverMoveEvent(QHoverEvent* event)
1410 {
1411     Q_D(QQuickWebView);
1412     d->pageView->eventHandler()->handleHoverMoveEvent(event);
1413 }
1414
1415 void QQuickWebView::hoverLeaveEvent(QHoverEvent* event)
1416 {
1417     Q_D(QQuickWebView);
1418     d->pageView->eventHandler()->handleHoverLeaveEvent(event);
1419 }
1420
1421 void QQuickWebView::dragMoveEvent(QDragMoveEvent* event)
1422 {
1423     Q_D(QQuickWebView);
1424     d->pageView->eventHandler()->handleDragMoveEvent(event);
1425 }
1426
1427 void QQuickWebView::dragEnterEvent(QDragEnterEvent* event)
1428 {
1429     Q_D(QQuickWebView);
1430     d->pageView->eventHandler()->handleDragEnterEvent(event);
1431 }
1432
1433 void QQuickWebView::dragLeaveEvent(QDragLeaveEvent* event)
1434 {
1435     Q_D(QQuickWebView);
1436     d->pageView->eventHandler()->handleDragLeaveEvent(event);
1437 }
1438
1439 void QQuickWebView::dropEvent(QDropEvent* event)
1440 {
1441     Q_D(QQuickWebView);
1442     d->pageView->eventHandler()->handleDropEvent(event);
1443 }
1444
1445 bool QQuickWebView::event(QEvent* ev)
1446 {
1447     // Re-implemented for possible future use without breaking binary compatibility.
1448     return QQuickItem::event(ev);
1449 }
1450
1451 WKPageRef QQuickWebView::pageRef() const
1452 {
1453     Q_D(const QQuickWebView);
1454     return toAPI(d->webPageProxy.get());
1455 }
1456
1457 /*!
1458     Loads the specified \a html as the content of the web view.
1459
1460     External objects such as stylesheets or images referenced in the HTML
1461     document are located relative to \a baseUrl.
1462
1463     \sa load()
1464 */
1465 void QQuickWebView::loadHtml(const QString& html, const QUrl& baseUrl)
1466 {
1467     Q_D(QQuickWebView);
1468     d->webPageProxy->loadHTMLString(html, baseUrl.toString());
1469 }
1470
1471 QPointF QQuickWebView::pageItemPos()
1472 {
1473     Q_D(QQuickWebView);
1474     return d->pageItemPos();
1475 }
1476
1477 void QQuickWebView::updateContentsSize(const QSizeF& size)
1478 {
1479     Q_D(QQuickWebView);
1480     d->updateContentsSize(size);
1481 }
1482
1483 #include "moc_qquickwebview_p.cpp"