summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
commit40736c5763bf61337c8c14e16d8587db021a87d4 (patch)
treeb17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
downloadqtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp')
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp988
1 files changed, 988 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
new file mode 100644
index 000000000..7bbef9182
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
@@ -0,0 +1,988 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "qquickwebview_p.h"
+
+#include "DownloadProxy.h"
+#include "DrawingAreaProxyImpl.h"
+#include "QtDialogRunner.h"
+#include "QtDownloadManager.h"
+#include "QtWebContext.h"
+#include "QtWebIconDatabaseClient.h"
+#include "QtWebPageEventHandler.h"
+#include "UtilsQt.h"
+#include "WebBackForwardList.h"
+#include "WebPageGroup.h"
+#include "WebPreferences.h"
+
+#include "qquicknetworkreply_p.h"
+#include "qquickwebpage_p_p.h"
+#include "qquickwebview_p_p.h"
+#include "qwebdownloaditem_p_p.h"
+#include "qwebnavigationhistory_p.h"
+#include "qwebnavigationhistory_p_p.h"
+#include "qwebpreferences_p.h"
+#include "qwebpreferences_p_p.h"
+#include "qwebviewportinfo_p.h"
+
+#include <JavaScriptCore/InitializeThreading.h>
+#include <QDeclarativeEngine>
+#include <QFileDialog>
+#include <QtQuick/QQuickCanvas>
+#include <WKOpenPanelResultListener.h>
+#include <wtf/text/WTFString.h>
+
+QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport)
+ : q_ptr(viewport)
+ , alertDialog(0)
+ , confirmDialog(0)
+ , promptDialog(0)
+ , itemSelector(0)
+ , postTransitionState(adoptPtr(new PostTransitionState(this)))
+ , isTransitioningToNewPage(false)
+ , pageIsSuspended(false)
+ , m_navigatorQtObjectEnabled(false)
+{
+ viewport->setFlags(QQuickItem::ItemClipsChildrenToShape);
+ QObject::connect(viewport, SIGNAL(visibleChanged()), viewport, SLOT(_q_onVisibleChanged()));
+ pageView.reset(new QQuickWebPage(viewport));
+}
+
+QQuickWebViewPrivate::~QQuickWebViewPrivate()
+{
+ if (interactionEngine)
+ interactionEngine->disconnect();
+ webPageProxy->close();
+}
+
+// Note: we delay this initialization to make sure that QQuickWebView has its d-ptr in-place.
+void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pageGroupRef)
+{
+ RefPtr<WebPageGroup> pageGroup;
+ if (pageGroupRef)
+ pageGroup = toImpl(pageGroupRef);
+ else
+ pageGroup = WebPageGroup::create();
+
+ context = contextRef ? QtWebContext::create(toImpl(contextRef)) : QtWebContext::defaultContext();
+ webPageProxy = context->createWebPage(&pageClient, pageGroup.get());
+
+ QQuickWebPagePrivate* const pageViewPrivate = pageView.data()->d;
+ pageViewPrivate->initialize(webPageProxy.get());
+
+ pageLoadClient.reset(new QtWebPageLoadClient(toAPI(webPageProxy.get()), q_ptr));
+ pagePolicyClient.reset(new QtWebPagePolicyClient(toAPI(webPageProxy.get()), q_ptr));
+ pageUIClient.reset(new QtWebPageUIClient(toAPI(webPageProxy.get()), q_ptr));
+ navigationHistory = adoptPtr(QWebNavigationHistoryPrivate::createHistory(toAPI(webPageProxy.get())));
+
+ QtWebIconDatabaseClient* iconDatabase = context->iconDatabase();
+ QObject::connect(iconDatabase, SIGNAL(iconChangedForPageURL(QUrl, QUrl)), q_ptr, SLOT(_q_onIconChangedForPageURL(QUrl, QUrl)));
+ QObject::connect(q_ptr, SIGNAL(urlChanged(QUrl)), iconDatabase, SLOT(requestIconForPageURL(QUrl)));
+
+ // Any page setting should preferrable be set before creating the page.
+ setUseTraditionalDesktopBehaviour(false);
+ webPageProxy->pageGroup()->preferences()->setAcceleratedCompositingEnabled(true);
+
+ pageClient.initialize(q_ptr, pageViewPrivate->eventHandler.data(), &undoController);
+ webPageProxy->initializeWebPage();
+
+ // Trigger setting of correct visibility flags after everything was allocated and initialized.
+ _q_onVisibleChanged();
+}
+
+void QQuickWebViewPrivate::enableMouseEvents()
+{
+ Q_Q(QQuickWebView);
+ q->setAcceptedMouseButtons(Qt::MouseButtonMask);
+ q->setAcceptHoverEvents(true);
+ pageView->setAcceptedMouseButtons(Qt::MouseButtonMask);
+ pageView->setAcceptHoverEvents(true);
+}
+
+void QQuickWebViewPrivate::disableMouseEvents()
+{
+ Q_Q(QQuickWebView);
+ q->setAcceptedMouseButtons(Qt::NoButton);
+ q->setAcceptHoverEvents(false);
+ pageView->setAcceptedMouseButtons(Qt::NoButton);
+ pageView->setAcceptHoverEvents(false);
+}
+
+void QQuickWebViewPrivate::initializeDesktop(QQuickWebView* viewport)
+{
+ if (interactionEngine) {
+ QObject::disconnect(interactionEngine.data(), SIGNAL(contentSuspendRequested()), viewport, SLOT(_q_suspend()));
+ QObject::disconnect(interactionEngine.data(), SIGNAL(contentResumeRequested()), viewport, SLOT(_q_resume()));
+ QObject::disconnect(interactionEngine.data(), SIGNAL(viewportTrajectoryVectorChanged(const QPointF&)), viewport, SLOT(_q_viewportTrajectoryVectorChanged(const QPointF&)));
+ }
+ interactionEngine.reset(0);
+ pageView->d->eventHandler->setViewportInteractionEngine(0);
+ enableMouseEvents();
+}
+
+void QQuickWebViewPrivate::initializeTouch(QQuickWebView* viewport)
+{
+ interactionEngine.reset(new QtViewportInteractionEngine(viewport, pageView.data()));
+ pageView->d->eventHandler->setViewportInteractionEngine(interactionEngine.data());
+ disableMouseEvents();
+ QObject::connect(interactionEngine.data(), SIGNAL(contentSuspendRequested()), viewport, SLOT(_q_suspend()));
+ QObject::connect(interactionEngine.data(), SIGNAL(contentResumeRequested()), viewport, SLOT(_q_resume()));
+ QObject::connect(interactionEngine.data(), SIGNAL(viewportTrajectoryVectorChanged(const QPointF&)), viewport, SLOT(_q_viewportTrajectoryVectorChanged(const QPointF&)));
+ updateViewportSize();
+}
+
+void QQuickWebViewPrivate::loadDidCommit()
+{
+ // Due to entering provisional load before committing, we
+ // might actually be suspended here.
+
+ if (useTraditionalDesktopBehaviour)
+ return;
+
+ isTransitioningToNewPage = true;
+}
+
+void QQuickWebViewPrivate::didFinishFirstNonEmptyLayout()
+{
+ if (useTraditionalDesktopBehaviour)
+ return;
+
+ if (!pageIsSuspended) {
+ isTransitioningToNewPage = false;
+ postTransitionState->apply();
+ }
+}
+
+void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURL)
+{
+ Q_Q(QQuickWebView);
+ if (q->url() != pageURL)
+ return;
+
+ setIcon(iconURL);
+}
+
+void QQuickWebViewPrivate::_q_suspend()
+{
+ pageIsSuspended = true;
+}
+
+void QQuickWebViewPrivate::_q_resume()
+{
+ pageIsSuspended = false;
+
+ if (isTransitioningToNewPage) {
+ isTransitioningToNewPage = false;
+ postTransitionState->apply();
+ }
+
+ updateVisibleContentRectAndScale();
+}
+
+void QQuickWebViewPrivate::didChangeContentsSize(const QSize& newSize)
+{
+ Q_Q(QQuickWebView);
+ if (useTraditionalDesktopBehaviour)
+ return;
+
+ // FIXME: We probably want to handle suspend here as well
+ if (isTransitioningToNewPage) {
+ postTransitionState->contentsSize = newSize;
+ return;
+ }
+
+ pageView->setWidth(newSize.width());
+ pageView->setHeight(newSize.height());
+
+ q->m_experimental->viewportInfo()->didUpdateContentsSize();
+}
+
+void QQuickWebViewPrivate::didChangeViewportProperties(const WebCore::ViewportArguments& args)
+{
+ if (useTraditionalDesktopBehaviour)
+ return;
+
+ viewportArguments = args;
+
+ if (isTransitioningToNewPage)
+ return;
+
+ interactionEngine->applyConstraints(computeViewportConstraints());
+}
+
+void QQuickWebViewPrivate::didChangeBackForwardList()
+{
+ navigationHistory->d->reset();
+}
+
+void QQuickWebViewPrivate::pageDidRequestScroll(const QPoint& pos)
+{
+ if (useTraditionalDesktopBehaviour)
+ return;
+
+ if (isTransitioningToNewPage) {
+ postTransitionState->position = pos;
+ return;
+ }
+
+ interactionEngine->pagePositionRequest(pos);
+}
+
+void QQuickWebViewPrivate::processDidCrash()
+{
+ emit q_ptr->navigationStateChanged();
+ pageView->d->eventHandler->resetGestureRecognizers();
+ WebCore::KURL url(WebCore::ParsedURLString, webPageProxy->urlAtProcessExit());
+ qWarning("WARNING: The web process experienced a crash on '%s'.", qPrintable(QUrl(url).toString(QUrl::RemoveUserInfo)));
+}
+
+void QQuickWebViewPrivate::didRelaunchProcess()
+{
+ emit q_ptr->navigationStateChanged();
+ qWarning("WARNING: The web process has been successfully restarted.");
+ pageView->d->setDrawingAreaSize(viewSize());
+}
+
+PassOwnPtr<DrawingAreaProxy> QQuickWebViewPrivate::createDrawingAreaProxy()
+{
+ return DrawingAreaProxyImpl::create(webPageProxy.get());
+}
+
+void QQuickWebViewPrivate::handleDownloadRequest(DownloadProxy* download)
+{
+ Q_Q(QQuickWebView);
+ // This function is responsible for hooking up a DownloadProxy to our API layer
+ // by creating a QWebDownloadItem. It will then wait for the QWebDownloadItem to be
+ // ready (filled with the ResourceResponse information) so we can pass it through to
+ // our WebViews.
+ QWebDownloadItem* downloadItem = new QWebDownloadItem();
+ downloadItem->d->downloadProxy = download;
+
+ q->connect(downloadItem->d, SIGNAL(receivedResponse(QWebDownloadItem*)), q, SLOT(_q_onReceivedResponseFromDownload(QWebDownloadItem*)));
+ context->downloadManager()->addDownload(download, downloadItem);
+}
+
+void QQuickWebViewPrivate::updateVisibleContentRectAndScale()
+{
+ DrawingAreaProxy* drawingArea = webPageProxy->drawingArea();
+ if (!drawingArea)
+ return;
+
+ Q_Q(QQuickWebView);
+ const QRectF visibleRectInPageViewCoordinates = q->mapRectToItem(pageView.data(), q->boundingRect()).intersected(pageView->boundingRect());
+ float scale = pageView->scale();
+
+ QRect alignedVisibleContentRect = visibleRectInPageViewCoordinates.toAlignedRect();
+ drawingArea->setVisibleContentsRectAndScale(alignedVisibleContentRect, scale);
+
+ // FIXME: Once we support suspend and resume, this should be delayed until the page is active if the page is suspended.
+ webPageProxy->setFixedVisibleContentRect(alignedVisibleContentRect);
+ q->m_experimental->viewportInfo()->didUpdateCurrentScale();
+}
+
+void QQuickWebViewPrivate::_q_viewportTrajectoryVectorChanged(const QPointF& trajectoryVector)
+{
+ DrawingAreaProxy* drawingArea = webPageProxy->drawingArea();
+ if (!drawingArea)
+ return;
+ drawingArea->setVisibleContentRectTrajectoryVector(trajectoryVector);
+}
+
+void QQuickWebViewPrivate::_q_onVisibleChanged()
+{
+ webPageProxy->viewStateDidChange(WebPageProxy::ViewIsVisible);
+}
+
+void QQuickWebViewPrivate::_q_onReceivedResponseFromDownload(QWebDownloadItem* downloadItem)
+{
+ // Now that our downloadItem has everything we need we can emit downloadRequested.
+ if (!downloadItem)
+ return;
+
+ Q_Q(QQuickWebView);
+ QDeclarativeEngine::setObjectOwnership(downloadItem, QDeclarativeEngine::JavaScriptOwnership);
+ emit q->experimental()->downloadRequested(downloadItem);
+}
+
+void QQuickWebViewPrivate::updateViewportSize()
+{
+ Q_Q(QQuickWebView);
+ QSize viewportSize = q->boundingRect().size().toSize();
+
+ if (viewportSize.isEmpty())
+ return;
+
+ // Let the WebProcess know about the new viewport size, so that
+ // it can resize the content accordingly.
+ webPageProxy->setViewportSize(viewportSize);
+
+ interactionEngine->applyConstraints(computeViewportConstraints());
+ updateVisibleContentRectAndScale();
+}
+
+void QQuickWebViewPrivate::PostTransitionState::apply()
+{
+ p->interactionEngine->reset();
+ p->interactionEngine->applyConstraints(p->computeViewportConstraints());
+ p->interactionEngine->pagePositionRequest(position);
+
+ if (contentsSize.isValid()) {
+ p->pageView->setWidth(contentsSize.width());
+ p->pageView->setHeight(contentsSize.height());
+ p->q_ptr->experimental()->viewportInfo()->didUpdateContentsSize();
+ }
+
+ position = QPoint();
+ contentsSize = QSize();
+}
+
+QtViewportInteractionEngine::Constraints QQuickWebViewPrivate::computeViewportConstraints()
+{
+ Q_Q(QQuickWebView);
+
+ QtViewportInteractionEngine::Constraints newConstraints;
+ QSize availableSize = q->boundingRect().size().toSize();
+
+ // Return default values for zero sized viewport.
+ if (availableSize.isEmpty())
+ return newConstraints;
+
+ WebPreferences* wkPrefs = webPageProxy->pageGroup()->preferences();
+
+ // FIXME: Remove later; Hardcode some values for now to make sure the DPI adjustment is being tested.
+ wkPrefs->setDeviceDPI(240);
+ wkPrefs->setDeviceWidth(480);
+ wkPrefs->setDeviceHeight(720);
+
+ int minimumLayoutFallbackWidth = qMax<int>(wkPrefs->layoutFallbackWidth(), availableSize.width());
+
+ WebCore::ViewportAttributes attr = WebCore::computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, wkPrefs->deviceWidth(), wkPrefs->deviceHeight(), wkPrefs->deviceDPI(), availableSize);
+ WebCore::restrictMinimumScaleFactorToViewportSize(attr, availableSize);
+ WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attr);
+
+ newConstraints.initialScale = attr.initialScale;
+ newConstraints.minimumScale = attr.minimumScale;
+ newConstraints.maximumScale = attr.maximumScale;
+ newConstraints.devicePixelRatio = attr.devicePixelRatio;
+ newConstraints.isUserScalable = !!attr.userScalable;
+ newConstraints.layoutSize = attr.layoutSize;
+
+ q->m_experimental->viewportInfo()->didUpdateViewportConstraints();
+
+ return newConstraints;
+}
+
+void QQuickWebViewPrivate::runJavaScriptAlert(const QString& alertText)
+{
+ if (!alertDialog)
+ return;
+
+ Q_Q(QQuickWebView);
+ QtDialogRunner dialogRunner;
+ if (!dialogRunner.initForAlert(alertDialog, q, alertText))
+ return;
+ setViewInAttachedProperties(dialogRunner.dialog());
+
+ disableMouseEvents();
+ dialogRunner.exec();
+ enableMouseEvents();
+}
+
+bool QQuickWebViewPrivate::runJavaScriptConfirm(const QString& message)
+{
+ if (!confirmDialog)
+ return true;
+
+ Q_Q(QQuickWebView);
+ QtDialogRunner dialogRunner;
+ if (!dialogRunner.initForConfirm(confirmDialog, q, message))
+ return true;
+ setViewInAttachedProperties(dialogRunner.dialog());
+
+ disableMouseEvents();
+ dialogRunner.exec();
+ enableMouseEvents();
+
+ return dialogRunner.wasAccepted();
+}
+
+QString QQuickWebViewPrivate::runJavaScriptPrompt(const QString& message, const QString& defaultValue, bool& ok)
+{
+ if (!promptDialog) {
+ ok = true;
+ return defaultValue;
+ }
+
+ Q_Q(QQuickWebView);
+ QtDialogRunner dialogRunner;
+ if (!dialogRunner.initForPrompt(promptDialog, q, message, defaultValue)) {
+ ok = true;
+ return defaultValue;
+ }
+ setViewInAttachedProperties(dialogRunner.dialog());
+
+ disableMouseEvents();
+ dialogRunner.exec();
+ enableMouseEvents();
+
+ ok = dialogRunner.wasAccepted();
+ return dialogRunner.result();
+}
+
+void QQuickWebViewPrivate::chooseFiles(WKOpenPanelResultListenerRef listenerRef, const QStringList& selectedFileNames, QtWebPageUIClient::FileChooserType type)
+{
+#ifndef QT_NO_FILEDIALOG
+ Q_Q(QQuickWebView);
+ openPanelResultListener = listenerRef;
+
+ // Qt does not support multiple files suggestion, so we get just the first suggestion.
+ QString selectedFileName;
+ if (!selectedFileNames.isEmpty())
+ selectedFileName = selectedFileNames.at(0);
+
+ Q_ASSERT(!fileDialog);
+
+ QWindow* window = q->canvas();
+ if (!window)
+ return;
+
+ fileDialog = new QFileDialog(0, QString(), selectedFileName);
+ fileDialog->window()->winId(); // Ensure that the dialog has a window
+ Q_ASSERT(fileDialog->window()->windowHandle());
+ fileDialog->window()->windowHandle()->setTransientParent(window);
+
+ fileDialog->open(q, SLOT(_q_onOpenPanelFilesSelected()));
+
+ q->connect(fileDialog, SIGNAL(finished(int)), SLOT(_q_onOpenPanelFinished(int)));
+#endif
+}
+
+void QQuickWebViewPrivate::_q_onOpenPanelFilesSelected()
+{
+ const QStringList fileList = fileDialog->selectedFiles();
+ Vector<RefPtr<APIObject> > wkFiles(fileList.size());
+
+ for (unsigned i = 0; i < fileList.size(); ++i)
+ wkFiles[i] = WebURL::create(QUrl::fromLocalFile(fileList.at(i)).toString());
+
+ WKOpenPanelResultListenerChooseFiles(openPanelResultListener, toAPI(ImmutableArray::adopt(wkFiles).leakRef()));
+}
+
+void QQuickWebViewPrivate::_q_onOpenPanelFinished(int result)
+{
+ if (result == QDialog::Rejected)
+ WKOpenPanelResultListenerCancel(openPanelResultListener);
+
+ fileDialog->deleteLater();
+ fileDialog = 0;
+}
+
+void QQuickWebViewPrivate::setUseTraditionalDesktopBehaviour(bool enable)
+{
+ Q_Q(QQuickWebView);
+
+ // Do not guard, testing for the same value, as we call this from the constructor.
+
+ webPageProxy->setUseFixedLayout(!enable);
+
+ useTraditionalDesktopBehaviour = enable;
+ if (useTraditionalDesktopBehaviour)
+ initializeDesktop(q);
+ else
+ initializeTouch(q);
+}
+
+void QQuickWebViewPrivate::setViewInAttachedProperties(QObject* object)
+{
+ Q_Q(QQuickWebView);
+ QQuickWebViewAttached* attached = static_cast<QQuickWebViewAttached*>(qmlAttachedPropertiesObject<QQuickWebView>(object));
+ attached->setView(q);
+}
+
+void QQuickWebViewPrivate::setIcon(const QUrl& iconURL)
+{
+ Q_Q(QQuickWebView);
+ if (m_iconURL == iconURL)
+ return;
+
+ String oldPageURL = QUrl::fromPercentEncoding(m_iconURL.encodedFragment());
+ String newPageURL = webPageProxy->mainFrame()->url();
+
+ if (oldPageURL != newPageURL) {
+ QtWebIconDatabaseClient* iconDatabase = context->iconDatabase();
+ if (!oldPageURL.isEmpty())
+ iconDatabase->releaseIconForPageURL(oldPageURL);
+
+ if (!newPageURL.isEmpty())
+ iconDatabase->retainIconForPageURL(newPageURL);
+ }
+
+ m_iconURL = iconURL;
+ emit q->iconChanged(m_iconURL);
+}
+
+bool QQuickWebViewPrivate::navigatorQtObjectEnabled() const
+{
+ return m_navigatorQtObjectEnabled;
+}
+
+void QQuickWebViewPrivate::setNavigatorQtObjectEnabled(bool enabled)
+{
+ ASSERT(enabled != m_navigatorQtObjectEnabled);
+ // FIXME: Currently we have to keep this information in both processes and the setting is asynchronous.
+ m_navigatorQtObjectEnabled = enabled;
+ context->setNavigatorQtObjectEnabled(webPageProxy.get(), enabled);
+}
+
+WebCore::IntSize QQuickWebViewPrivate::viewSize() const
+{
+ return WebCore::IntSize(pageView->width(), pageView->height());
+}
+
+void QQuickWebViewPrivate::didReceiveMessageFromNavigatorQtObject(const String& message)
+{
+ QVariantMap variantMap;
+ variantMap.insert(QLatin1String("data"), QString(message));
+ variantMap.insert(QLatin1String("origin"), q_ptr->url());
+ emit q_ptr->experimental()->messageReceived(variantMap);
+}
+
+/*!
+ \qmlsignal WebView::onNavigationRequested(request)
+
+ This signal is emitted for every navigation request. The request object contains url, button and modifiers properties
+ describing the navigation action, e.g. "a middle click with shift key pressed to 'http://qt-project.org'".
+
+ The navigation will be accepted by default. To change that, one can set the action property to WebView.IgnoreRequest to reject
+ the request or WebView.DownloadRequest to trigger a download instead of navigating to the url.
+
+ The request object cannot be used after the signal handler function ends.
+*/
+
+QQuickWebViewAttached::QQuickWebViewAttached(QObject* object)
+ : QObject(object)
+ , m_view(0)
+{
+
+}
+
+void QQuickWebViewAttached::setView(QQuickWebView* view)
+{
+ if (m_view == view)
+ return;
+ m_view = view;
+ emit viewChanged();
+}
+
+QQuickWebViewExperimental::QQuickWebViewExperimental(QQuickWebView *webView)
+ : QObject(webView)
+ , q_ptr(webView)
+ , d_ptr(webView->d_ptr.data())
+ , schemeParent(new QObject(this))
+ , m_viewportInfo(new QWebViewportInfo(webView->d_ptr.data(), this))
+{
+}
+
+QQuickWebViewExperimental::~QQuickWebViewExperimental()
+{
+}
+
+void QQuickWebViewExperimental::setUseTraditionalDesktopBehaviour(bool enable)
+{
+ Q_D(QQuickWebView);
+
+ if (enable == d->useTraditionalDesktopBehaviour)
+ return;
+
+ d->setUseTraditionalDesktopBehaviour(enable);
+}
+
+void QQuickWebViewExperimental::postMessage(const QString& message)
+{
+ Q_D(QQuickWebView);
+ d->context->postMessageToNavigatorQtObject(d->webPageProxy.get(), message);
+}
+
+QDeclarativeComponent* QQuickWebViewExperimental::alertDialog() const
+{
+ Q_D(const QQuickWebView);
+ return d->alertDialog;
+}
+
+void QQuickWebViewExperimental::setAlertDialog(QDeclarativeComponent* alertDialog)
+{
+ Q_D(QQuickWebView);
+ if (d->alertDialog == alertDialog)
+ return;
+ d->alertDialog = alertDialog;
+ emit alertDialogChanged();
+}
+
+QDeclarativeComponent* QQuickWebViewExperimental::confirmDialog() const
+{
+ Q_D(const QQuickWebView);
+ return d->confirmDialog;
+}
+
+void QQuickWebViewExperimental::setConfirmDialog(QDeclarativeComponent* confirmDialog)
+{
+ Q_D(QQuickWebView);
+ if (d->confirmDialog == confirmDialog)
+ return;
+ d->confirmDialog = confirmDialog;
+ emit confirmDialogChanged();
+}
+
+QWebNavigationHistory* QQuickWebViewExperimental::navigationHistory() const
+{
+ return d_ptr->navigationHistory.get();
+}
+
+QDeclarativeComponent* QQuickWebViewExperimental::promptDialog() const
+{
+ Q_D(const QQuickWebView);
+ return d->promptDialog;
+}
+
+QWebPreferences* QQuickWebViewExperimental::preferences() const
+{
+ QQuickWebViewPrivate* const d = d_ptr;
+ if (!d->preferences)
+ d->preferences = adoptPtr(QWebPreferencesPrivate::createPreferences(d));
+ return d->preferences.get();
+}
+
+void QQuickWebViewExperimental::setPromptDialog(QDeclarativeComponent* promptDialog)
+{
+ Q_D(QQuickWebView);
+ if (d->promptDialog == promptDialog)
+ return;
+ d->promptDialog = promptDialog;
+ emit promptDialogChanged();
+}
+
+QDeclarativeComponent* QQuickWebViewExperimental::itemSelector() const
+{
+ Q_D(const QQuickWebView);
+ return d->itemSelector;
+}
+
+void QQuickWebViewExperimental::setItemSelector(QDeclarativeComponent* itemSelector)
+{
+ Q_D(QQuickWebView);
+ if (d->itemSelector == itemSelector)
+ return;
+ d->itemSelector = itemSelector;
+ emit itemSelectorChanged();
+}
+
+bool QQuickWebViewExperimental::useTraditionalDesktopBehaviour() const
+{
+ Q_D(const QQuickWebView);
+ return d->useTraditionalDesktopBehaviour;
+}
+
+QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property, int index)
+{
+ const QObjectList children = property->object->children();
+ if (index < children.count())
+ return static_cast<QQuickUrlSchemeDelegate*>(children.at(index));
+ return 0;
+}
+
+void QQuickWebViewExperimental::schemeDelegates_Append(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property, QQuickUrlSchemeDelegate *scheme)
+{
+ QObject* schemeParent = property->object;
+ scheme->setParent(schemeParent);
+ QQuickWebViewExperimental* webViewExperimental = qobject_cast<QQuickWebViewExperimental*>(property->object->parent());
+ if (!webViewExperimental)
+ return;
+ QQuickWebViewPrivate* d = webViewExperimental->d_func();
+ d->webPageProxy->registerApplicationScheme(scheme->scheme());
+}
+
+int QQuickWebViewExperimental::schemeDelegates_Count(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property)
+{
+ return property->object->children().count();
+}
+
+void QQuickWebViewExperimental::schemeDelegates_Clear(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property)
+{
+ const QObjectList children = property->object->children();
+ for (int index = 0; index < children.count(); index++) {
+ QObject* child = children.at(index);
+ child->setParent(0);
+ delete child;
+ }
+}
+
+QDeclarativeListProperty<QQuickUrlSchemeDelegate> QQuickWebViewExperimental::schemeDelegates()
+{
+ return QDeclarativeListProperty<QQuickUrlSchemeDelegate>(schemeParent, 0,
+ QQuickWebViewExperimental::schemeDelegates_Append,
+ QQuickWebViewExperimental::schemeDelegates_Count,
+ QQuickWebViewExperimental::schemeDelegates_At,
+ QQuickWebViewExperimental::schemeDelegates_Clear);
+}
+
+void QQuickWebViewExperimental::invokeApplicationSchemeHandler(PassRefPtr<QtNetworkRequestData> request)
+{
+ const QObjectList children = schemeParent->children();
+ for (int index = 0; index < children.count(); index++) {
+ QQuickUrlSchemeDelegate* delegate = qobject_cast<QQuickUrlSchemeDelegate*>(children.at(index));
+ if (!delegate)
+ continue;
+ if (!delegate->scheme().compare(QString(request->m_scheme), Qt::CaseInsensitive)) {
+ delegate->reply()->setNetworkRequestData(request);
+ emit delegate->receivedRequest();
+ return;
+ }
+ }
+}
+
+void QQuickWebViewExperimental::sendApplicationSchemeReply(QQuickNetworkReply* reply)
+{
+ d_ptr->webPageProxy->sendApplicationSchemeReply(reply);
+}
+
+void QQuickWebViewExperimental::goForwardTo(int index)
+{
+ d_ptr->navigationHistory->d->goForwardTo(index);
+}
+
+void QQuickWebViewExperimental::goBackTo(int index)
+{
+ d_ptr->navigationHistory->d->goBackTo(index);
+}
+
+QWebViewportInfo* QQuickWebViewExperimental::viewportInfo()
+{
+ return m_viewportInfo;
+}
+
+QQuickWebPage* QQuickWebViewExperimental::page()
+{
+ return q_ptr->page();
+}
+
+QQuickWebView::QQuickWebView(QQuickItem* parent)
+ : QQuickItem(parent)
+ , d_ptr(new QQuickWebViewPrivate(this))
+ , m_experimental(new QQuickWebViewExperimental(this))
+{
+ Q_D(QQuickWebView);
+ d->initialize();
+ d->initializeTouch(this);
+}
+
+QQuickWebView::QQuickWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef, QQuickItem* parent)
+ : QQuickItem(parent)
+ , d_ptr(new QQuickWebViewPrivate(this))
+ , m_experimental(new QQuickWebViewExperimental(this))
+{
+ Q_D(QQuickWebView);
+ d->initialize(contextRef, pageGroupRef);
+}
+
+QQuickWebView::~QQuickWebView()
+{
+}
+
+QQuickWebPage* QQuickWebView::page()
+{
+ Q_D(QQuickWebView);
+ return d->pageView.data();
+}
+
+void QQuickWebView::load(const QUrl& url)
+{
+ Q_D(QQuickWebView);
+ d->webPageProxy->loadURL(url.toString());
+}
+
+void QQuickWebView::goBack()
+{
+ Q_D(QQuickWebView);
+ d->webPageProxy->goBack();
+}
+
+void QQuickWebView::goForward()
+{
+ Q_D(QQuickWebView);
+ d->webPageProxy->goForward();
+}
+
+void QQuickWebView::stop()
+{
+ Q_D(QQuickWebView);
+ d->webPageProxy->stopLoading();
+}
+
+void QQuickWebView::reload()
+{
+ Q_D(QQuickWebView);
+ const bool reloadFromOrigin = true;
+ d->webPageProxy->reload(reloadFromOrigin);
+}
+
+QUrl QQuickWebView::url() const
+{
+ Q_D(const QQuickWebView);
+ RefPtr<WebFrameProxy> mainFrame = d->webPageProxy->mainFrame();
+ if (!mainFrame)
+ return QUrl();
+ return QUrl(QString(mainFrame->url()));
+}
+
+QUrl QQuickWebView::icon() const
+{
+ Q_D(const QQuickWebView);
+ return d->m_iconURL;
+}
+
+int QQuickWebView::loadProgress() const
+{
+ Q_D(const QQuickWebView);
+ return d->pageLoadClient->loadProgress();
+}
+
+bool QQuickWebView::canGoBack() const
+{
+ Q_D(const QQuickWebView);
+ return d->webPageProxy->canGoBack();
+}
+
+bool QQuickWebView::canGoForward() const
+{
+ Q_D(const QQuickWebView);
+ return d->webPageProxy->canGoForward();
+}
+
+bool QQuickWebView::loading() const
+{
+ Q_D(const QQuickWebView);
+ RefPtr<WebKit::WebFrameProxy> mainFrame = d->webPageProxy->mainFrame();
+ return mainFrame && !(WebFrameProxy::LoadStateFinished == mainFrame->loadState());
+}
+
+bool QQuickWebView::canReload() const
+{
+ Q_D(const QQuickWebView);
+ RefPtr<WebKit::WebFrameProxy> mainFrame = d->webPageProxy->mainFrame();
+ if (mainFrame)
+ return (WebFrameProxy::LoadStateFinished == mainFrame->loadState());
+ return d->webPageProxy->backForwardList()->currentItem();
+}
+
+QString QQuickWebView::title() const
+{
+ Q_D(const QQuickWebView);
+ return d->webPageProxy->pageTitle();
+}
+
+QVariant QQuickWebView::inputMethodQuery(Qt::InputMethodQuery property) const
+{
+ Q_D(const QQuickWebView);
+ const EditorState& state = d->webPageProxy->editorState();
+
+ switch(property) {
+ case Qt::ImCursorRectangle:
+ return QRectF(state.microFocus);
+ case Qt::ImFont:
+ return QVariant();
+ case Qt::ImCursorPosition:
+ return QVariant(static_cast<int>(state.cursorPosition));
+ case Qt::ImAnchorPosition:
+ return QVariant(static_cast<int>(state.anchorPosition));
+ case Qt::ImSurroundingText:
+ return QString(state.surroundingText);
+ case Qt::ImCurrentSelection:
+ return QString(state.selectedText);
+ case Qt::ImMaximumTextLength:
+ return QVariant(); // No limit.
+ default:
+ // Rely on the base implementation for ImEnabled, ImHints and ImPreferredLanguage.
+ return QQuickItem::inputMethodQuery(property);
+ }
+}
+
+QQuickWebViewExperimental* QQuickWebView::experimental() const
+{
+ return m_experimental;
+}
+
+QQuickWebViewAttached* QQuickWebView::qmlAttachedProperties(QObject* object)
+{
+ return new QQuickWebViewAttached(object);
+}
+
+void QQuickWebView::platformInitialize()
+{
+ JSC::initializeThreading();
+ WTF::initializeMainThread();
+}
+
+void QQuickWebView::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry)
+{
+ Q_D(QQuickWebView);
+ QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ if (newGeometry.size() != oldGeometry.size()) {
+ if (d->useTraditionalDesktopBehaviour) {
+ d->pageView->setWidth(newGeometry.width());
+ d->pageView->setHeight(newGeometry.height());
+ } else
+ d->updateViewportSize();
+ }
+}
+
+void QQuickWebView::focusInEvent(QFocusEvent* event)
+{
+ Q_D(QQuickWebView);
+ d->pageView->event(event);
+}
+
+void QQuickWebView::focusOutEvent(QFocusEvent* event)
+{
+ Q_D(QQuickWebView);
+ d->pageView->event(event);
+}
+
+WKPageRef QQuickWebView::pageRef() const
+{
+ Q_D(const QQuickWebView);
+ return toAPI(d->webPageProxy.get());
+}
+
+/*!
+ Loads the specified \a html as the content of the web view.
+
+ External objects such as stylesheets or images referenced in the HTML
+ document are located relative to \a baseUrl.
+
+ \sa load()
+*/
+void QQuickWebView::loadHtml(const QString& html, const QUrl& baseUrl)
+{
+ Q_D(QQuickWebView);
+ d->webPageProxy->loadHTMLString(html, baseUrl.toString());
+}
+
+#include "moc_qquickwebview_p.cpp"