diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/API/qt')
9 files changed, 390 insertions, 143 deletions
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp index b1b465526..167c50f6a 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp @@ -27,6 +27,7 @@ #include "QtDownloadManager.h" #include "QtViewportInteractionEngine.h" #include "QtWebContext.h" +#include "QtWebError.h" #include "QtWebIconDatabaseClient.h" #include "QtWebPageEventHandler.h" #include "QtWebPageLoadClient.h" @@ -52,10 +53,14 @@ #include "qwebviewportinfo_p.h" #include <JavaScriptCore/InitializeThreading.h> +#include <JavaScriptCore/JSBase.h> +#include <JavaScriptCore/JSRetainPtr.h> #include <QDateTime> +#include <QtQml/QJSValue> +#include <WKOpenPanelResultListener.h> +#include <WKSerializedScriptValue.h> #include <WebCore/IntPoint.h> #include <WebCore/IntRect.h> -#include <WKOpenPanelResultListener.h> #include <wtf/Assertions.h> #include <wtf/MainThread.h> #include <wtf/text/WTFString.h> @@ -68,6 +73,105 @@ static const int kAxisLockSampleCount = 5; static const qreal kAxisLockVelocityThreshold = 300; static const qreal kAxisLockVelocityDirectionThreshold = 50; +struct JSCallbackClosure { + QPointer<QObject> receiver; + QByteArray method; + QJSValue value; +}; + +static inline QString toQString(JSStringRef string) +{ + return QString(reinterpret_cast<const QChar*>(JSStringGetCharactersPtr(string)), JSStringGetLength(string)); +} + +static inline QJSValue toQJSValue(JSStringRef string) +{ + return QJSValue(toQString(string)); +} + +static QJSValue buildQJSValue(QJSEngine* engine, JSGlobalContextRef context, JSValueRef value, int depth) +{ + QJSValue var; + JSValueRef exception = 0; + + if (depth > 10) + return var; + + switch (JSValueGetType(context, value)) { + case kJSTypeBoolean: + var = QJSValue(JSValueToBoolean(context, value)); + break; + case kJSTypeNumber: + { + double number = JSValueToNumber(context, value, &exception); + if (!exception) + var = QJSValue(number); + } + break; + case kJSTypeString: + { + JSRetainPtr<JSStringRef> string = JSValueToStringCopy(context, value, &exception); + if (!exception) + var = toQJSValue(string.get()); + } + break; + case kJSTypeObject: + { + JSObjectRef obj = JSValueToObject(context, value, &exception); + + JSPropertyNameArrayRef names = JSObjectCopyPropertyNames(context, obj); + size_t length = JSPropertyNameArrayGetCount(names); + + var = engine->newObject(); + + for (size_t i = 0; i < length; ++i) { + JSRetainPtr<JSStringRef> name = JSPropertyNameArrayGetNameAtIndex(names, i); + JSValueRef property = JSObjectGetProperty(context, obj, name.get(), &exception); + + if (!exception) { + QJSValue value = buildQJSValue(engine, context, property, depth + 1); + var.setProperty(toQString(name.get()), value); + } + } + } + break; + } + return var; +} + +static void javaScriptCallback(WKSerializedScriptValueRef valueRef, WKErrorRef, void* data) +{ + JSCallbackClosure* closure = reinterpret_cast<JSCallbackClosure*>(data); + + if (closure->method.size()) + QMetaObject::invokeMethod(closure->receiver, closure->method); + else { + QJSValue function = closure->value; + + // If a callable function is supplied, we build a JavaScript value accessible + // in the QML engine, and calls the function with that. + if (function.isCallable()) { + QJSValue var; + if (valueRef) { + // FIXME: Slow but OK for now. + JSGlobalContextRef context = JSGlobalContextCreate(0); + + JSValueRef exception = 0; + JSValueRef value = WKSerializedScriptValueDeserialize(valueRef, context, &exception); + var = buildQJSValue(function.engine(), context, value, /* depth */ 0); + + JSGlobalContextRelease(context); + } + + QList<QJSValue> args; + args.append(var); + function.call(args); + } + } + + delete closure; +} + static QQuickWebViewPrivate* createPrivateObject(QQuickWebView* publicObject) { if (s_flickableViewportEnabled) @@ -162,6 +266,7 @@ QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport) , m_navigatorQtObjectEnabled(false) , m_renderToOffscreenBuffer(false) , m_dialogActive(false) + , m_loadProgress(0) { viewport->setClip(true); viewport->setPixelAligned(true); @@ -230,20 +335,72 @@ QPointF QQuickWebViewPrivate::pageItemPos() \qmlsignal WebView::loadingChanged(WebLoadRequest request) */ +void QQuickWebViewPrivate::provisionalLoadDidStart(const QUrl& url) +{ + Q_Q(QQuickWebView); + + QWebLoadRequest loadRequest(url, QQuickWebView::LoadStartedStatus); + emit q->loadingChanged(&loadRequest); +} + +void QQuickWebViewPrivate::loadDidCommit() +{ + Q_Q(QQuickWebView); + ASSERT(q->loading()); + + emit q->navigationHistoryChanged(); + emit q->urlChanged(); + emit q->titleChanged(); +} + +void QQuickWebViewPrivate::didSameDocumentNavigation() +{ + Q_Q(QQuickWebView); + + emit q->navigationHistoryChanged(); + emit q->urlChanged(); +} + +void QQuickWebViewPrivate::titleDidChange() +{ + Q_Q(QQuickWebView); + + emit q->titleChanged(); +} + +void QQuickWebViewPrivate::loadProgressDidChange(int loadProgress) +{ + Q_Q(QQuickWebView); + + if (!loadProgress) + setIcon(QUrl()); + + m_loadProgress = loadProgress; + + emit q->loadProgressChanged(); +} + +void QQuickWebViewPrivate::backForwardListDidChange() +{ + navigationHistory->d->reset(); +} + void QQuickWebViewPrivate::loadDidSucceed() { Q_Q(QQuickWebView); ASSERT(!q->loading()); + QWebLoadRequest loadRequest(q->url(), QQuickWebView::LoadSucceededStatus); emit q->loadingChanged(&loadRequest); } -void QQuickWebViewPrivate::onComponentComplete() +void QQuickWebViewPrivate::loadDidFail(const QtWebError& error) { - if (m_deferedUrlToLoad.isEmpty()) - return; + Q_Q(QQuickWebView); + ASSERT(!q->loading()); - q_ptr->setUrl(m_deferedUrlToLoad); + QWebLoadRequest loadRequest(error.url(), QQuickWebView::LoadFailedStatus, error.description(), static_cast<QQuickWebView::ErrorDomain>(error.type()), error.errorCode()); + emit q->loadingChanged(&loadRequest); } void QQuickWebViewPrivate::setNeedsDisplay() @@ -269,18 +426,22 @@ void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QUrl& pageURL, const setIcon(iconURL); } -void QQuickWebViewPrivate::didChangeBackForwardList() -{ - navigationHistory->d->reset(); -} - void QQuickWebViewPrivate::processDidCrash() { - pageView->eventHandler()->resetGestureRecognizers(); - pageLoadClient->completeLoadWhenProcessDidCrashIfNeeded(); + Q_Q(QQuickWebView); QUrl url(KURL(WebCore::ParsedURLString, webPageProxy->urlAtProcessExit())); qWarning("WARNING: The web process experienced a crash on '%s'.", qPrintable(url.toString(QUrl::RemoveUserInfo))); + + pageView->eventHandler()->resetGestureRecognizers(); + + // Check if loading was ongoing, when process crashed. + if (m_loadProgress > 0 && m_loadProgress < 100) { + QWebLoadRequest loadRequest(url, QQuickWebView::LoadFailedStatus, QLatin1String("The web process crashed."), QQuickWebView::InternalErrorDomain, 0); + + loadProgressDidChange(100); + emit q->loadingChanged(&loadRequest); + } } void QQuickWebViewPrivate::didRelaunchProcess() @@ -328,7 +489,7 @@ void QQuickWebViewPrivate::_q_onReceivedResponseFromDownload(QWebDownloadItem* d return; Q_Q(QQuickWebView); - QDeclarativeEngine::setObjectOwnership(downloadItem, QDeclarativeEngine::JavaScriptOwnership); + QQmlEngine::setObjectOwnership(downloadItem, QQmlEngine::JavaScriptOwnership); emit q->experimental()->downloadRequested(downloadItem); } @@ -626,7 +787,6 @@ void QQuickWebViewLegacyPrivate::setZoomFactor(qreal factor) QQuickWebViewFlickablePrivate::QQuickWebViewFlickablePrivate(QQuickWebView* viewport) : QQuickWebViewPrivate(viewport) , pageIsSuspended(true) - , loadSuccessDispatchIsPending(false) { // Disable mouse events on the flickable web view so we do not // select text during pan gestures on platforms which send both @@ -689,44 +849,16 @@ void QQuickWebViewFlickablePrivate::onComponentComplete() _q_resume(); - if (loadSuccessDispatchIsPending) { - QQuickWebViewPrivate::loadDidSucceed(); - loadSuccessDispatchIsPending = false; - } - // Trigger setting of correct visibility flags after everything was allocated and initialized. _q_onVisibleChanged(); - - QQuickWebViewPrivate::onComponentComplete(); -} - -void QQuickWebViewFlickablePrivate::loadDidSucceed() -{ - if (interactionEngine) - QQuickWebViewPrivate::loadDidSucceed(); - else - loadSuccessDispatchIsPending = true; -} - -void QQuickWebViewFlickablePrivate::loadDidCommit() -{ - // Due to entering provisional load before committing, we - // might actually be suspended here. -} - -void QQuickWebViewFlickablePrivate::didFinishFirstNonEmptyLayout() -{ } void QQuickWebViewFlickablePrivate::didChangeViewportProperties(const WebCore::ViewportAttributes& newAttributes) { Q_Q(QQuickWebView); - QSize viewportSize = q->boundingRect().size().toSize(); - // FIXME: Revise these when implementing fit-to-width. WebCore::ViewportAttributes attr = newAttributes; - WebCore::restrictMinimumScaleFactorToViewportSize(attr, viewportSize); WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attr); // FIXME: Resetting here can reset more than needed. For instance it will end deferrers. @@ -814,8 +946,20 @@ void QQuickWebViewFlickablePrivate::pageDidRequestScroll(const QPoint& pos) void QQuickWebViewFlickablePrivate::didChangeContentsSize(const QSize& newSize) { Q_Q(QQuickWebView); + QSize viewportSize = q->boundingRect().size().toSize(); + pageView->setContentsSize(newSize); q->experimental()->viewportInfo()->didUpdateContentsSize(); + + float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(attributes, viewportSize, newSize); + + if (!qFuzzyCompare(minimumScale, attributes.minimumScale)) { + interactionEngine->setCSSScaleBounds(minimumScale, attributes.maximumScale); + q->experimental()->viewportInfo()->didUpdateViewportConstraints(); + + if (!interactionEngine->hadUserInteraction() && !pageIsSuspended) + interactionEngine->setCSSScale(minimumScale); + } } /*! @@ -955,13 +1099,13 @@ void QQuickWebViewExperimental::postMessage(const QString& message) d->context->postMessageToNavigatorQtObject(d->webPageProxy.get(), message); } -QDeclarativeComponent* QQuickWebViewExperimental::alertDialog() const +QQmlComponent* QQuickWebViewExperimental::alertDialog() const { Q_D(const QQuickWebView); return d->alertDialog; } -void QQuickWebViewExperimental::setAlertDialog(QDeclarativeComponent* alertDialog) +void QQuickWebViewExperimental::setAlertDialog(QQmlComponent* alertDialog) { Q_D(QQuickWebView); if (d->alertDialog == alertDialog) @@ -970,13 +1114,13 @@ void QQuickWebViewExperimental::setAlertDialog(QDeclarativeComponent* alertDialo emit alertDialogChanged(); } -QDeclarativeComponent* QQuickWebViewExperimental::confirmDialog() const +QQmlComponent* QQuickWebViewExperimental::confirmDialog() const { Q_D(const QQuickWebView); return d->confirmDialog; } -void QQuickWebViewExperimental::setConfirmDialog(QDeclarativeComponent* confirmDialog) +void QQuickWebViewExperimental::setConfirmDialog(QQmlComponent* confirmDialog) { Q_D(QQuickWebView); if (d->confirmDialog == confirmDialog) @@ -990,7 +1134,7 @@ QWebNavigationHistory* QQuickWebViewExperimental::navigationHistory() const return d_ptr->navigationHistory.get(); } -QDeclarativeComponent* QQuickWebViewExperimental::promptDialog() const +QQmlComponent* QQuickWebViewExperimental::promptDialog() const { Q_D(const QQuickWebView); return d->promptDialog; @@ -1004,7 +1148,7 @@ QWebPreferences* QQuickWebViewExperimental::preferences() const return d->preferences.get(); } -void QQuickWebViewExperimental::setPromptDialog(QDeclarativeComponent* promptDialog) +void QQuickWebViewExperimental::setPromptDialog(QQmlComponent* promptDialog) { Q_D(QQuickWebView); if (d->promptDialog == promptDialog) @@ -1013,13 +1157,13 @@ void QQuickWebViewExperimental::setPromptDialog(QDeclarativeComponent* promptDia emit promptDialogChanged(); } -QDeclarativeComponent* QQuickWebViewExperimental::authenticationDialog() const +QQmlComponent* QQuickWebViewExperimental::authenticationDialog() const { Q_D(const QQuickWebView); return d->authenticationDialog; } -void QQuickWebViewExperimental::setAuthenticationDialog(QDeclarativeComponent* authenticationDialog) +void QQuickWebViewExperimental::setAuthenticationDialog(QQmlComponent* authenticationDialog) { Q_D(QQuickWebView); if (d->authenticationDialog == authenticationDialog) @@ -1028,13 +1172,13 @@ void QQuickWebViewExperimental::setAuthenticationDialog(QDeclarativeComponent* a emit authenticationDialogChanged(); } -QDeclarativeComponent* QQuickWebViewExperimental::proxyAuthenticationDialog() const +QQmlComponent* QQuickWebViewExperimental::proxyAuthenticationDialog() const { Q_D(const QQuickWebView); return d->proxyAuthenticationDialog; } -void QQuickWebViewExperimental::setProxyAuthenticationDialog(QDeclarativeComponent* proxyAuthenticationDialog) +void QQuickWebViewExperimental::setProxyAuthenticationDialog(QQmlComponent* proxyAuthenticationDialog) { Q_D(QQuickWebView); if (d->proxyAuthenticationDialog == proxyAuthenticationDialog) @@ -1042,13 +1186,13 @@ void QQuickWebViewExperimental::setProxyAuthenticationDialog(QDeclarativeCompone d->proxyAuthenticationDialog = proxyAuthenticationDialog; emit proxyAuthenticationDialogChanged(); } -QDeclarativeComponent* QQuickWebViewExperimental::certificateVerificationDialog() const +QQmlComponent* QQuickWebViewExperimental::certificateVerificationDialog() const { Q_D(const QQuickWebView); return d->certificateVerificationDialog; } -void QQuickWebViewExperimental::setCertificateVerificationDialog(QDeclarativeComponent* certificateVerificationDialog) +void QQuickWebViewExperimental::setCertificateVerificationDialog(QQmlComponent* certificateVerificationDialog) { Q_D(QQuickWebView); if (d->certificateVerificationDialog == certificateVerificationDialog) @@ -1057,13 +1201,13 @@ void QQuickWebViewExperimental::setCertificateVerificationDialog(QDeclarativeCom emit certificateVerificationDialogChanged(); } -QDeclarativeComponent* QQuickWebViewExperimental::itemSelector() const +QQmlComponent* QQuickWebViewExperimental::itemSelector() const { Q_D(const QQuickWebView); return d->itemSelector; } -void QQuickWebViewExperimental::setItemSelector(QDeclarativeComponent* itemSelector) +void QQuickWebViewExperimental::setItemSelector(QQmlComponent* itemSelector) { Q_D(QQuickWebView); if (d->itemSelector == itemSelector) @@ -1072,13 +1216,13 @@ void QQuickWebViewExperimental::setItemSelector(QDeclarativeComponent* itemSelec emit itemSelectorChanged(); } -QDeclarativeComponent* QQuickWebViewExperimental::filePicker() const +QQmlComponent* QQuickWebViewExperimental::filePicker() const { Q_D(const QQuickWebView); return d->filePicker; } -void QQuickWebViewExperimental::setFilePicker(QDeclarativeComponent* filePicker) +void QQuickWebViewExperimental::setFilePicker(QQmlComponent* filePicker) { Q_D(QQuickWebView); if (d->filePicker == filePicker) @@ -1087,13 +1231,13 @@ void QQuickWebViewExperimental::setFilePicker(QDeclarativeComponent* filePicker) emit filePickerChanged(); } -QDeclarativeComponent* QQuickWebViewExperimental::databaseQuotaDialog() const +QQmlComponent* QQuickWebViewExperimental::databaseQuotaDialog() const { Q_D(const QQuickWebView); return d->databaseQuotaDialog; } -void QQuickWebViewExperimental::setDatabaseQuotaDialog(QDeclarativeComponent* databaseQuotaDialog) +void QQuickWebViewExperimental::setDatabaseQuotaDialog(QQmlComponent* databaseQuotaDialog) { Q_D(QQuickWebView); if (d->databaseQuotaDialog == databaseQuotaDialog) @@ -1171,7 +1315,25 @@ void QQuickWebViewExperimental::setDevicePixelRatio(double devicePixelRatio) emit devicePixelRatioChanged(); } -QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property, int index) +/*! + \internal + + \qmlmethod void WebViewExperimental::evaluateJavaScript(string script [, function(result)]) + + \brief Evaluates the specified JavaScript and, if supplied, calls a function with the result. +*/ + +void QQuickWebViewExperimental::evaluateJavaScript(const QString& script, const QJSValue& value) +{ + JSCallbackClosure* closure = new JSCallbackClosure; + + closure->receiver = this; + closure->value = value; + + d_ptr->webPageProxy.get()->runJavaScriptInMainFrame(script, ScriptValueCallback::create(closure, javaScriptCallback)); +} + +QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QQmlListProperty<QQuickUrlSchemeDelegate>* property, int index) { const QObjectList children = property->object->children(); if (index < children.count()) @@ -1179,7 +1341,7 @@ QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QDeclarat return 0; } -void QQuickWebViewExperimental::schemeDelegates_Append(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property, QQuickUrlSchemeDelegate *scheme) +void QQuickWebViewExperimental::schemeDelegates_Append(QQmlListProperty<QQuickUrlSchemeDelegate>* property, QQuickUrlSchemeDelegate *scheme) { QObject* schemeParent = property->object; scheme->setParent(schemeParent); @@ -1191,12 +1353,12 @@ void QQuickWebViewExperimental::schemeDelegates_Append(QDeclarativeListProperty< d->webPageProxy->registerApplicationScheme(scheme->scheme()); } -int QQuickWebViewExperimental::schemeDelegates_Count(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property) +int QQuickWebViewExperimental::schemeDelegates_Count(QQmlListProperty<QQuickUrlSchemeDelegate>* property) { return property->object->children().count(); } -void QQuickWebViewExperimental::schemeDelegates_Clear(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property) +void QQuickWebViewExperimental::schemeDelegates_Clear(QQmlListProperty<QQuickUrlSchemeDelegate>* property) { const QObjectList children = property->object->children(); for (int index = 0; index < children.count(); index++) { @@ -1206,9 +1368,9 @@ void QQuickWebViewExperimental::schemeDelegates_Clear(QDeclarativeListProperty<Q } } -QDeclarativeListProperty<QQuickUrlSchemeDelegate> QQuickWebViewExperimental::schemeDelegates() +QQmlListProperty<QQuickUrlSchemeDelegate> QQuickWebViewExperimental::schemeDelegates() { - return QDeclarativeListProperty<QQuickUrlSchemeDelegate>(schemeParent, 0, + return QQmlListProperty<QQuickUrlSchemeDelegate>(schemeParent, 0, QQuickWebViewExperimental::schemeDelegates_Append, QQuickWebViewExperimental::schemeDelegates_Count, QQuickWebViewExperimental::schemeDelegates_At, @@ -1336,11 +1498,6 @@ void QQuickWebView::setUrl(const QUrl& url) if (url.isEmpty()) return; - if (!isComponentComplete()) { - d->m_deferedUrlToLoad = url; - return; - } - d->webPageProxy->loadURL(url.toString()); } @@ -1360,7 +1517,7 @@ QUrl QQuickWebView::icon() const int QQuickWebView::loadProgress() const { Q_D(const QQuickWebView); - return d->pageLoadClient->loadProgress(); + return d->loadProgress(); } bool QQuickWebView::canGoBack() const @@ -1725,24 +1882,14 @@ void QQuickWebView::setZoomFactor(qreal factor) d->setZoomFactor(factor); } -struct JSCallbackClosure { - QPointer<QObject> receiver; - QByteArray method; -}; - -static void javaScriptCallback(WKSerializedScriptValueRef, WKErrorRef, void* context) -{ - JSCallbackClosure* closure = reinterpret_cast<JSCallbackClosure*>(context); - QMetaObject::invokeMethod(closure->receiver, closure->method); - delete closure; -} - void QQuickWebView::runJavaScriptInMainFrame(const QString &script, QObject *receiver, const char *method) { Q_D(QQuickWebView); + JSCallbackClosure* closure = new JSCallbackClosure; closure->receiver = receiver; closure->method = method; + d->webPageProxy.get()->runJavaScriptInMainFrame(script, ScriptValueCallback::create(closure, javaScriptCallback)); } diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h index 916f2282d..4bdd0fbbd 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h @@ -28,7 +28,7 @@ #include <private/qquickflickable_p.h> class QWebNavigationRequest; -class QDeclarativeComponent; +class QQmlComponent; class QQuickWebPage; class QQuickWebViewAttached; class QWebLoadRequest; @@ -65,11 +65,12 @@ QT_BEGIN_NAMESPACE class QPainter; class QUrl; class QQuickFlickable; +class QJSValue; QT_END_NAMESPACE // Instantiating the WebView in C++ is only possible by creating -// a QDeclarativeComponent as the initialization depends on the +// a QQmlComponent as the initialization depends on the // componentComplete method being called. class QWEBKIT_EXPORT QQuickWebView : public QQuickFlickable { Q_OBJECT @@ -252,18 +253,18 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject { Q_PROPERTY(int preferredMinimumContentsWidth WRITE setPreferredMinimumContentsWidth READ preferredMinimumContentsWidth) Q_PROPERTY(QWebNavigationHistory* navigationHistory READ navigationHistory CONSTANT FINAL) - Q_PROPERTY(QDeclarativeComponent* alertDialog READ alertDialog WRITE setAlertDialog NOTIFY alertDialogChanged) - Q_PROPERTY(QDeclarativeComponent* confirmDialog READ confirmDialog WRITE setConfirmDialog NOTIFY confirmDialogChanged) - Q_PROPERTY(QDeclarativeComponent* promptDialog READ promptDialog WRITE setPromptDialog NOTIFY promptDialogChanged) - Q_PROPERTY(QDeclarativeComponent* authenticationDialog READ authenticationDialog WRITE setAuthenticationDialog NOTIFY authenticationDialogChanged) - Q_PROPERTY(QDeclarativeComponent* proxyAuthenticationDialog READ proxyAuthenticationDialog WRITE setProxyAuthenticationDialog NOTIFY proxyAuthenticationDialogChanged) - Q_PROPERTY(QDeclarativeComponent* certificateVerificationDialog READ certificateVerificationDialog WRITE setCertificateVerificationDialog NOTIFY certificateVerificationDialogChanged) - Q_PROPERTY(QDeclarativeComponent* itemSelector READ itemSelector WRITE setItemSelector NOTIFY itemSelectorChanged) - Q_PROPERTY(QDeclarativeComponent* filePicker READ filePicker WRITE setFilePicker NOTIFY filePickerChanged) - Q_PROPERTY(QDeclarativeComponent* databaseQuotaDialog READ databaseQuotaDialog WRITE setDatabaseQuotaDialog NOTIFY databaseQuotaDialogChanged) + Q_PROPERTY(QQmlComponent* alertDialog READ alertDialog WRITE setAlertDialog NOTIFY alertDialogChanged) + Q_PROPERTY(QQmlComponent* confirmDialog READ confirmDialog WRITE setConfirmDialog NOTIFY confirmDialogChanged) + Q_PROPERTY(QQmlComponent* promptDialog READ promptDialog WRITE setPromptDialog NOTIFY promptDialogChanged) + Q_PROPERTY(QQmlComponent* authenticationDialog READ authenticationDialog WRITE setAuthenticationDialog NOTIFY authenticationDialogChanged) + Q_PROPERTY(QQmlComponent* proxyAuthenticationDialog READ proxyAuthenticationDialog WRITE setProxyAuthenticationDialog NOTIFY proxyAuthenticationDialogChanged) + Q_PROPERTY(QQmlComponent* certificateVerificationDialog READ certificateVerificationDialog WRITE setCertificateVerificationDialog NOTIFY certificateVerificationDialogChanged) + Q_PROPERTY(QQmlComponent* itemSelector READ itemSelector WRITE setItemSelector NOTIFY itemSelectorChanged) + Q_PROPERTY(QQmlComponent* filePicker READ filePicker WRITE setFilePicker NOTIFY filePickerChanged) + Q_PROPERTY(QQmlComponent* databaseQuotaDialog READ databaseQuotaDialog WRITE setDatabaseQuotaDialog NOTIFY databaseQuotaDialogChanged) Q_PROPERTY(QWebPreferences* preferences READ preferences CONSTANT FINAL) Q_PROPERTY(QWebViewportInfo* viewportInfo READ viewportInfo CONSTANT FINAL) - Q_PROPERTY(QDeclarativeListProperty<QQuickUrlSchemeDelegate> urlSchemeDelegates READ schemeDelegates) + Q_PROPERTY(QQmlListProperty<QQuickUrlSchemeDelegate> urlSchemeDelegates READ schemeDelegates) Q_PROPERTY(QString userAgent READ userAgent WRITE setUserAgent NOTIFY userAgentChanged) Q_PROPERTY(double devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged) Q_ENUMS(NavigationRequestActionExperimental) @@ -276,24 +277,24 @@ public: QQuickWebViewExperimental(QQuickWebView* webView); virtual ~QQuickWebViewExperimental(); - QDeclarativeComponent* alertDialog() const; - void setAlertDialog(QDeclarativeComponent*); - QDeclarativeComponent* confirmDialog() const; - void setConfirmDialog(QDeclarativeComponent*); - QDeclarativeComponent* promptDialog() const; - void setPromptDialog(QDeclarativeComponent*); - QDeclarativeComponent* authenticationDialog() const; - void setAuthenticationDialog(QDeclarativeComponent*); - QDeclarativeComponent* certificateVerificationDialog() const; - void setCertificateVerificationDialog(QDeclarativeComponent*); - QDeclarativeComponent* itemSelector() const; - void setItemSelector(QDeclarativeComponent*); - QDeclarativeComponent* proxyAuthenticationDialog() const; - void setProxyAuthenticationDialog(QDeclarativeComponent*); - QDeclarativeComponent* filePicker() const; - void setFilePicker(QDeclarativeComponent*); - QDeclarativeComponent* databaseQuotaDialog() const; - void setDatabaseQuotaDialog(QDeclarativeComponent*); + QQmlComponent* alertDialog() const; + void setAlertDialog(QQmlComponent*); + QQmlComponent* confirmDialog() const; + void setConfirmDialog(QQmlComponent*); + QQmlComponent* promptDialog() const; + void setPromptDialog(QQmlComponent*); + QQmlComponent* authenticationDialog() const; + void setAuthenticationDialog(QQmlComponent*); + QQmlComponent* certificateVerificationDialog() const; + void setCertificateVerificationDialog(QQmlComponent*); + QQmlComponent* itemSelector() const; + void setItemSelector(QQmlComponent*); + QQmlComponent* proxyAuthenticationDialog() const; + void setProxyAuthenticationDialog(QQmlComponent*); + QQmlComponent* filePicker() const; + void setFilePicker(QQmlComponent*); + QQmlComponent* databaseQuotaDialog() const; + void setDatabaseQuotaDialog(QQmlComponent*); QString userAgent() const; void setUserAgent(const QString& userAgent); double devicePixelRatio() const; @@ -305,11 +306,11 @@ public: QWebNavigationHistory* navigationHistory() const; QQuickWebPage* page(); - static QQuickUrlSchemeDelegate* schemeDelegates_At(QDeclarativeListProperty<QQuickUrlSchemeDelegate>*, int index); - static void schemeDelegates_Append(QDeclarativeListProperty<QQuickUrlSchemeDelegate>*, QQuickUrlSchemeDelegate*); - static int schemeDelegates_Count(QDeclarativeListProperty<QQuickUrlSchemeDelegate>*); - static void schemeDelegates_Clear(QDeclarativeListProperty<QQuickUrlSchemeDelegate>*); - QDeclarativeListProperty<QQuickUrlSchemeDelegate> schemeDelegates(); + static QQuickUrlSchemeDelegate* schemeDelegates_At(QQmlListProperty<QQuickUrlSchemeDelegate>*, int index); + static void schemeDelegates_Append(QQmlListProperty<QQuickUrlSchemeDelegate>*, QQuickUrlSchemeDelegate*); + static int schemeDelegates_Count(QQmlListProperty<QQuickUrlSchemeDelegate>*); + static void schemeDelegates_Clear(QQmlListProperty<QQuickUrlSchemeDelegate>*); + QQmlListProperty<QQuickUrlSchemeDelegate> schemeDelegates(); void invokeApplicationSchemeHandler(WTF::PassRefPtr<WebKit::QtRefCountedNetworkRequestData>); void sendApplicationSchemeReply(QQuickNetworkReply*); @@ -332,6 +333,7 @@ public Q_SLOTS: void goBackTo(int index); void goForwardTo(int index); void postMessage(const QString&); + void evaluateJavaScript(const QString& script, const QJSValue& value = QJSValue()); Q_SIGNALS: void alertDialogChanged(); diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h index 417618d0a..de62d39bb 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h @@ -41,6 +41,7 @@ class DrawingAreaProxy; class QtDialogRunner; class QtViewportInteractionEngine; class QtWebContext; +class QtWebError; class QtWebPageLoadClient; class QtWebPagePolicyClient; class WebPageProxy; @@ -50,7 +51,7 @@ class QWebNavigationHistory; class QWebViewportInfo; QT_BEGIN_NAMESPACE -class QDeclarativeComponent; +class QQmlComponent; QT_END_NAMESPACE class QQuickWebViewPrivate { @@ -67,19 +68,26 @@ public: virtual void initialize(WKContextRef contextRef = 0, WKPageGroupRef pageGroupRef = 0); + virtual void onComponentComplete() { } + virtual void enableMouseEvents() { } virtual void disableMouseEvents() { } virtual QPointF pageItemPos(); virtual void updateContentsSize(const QSizeF&) { } + virtual void provisionalLoadDidStart(const QUrl& url); + virtual void loadDidCommit(); + virtual void didSameDocumentNavigation(); + virtual void titleDidChange(); + virtual void loadProgressDidChange(int loadProgress); + virtual void backForwardListDidChange(); virtual void loadDidSucceed(); - virtual void onComponentComplete(); - virtual void loadDidCommit() { } - virtual void didFinishFirstNonEmptyLayout() { } + virtual void loadDidFail(const WebKit::QtWebError& error); + virtual void didChangeViewportProperties(const WebCore::ViewportAttributes& attr) { } - void didChangeBackForwardList(); + int loadProgress() const { return m_loadProgress; } void setNeedsDisplay(); virtual WebKit::QtViewportInteractionEngine* viewportInteractionEngine() { return 0; } @@ -175,15 +183,15 @@ protected: FlickableAxisLocker axisLocker; - QDeclarativeComponent* alertDialog; - QDeclarativeComponent* confirmDialog; - QDeclarativeComponent* promptDialog; - QDeclarativeComponent* authenticationDialog; - QDeclarativeComponent* certificateVerificationDialog; - QDeclarativeComponent* itemSelector; - QDeclarativeComponent* proxyAuthenticationDialog; - QDeclarativeComponent* filePicker; - QDeclarativeComponent* databaseQuotaDialog; + QQmlComponent* alertDialog; + QQmlComponent* confirmDialog; + QQmlComponent* promptDialog; + QQmlComponent* authenticationDialog; + QQmlComponent* certificateVerificationDialog; + QQmlComponent* itemSelector; + QQmlComponent* proxyAuthenticationDialog; + QQmlComponent* filePicker; + QQmlComponent* databaseQuotaDialog; WebCore::ViewportAttributes attributes; @@ -192,7 +200,7 @@ protected: bool m_renderToOffscreenBuffer; bool m_dialogActive; QUrl m_iconURL; - QUrl m_deferedUrlToLoad; + int m_loadProgress; }; class QQuickWebViewLegacyPrivate : public QQuickWebViewPrivate { @@ -216,13 +224,11 @@ public: virtual ~QQuickWebViewFlickablePrivate(); virtual void initialize(WKContextRef contextRef = 0, WKPageGroupRef pageGroupRef = 0); + virtual void onComponentComplete(); + virtual QPointF pageItemPos(); virtual void updateContentsSize(const QSizeF&); - virtual void loadDidSucceed(); - virtual void onComponentComplete(); - virtual void loadDidCommit(); - virtual void didFinishFirstNonEmptyLayout(); virtual void didChangeViewportProperties(const WebCore::ViewportAttributes&); virtual WebKit::QtViewportInteractionEngine* viewportInteractionEngine() { return interactionEngine.data(); } virtual void updateViewportSize(); @@ -237,7 +243,6 @@ public: private: QScopedPointer<WebKit::QtViewportInteractionEngine> interactionEngine; bool pageIsSuspended; - bool loadSuccessDispatchIsPending; }; #endif // qquickwebview_p_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp index dce6ee9df..71342a1e3 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp @@ -29,7 +29,7 @@ using namespace WebKit; QWebIconImageProvider::QWebIconImageProvider() - : QDeclarativeImageProvider(QDeclarativeImageProvider::Image) + : QQuickImageProvider(QQuickImageProvider::Image) { } diff --git a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h index 74f55995f..a54008a2c 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h @@ -23,7 +23,7 @@ #include "qwebkitglobal.h" #include <QtQuick/QQuickImageProvider> -class QWEBKIT_EXPORT QWebIconImageProvider : public QDeclarativeImageProvider { +class QWEBKIT_EXPORT QWebIconImageProvider : public QQuickImageProvider { public: QWebIconImageProvider(); ~QWebIconImageProvider(); diff --git a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp index 170604d1d..ea16732f5 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp @@ -62,11 +62,17 @@ QVariant QWebViewportInfo::initialScale() const QVariant QWebViewportInfo::minimumScale() const { + if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine()) + return interactionEngine->m_minimumScale; + return m_webViewPrivate->attributes.minimumScale; } QVariant QWebViewportInfo::maximumScale() const { + if (QtViewportInteractionEngine* interactionEngine = m_webViewPrivate->viewportInteractionEngine()) + return interactionEngine->m_maximumScale; + return m_webViewPrivate->attributes.maximumScale; } diff --git a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h index ab422e4e7..d3060bbe6 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h @@ -27,7 +27,7 @@ #include <QtCore/QPointer> #include <QtCore/QSize> #include <QtCore/QVariant> -#include <QtDeclarative/QtDeclarative> +#include <QtQml/QtQml> class QQuickWebViewPrivate; diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_evaluateJavaScript.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_evaluateJavaScript.qml new file mode 100644 index 000000000..a3083144d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_evaluateJavaScript.qml @@ -0,0 +1,87 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 1.0 +import "../common" + +Item { + TestWebView { + id: webView + property variant lastMessage + property variant lastResult + + signal resultReceived + + experimental.preferences.navigatorQtObjectEnabled: true + experimental.onMessageReceived: { + lastMessage = message + } + } + + SignalSpy { + id: messageSpy + target: webView.experimental + signalName: "messageReceived" + } + + SignalSpy { + id: resultSpy + target: webView + signalName: "resultReceived" + } + + TestCase { + name: "JavaScriptEvaluation" + + function init() { + messageSpy.clear() + webView.lastMessage = null + + resultSpy.clear() + webView.lastResult = null + } + + function test_basic() { + messageSpy.clear() + webView.url = "about:blank" + verify(webView.waitForLoadSucceeded()) + + webView.experimental.evaluateJavaScript( + "navigator.qt.onmessage = function(message) {" + + " var result = message.data.split('');" + + " result = result.reverse().join('');" + + " navigator.qt.postMessage(result);" + + "}"); + + webView.experimental.postMessage("DLROW OLLEH"); + messageSpy.wait() + compare(webView.lastMessage.data, "HELLO WORLD") + } + + function test_propertyObjectWithChild() { + messageSpy.clear() + webView.url = "about:blank" + verify(webView.waitForLoadSucceeded()) + + webView.experimental.evaluateJavaScript( + "(function() {" + + " var parent = new Object;" + + " var child = new Object;" + + " parent['level'] = '1';" + + " child['level'] = 2;" + + " parent['child'] = child;" + + " return parent;" + + "})()", + + function(result) { + webView.lastResult = result + webView.resultReceived() + }); + + resultSpy.wait() + + compare(JSON.stringify(webView.lastResult), + '{"child":{"level":2},"level":"1"}') + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/tests.pri b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri index ded493f88..358a2328c 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/tests.pri +++ b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri @@ -10,7 +10,7 @@ SOURCES += ../util.cpp \ ../bytearraytestdata.cpp INCLUDEPATH += $$PWD -QT += testlib declarative quick quick-private webkit +QT += testlib qml quick quick-private webkit DEFINES += TESTS_SOURCE_DIR=\\\"$$PWD\\\" \ QWP_PATH=\\\"$${ROOT_BUILD_DIR}/bin\\\" |