diff options
Diffstat (limited to 'Source')
37 files changed, 624 insertions, 138 deletions
diff --git a/Source/ThirdParty/leveldb/db/version_set.cc b/Source/ThirdParty/leveldb/db/version_set.cc index 7d0a5de2b..f955b5ed0 100644 --- a/Source/ThirdParty/leveldb/db/version_set.cc +++ b/Source/ThirdParty/leveldb/db/version_set.cc @@ -54,6 +54,7 @@ static int64_t TotalFileSize(const std::vector<FileMetaData*>& files) { return sum; } +#if 0 // unused namespace { std::string IntSetToString(const std::set<uint64_t>& s) { std::string result = "{"; @@ -67,6 +68,7 @@ std::string IntSetToString(const std::set<uint64_t>& s) { return result; } } // namespace +#endif Version::~Version() { assert(refs_ == 0); diff --git a/Source/WebCore/WebCore.exp.in b/Source/WebCore/WebCore.exp.in index 6b1ce256d..d8957fec6 100644 --- a/Source/WebCore/WebCore.exp.in +++ b/Source/WebCore/WebCore.exp.in @@ -175,6 +175,7 @@ __ZN7WebCore11startOfWordERKNS_15VisiblePositionENS_9EWordSideE __ZN7WebCore11writeToFileEiPKci __ZN7WebCore12ChromeClient23paintCustomOverhangAreaEPNS_15GraphicsContextERKNS_7IntRectES5_S5_ __ZN7WebCore12EditingStyleD1Ev +__ZN7WebCore11RenderTheme29setDelegatesMenuListRenderingEb __ZN7WebCore12EventHandler10mouseMovedERKNS_18PlatformMouseEventE __ZN7WebCore12EventHandler14scrollOverflowENS_15ScrollDirectionENS_17ScrollGranularityEPNS_4NodeE __ZN7WebCore12EventHandler15handleAccessKeyERKNS_21PlatformKeyboardEventE diff --git a/Source/WebCore/html/HTMLSelectElement.cpp b/Source/WebCore/html/HTMLSelectElement.cpp index a437b375b..31958c89a 100644 --- a/Source/WebCore/html/HTMLSelectElement.cpp +++ b/Source/WebCore/html/HTMLSelectElement.cpp @@ -182,6 +182,8 @@ void HTMLSelectElement::listBoxSelectItem(int listIndex, bool allowMultiplySelec if (fireOnChangeNow) listBoxOnChange(); } + if (usesMenuList() && renderer()) + toRenderMenuList(renderer())->setTextFromOption(selectedIndex()); } bool HTMLSelectElement::usesMenuList() const @@ -826,6 +828,8 @@ void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, b selectOption(option->index()); else if (!usesMenuList()) selectOption(-1); + else if (m_multiple) + selectOption(selectedIndex()); else selectOption(nextSelectableListIndex(-1)); } @@ -862,12 +866,12 @@ void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags) m_isProcessingUserDrivenChange = flags & UserDriven; if (flags & DispatchChangeEvent) dispatchChangeEventForMenuList(); - if (RenderObject* renderer = this->renderer()) { - if (usesMenuList()) - toRenderMenuList(renderer)->didSetSelectedIndex(listIndex); - else if (renderer->isListBox()) - toRenderListBox(renderer)->selectionChanged(); - } + } + if (RenderObject* renderer = this->renderer()) { + if (usesMenuList()) + toRenderMenuList(renderer)->didSetSelectedIndex(listIndex); + else if (renderer->isListBox()) + toRenderListBox(renderer)->selectionChanged(); } setNeedsValidityCheck(); diff --git a/Source/WebCore/platform/MIMETypeRegistry.cpp b/Source/WebCore/platform/MIMETypeRegistry.cpp index da77f1003..817f7386b 100644 --- a/Source/WebCore/platform/MIMETypeRegistry.cpp +++ b/Source/WebCore/platform/MIMETypeRegistry.cpp @@ -252,22 +252,11 @@ static void initializeSupportedImageMIMETypes() #endif #if PLATFORM(QT) -#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) QList<QByteArray> mimeTypes = QImageReader::supportedMimeTypes(); Q_FOREACH(const QByteArray& mimeType, mimeTypes) { supportedImageMIMETypes->add(mimeType.constData()); supportedImageResourceMIMETypes->add(mimeType.constData()); } -#else - QList<QByteArray> formats = QImageReader::supportedImageFormats(); - for (int i = 0; i < formats.size(); ++i) { - String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData()); - if (!mimeType.isEmpty()) { - supportedImageMIMETypes->add(mimeType); - supportedImageResourceMIMETypes->add(mimeType); - } - } -#endif // QT_VERSION #if ENABLE(SVG) // Do not treat SVG as images directly if WebKit can handle them. supportedImageMIMETypes->remove("image/svg+xml"); @@ -299,19 +288,10 @@ static void initializeSupportedImageMIMETypesForEncoding() supportedImageMIMETypesForEncoding->add("image/gif"); #endif #elif PLATFORM(QT) -#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) QList<QByteArray> mimeTypes = QImageWriter::supportedMimeTypes(); Q_FOREACH(const QByteArray& mimeType, mimeTypes) { supportedImageMIMETypesForEncoding->add(mimeType.constData()); } -#else - QList<QByteArray> formats = QImageWriter::supportedImageFormats(); - for (int i = 0; i < formats.size(); ++i) { - String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData()); - if (!mimeType.isEmpty()) - supportedImageMIMETypesForEncoding->add(mimeType); - } -#endif // QT_VERSION #elif PLATFORM(GTK) supportedImageMIMETypesForEncoding->add("image/png"); supportedImageMIMETypesForEncoding->add("image/jpeg"); diff --git a/Source/WebCore/platform/graphics/NativeImagePtr.h b/Source/WebCore/platform/graphics/NativeImagePtr.h index 37540bc4d..81dcd2319 100644 --- a/Source/WebCore/platform/graphics/NativeImagePtr.h +++ b/Source/WebCore/platform/graphics/NativeImagePtr.h @@ -31,8 +31,6 @@ #if USE(CG) typedef struct CGImage* CGImageRef; #elif PLATFORM(QT) -#include "NativeImageQt.h" -#include <qglobal.h> QT_BEGIN_NAMESPACE class QPixmap; QT_END_NAMESPACE diff --git a/Source/WebCore/platform/graphics/SimpleFontData.h b/Source/WebCore/platform/graphics/SimpleFontData.h index 637b77f85..ee0375bef 100644 --- a/Source/WebCore/platform/graphics/SimpleFontData.h +++ b/Source/WebCore/platform/graphics/SimpleFontData.h @@ -204,7 +204,7 @@ public: #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED > 1080 wkCTFontTransformOptions options = (typesettingFeatures & Kerning ? wkCTFontTransformApplyPositioning : 0) | (typesettingFeatures & Ligatures ? wkCTFontTransformApplyShaping : 0); return wkCTFontTransformGlyphs(m_platformData.ctFont(), glyphs, reinterpret_cast<CGSize*>(advances), glyphCount, options); -#elif PLATFORM(QT) && QT_VERSION >= 0x050100 +#elif PLATFORM(QT) QRawFont::LayoutFlags flags = (typesettingFeatures & Kerning) ? QRawFont::KernedAdvances : QRawFont::SeparateAdvances; return m_platformData.rawFont().advancesForGlyphIndexes(glyphs, advances, glyphCount, flags); #else diff --git a/Source/WebCore/platform/graphics/WidthIterator.h b/Source/WebCore/platform/graphics/WidthIterator.h index 8aa26782c..257142dae 100644 --- a/Source/WebCore/platform/graphics/WidthIterator.h +++ b/Source/WebCore/platform/graphics/WidthIterator.h @@ -65,7 +65,7 @@ public: return !font.typesettingFeatures(); return !(font.typesettingFeatures() & ~(Kerning | Ligatures)); -#elif PLATFORM(QT) && QT_VERSION >= 0x050100 +#elif PLATFORM(QT) return !(font.typesettingFeatures() & ~Kerning) && !font.isSmallCaps() && !font.letterSpacing(); #else return !font.typesettingFeatures(); diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp index a1b442eea..87ba95396 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp @@ -38,11 +38,7 @@ #include <qpa/qplatformpixmap.h> #include <wtf/text/CString.h> -#if QT_VERSION >= 0x050100 #include <QOffscreenSurface> -#else -#include <QWindow> -#endif #if USE(TEXTURE_MAPPER_GL) #include <texmap/TextureMapperGL.h> @@ -124,19 +120,10 @@ GraphicsContext3DPrivate::GraphicsContext3DPrivate(GraphicsContext3D* context, H if (hostWindow && hostWindow->platformPageClient()) shareContext = hostWindow->platformPageClient()->openGLContextIfAvailable(); -#if QT_VERSION >= 0x050100 QOffscreenSurface* surface = new QOffscreenSurface; surface->create(); m_surface = surface; m_surfaceOwner = surface; -#else - QWindow* window = new QWindow; - window->setSurfaceType(QSurface::OpenGLSurface); - window->setGeometry(-10, -10, 1, 1); - window->create(); - m_surface = window; - m_surfaceOwner = window; -#endif m_platformContext = new QOpenGLContext(m_surfaceOwner); if (shareContext) diff --git a/Source/WebCore/platform/network/MIMESniffing.cpp b/Source/WebCore/platform/network/MIMESniffing.cpp index 27aefcbcf..6198fa765 100644 --- a/Source/WebCore/platform/network/MIMESniffing.cpp +++ b/Source/WebCore/platform/network/MIMESniffing.cpp @@ -331,6 +331,7 @@ static inline const char* findSimpleMIMEType(const char* data, size_t dataSize, return 0; } +#if !ASSERT_DISABLED bool isTypeInList(const char* type, const MagicNumbers* types, size_t typesCount) { for (size_t i = 0; i < typesCount; ++i) { @@ -339,6 +340,7 @@ bool isTypeInList(const char* type, const MagicNumbers* types, size_t typesCount } return false; } +#endif // http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-8 static const char* internalTextOrBinaryTypeSniffingProcedure(const char* data, size_t dataSize) diff --git a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp index 8ac6e0099..67b85ceef 100644 --- a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp +++ b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp @@ -312,7 +312,6 @@ String keyIdentifierForQtKeyCode(int keyCode) return ASCIILiteral("MediaRewind"); case Qt::Key_Subtitle: return ASCIILiteral("Subtitle"); -#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) case Qt::Key_Blue: return ASCIILiteral("Blue"); case Qt::Key_ChannelDown: @@ -325,7 +324,6 @@ String keyIdentifierForQtKeyCode(int keyCode) return ASCIILiteral("Red"); case Qt::Key_Yellow: return ASCIILiteral("Yellow"); -#endif // Keys we have returned U+charcode for in the past. // FIXME: Change them to correct standard values if others do. case Qt::Key_Tab: diff --git a/Source/WebCore/platform/qt/RenderThemeQStyle.cpp b/Source/WebCore/platform/qt/RenderThemeQStyle.cpp index f14358c64..999c670c4 100644 --- a/Source/WebCore/platform/qt/RenderThemeQStyle.cpp +++ b/Source/WebCore/platform/qt/RenderThemeQStyle.cpp @@ -155,7 +155,7 @@ QRect RenderThemeQStyle::inflateButtonRect(const QRect& originalRect) const int extendFixedPadding(Length oldPadding, int padding) { if (oldPadding.isFixed()) { - return oldPadding.value() + padding; + return std::max(oldPadding.intValue(), padding); } return padding; } diff --git a/Source/WebCore/rendering/RenderMenuList.h b/Source/WebCore/rendering/RenderMenuList.h index 7287ac300..eb90a5fc8 100644 --- a/Source/WebCore/rendering/RenderMenuList.h +++ b/Source/WebCore/rendering/RenderMenuList.h @@ -54,6 +54,7 @@ public: void setOptionsChanged(bool changed) { m_needsOptionsWidthUpdate = changed; } void didSetSelectedIndex(int listIndex); + void setTextFromOption(int optionIndex); String text() const; @@ -129,7 +130,6 @@ private: void createInnerBlock(); void adjustInnerStyle(); void setText(const String&); - void setTextFromOption(int optionIndex); void updateOptionsWidth(); void didUpdateActiveOption(int optionIndex); diff --git a/Source/WebCore/rendering/RenderTheme.cpp b/Source/WebCore/rendering/RenderTheme.cpp index c0c584ddc..5dd361fed 100644 --- a/Source/WebCore/rendering/RenderTheme.cpp +++ b/Source/WebCore/rendering/RenderTheme.cpp @@ -74,6 +74,8 @@ static Color& customFocusRingColor() return color; } +static bool forceMenuListDelegation = false; + RenderTheme::RenderTheme() #if USE(NEW_THEME) : m_theme(platformTheme()) @@ -1071,6 +1073,16 @@ bool RenderTheme::shouldHaveSpinButton(HTMLInputElement* inputElement) const return inputElement->isSteppable() && !inputElement->isRangeControl(); } +bool RenderTheme::delegatesMenuListRendering() const +{ + return forceMenuListDelegation; +} + +void RenderTheme::setDelegatesMenuListRendering(bool on) +{ + forceMenuListDelegation = on; +} + void RenderTheme::adjustMenuListButtonStyle(StyleResolver*, RenderStyle*, Element*) const { } diff --git a/Source/WebCore/rendering/RenderTheme.h b/Source/WebCore/rendering/RenderTheme.h index d3b92b2b1..1e35f14b8 100644 --- a/Source/WebCore/rendering/RenderTheme.h +++ b/Source/WebCore/rendering/RenderTheme.h @@ -228,9 +228,10 @@ public: virtual bool shouldHaveSpinButton(HTMLInputElement*) const; // Functions for <select> elements. - virtual bool delegatesMenuListRendering() const { return false; } + virtual bool delegatesMenuListRendering() const; virtual bool popsMenuByArrowKeys() const { return false; } virtual bool popsMenuBySpaceOrReturn() const { return false; } + static void setDelegatesMenuListRendering(bool on); virtual String fileListDefaultLabel(bool multipleFilesAllowed) const; virtual String fileListNameForWidth(const FileList*, const Font&, int width, bool multipleFilesAllowed) const; diff --git a/Source/WebCore/testing/Internals.cpp b/Source/WebCore/testing/Internals.cpp index b1064e91d..4cfbfdb74 100644 --- a/Source/WebCore/testing/Internals.cpp +++ b/Source/WebCore/testing/Internals.cpp @@ -81,6 +81,7 @@ #include "RenderEmbeddedObject.h" #include "RenderMenuList.h" #include "RenderObject.h" +#include "RenderTheme.h" #include "RenderTreeAsText.h" #include "RenderView.h" #include "RuntimeEnabledFeatures.h" @@ -263,6 +264,7 @@ void Internals::resetToConsistentState(Page* page) page->setPagination(Pagination()); #if USE(ACCELERATED_COMPOSITING) + RenderTheme::setDelegatesMenuListRendering(false); FrameView* mainFrameView = page->mainFrame()->view(); if (mainFrameView) { mainFrameView->setHeaderHeight(0); @@ -2205,4 +2207,9 @@ bool Internals::isPluginUnavailabilityIndicatorObscured(Element* element, Except return embed->isReplacementObscured(); } +void Internals::setDelegatesMenuListRendering(bool forceOn) +{ + RenderTheme::setDelegatesMenuListRendering(forceOn); +} + } diff --git a/Source/WebCore/testing/Internals.h b/Source/WebCore/testing/Internals.h index 25ba4498e..1e1aefad1 100644 --- a/Source/WebCore/testing/Internals.h +++ b/Source/WebCore/testing/Internals.h @@ -287,6 +287,8 @@ public: void setUsesOverlayScrollbars(bool enabled); + void setDelegatesMenuListRendering(bool); + String getCurrentCursorInfo(Document*, ExceptionCode&); String markerTextForListItem(Element*, ExceptionCode&); diff --git a/Source/WebCore/testing/Internals.idl b/Source/WebCore/testing/Internals.idl index 9622e5020..a550ac7c6 100644 --- a/Source/WebCore/testing/Internals.idl +++ b/Source/WebCore/testing/Internals.idl @@ -258,6 +258,7 @@ [Conditional=ENCRYPTED_MEDIA_V2] void initializeMockCDM(); [Conditional=SPEECH_SYNTHESIS] void enableMockSpeechSynthesizer(); + void setDelegatesMenuListRendering(in boolean forceOn); [RaisesException] DOMString getImageSourceURL(Element element); diff --git a/Source/WebKit/qt/WebCoreSupport/InitWebCoreQt.cpp b/Source/WebKit/qt/WebCoreSupport/InitWebCoreQt.cpp index 113eefbe2..8ba625a82 100644 --- a/Source/WebKit/qt/WebCoreSupport/InitWebCoreQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/InitWebCoreQt.cpp @@ -72,11 +72,7 @@ Q_DECL_EXPORT void initializeWebKitQt() if (initCallback) { WebCore::RenderThemeQStyle::setStyleFactoryFunction(createStyleForPage); WebCore::RenderThemeQt::setCustomTheme(WebCore::RenderThemeQStyle::create, new WebCore::ScrollbarThemeQStyle); -#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) - // Only enable kerning by default in Qt 5.1 where it can use the fast font path. - // In Qt 5.0 this would have forced the complex font path. WebCore::Font::setDefaultTypesettingFeatures(WebCore::Kerning); -#endif } } diff --git a/Source/WebKit/qt/WidgetApi/qwebviewaccessible_p.h b/Source/WebKit/qt/WidgetApi/qwebviewaccessible_p.h index 3ba10b694..7cbf44870 100644 --- a/Source/WebKit/qt/WidgetApi/qwebviewaccessible_p.h +++ b/Source/WebKit/qt/WidgetApi/qwebviewaccessible_p.h @@ -22,11 +22,7 @@ #include <qaccessible.h> #include <qaccessibleobject.h> -#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) && QT_VERSION < QT_VERSION_CHECK(5, 2, 0) -#include <private/qaccessiblewidget_p.h> -#else #include <qaccessiblewidget.h> -#endif class QWebFrame; class QWebPage; diff --git a/Source/WebKit2/Target.pri b/Source/WebKit2/Target.pri index c4f57b0e0..a9179d971 100644 --- a/Source/WebKit2/Target.pri +++ b/Source/WebKit2/Target.pri @@ -860,6 +860,13 @@ have?(QTQUICK) { SOURCES += \ UIProcess/qt/WebColorPickerQt.cpp } + + qtHaveModule(webchannel) { + SOURCES += \ + UIProcess/API/qt/qwebchannelwebkittransport.cpp + HEADERS += \ + UIProcess/API/qt/qwebchannelwebkittransport_p.h + } } mac: { diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp index a46b6972e..86b8cb4d4 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp @@ -84,6 +84,11 @@ #include <wtf/Vector.h> #include <wtf/text/WTFString.h> +#ifdef HAVE_WEBCHANNEL +#include <QtWebChannel/QQmlWebChannel> +#include "qwebchannelwebkittransport_p.h" +#endif + using namespace WebCore; using namespace WebKit; @@ -959,6 +964,14 @@ void QQuickWebViewPrivate::didReceiveMessageFromNavigatorQtObject(WKStringRef me emit q_ptr->experimental()->messageReceived(variantMap); } +#ifdef HAVE_WEBCHANNEL +void QQuickWebViewPrivate::didReceiveMessageFromNavigatorQtWebChannelTransportObject(WKStringRef message) +{ + // TODO: can I convert a WKStringRef to a UTF8 QByteArray directly? + q_ptr->experimental()->m_webChannelTransport->receiveMessage(WKStringCopyQString(message).toUtf8()); +} +#endif + CoordinatedGraphicsScene* QQuickWebViewPrivate::coordinatedGraphicsScene() { if (webPageProxy && webPageProxy->drawingArea() && webPageProxy->drawingArea()->coordinatedLayerTreeHostProxy()) @@ -1074,7 +1087,14 @@ QQuickWebViewExperimental::QQuickWebViewExperimental(QQuickWebView *webView, QQu , d_ptr(webViewPrivate) , schemeParent(new QObject(this)) , m_test(new QWebKitTest(webViewPrivate, this)) +#ifdef HAVE_WEBCHANNEL + , m_webChannel(new QQmlWebChannel(this)) + , m_webChannelTransport(new QWebChannelWebKitTransport(this)) +#endif { +#ifdef HAVE_WEBCHANNEL + m_webChannel->connectTo(m_webChannelTransport); +#endif } QQuickWebViewExperimental::~QQuickWebViewExperimental() @@ -1163,6 +1183,29 @@ bool QQuickWebViewExperimental::flickableViewportEnabled() return s_flickableViewportEnabled; } +#ifdef HAVE_WEBCHANNEL +QQmlWebChannel* QQuickWebViewExperimental::webChannel() const +{ + return m_webChannel; +} + +void QQuickWebViewExperimental::setWebChannel(QQmlWebChannel* channel) +{ + if (channel == m_webChannel) + return; + + if (m_webChannel) + m_webChannel->disconnectFrom(m_webChannelTransport); + + m_webChannel = channel; + + if (m_webChannel) + m_webChannel->connectTo(m_webChannelTransport); + + emit webChannelChanged(channel); +} +#endif + /*! \internal @@ -1182,6 +1225,16 @@ void QQuickWebViewExperimental::postMessage(const QString& message) WKPagePostMessageToInjectedBundle(d->webPage.get(), messageName, contents.get()); } +#ifdef HAVE_WEBCHANNEL +void QQuickWebViewExperimental::postQtWebChannelTransportMessage(const QByteArray& message) +{ + Q_D(QQuickWebView); + static WKStringRef messageName = WKStringCreateWithUTF8CString("MessageToNavigatorQtWebChannelTransportObject"); + WKRetainPtr<WKStringRef> contents = adoptWK(WKStringCreateWithUTF8CString(message.constData())); + WKPagePostMessageToInjectedBundle(d->webPage.get(), messageName, contents.get()); +} +#endif + QQmlComponent* QQuickWebViewExperimental::alertDialog() const { Q_D(const QQuickWebView); diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h index 86d68fc15..8604dead2 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h @@ -30,6 +30,7 @@ QT_BEGIN_NAMESPACE class QQmlComponent; +class QQmlWebChannel; QT_END_NAMESPACE class QWebNavigationRequest; class QQuickWebPage; @@ -43,6 +44,7 @@ class QWebPreferences; class QWebPermissionRequest; class QWebKitTest; class QQuickNetworkReply; +class QWebChannelWebKitTransport; namespace WTR { class PlatformWebView; @@ -280,6 +282,9 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject { Q_PROPERTY(QString userAgent READ userAgent WRITE setUserAgent NOTIFY userAgentChanged) Q_PROPERTY(QList<QUrl> userScripts READ userScripts WRITE setUserScripts NOTIFY userScriptsChanged) Q_PROPERTY(QUrl remoteInspectorUrl READ remoteInspectorUrl NOTIFY remoteInspectorUrlChanged FINAL) +#ifdef HAVE_WEBCHANNEL + Q_PROPERTY(QQmlWebChannel* webChannel READ webChannel WRITE setWebChannel NOTIFY webChannelChanged) +#endif Q_ENUMS(NavigationRequestActionExperimental) Q_FLAGS(FindFlags) @@ -357,6 +362,12 @@ public: static void setFlickableViewportEnabled(bool enable); static bool flickableViewportEnabled(); +#ifdef HAVE_WEBCHANNEL + QQmlWebChannel* webChannel() const; + void setWebChannel(QQmlWebChannel* channel); + void postQtWebChannelTransportMessage(const QByteArray& message); +#endif + public Q_SLOTS: void goBackTo(int index); void goForwardTo(int index); @@ -394,6 +405,10 @@ Q_SIGNALS: void processDidBecomeUnresponsive(); void processDidBecomeResponsive(); +#ifdef HAVE_WEBCHANNEL + void webChannelChanged(QQmlWebChannel* channel); +#endif + private: QQuickWebViewExperimental(QQuickWebView* webView, QQuickWebViewPrivate* webViewPrivate); QQuickWebView* q_ptr; @@ -401,6 +416,11 @@ private: QObject* schemeParent; QWebKitTest* m_test; +#ifdef HAVE_WEBCHANNEL + QQmlWebChannel* m_webChannel; + QWebChannelWebKitTransport* m_webChannelTransport; +#endif + friend class WebKit::QtWebPageUIClient; Q_DECLARE_PRIVATE(QQuickWebView) diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h index b39a4f071..f09c16e90 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h @@ -55,6 +55,7 @@ class WebPageProxy; class QWebNavigationHistory; class QWebKitTest; +class QWebChannelWebKitTransport; QT_BEGIN_NAMESPACE class QQmlComponent; @@ -137,6 +138,9 @@ public: void handleDownloadRequest(WebKit::DownloadProxy*); void didReceiveMessageFromNavigatorQtObject(WKStringRef message); +#ifdef HAVE_WEBCHANNEL + void didReceiveMessageFromNavigatorQtWebChannelTransportObject(WKStringRef message); +#endif WebCore::CoordinatedGraphicsScene* coordinatedGraphicsScene(); float deviceScaleFactor(); diff --git a/Source/WebKit2/UIProcess/API/qt/qwebchannelwebkittransport.cpp b/Source/WebKit2/UIProcess/API/qt/qwebchannelwebkittransport.cpp new file mode 100644 index 000000000..209596954 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebchannelwebkittransport.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebChannel module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwebchannelwebkittransport_p.h" + +#include <QJsonObject> +#include <QJsonDocument> + +#include "qquickwebview_p.h" + +QWebChannelWebKitTransport::QWebChannelWebKitTransport(QQuickWebViewExperimental* experimental) + : QWebChannelAbstractTransport(experimental) + , m_experimental(experimental) +{ +} + +void QWebChannelWebKitTransport::sendMessage(const QJsonObject& message) +{ + const QByteArray data = QJsonDocument(message).toJson(QJsonDocument::Compact); + m_experimental->postQtWebChannelTransportMessage(data); +} + +void QWebChannelWebKitTransport::receiveMessage(const QByteArray& message) +{ + QJsonParseError error; + const QJsonDocument doc = QJsonDocument::fromJson(message, &error); + if (error.error != QJsonParseError::NoError) { + qWarning() << "Failed to parse the client WebKit QWebChannel message as JSON: " << message + << "Error message is:" << error.errorString(); + return; + } else if (!doc.isObject()) { + qWarning() << "Received WebKit QWebChannel message is not a JSON object: " << message; + return; + } + emit messageReceived(doc.object(), this); +} diff --git a/Source/WebKit2/UIProcess/API/qt/qwebchannelwebkittransport_p.h b/Source/WebKit2/UIProcess/API/qt/qwebchannelwebkittransport_p.h new file mode 100644 index 000000000..ef6140359 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebchannelwebkittransport_p.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebChannel module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBCHANNELWEBKITTRANSPORT_H +#define QWEBCHANNELWEBKITTRANSPORT_H + +#include <QtWebChannel/QWebChannelAbstractTransport> + +class QQuickWebViewExperimental; + +class QWebChannelWebKitTransport : public QWebChannelAbstractTransport +{ + Q_OBJECT +public: + explicit QWebChannelWebKitTransport(QQuickWebViewExperimental* experimental); + + void sendMessage(const QJsonObject& message) Q_DECL_OVERRIDE; + + void receiveMessage(const QByteArray& message); + +private: + QQuickWebViewExperimental* m_experimental; +}; + +#endif // QWEBCHANNELWEBKITTRANSPORT_H diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_webchannel.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_webchannel.qml new file mode 100644 index 000000000..e16b7866e --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_webchannel.qml @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebChannel module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 1.0 +import "../common" + +import QtWebChannel 1.0 + +Item { + id: test + signal barCalled(var arg) + signal clientInitializedCalled(var arg) + + QtObject { + id: testObject + WebChannel.id: "testObject" + + property var foo: 42 + + function clientInitialized(arg) + { + clientInitializedCalled(arg); + } + + function bar(arg) { + barCalled(arg); + } + + signal runTest(var foo) + } + + TestWebView { + id: webView + experimental.windowObjects: [testObject] + experimental.preferences.developerExtrasEnabled: true + } + + SignalSpy { + id: initializedSpy + target: test + signalName: "clientInitializedCalled" + } + + SignalSpy { + id: barSpy + target: test + signalName: "barCalled" + } + + TestCase { + name: "WebViewWebChannel" + property url testUrl: Qt.resolvedUrl("../common/webchannel.html") + + function init() { + initializedSpy.clear(); + barSpy.clear(); + } + + function test_basic() { + webView.url = testUrl; + verify(webView.waitForLoadSucceeded()); + + initializedSpy.wait(); + compare(initializedSpy.signalArguments.length, 1); + compare(initializedSpy.signalArguments[0][0], 42); + + var newValue = "roundtrip"; + testObject.runTest(newValue); + barSpy.wait(); + compare(barSpy.signalArguments.length, 1); + compare(barSpy.signalArguments[0][0], newValue); + + compare(testObject.foo, newValue); + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/webchannel.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/webchannel.html new file mode 100644 index 000000000..940821209 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/webchannel.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script> + <script type="text/javascript"> + //BEGIN SETUP + var channel = new QWebChannel(navigator.qtWebChannelTransport, function(channel) { + window.testObject = channel.objects.testObject; + testObject.runTest.connect(function(foo) { + testObject.foo = foo; + testObject.bar(foo); + }); + testObject.clientInitialized(testObject.foo); + }); + //END SETUP + </script> + </head> + <body> + </body> +</html> diff --git a/Source/WebKit2/UIProcess/qt/QtWebContext.cpp b/Source/WebKit2/UIProcess/qt/QtWebContext.cpp index 4489d74c8..6d80596dd 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebContext.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebContext.cpp @@ -89,8 +89,14 @@ static void globalInitialization() static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void*) { - if (!WKStringIsEqualToUTF8CString(messageName, "MessageFromNavigatorQtObject")) + if (!WKStringIsEqualToUTF8CString(messageName, "MessageFromNavigatorQtObject") +#ifdef HAVE_WEBCHANNEL + && !WKStringIsEqualToUTF8CString(messageName, "MessageFromNavigatorQtWebChannelTransportObject") +#endif + ) + { return; + } ASSERT(messageBody); ASSERT(WKGetTypeID(messageBody) == WKArrayGetTypeID()); @@ -103,7 +109,12 @@ static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messag WKPageRef page = static_cast<WKPageRef>(WKArrayGetItemAtIndex(body, 0)); WKStringRef str = static_cast<WKStringRef>(WKArrayGetItemAtIndex(body, 1)); - QQuickWebViewPrivate::get(page)->didReceiveMessageFromNavigatorQtObject(str); + if (WKStringIsEqualToUTF8CString(messageName, "MessageFromNavigatorQtObject")) + QQuickWebViewPrivate::get(page)->didReceiveMessageFromNavigatorQtObject(str); +#ifdef HAVE_WEBCHANNEL + else if (WKStringIsEqualToUTF8CString(messageName, "MessageFromNavigatorQtWebChannelTransportObject")) + QQuickWebViewPrivate::get(page)->didReceiveMessageFromNavigatorQtWebChannelTransportObject(str); +#endif } static void initializeContextInjectedBundleClient(WKContextRef context) diff --git a/Source/WebKit2/WebKit2.pri b/Source/WebKit2/WebKit2.pri index e8d4b80d0..3611524e6 100644 --- a/Source/WebKit2/WebKit2.pri +++ b/Source/WebKit2/WebKit2.pri @@ -80,7 +80,13 @@ linux-*:!android { LIBS += -lrt } -have?(QTQUICK): QT += qml quick +have?(QTQUICK): { + QT += qml quick + qtHaveModule(webchannel) { + QT += webchannel + DEFINES += HAVE_WEBCHANNEL + } +} have?(qtpositioning):enable?(GEOLOCATION): QT += positioning diff --git a/Source/WebKit2/WebKit2.pro b/Source/WebKit2/WebKit2.pro index 66129d359..7013d3038 100644 --- a/Source/WebKit2/WebKit2.pro +++ b/Source/WebKit2/WebKit2.pro @@ -10,5 +10,3 @@ derived_sources.file = DerivedSources.pri target.file = Target.pri SUBDIRS += derived_sources target - -addStrictSubdirOrderBetween(derived_sources, target) diff --git a/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.cpp b/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.cpp index c75a446dd..3bb795cad 100644 --- a/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.cpp +++ b/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.cpp @@ -93,6 +93,10 @@ void QtBuiltinBundle::didReceiveMessageToPage(WKBundlePageRef page, WKStringRef handleMessageToNavigatorQtObject(page, messageBody); else if (WKStringIsEqualToUTF8CString(messageName, "SetNavigatorQtObjectEnabled")) handleSetNavigatorQtObjectEnabled(page, messageBody); +#ifdef HAVE_WEBCHANNEL + else if (WKStringIsEqualToUTF8CString(messageName, "MessageToNavigatorQtWebChannelTransportObject")) + handleMessageToNavigatorQtWebChannelTransport(page, messageBody); +#endif } void QtBuiltinBundle::handleMessageToNavigatorQtObject(WKBundlePageRef page, WKTypeRef messageBody) @@ -119,4 +123,18 @@ void QtBuiltinBundle::handleSetNavigatorQtObjectEnabled(WKBundlePageRef page, WK bundlePage->setNavigatorQtObjectEnabled(enabled); } +#ifdef HAVE_WEBCHANNEL +void QtBuiltinBundle::handleMessageToNavigatorQtWebChannelTransport(WKBundlePageRef page, WKTypeRef messageBody) +{ + ASSERT(messageBody); + ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); + WKStringRef contents = static_cast<WKStringRef>(messageBody); + + QtBuiltinBundlePage* bundlePage = m_pages.get(page); + if (!bundlePage) + return; + bundlePage->didReceiveMessageToNavigatorQtWebChannelTransport(contents); +} +#endif + } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.h b/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.h index 2a6a414f3..55f042b6c 100644 --- a/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.h +++ b/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.h @@ -57,6 +57,9 @@ public: private: void handleMessageToNavigatorQtObject(WKBundlePageRef, WKTypeRef messageBody); void handleSetNavigatorQtObjectEnabled(WKBundlePageRef, WKTypeRef messageBody); +#ifdef HAVE_WEBCHANNEL + void handleMessageToNavigatorQtWebChannelTransport(WKBundlePageRef, WKTypeRef messageBody); +#endif HashMap<WKBundlePageRef, OwnPtr<QtBuiltinBundlePage> > m_pages; WKBundleRef m_bundle; diff --git a/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.cpp b/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.cpp index b32fedf91..4abd77d37 100644 --- a/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.cpp +++ b/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.cpp @@ -39,11 +39,127 @@ namespace WebKit { +typedef JSClassRef (*CreateClassRefCallback)(); + +static void registerNavigatorObject(JSObjectRef *object, JSStringRef name, + JSGlobalContextRef context, void* data, + CreateClassRefCallback createClassRefCallback, + JSStringRef postMessageName, JSObjectCallAsFunctionCallback postMessageCallback) +{ + static JSStringRef navigatorName = JSStringCreateWithUTF8CString("navigator"); + + if (*object) + JSValueUnprotect(context, *object); + *object = JSObjectMake(context, createClassRefCallback(), data); + JSValueProtect(context, *object); + + JSObjectRef postMessage = JSObjectMakeFunctionWithCallback(context, postMessageName, postMessageCallback); + JSObjectSetProperty(context, *object, postMessageName, postMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0); + + JSValueRef navigatorValue = JSObjectGetProperty(context, JSContextGetGlobalObject(context), navigatorName, 0); + if (!JSValueIsObject(context, navigatorValue)) + return; + JSObjectRef navigatorObject = JSValueToObject(context, navigatorValue, 0); + JSObjectSetProperty(context, navigatorObject, name, *object, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0); +} + +static JSClassRef createEmptyJSClassRef() +{ + const JSClassDefinition definition = kJSClassDefinitionEmpty; + return JSClassCreate(&definition); +} + +static JSClassRef navigatorQtObjectClass() +{ + static JSClassRef classRef = createEmptyJSClassRef(); + return classRef; +} + +static JSValueRef qt_postMessageCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef*) +{ + // FIXME: should it work regardless of the thisObject? + + if (argumentCount < 1 || !JSValueIsString(context, arguments[0])) + return JSValueMakeUndefined(context); + + QtBuiltinBundlePage* bundlePage = reinterpret_cast<QtBuiltinBundlePage*>(JSObjectGetPrivate(thisObject)); + ASSERT(bundlePage); + + // FIXME: needed? + if (!bundlePage->navigatorQtObjectEnabled()) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> jsContents = JSValueToStringCopy(context, arguments[0], 0); + WKRetainPtr<WKStringRef> contents(AdoptWK, WKStringCreateWithJSString(jsContents.get())); + bundlePage->postMessageFromNavigatorQtObject(contents.get()); + return JSValueMakeUndefined(context); +} + +static JSObjectRef createWrappedMessage(JSGlobalContextRef context, WKStringRef data) +{ + static JSStringRef dataName = JSStringCreateWithUTF8CString("data"); + + JSRetainPtr<JSStringRef> jsData = WKStringCopyJSString(data); + JSObjectRef wrappedMessage = JSObjectMake(context, 0, 0); + JSObjectSetProperty(context, wrappedMessage, dataName, JSValueMakeString(context, jsData.get()), kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0); + return wrappedMessage; +} + +static void callOnMessage(JSObjectRef object, WKStringRef contents, WKBundlePageRef page) +{ + static JSStringRef onmessageName = JSStringCreateWithUTF8CString("onmessage"); + + if (!object) + return; + + WKBundleFrameRef frame = WKBundlePageGetMainFrame(page); + JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); + + JSValueRef onmessageValue = JSObjectGetProperty(context, object, onmessageName, 0); + if (!JSValueIsObject(context, onmessageValue)) + return; + + JSObjectRef onmessageFunction = JSValueToObject(context, onmessageValue, 0); + if (!JSObjectIsFunction(context, onmessageFunction)) + return; + + JSObjectRef wrappedMessage = createWrappedMessage(context, contents); + JSObjectCallAsFunction(context, onmessageFunction, 0, 1, &wrappedMessage, 0); +} + +#ifdef HAVE_WEBCHANNEL +static JSClassRef navigatorQtWebChannelTransportObjectClass() +{ + static JSClassRef classRef = createEmptyJSClassRef(); + return classRef; +} + +static JSValueRef qt_postWebChannelMessageCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef*) +{ + // FIXME: should it work regardless of the thisObject? + + if (argumentCount < 1 || !JSValueIsString(context, arguments[0])) + return JSValueMakeUndefined(context); + + QtBuiltinBundlePage* bundlePage = reinterpret_cast<QtBuiltinBundlePage*>(JSObjectGetPrivate(thisObject)); + ASSERT(bundlePage); + + // TODO: can we transmit the data as JS object, instead of as a string? + JSRetainPtr<JSStringRef> jsContents = JSValueToStringCopy(context, arguments[0], 0); + WKRetainPtr<WKStringRef> contents(AdoptWK, WKStringCreateWithJSString(jsContents.get())); + bundlePage->postMessageFromNavigatorQtWebChannelTransport(contents.get()); + return JSValueMakeUndefined(context); +} +#endif + QtBuiltinBundlePage::QtBuiltinBundlePage(QtBuiltinBundle* bundle, WKBundlePageRef page) : m_bundle(bundle) , m_page(page) , m_navigatorQtObject(0) , m_navigatorQtObjectEnabled(false) +#ifdef HAVE_WEBCHANNEL + , m_navigatorQtWebChannelTransportObject(0) +#endif { WKBundlePageLoaderClient loaderClient = { kWKBundlePageLoaderClientCurrentVersion, @@ -88,11 +204,25 @@ QtBuiltinBundlePage::QtBuiltinBundlePage(QtBuiltinBundle* bundle, WKBundlePageRe QtBuiltinBundlePage::~QtBuiltinBundlePage() { - if (!m_navigatorQtObject) + if (!m_navigatorQtObject +#ifdef HAVE_WEBCHANNEL + && !m_navigatorQtWebChannelTransportObject +#endif + ) + { return; + } + WKBundleFrameRef frame = WKBundlePageGetMainFrame(m_page); JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); - JSValueUnprotect(context, m_navigatorQtObject); + + if (m_navigatorQtObject) + JSValueUnprotect(context, m_navigatorQtObject); + +#ifdef HAVE_WEBCHANNEL + if (m_navigatorQtWebChannelTransportObject) + JSValueUnprotect(context, m_navigatorQtWebChannelTransportObject); +#endif } void QtBuiltinBundlePage::didClearWindowForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKBundleScriptWorldRef world, const void* clientInfo) @@ -100,72 +230,26 @@ void QtBuiltinBundlePage::didClearWindowForFrame(WKBundlePageRef page, WKBundleF static_cast<QtBuiltinBundlePage*>(const_cast<void*>(clientInfo))->didClearWindowForFrame(frame, world); } -static JSValueRef qt_postMessageCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef*) -{ - // FIXME: should it work regardless of the thisObject? - - if (argumentCount < 1 || !JSValueIsString(context, arguments[0])) - return JSValueMakeUndefined(context); - - QtBuiltinBundlePage* bundlePage = reinterpret_cast<QtBuiltinBundlePage*>(JSObjectGetPrivate(thisObject)); - ASSERT(bundlePage); - - // FIXME: needed? - if (!bundlePage->navigatorQtObjectEnabled()) - return JSValueMakeUndefined(context); - - JSRetainPtr<JSStringRef> jsContents = JSValueToStringCopy(context, arguments[0], 0); - WKRetainPtr<WKStringRef> contents(AdoptWK, WKStringCreateWithJSString(jsContents.get())); - bundlePage->postMessageFromNavigatorQtObject(contents.get()); - return JSValueMakeUndefined(context); -} - void QtBuiltinBundlePage::didClearWindowForFrame(WKBundleFrameRef frame, WKBundleScriptWorldRef world) { if (!WKBundleFrameIsMainFrame(frame) || WKBundleScriptWorldNormalWorld() != world) return; JSGlobalContextRef context = WKBundleFrameGetJavaScriptContextForWorld(frame, world); registerNavigatorQtObject(context); +#ifdef HAVE_WEBCHANNEL + registerNavigatorQtWebChannelTransportObject(context); +#endif } -void QtBuiltinBundlePage::postMessageFromNavigatorQtObject(WKStringRef contents) +void QtBuiltinBundlePage::postMessageFromNavigatorQtObject(WKStringRef message) { static WKStringRef messageName = WKStringCreateWithUTF8CString("MessageFromNavigatorQtObject"); - WKTypeRef body[] = { page(), contents }; - WKRetainPtr<WKArrayRef> messageBody(AdoptWK, WKArrayCreate(body, sizeof(body) / sizeof(WKTypeRef))); - WKBundlePostMessage(m_bundle->toRef(), messageName, messageBody.get()); -} - -static JSObjectRef createWrappedMessage(JSGlobalContextRef context, WKStringRef data) -{ - static JSStringRef dataName = JSStringCreateWithUTF8CString("data"); - - JSRetainPtr<JSStringRef> jsData = WKStringCopyJSString(data); - JSObjectRef wrappedMessage = JSObjectMake(context, 0, 0); - JSObjectSetProperty(context, wrappedMessage, dataName, JSValueMakeString(context, jsData.get()), kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0); - return wrappedMessage; + postNavigatorMessage(messageName, message); } -void QtBuiltinBundlePage::didReceiveMessageToNavigatorQtObject(WKStringRef contents) +void QtBuiltinBundlePage::didReceiveMessageToNavigatorQtObject(WKStringRef message) { - static JSStringRef onmessageName = JSStringCreateWithUTF8CString("onmessage"); - - if (!m_navigatorQtObject) - return; - - WKBundleFrameRef frame = WKBundlePageGetMainFrame(m_page); - JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); - - JSValueRef onmessageValue = JSObjectGetProperty(context, m_navigatorQtObject, onmessageName, 0); - if (!JSValueIsObject(context, onmessageValue)) - return; - - JSObjectRef onmessageFunction = JSValueToObject(context, onmessageValue, 0); - if (!JSObjectIsFunction(context, onmessageFunction)) - return; - - JSObjectRef wrappedMessage = createWrappedMessage(context, contents); - JSObjectCallAsFunction(context, onmessageFunction, 0, 1, &wrappedMessage, 0); + callOnMessage(m_navigatorQtObject, message, m_page); } void QtBuiltinBundlePage::setNavigatorQtObjectEnabled(bool enabled) @@ -178,33 +262,40 @@ void QtBuiltinBundlePage::setNavigatorQtObjectEnabled(bool enabled) void QtBuiltinBundlePage::registerNavigatorQtObject(JSGlobalContextRef context) { + static JSStringRef name = JSStringCreateWithUTF8CString("qt"); static JSStringRef postMessageName = JSStringCreateWithUTF8CString("postMessage"); - static JSStringRef navigatorName = JSStringCreateWithUTF8CString("navigator"); - static JSStringRef qtName = JSStringCreateWithUTF8CString("qt"); + registerNavigatorObject(&m_navigatorQtObject, name, context, this, + &navigatorQtObjectClass, + postMessageName, &qt_postMessageCallback); +} - if (m_navigatorQtObject) - JSValueUnprotect(context, m_navigatorQtObject); - m_navigatorQtObject = JSObjectMake(context, navigatorQtObjectClass(), this); - JSValueProtect(context, m_navigatorQtObject); +#ifdef HAVE_WEBCHANNEL +void QtBuiltinBundlePage::registerNavigatorQtWebChannelTransportObject(JSGlobalContextRef context) +{ + static JSStringRef name = JSStringCreateWithUTF8CString("qtWebChannelTransport"); + static JSStringRef postMessageName = JSStringCreateWithUTF8CString("send"); + registerNavigatorObject(&m_navigatorQtWebChannelTransportObject, name, context, this, + &navigatorQtWebChannelTransportObjectClass, + postMessageName, &qt_postWebChannelMessageCallback); +} - JSObjectRef postMessage = JSObjectMakeFunctionWithCallback(context, postMessageName, qt_postMessageCallback); - JSObjectSetProperty(context, m_navigatorQtObject, postMessageName, postMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0); +void QtBuiltinBundlePage::didReceiveMessageToNavigatorQtWebChannelTransport(WKStringRef contents) +{ + callOnMessage(m_navigatorQtWebChannelTransportObject, contents, m_page); +} - JSValueRef navigatorValue = JSObjectGetProperty(context, JSContextGetGlobalObject(context), navigatorName, 0); - if (!JSValueIsObject(context, navigatorValue)) - return; - JSObjectRef navigatorObject = JSValueToObject(context, navigatorValue, 0); - JSObjectSetProperty(context, navigatorObject, qtName, m_navigatorQtObject, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0); +void QtBuiltinBundlePage::postMessageFromNavigatorQtWebChannelTransport(WKStringRef message) +{ + static WKStringRef messageName = WKStringCreateWithUTF8CString("MessageFromNavigatorQtWebChannelTransportObject"); + postNavigatorMessage(messageName, message); } +#endif -JSClassRef QtBuiltinBundlePage::navigatorQtObjectClass() +void QtBuiltinBundlePage::postNavigatorMessage(WKStringRef messageName, WKStringRef message) { - static JSClassRef classRef = 0; - if (!classRef) { - const JSClassDefinition navigatorQtObjectClass = kJSClassDefinitionEmpty; - classRef = JSClassCreate(&navigatorQtObjectClass); - } - return classRef; + WKTypeRef body[] = { page(), message }; + WKRetainPtr<WKArrayRef> messageBody(AdoptWK, WKArrayCreate(body, sizeof(body) / sizeof(WKTypeRef))); + WKBundlePostMessage(m_bundle->toRef(), messageName, messageBody.get()); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.h b/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.h index 3ffb3f008..3c466f040 100644 --- a/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.h +++ b/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.h @@ -53,15 +53,26 @@ public: bool navigatorQtObjectEnabled() const { return m_navigatorQtObjectEnabled; } void setNavigatorQtObjectEnabled(bool); +#ifdef HAVE_WEBCHANNEL + void postMessageFromNavigatorQtWebChannelTransport(WKStringRef message); + void didReceiveMessageToNavigatorQtWebChannelTransport(WKStringRef message); +#endif + private: void registerNavigatorQtObject(JSGlobalContextRef); +#ifdef HAVE_WEBCHANNEL + void registerNavigatorQtWebChannelTransportObject(JSGlobalContextRef); +#endif - static JSClassRef navigatorQtObjectClass(); + void postNavigatorMessage(WKStringRef messageName, WKStringRef message); QtBuiltinBundle* m_bundle; WKBundlePageRef m_page; JSObjectRef m_navigatorQtObject; bool m_navigatorQtObjectEnabled; +#ifdef HAVE_WEBCHANNEL + JSObjectRef m_navigatorQtWebChannelTransportObject; +#endif }; } // namespace WebKit diff --git a/Source/autotools/symbols.filter b/Source/autotools/symbols.filter index 4a66ac6c9..aea145813 100644 --- a/Source/autotools/symbols.filter +++ b/Source/autotools/symbols.filter @@ -64,6 +64,7 @@ _ZN7WebCore11memoryCacheEv; _ZN7WebCore11EventTarget17toGeneratedStreamEv; _ZN7WebCore11EventTarget8toStreamEv; _ZN7WebCore11MemoryCache14resourceForURLERKNS_4KURLE; +_ZN7WebCore11RenderTheme29setDelegatesMenuListRenderingEb; _ZN7WebCore12TextIterator26rangeFromLocationAndLengthEPNS_13ContainerNodeEiib; _ZN7WebCore12TextIterator29getLocationAndLengthFromRangeEPNS_4NodeEPKNS_5RangeERjS6_; _ZN7WebCore12TextIterator29getLocationAndLengthFromRangeEPNS_4NodeEPKNS_5RangeERmS6_; diff --git a/Source/sync.profile b/Source/sync.profile index 9eb0fe910..c0f687dc0 100644 --- a/Source/sync.profile +++ b/Source/sync.profile @@ -24,4 +24,5 @@ "qtlocation" => "", "qtmultimedia" => "", "qtsensors" => "", + "qtwebchannel" => "", ); diff --git a/Source/widgetsapi.pri b/Source/widgetsapi.pri index e4fa8230f..5c0ad57fc 100644 --- a/Source/widgetsapi.pri +++ b/Source/widgetsapi.pri @@ -45,7 +45,7 @@ QT += webkit use?(3D_GRAPHICS): WEBKIT += ANGLE -WEBKIT += javascriptcore wtf webcore +WEBKIT += javascriptcore wtf webcore webkit1 MODULE = webkitwidgets CONFIG += creating_module |
