diff options
Diffstat (limited to 'Source')
121 files changed, 4765 insertions, 2926 deletions
diff --git a/Source/Platform/ChangeLog b/Source/Platform/ChangeLog index b8710abfc..0a625f046 100644 --- a/Source/Platform/ChangeLog +++ b/Source/Platform/ChangeLog @@ -1,3 +1,15 @@ +2012-06-01 Mark Pilgrim <pilgrim@chromium.org> + + [Chromium] Call clipboard methods directly + https://bugs.webkit.org/show_bug.cgi?id=88038 + + Reviewed by Adam Barth. + + Part of a refactoring series. See tracking bug 82948. + + * chromium/public/WebClipboard.h: + (WebKit::WebClipboard::sequenceNumber): + 2012-05-31 Shawn Singh <shawnsingh@chromium.org> [chromium] Migrate to WebTransformationMatrix diff --git a/Source/Platform/chromium/public/WebClipboard.h b/Source/Platform/chromium/public/WebClipboard.h index eb208237e..f366efc89 100644 --- a/Source/Platform/chromium/public/WebClipboard.h +++ b/Source/Platform/chromium/public/WebClipboard.h @@ -33,7 +33,9 @@ #include "WebCommon.h" #include "WebData.h" +#include "WebImage.h" #include "WebString.h" +#include "WebURL.h" #include "WebVector.h" namespace WebKit { @@ -60,7 +62,7 @@ public: // Returns an identifier which can be used to determine whether the data // contained within the clipboard has changed. - virtual uint64 sequenceNumber(Buffer) { return 0; } + virtual uint64_t sequenceNumber(Buffer) { return 0; } virtual bool isFormatAvailable(Format, Buffer) { return false; } diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog index dc0480385..5ec8f797f 100644 --- a/Source/WTF/ChangeLog +++ b/Source/WTF/ChangeLog @@ -1,3 +1,58 @@ +2012-06-01 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + [Qt] Save one copy when going from 8-bit WTF::String to QString + + Asking for characters() of an 8-bit string will make a 16-bit copy internally + in WTF::String. Since we're going to copy the data to QStringData anyways, which + is 16-bit, we can do the conversion ourselves and save one copy. + + Reviewed by Simon Hausmann. + + * wtf/qt/StringQt.cpp: + (WTF::String::operator QString): + +2012-05-30 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + [Qt] Make conversion from QString to WTF::String (and back again) ~free + + https://bugs.webkit.org/show_bug.cgi?id=87847 + + Instead of copying the QString data when converting to a WTF::String we + make the WTF::String adopt the QString data by introducing a new buffer + ownership type, and pointing the internal WTF::StringImpl 16-bit data + member to the string data managed by QStringData. + + We make sure to reference the QStringData when adopting, so that the + data will stay alive, and then dereference it when the WTF::StringImpl + is deleted, which will free the QStringData (either straight away, if + we're the only one holding a reference still, or later, when the ref + count goes to 0). + + In the case of going back from a WTF::String to a QString we can cheat + a bit (avoid a copy), if we know that the WTF::String was adopted from + a QString, since it's then just a matter of having the QString adopt + the existing QStringData (just like a regular QString copy). + + If the WTF::String buffer is not owned by QStringData, eg a regular + 8-bit or 16-bit string/substring, we have to fall back to copying, + as before (though there are potential optimization tricks we can + apply here later on). + + Reviewed by Gavin Barraclough. + + * wtf/qt/StringQt.cpp: + * wtf/text/StringImpl.cpp: + * wtf/text/StringImpl.h: + +2012-06-01 Sudarsana Nagineni <sudarsana.nagineni@linux.intel.com> + + [EFL] Implement PlatformStrategies + https://bugs.webkit.org/show_bug.cgi?id=86946 + + Reviewed by Carlos Garcia Campos. + + * wtf/Platform.h: Enable PLATFORM_STRATEGIES for EFL platform. + 2012-05-31 Anders Carlsson <andersca@apple.com> Enable support for rvalue references when building with a version of clang that supports them diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h index 06c9c136c..3826a3927 100644 --- a/Source/WTF/wtf/Platform.h +++ b/Source/WTF/wtf/Platform.h @@ -1024,7 +1024,7 @@ #define WTF_PLATFORM_CFNETWORK Error USE_macro_should_be_used_with_CFNETWORK /* FIXME: Eventually we should enable this for all platforms and get rid of the define. */ -#if PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(QT) || PLATFORM(GTK) +#if PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL) #define WTF_USE_PLATFORM_STRATEGIES 1 #endif diff --git a/Source/WTF/wtf/qt/StringQt.cpp b/Source/WTF/wtf/qt/StringQt.cpp index 16dd439e3..43c4f81f0 100644 --- a/Source/WTF/wtf/qt/StringQt.cpp +++ b/Source/WTF/wtf/qt/StringQt.cpp @@ -37,7 +37,11 @@ String::String(const QString& qstr) { if (qstr.isNull()) return; +#if HAVE(QT5) + m_impl = StringImpl::adopt(const_cast<QString&>(qstr).data_ptr()); +#else m_impl = StringImpl::create(reinterpret_cast_ptr<const UChar*>(qstr.constData()), qstr.length()); +#endif } String::String(const QStringRef& ref) @@ -49,6 +53,25 @@ String::String(const QStringRef& ref) String::operator QString() const { + if (!m_impl) + return QString(); + +#if HAVE(QT5) + if (QStringData* qStringData = m_impl->qStringData()) { + // The WTF string was adopted from a QString at some point, so we + // can just adopt the QStringData like a regular QString copy. + qStringData->ref.ref(); + QStringDataPtr qStringDataPointer = { qStringData }; + return QString(qStringDataPointer); + } +#endif + if (is8Bit() && !m_impl->has16BitShadow()) { + // Asking for characters() of an 8-bit string will make a 16-bit copy internally + // in WTF::String. Since we're going to copy the data to QStringData anyways, we + // can do the conversion ourselves and save one copy. + return QString::fromLatin1(reinterpret_cast<const char*>(characters8()), length()); + } + return QString(reinterpret_cast<const QChar*>(characters()), length()); } diff --git a/Source/WTF/wtf/text/StringImpl.cpp b/Source/WTF/wtf/text/StringImpl.cpp index 372db1766..c4359c113 100644 --- a/Source/WTF/wtf/text/StringImpl.cpp +++ b/Source/WTF/wtf/text/StringImpl.cpp @@ -69,6 +69,13 @@ StringImpl::~StringImpl() fastFree(const_cast<LChar*>(m_data8)); return; } +#if PLATFORM(QT) && HAVE(QT5) + if (ownership == BufferAdoptedQString) { + if (!m_qStringData->ref.deref()) + QStringData::deallocate(m_qStringData); + return; + } +#endif ASSERT(ownership == BufferSubstring); ASSERT(m_substringBuffer); @@ -1644,6 +1651,18 @@ PassRefPtr<StringImpl> StringImpl::adopt(StringBuffer<UChar>& buffer) return adoptRef(new StringImpl(buffer.release(), length)); } +#if PLATFORM(QT) && HAVE(QT5) +PassRefPtr<StringImpl> StringImpl::adopt(QStringData* qStringData) +{ + ASSERT(qStringData); + + if (!qStringData->size) + return empty(); + + return adoptRef(new StringImpl(qStringData, ConstructAdoptedQString)); +} +#endif + PassRefPtr<StringImpl> StringImpl::createWithTerminatingNullCharacter(const StringImpl& string) { // Use createUninitialized instead of 'new StringImpl' so that the string and its buffer diff --git a/Source/WTF/wtf/text/StringImpl.h b/Source/WTF/wtf/text/StringImpl.h index b8073b309..ec4493e73 100644 --- a/Source/WTF/wtf/text/StringImpl.h +++ b/Source/WTF/wtf/text/StringImpl.h @@ -31,6 +31,10 @@ #include <wtf/Vector.h> #include <wtf/unicode/Unicode.h> +#if PLATFORM(QT) && HAVE(QT5) +#include <QString> +#endif + #if USE(CF) typedef const struct __CFString * CFStringRef; #endif @@ -82,6 +86,10 @@ private: BufferInternal, BufferOwned, BufferSubstring, +#if PLATFORM(QT) && HAVE(QT5) + BufferAdoptedQString +#endif + // NOTE: Adding more ownership types needs to extend m_hashAndFlags as we're at capacity }; // Used to construct static strings, which have an special refCount that can never hit zero. @@ -215,6 +223,29 @@ private: m_hashAndFlags = hash | BufferInternal; } +#if PLATFORM(QT) && HAVE(QT5) + // Used to create new strings that adopt an existing QString's data + enum ConstructAdoptedQStringTag { ConstructAdoptedQString }; + StringImpl(QStringData* qStringData, ConstructAdoptedQStringTag) + : m_refCount(s_refCountIncrement) + , m_length(qStringData->size) + , m_data16(0) + , m_qStringData(qStringData) + , m_hashAndFlags(BufferAdoptedQString) + { + ASSERT(m_length); + + // We ref the string-data to ensure it will be valid for the lifetime of + // this string. We then deref it in the destructor, so that the string + // data can eventually be freed. + m_qStringData->ref.ref(); + + // Now that we have a ref we can safely reference the string data + m_data16 = reinterpret_cast_ptr<const UChar*>(qStringData->data()); + ASSERT(m_data16); + } +#endif + public: WTF_EXPORT_PRIVATE ~StringImpl(); @@ -308,6 +339,10 @@ public: static PassRefPtr<StringImpl> adopt(StringBuffer<LChar>& buffer); WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> adopt(StringBuffer<UChar>& buffer); +#if PLATFORM(QT) && HAVE(QT5) + static PassRefPtr<StringImpl> adopt(QStringData*); +#endif + unsigned length() const { return m_length; } bool is8Bit() const { return m_hashAndFlags & s_hashFlag8BitBuffer; } @@ -367,6 +402,10 @@ public: m_hashAndFlags &= ~s_hashFlagIsAtomic; } +#if PLATFORM(QT) && HAVE(QT5) + QStringData* qStringData() { return bufferOwnership() == BufferAdoptedQString ? m_qStringData : 0; } +#endif + private: // The high bits of 'hash' are always empty, but we prefer to store our flags // in the low bits because it makes them slightly more efficient to access. @@ -591,6 +630,9 @@ private: void* m_buffer; StringImpl* m_substringBuffer; mutable UChar* m_copyData16; +#if PLATFORM(QT) && HAVE(QT5) + QStringData* m_qStringData; +#endif }; mutable unsigned m_hashAndFlags; }; diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index 7d6ea1cfc..a048729be 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -288,6 +288,7 @@ SET(WebCore_IDL_FILES html/HTMLHtmlElement.idl html/HTMLIFrameElement.idl html/HTMLImageElement.idl + html/HTMLIntentElement.idl html/HTMLInputElement.idl html/HTMLKeygenElement.idl html/HTMLLabelElement.idl @@ -800,6 +801,7 @@ SET(WebCore_SOURCES html/HTMLIFrameElement.cpp html/HTMLImageElement.cpp html/HTMLImageLoader.cpp + html/HTMLIntentElement.cpp html/HTMLInputElement.cpp html/HTMLKeygenElement.cpp html/HTMLLIElement.cpp diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index b9f59d6bd..bfe50e01a 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,610 @@ +2012-06-01 Joe Thomas <joethomas@motorola.com> + + getComputedStyle for background shorthand property does not return background-origin and background-clip. + https://bugs.webkit.org/show_bug.cgi?id=86155 + + Reviewed by Tony Chang. + + Added background-origin and background-clip CSS Property values to the background shorthand CSSValueList. + + * css/CSSComputedStyleDeclaration.cpp: + (WebCore::CSSComputedStyleDeclaration::getBackgroundShorthandValue): + +2012-06-01 Mark Pilgrim <pilgrim@chromium.org> + + [Chromium] Call clipboard methods directly + https://bugs.webkit.org/show_bug.cgi?id=88038 + + Reviewed by Adam Barth. + + Part of a refactoring series. See tracking bug 82948. + + * WebCore.gypi: + * platform/Pasteboard.h: + (Pasteboard): + * platform/chromium/ChromiumDataObject.cpp: + (WebCore::ChromiumDataObject::createFromPasteboard): + * platform/chromium/ChromiumDataObjectItem.cpp: + (WebCore::ChromiumDataObjectItem::getAsFile): + (WebCore::ChromiumDataObjectItem::internalGetAsString): + * platform/chromium/ClipboardUtilitiesChromium.cpp: + (WebCore::currentPasteboardBuffer): + * platform/chromium/ClipboardUtilitiesChromium.h: + (WebCore): + * platform/chromium/PasteboardChromium.cpp: + (WebCore::Pasteboard::writeSelection): + (WebCore::Pasteboard::writePlainText): + (WebCore::Pasteboard::writeURL): + (WebCore::Pasteboard::writeImage): + (WebCore::Pasteboard::writeClipboard): + (WebCore::Pasteboard::canSmartReplace): + (WebCore::Pasteboard::plainText): + (WebCore::Pasteboard::documentFragment): + * platform/chromium/PasteboardPrivate.h: Removed. + * platform/chromium/PlatformSupport.h: + (WebCore): + (PlatformSupport): + +2012-06-01 Hugo Parente Lima <hugo.lima@openbossa.org> + + Improve handling of legacy viewport meta tags + https://bugs.webkit.org/show_bug.cgi?id=55874 + + Reviewed by Adam Barth. + + We now support MobileOptimized and HandheldFriendly as well. + + We set width equal to device-width for HandheldFriendly and + for MobileOptimized, the content value of MobileOptimized is + ignored and the initial-scale set to 1 to fit Android behavior. + + The prioritizing is done the same way as on Windows Phone 7: + + XHTML Mobile Profile found + HandheldFriendly + MobileOptimized (overrides HandheldFriendly) + Viewport (overrides all above) + + Original patch by Kenneth Rohde Christiansen. + + Tests: fast/viewport/viewport-legacy-handheldfriendly.html + fast/viewport/viewport-legacy-mobileoptimized-2.html + fast/viewport/viewport-legacy-mobileoptimized-3.html + fast/viewport/viewport-legacy-mobileoptimized.html + fast/viewport/viewport-legacy-ordering-1.html + fast/viewport/viewport-legacy-ordering-2.html + fast/viewport/viewport-legacy-ordering-3.html + fast/viewport/viewport-legacy-ordering-4.html + fast/viewport/viewport-legacy-ordering-5.html + fast/viewport/viewport-legacy-ordering-6.html + fast/viewport/viewport-legacy-ordering-7.html + fast/viewport/viewport-legacy-ordering-8.html + fast/viewport/viewport-legacy-ordering-9.html + + * dom/Document.cpp: + (WebCore::Document::setDocType): + (WebCore::Document::processViewport): Add an origin parameter to + tell what is changing the viewport. + * dom/Document.h: + (Document): + * dom/ViewportArguments.h: + * html/HTMLMetaElement.cpp: + (WebCore::HTMLMetaElement::process): + +2012-06-01 Tony Chang <tony@chromium.org> + + rename -webkit-flex-order to -webkit-order + https://bugs.webkit.org/show_bug.cgi?id=88104 + + Reviewed by Ojan Vafai. + + This recently changed in the spec: + http://dev.w3.org/csswg/css3-flexbox/#order-property + + No new tests, just updated existing results. + + * css/CSSComputedStyleDeclaration.cpp: + (WebCore): + (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): + * css/CSSParser.cpp: + (WebCore::CSSParser::parseValue): + * css/CSSProperty.cpp: + (WebCore::CSSProperty::isInheritedProperty): + * css/CSSPropertyNames.in: + * css/StyleBuilder.cpp: + (WebCore::StyleBuilder::StyleBuilder): + * css/StyleResolver.cpp: + (WebCore::StyleResolver::collectMatchingRulesForList): + * rendering/RenderFlexibleBox.cpp: + (WebCore::RenderFlexibleBox::OrderIterator::OrderIterator): + (WebCore::RenderFlexibleBox::OrderIterator::next): + (WebCore::RenderFlexibleBox::layoutBlock): + (WebCore::RenderFlexibleBox::repositionLogicalHeightDependentFlexItems): + (WebCore::RenderFlexibleBox::layoutFlexItems): + (WebCore::RenderFlexibleBox::computeMainAxisPreferredSizes): + (WebCore::RenderFlexibleBox::computeNextFlexLine): + (WebCore::RenderFlexibleBox::packFlexLines): + (WebCore::RenderFlexibleBox::alignChildren): + (WebCore::RenderFlexibleBox::flipForRightToLeftColumn): + (WebCore::RenderFlexibleBox::flipForWrapReverse): + * rendering/RenderFlexibleBox.h: + * rendering/style/RenderStyle.h: + * rendering/style/StyleFlexibleBoxData.cpp: + (WebCore::StyleFlexibleBoxData::StyleFlexibleBoxData): + (WebCore::StyleFlexibleBoxData::operator==): + * rendering/style/StyleFlexibleBoxData.h: + (StyleFlexibleBoxData): + * rendering/style/StyleRareNonInheritedData.cpp: + (WebCore::StyleRareNonInheritedData::StyleRareNonInheritedData): + (WebCore::StyleRareNonInheritedData::operator==): + * rendering/style/StyleRareNonInheritedData.h: + (StyleRareNonInheritedData): + +2012-06-01 Zeno Albisser <zeno@webkit.org> + + Unreviewed build fix after r119247. + + Do not include TextureMapperGL.h when not building + with GRAPHICS_SURFACE. + + * platform/graphics/texmap/TextureMapperBackingStore.cpp: + +2012-06-01 Mario Sanchez Prada <msanchez@igalia.com> + + [GTK] Add a new and reusable Geoclue-based geolocation provider in WebCore + https://bugs.webkit.org/show_bug.cgi?id=87800 + + Reviewed by Carlos Garcia Campos. + + Added new and reusable Geoclue-based geolocation provider to WebCore. + + * GNUmakefile.am: + * GNUmakefile.list.am: + * platform/geoclue/GeolocationProviderGeoclue.cpp: Added. + (getPositionCallback): + (positionChangedCallback): + (GeolocationProviderGeoclue::GeolocationProviderGeoclue): + (GeolocationProviderGeoclue::~GeolocationProviderGeoclue): + (GeolocationProviderGeoclue::startUpdating): + (GeolocationProviderGeoclue::stopUpdating): + (GeolocationProviderGeoclue::setEnableHighAccuracy): + (GeolocationProviderGeoclue::setGeoclueClient): + (GeolocationProviderGeoclue::setGeocluePosition): + (GeolocationProviderGeoclue::updateClientRequirements): + (GeolocationProviderGeoclue::positionChanged): + (GeolocationProviderGeoclue::errorOccured): + * platform/geoclue/GeolocationProviderGeoclue.h: Added. + (WebCore): + (GeolocationProviderGeoclue): + * platform/geoclue/GeolocationProviderGeoclueClient.h: Added. + (WebCore): + (GeolocationProviderGeoclueClient): + +2012-06-01 Thiago Marcos P. Santos <thiago.santos@intel.com> + + [Qt] Remove deprecated Q_GLOBAL_STATIC_WITH_INITIALIZER + https://bugs.webkit.org/show_bug.cgi?id=88100 + + Reviewed by Tor Arne Vestbø. + + It will be deprecated on Qt5. + + * platform/text/qt/TextBreakIteratorInternalICUQt.cpp: + (WebCore): + +2012-06-01 Zeno Albisser <zeno@webkit.org> + + Make TextureMapper work with GraphicsSurface. + https://bugs.webkit.org/show_bug.cgi?id=87738 + + Add TextureMapperSurfaceBackingStore, a new backing store + that allows to import textures from a GraphicsSurface. + On Mac the GraphicsSurface is backed by an IOSurface + which must be used with a GL_TEXTURE_RECTANGLE_ARB texture. + Therefore it is also necessary to add new shader programs + for directly painting these textures on screen. + + Reviewed by Noam Rosenthal. + + * platform/graphics/texmap/TextureMapperBackingStore.cpp: + Add a new TextureMapperBackingStore implementation that can directly + reuse textures as they are being passed from the GraphicsSurface. + (WebCore::TextureMapperSurfaceBackingStore::setGraphicsSurface): + (WebCore::TextureMapperSurfaceBackingStore::texture): + (WebCore::TextureMapperSurfaceBackingStore::paintToTextureMapper): + * platform/graphics/texmap/TextureMapperBackingStore.h: + (GraphicsSurfaceData): + (WebCore::GraphicsSurfaceData::setSurface): + (WebCore::GraphicsSurfaceData::GraphicsSurfaceData): + (TextureMapperSurfaceBackingStore): + (WebCore::TextureMapperSurfaceBackingStore::create): + (WebCore::TextureMapperSurfaceBackingStore::~TextureMapperSurfaceBackingStore): + (WebCore::TextureMapperSurfaceBackingStore::TextureMapperSurfaceBackingStore): + + * platform/graphics/texmap/TextureMapperGL.cpp: + Add a drawing function for textures of type GL_TEXTURE_RECTANGLE_ARB. + (WebCore::TextureMapperGL::drawTextureRectangleARB): + * platform/graphics/texmap/TextureMapperShaderManager.cpp: + (WebCore::TextureMapperShaderManager::getShaderProgram): + (WebCore::TextureMapperShaderProgramSimple::create): + (WebCore::TextureMapperShaderProgramSimple::initialize): + (WebCore::TextureMapperShaderProgramSolidColor::create): + (WebCore::TextureMapperShaderProgramSolidColor::initialize): + (WebCore::TextureMapperShaderProgramRectSimple::create): + (WebCore::TextureMapperShaderProgramRectSimple::fragmentShaderSource): + (WebCore::TextureMapperShaderProgramOpacityAndMask::create): + (WebCore::TextureMapperShaderProgramOpacityAndMask::initialize): + (WebCore::TextureMapperShaderProgramRectOpacityAndMask::create): + (WebCore::TextureMapperShaderProgramRectOpacityAndMask::fragmentShaderSource): + + * platform/graphics/texmap/TextureMapperShaderManager.h: + Add new shader programs that can be used with GL_TEXTURE_RECTANGLE_ARB textures. + This is mainly necessary, because this type of texture uses non-normalized coordinates. + Further move the calls to initializeProgram() from the constructor into a separate + initialize() function, as initializeProgram() calls vertexShaderSource() (and friends) + and we should not call virtual functions in the constructor. + (WebCore::TextureMapperShaderProgram::initialize): + (TextureMapperShaderProgramSimple): + (WebCore::TextureMapperShaderProgramSimple::TextureMapperShaderProgramSimple): + (TextureMapperShaderProgramRectSimple): + (WebCore::TextureMapperShaderProgramRectSimple::TextureMapperShaderProgramRectSimple): + (TextureMapperShaderProgramOpacityAndMask): + (WebCore::TextureMapperShaderProgramOpacityAndMask::TextureMapperShaderProgramOpacityAndMask): + (TextureMapperShaderProgramRectOpacityAndMask): + (WebCore::TextureMapperShaderProgramRectOpacityAndMask::TextureMapperShaderProgramRectOpacityAndMask): + (TextureMapperShaderProgramSolidColor): + (WebCore::TextureMapperShaderProgramSolidColor::TextureMapperShaderProgramSolidColor): + +2012-06-01 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] EFL port does not enable WEB_INTENTS_TAG flag + https://bugs.webkit.org/show_bug.cgi?id=86866 + + Reviewed by Adam Barth. + + Fix compilation error when WEB_INTENTS_TAG flag is enabled. + HTMLElement::insertedInto() takes a ContainerNode* in argument, not a + Node*. + + Test: webintents/intent-tag.html + + * CMakeLists.txt: + * html/HTMLIntentElement.cpp: + (WebCore::HTMLIntentElement::insertedInto): + * html/HTMLIntentElement.h: + (HTMLIntentElement): + +2012-06-01 Dominik Röttsches <dominik.rottsches@intel.com> + + [cairo] Pixel artifacts can be seen on reflections + https://bugs.webkit.org/show_bug.cgi?id=85483 + + Antialiased clipping in the simple rectangular clip method + leads to edge artifacts when transformations are applied to the layer. + Explicitly disabling antialiased clipping for this function solves this issue. + Comparing Cairo GraphicsContext to Qt and Skia GC, it seems that these + backends do not expect the platform context to clip antialiased in this + case either. + + Reviewed by Martin Robinson. + + No new tests, covered by fast/css/transformed-mask.html. + + * platform/graphics/cairo/GraphicsContextCairo.cpp: + (WebCore::GraphicsContext::clip): + +2012-06-01 Florin Malita <fmalita@chromium.org> + + http://shinydemos.com/clock/ doesn't seem to work + https://bugs.webkit.org/show_bug.cgi?id=79682 + + Reviewed by Nikolas Zimmermann. + + Test: svg/repaint/text-mask-update.svg + + Currently, parent resources are not invalidated when SVGInlineText nodes + are added or removed. Adjusting SVGResourcesCache::clientWasAddedToTree() + and SVGResourcesCache::clientWillBeRemovedFromTree() to cover this case. + + * rendering/svg/SVGResourcesCache.cpp: + (WebCore::SVGResourcesCache::clientWasAddedToTree): + (WebCore::SVGResourcesCache::clientWillBeRemovedFromTree): + +2012-06-01 John Mellor <johnme@chromium.org> + + Don't set scroll position twice in HistoryController::restoreScrollPositionAndViewState + https://bugs.webkit.org/show_bug.cgi?id=88068 + + Reviewed by Adam Barth. + + In the case where pageScaleFactor changes, we were calling + setScrollPosition with an incorrect scroll position (i.e. a scroll + position scaled by the pageScaleFactor we hadn't yet applied), then + fixing it by setting the pageScaleFactor and scroll position together, + overwriting the old scroll position. It's cleaner to just set the + pageScaleFactor and scroll position together. + + No new tests as this isn't expected to change the ultimate behavior, just clean up how it happens. + + * loader/HistoryController.cpp: + (WebCore::HistoryController::restoreScrollPositionAndViewState): + +2012-06-01 Thiago Marcos P. Santos <thiago.santos@intel.com> + + [Qt] Remove deprecated to/fromAscii() + https://bugs.webkit.org/show_bug.cgi?id=88086 + + Reviewed by Simon Hausmann. + + Replacing to/fromAscii with to/fromLatin1 since it + is deprecated on Qt5. + + * bridge/qt/qt_class.cpp: + (JSC::Bindings::QtClass::fallbackObject): + * platform/network/qt/ResourceRequestQt.cpp: + (WebCore::ResourceRequest::toNetworkRequest): + +2012-06-01 Dan Bernstein <mitz@apple.com> + + Layout not updated after setting -webkit-line-clamp to none + https://bugs.webkit.org/show_bug.cgi?id=88049 + + Reviewed by Abhishek Arya. + + Test: fast/flexbox/line-clamp-removed-dynamically.html + + * rendering/RenderDeprecatedFlexibleBox.cpp: + (WebCore::RenderDeprecatedFlexibleBox::styleWillChange): Added. Calls clearLineClamp if + line-clamp will change to none. + (WebCore::RenderDeprecatedFlexibleBox::clearLineClamp): Added. Marks possibly-clamped + children for layout and clears truncation from blocks. + * rendering/RenderDeprecatedFlexibleBox.h: + +2012-06-01 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r119213. + http://trac.webkit.org/changeset/119213 + https://bugs.webkit.org/show_bug.cgi?id=88084 + + This patch broke two tests on all platform except Chromium. + The authors are unavailable. (Requested by zherczeg on + #webkit). + + * css/StyleResolver.cpp: + (WebCore::StyleResolver::collectMatchingRulesForList): + +2012-06-01 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r119219. + http://trac.webkit.org/changeset/119219 + https://bugs.webkit.org/show_bug.cgi?id=88088 + + This patch broke two tests on GTK/Qt. The authors are + unavailable. (Requested by kkristof on #webkit). + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::closeAndRemoveChild): + (WebCore::FrameLoader::detachFromParent): + * page/Frame.cpp: + (WebCore::Frame::willDetachPage): + * page/Frame.h: + (Frame): + (WebCore::Frame::detachFromPage): + (WebCore): + * page/Page.cpp: + (WebCore::Page::~Page): + +2012-06-01 Alexei Filippov <alexeif@chromium.org> + + Web Inspector: Add Closure compiler annotations to WorkerConsole + https://bugs.webkit.org/show_bug.cgi?id=88073 + + Reviewed by Yury Semikhatsky. + + * inspector/front-end/HeapSnapshotWorker.js: + (WebInspector.WorkerConsole.prototype.log): + (WebInspector.WorkerConsole.prototype.error): + (WebInspector.WorkerConsole.prototype.info): + +2012-06-01 MORITA Hajime <morrita@google.com> + + Frame::willDetachPage() shouldn't be called more than once. + https://bugs.webkit.org/show_bug.cgi?id=88056 + + Reviewed by Ryosuke Niwa. + + This change moved willDetachPage() to private and calls it from + detachFromParent(). Also, it checks m_page and call + willDetachPage() only once, if m_page is available. + + No new tests. Covered by existing suites. + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::closeAndRemoveChild): + (WebCore::FrameLoader::detachFromParent): + * page/Frame.cpp: + (WebCore::Frame::detachFromPage): + (WebCore): + (WebCore::Frame::willDetachPage): + * page/Frame.h: + (Frame): + * page/Page.cpp: + (WebCore::Page::~Page): + +2012-06-01 Pierre Rossi <pierre.rossi@gmail.com> + + [Qt] Support drawing a pattern with a translation. + https://bugs.webkit.org/show_bug.cgi?id=87025 + + Drawing an SVG pattern that has its x or y attribute set + works by setting a transform on the Pattern. + We would ignore this by only taking into account the texture and + target rect. + + Reviewed by Kenneth Rohde Christiansen. + + test: svg/W3C-SVG-1.1-SE/pservers-pattern-04-f.svg + + * platform/graphics/qt/GraphicsContextQt.cpp: + (WebCore::drawRepeatPattern): refactored to take into account the translation set on the brush. + (WebCore::GraphicsContext::fillRect): + +2012-06-01 Yoshifumi Inoue <yosin@chromium.org> + + REGRESSION(r109729) [Form] Rendering of select/optgroup/option combination is too slow. + https://bugs.webkit.org/show_bug.cgi?id=88059 + + Reviewed by Kent Tamura. + + This patch changes to share RenderStyle object among the "option" + elements to improve rendering performance and reducing memory usage + of RenderStyle. + + No new tests. This patch doesn't change behavior but rendering performance. + + * css/StyleResolver.cpp: + (WebCore::StyleResolver::canShareStyleWithElement): Check attribute value + mismatching for "option" element. + +2012-06-01 Alexander Pavlov <apavlov@chromium.org> + + Web Inspector: [REGRESSION] Bad layout of "Override device metrics" controls in the Settings dialog + https://bugs.webkit.org/show_bug.cgi?id=88074 + + Reviewed by Yury Semikhatsky. + + The "Override device metrics" controls are placed in a table, which gets too narrow. Give it a + "white-space: nowrap" to avoid wrapping individual cells. + + * inspector/front-end/SettingsScreen.js: + (WebInspector.SettingsScreen.prototype._createDeviceMetricsElement): + * inspector/front-end/elementsPanel.css: + * inspector/front-end/inspector.css: + (.nowrap): + +2012-06-01 Sudarsana Nagineni <sudarsana.nagineni@linux.intel.com> + + [EFL] Implement PlatformStrategies + https://bugs.webkit.org/show_bug.cgi?id=86946 + + Reviewed by Carlos Garcia Campos. + + * PlatformEfl.cmake: Add PlatformStrategies.cpp file to the build system. + Also, remove PluginDataEfl.cpp because the same functionality is now + implemented in PlatformStrategiesEfl.cpp. + +2012-06-01 Adam Barth <abarth@webkit.org> + + ASSERT(m_fontSelector->document()) is bogus and should be removed + https://bugs.webkit.org/show_bug.cgi?id=88053 + + Reviewed by Abhishek Arya. + + This ASSERT was introduced in http://trac.webkit.org/changeset/97402 + together with a branch that handled the case of the ASSERT firing. + This ASSERT fires when running tests on Android (which runs with + ASSERTs enabled). The ASSERT appears to be bogus, so this patch removes + it. + + * css/CSSSegmentedFontFace.cpp: + (WebCore::CSSSegmentedFontFace::getFontData): + +2012-06-01 Yoshifumi Inoue <yosin@chromium.org> + + [Platform][Decimal] UInt128::operator/= calls makeUInt128 with wrong argument order + https://bugs.webkit.org/show_bug.cgi?id=88044 + + Reviewed by Kent Tamura. + + This patch fixed wrong argument of makeUInt128 in UInt128::operator/= to get right + result for decimal multiplication. + + Test: WebKit/chromium/tests/DecimalTest.cpp: Add new a new test case. + + * platform/Decimal.cpp: + (WebCore::DecimalPrivate::UInt128::operator/=): + +2012-06-01 Adam Barth <abarth@webkit.org> + + sandbox directive in X-WebKit-CSP header unable to create a unique origin + https://bugs.webkit.org/show_bug.cgi?id=88014 + + Reviewed by Ryosuke Niwa. + + We process the HTTP headers for a response after we create a document + object for the response. Previously, the SecurityOrigin of a document + was determined when the document was created, which meant that the + sandbox directive in CSP couldn't create a unique origin. + + In this patch, we transition to a unique origin when we start enforcing + the SandboxOrigin bit. This patch is more complicated than you might + expect because we redundantly store the SecurityOrigin object in + DOMWindow. Removing that redundant state is + https://bugs.webkit.org/show_bug.cgi?id=75793. + + The CSP sandbox directive is defined in + http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-1.0-specification.html + by reference to + http://www.whatwg.org/specs/web-apps/current-work/#forced-sandboxing-flag-set. + The relation between sandbox and unique origin arises from + http://www.whatwg.org/specs/web-apps/current-work/#origin-0. + + Test: http/tests/security/contentSecurityPolicy/sandbox-allow-scripts-in-http-header-control.html + http/tests/security/contentSecurityPolicy/sandbox-allow-scripts-in-http-header.html + http/tests/security/contentSecurityPolicy/sandbox-in-http-header-control.html + http/tests/security/contentSecurityPolicy/sandbox-in-http-header.html + + * dom/Document.cpp: + (WebCore::Document::didUpdateSecurityOrigin): + (WebCore::Document::initContentSecurityPolicy): + * dom/Document.h: + (Document): + * dom/SecurityContext.cpp: + (WebCore::SecurityContext::enforceSandboxFlags): + (WebCore): + (WebCore::SecurityContext::didUpdateSecurityOrigin): + * dom/SecurityContext.h: + (SecurityContext): + +2012-05-31 Yury Semikhatsky <yurys@chromium.org> + + Web Inspector: expose MemoryCache statistics in the inspector protocol + https://bugs.webkit.org/show_bug.cgi?id=87984 + + Reviewed by Pavel Feldman. + + Added MemoryCache statistics to Memory.getProcessMemoryDistribution command + result. Corresponding sector is added to the memory pie-chart. + + * inspector/InspectorMemoryAgent.cpp: + (MemoryBlockName): + (WebCore): + (WebCore::addMemoryBlockFor): + (WebCore::memoryCacheInfo): + (WebCore::InspectorMemoryAgent::getProcessMemoryDistribution): + * inspector/front-end/NativeMemorySnapshotView.js: + (WebInspector.MemoryBlockViewProperties._initialize): + +2012-05-31 Yury Semikhatsky <yurys@chromium.org> + + Web Inspector: add RenderArena sizes to the memory pie-chart + https://bugs.webkit.org/show_bug.cgi?id=87971 + + Reviewed by Pavel Feldman. + + Added allocated and used sizes of page render arenas to the memory + report returned by the InspectorMemoryAgent. Total allocated size of + the inspected page's render arenas will be displayed on the memory + pie-chart. + + * inspector/InspectorMemoryAgent.cpp: + (MemoryBlockName): + (WebCore): + (WebCore::renderTreeInfo): + (WebCore::InspectorMemoryAgent::getProcessMemoryDistribution): + * inspector/front-end/NativeMemorySnapshotView.js: + (WebInspector.MemoryBlockViewProperties._initialize): + 2012-05-30 Yury Semikhatsky <yurys@chromium.org> Web Inspector: change type of injected script id from long to int diff --git a/Source/WebCore/GNUmakefile.am b/Source/WebCore/GNUmakefile.am index a97d24fb8..8368c6d44 100644 --- a/Source/WebCore/GNUmakefile.am +++ b/Source/WebCore/GNUmakefile.am @@ -107,6 +107,7 @@ webcoregtk_cppflags += \ -I$(srcdir)/Source/WebCore/page/gtk \ -I$(srcdir)/Source/WebCore/platform/cairo \ -I$(srcdir)/Source/WebCore/platform/audio/gstreamer \ + -I$(srcdir)/Source/WebCore/platform/geoclue \ -I$(srcdir)/Source/WebCore/platform/graphics/cairo \ -I$(srcdir)/Source/WebCore/platform/graphics/glx \ -I$(srcdir)/Source/WebCore/platform/graphics/gstreamer \ diff --git a/Source/WebCore/GNUmakefile.list.am b/Source/WebCore/GNUmakefile.list.am index 9a98ba087..7257bdd3c 100644 --- a/Source/WebCore/GNUmakefile.list.am +++ b/Source/WebCore/GNUmakefile.list.am @@ -4707,6 +4707,9 @@ webcoregtk_sources += \ Source/WebCore/page/gtk/DragControllerGtk.cpp \ Source/WebCore/page/gtk/EventHandlerGtk.cpp \ Source/WebCore/platform/cairo/WidgetBackingStore.h \ + Source/WebCore/platform/geoclue/GeolocationProviderGeoclue.h \ + Source/WebCore/platform/geoclue/GeolocationProviderGeoclue.cpp \ + Source/WebCore/platform/geoclue/GeolocationProviderGeoclueClient.h \ Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp \ Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h \ Source/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp \ diff --git a/Source/WebCore/PlatformEfl.cmake b/Source/WebCore/PlatformEfl.cmake index e90d78190..d3cd0df19 100644 --- a/Source/WebCore/PlatformEfl.cmake +++ b/Source/WebCore/PlatformEfl.cmake @@ -83,6 +83,7 @@ LIST(APPEND WebCore_SOURCES platform/network/soup/ResourceResponseSoup.cpp platform/network/soup/SocketStreamHandleSoup.cpp platform/network/soup/SoupURIUtils.cpp + platform/PlatformStrategies.cpp platform/posix/FileSystemPOSIX.cpp platform/text/efl/TextBreakIteratorInternalICUEfl.cpp ) @@ -95,13 +96,11 @@ IF (ENABLE_NETSCAPE_PLUGIN_API) plugins/PluginStream.cpp plugins/PluginView.cpp - plugins/efl/PluginDataEfl.cpp plugins/efl/PluginPackageEfl.cpp plugins/efl/PluginViewEfl.cpp ) ELSE () LIST(APPEND WebCore_SOURCES - plugins/PluginDataNone.cpp plugins/PluginPackageNone.cpp plugins/PluginViewNone.cpp ) diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi index 18a514f25..87b7b7e9c 100644 --- a/Source/WebCore/WebCore.gypi +++ b/Source/WebCore/WebCore.gypi @@ -3346,7 +3346,6 @@ 'platform/chromium/MemoryUsageSupportChromium.cpp', 'platform/chromium/MIMETypeRegistryChromium.cpp', 'platform/chromium/PasteboardChromium.cpp', - 'platform/chromium/PasteboardPrivate.h', 'platform/chromium/PlatformCursor.h', 'platform/chromium/PlatformKeyboardEventChromium.cpp', 'platform/chromium/PlatformScreenChromium.cpp', diff --git a/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp b/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp index 1f98fd508..056239b4f 100644 --- a/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp +++ b/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp @@ -592,6 +592,8 @@ void V8DOMWindowShell::namedItemRemoved(HTMLDocument* doc, const AtomicString& n void V8DOMWindowShell::updateSecurityOrigin() { + if (m_context.IsEmpty()) + return; v8::HandleScope scope; setSecurityToken(); } diff --git a/Source/WebCore/bridge/qt/qt_class.cpp b/Source/WebCore/bridge/qt/qt_class.cpp index 3803d4787..1528d6b9b 100644 --- a/Source/WebCore/bridge/qt/qt_class.cpp +++ b/Source/WebCore/bridge/qt/qt_class.cpp @@ -71,7 +71,7 @@ JSValue QtClass::fallbackObject(ExecState* exec, Instance* inst, PropertyName id QtInstance* qtinst = static_cast<QtInstance*>(inst); UString ustring(identifier.publicName()); - const QByteArray name = QString(reinterpret_cast<const QChar*>(ustring.characters()), ustring.length()).toAscii(); + const QByteArray name = QString(reinterpret_cast<const QChar*>(ustring.characters()), ustring.length()).toLatin1(); // First see if we have a cache hit JSObject* val = qtinst->m_methods.value(name).get(); @@ -135,7 +135,7 @@ Field* QtClass::fieldNamed(PropertyName identifier, Instance* instance) const QObject* obj = qtinst->getObject(); UString ustring(identifier.publicName()); const QString name(reinterpret_cast<const QChar*>(ustring.characters()), ustring.length()); - const QByteArray ascii = name.toAscii(); + const QByteArray ascii = name.toLatin1(); // First check for a cached field QtField* f = qtinst->m_fields.value(name); diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp index 589cc2f35..89d84597e 100644 --- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp @@ -231,7 +231,6 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyWebkitAlignItems, CSSPropertyWebkitAlignSelf, CSSPropertyWebkitFlex, - CSSPropertyWebkitFlexOrder, CSSPropertyWebkitFlexPack, CSSPropertyWebkitFlexDirection, CSSPropertyWebkitFlexFlow, @@ -279,6 +278,7 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyWebkitMaskRepeat, CSSPropertyWebkitMaskSize, CSSPropertyWebkitNbspMode, + CSSPropertyWebkitOrder, #if ENABLE(OVERFLOW_SCROLLING) CSSPropertyWebkitOverflowScrolling, #endif @@ -1650,8 +1650,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert return list.release(); } - case CSSPropertyWebkitFlexOrder: - return cssValuePool().createValue(style->flexOrder(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyWebkitOrder: + return cssValuePool().createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitFlexPack: return cssValuePool().createValue(style->flexPack()); case CSSPropertyWebkitAlignItems: @@ -2715,14 +2715,15 @@ void CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const Strin PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getBackgroundShorthandValue() const { - // CSSPropertyBackgroundPosition should be at the end of the array so that CSSPropertyBackgroundSize can be appended followed by '/'. - static const CSSPropertyID properties[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, - CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, - CSSPropertyBackgroundPosition }; + static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, + CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, + CSSPropertyBackgroundPosition }; + static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin, + CSSPropertyBackgroundClip }; RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated(); - list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(properties, WTF_ARRAY_LENGTH(properties)))); - list->append(getPropertyCSSValue(CSSPropertyBackgroundSize, DoNotUpdateLayout)); + list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(propertiesBeforeSlashSeperator, WTF_ARRAY_LENGTH(propertiesBeforeSlashSeperator)))); + list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(propertiesAfterSlashSeperator, WTF_ARRAY_LENGTH(propertiesAfterSlashSeperator)))); return list.release(); } diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp index 695dee916..380765b24 100644 --- a/Source/WebCore/css/CSSParser.cpp +++ b/Source/WebCore/css/CSSParser.cpp @@ -2095,7 +2095,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) else parsedValue = parseFlex(m_valueList.get()); break; - case CSSPropertyWebkitFlexOrder: + case CSSPropertyWebkitOrder: if (validUnit(value, FInteger, CSSStrictMode)) { // We restrict the smallest value to int min + 2 because we use int min and int min + 1 as special values in a hash set. parsedValue = cssValuePool().createValue(max(static_cast<double>(std::numeric_limits<int>::min() + 2), value->fValue), diff --git a/Source/WebCore/css/CSSProperty.cpp b/Source/WebCore/css/CSSProperty.cpp index 29eb85033..a392cfacd 100644 --- a/Source/WebCore/css/CSSProperty.cpp +++ b/Source/WebCore/css/CSSProperty.cpp @@ -542,7 +542,6 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID) case CSSPropertyWebkitAlignItems: case CSSPropertyWebkitAlignSelf: case CSSPropertyWebkitFlex: - case CSSPropertyWebkitFlexOrder: case CSSPropertyWebkitFlexPack: case CSSPropertyWebkitFlexDirection: case CSSPropertyWebkitFlexFlow: @@ -596,6 +595,7 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID) case CSSPropertyWebkitMaxLogicalHeight: case CSSPropertyWebkitMinLogicalWidth: case CSSPropertyWebkitMinLogicalHeight: + case CSSPropertyWebkitOrder: case CSSPropertyWebkitPaddingAfter: case CSSPropertyWebkitPaddingBefore: case CSSPropertyWebkitPaddingEnd: diff --git a/Source/WebCore/css/CSSPropertyNames.in b/Source/WebCore/css/CSSPropertyNames.in index 34985f255..633e10967 100644 --- a/Source/WebCore/css/CSSPropertyNames.in +++ b/Source/WebCore/css/CSSPropertyNames.in @@ -264,7 +264,6 @@ z-index -webkit-flex-direction -webkit-flex-flow -webkit-flex-line-pack --webkit-flex-order -webkit-flex-pack -webkit-flex-wrap #endif @@ -328,6 +327,7 @@ z-index -webkit-min-logical-width -webkit-min-logical-height -webkit-nbsp-mode +-webkit-order -webkit-padding-after -webkit-padding-before -webkit-padding-end diff --git a/Source/WebCore/css/CSSSegmentedFontFace.cpp b/Source/WebCore/css/CSSSegmentedFontFace.cpp index cf9ec9e2e..983425469 100644 --- a/Source/WebCore/css/CSSSegmentedFontFace.cpp +++ b/Source/WebCore/css/CSSSegmentedFontFace.cpp @@ -125,7 +125,6 @@ FontData* CSSSegmentedFontFace::getFontData(const FontDescription& fontDescripti } } if (newFontData->numRanges()) { - ASSERT(m_fontSelector->document()); if (Document* document = m_fontSelector->document()) { fontData = newFontData.get(); document->registerCustomFont(newFontData.release()); diff --git a/Source/WebCore/css/StyleBuilder.cpp b/Source/WebCore/css/StyleBuilder.cpp index 7c974dc27..1492e04c7 100644 --- a/Source/WebCore/css/StyleBuilder.cpp +++ b/Source/WebCore/css/StyleBuilder.cpp @@ -1942,7 +1942,6 @@ StyleBuilder::StyleBuilder() setPropertyHandler(CSSPropertyWebkitFlexDirection, ApplyPropertyDefault<EFlexDirection, &RenderStyle::flexDirection, EFlexDirection, &RenderStyle::setFlexDirection, EFlexDirection, &RenderStyle::initialFlexDirection>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexFlow, ApplyPropertyExpanding<SuppressValue, CSSPropertyWebkitFlexDirection, CSSPropertyWebkitFlexWrap>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexLinePack, ApplyPropertyDefault<EFlexLinePack, &RenderStyle::flexLinePack, EFlexLinePack, &RenderStyle::setFlexLinePack, EFlexLinePack, &RenderStyle::initialFlexLinePack>::createHandler()); - setPropertyHandler(CSSPropertyWebkitFlexOrder, ApplyPropertyDefault<int, &RenderStyle::flexOrder, int, &RenderStyle::setFlexOrder, int, &RenderStyle::initialFlexOrder>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexPack, ApplyPropertyDefault<EFlexPack, &RenderStyle::flexPack, EFlexPack, &RenderStyle::setFlexPack, EFlexPack, &RenderStyle::initialFlexPack>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexWrap, ApplyPropertyDefault<EFlexWrap, &RenderStyle::flexWrap, EFlexWrap, &RenderStyle::setFlexWrap, EFlexWrap, &RenderStyle::initialFlexWrap>::createHandler()); #endif @@ -1990,6 +1989,7 @@ StyleBuilder::StyleBuilder() setPropertyHandler(CSSPropertyWebkitMaskSize, ApplyPropertyFillLayer<FillSize, CSSPropertyWebkitMaskSize, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isSizeSet, &FillLayer::size, &FillLayer::setSize, &FillLayer::clearSize, &FillLayer::initialFillSize, &StyleResolver::mapFillSize>::createHandler()); setPropertyHandler(CSSPropertyWebkitMatchNearestMailBlockquoteColor, ApplyPropertyDefault<EMatchNearestMailBlockquoteColor, &RenderStyle::matchNearestMailBlockquoteColor, EMatchNearestMailBlockquoteColor, &RenderStyle::setMatchNearestMailBlockquoteColor, EMatchNearestMailBlockquoteColor, &RenderStyle::initialMatchNearestMailBlockquoteColor>::createHandler()); setPropertyHandler(CSSPropertyWebkitNbspMode, ApplyPropertyDefault<ENBSPMode, &RenderStyle::nbspMode, ENBSPMode, &RenderStyle::setNBSPMode, ENBSPMode, &RenderStyle::initialNBSPMode>::createHandler()); + setPropertyHandler(CSSPropertyWebkitOrder, ApplyPropertyDefault<int, &RenderStyle::order, int, &RenderStyle::setOrder, int, &RenderStyle::initialOrder>::createHandler()); setPropertyHandler(CSSPropertyWebkitPerspectiveOrigin, ApplyPropertyExpanding<SuppressValue, CSSPropertyWebkitPerspectiveOriginX, CSSPropertyWebkitPerspectiveOriginY>::createHandler()); setPropertyHandler(CSSPropertyWebkitPerspectiveOriginX, ApplyPropertyLength<&RenderStyle::perspectiveOriginX, &RenderStyle::setPerspectiveOriginX, &RenderStyle::initialPerspectiveOriginX>::createHandler()); setPropertyHandler(CSSPropertyWebkitPerspectiveOriginY, ApplyPropertyLength<&RenderStyle::perspectiveOriginY, &RenderStyle::setPerspectiveOriginY, &RenderStyle::initialPerspectiveOriginY>::createHandler()); diff --git a/Source/WebCore/css/StyleResolver.cpp b/Source/WebCore/css/StyleResolver.cpp index 1f023d2bd..abbaff1c2 100644 --- a/Source/WebCore/css/StyleResolver.cpp +++ b/Source/WebCore/css/StyleResolver.cpp @@ -4127,7 +4127,6 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue *value) case CSSPropertyWebkitFlexDirection: case CSSPropertyWebkitFlexFlow: case CSSPropertyWebkitFlexLinePack: - case CSSPropertyWebkitFlexOrder: case CSSPropertyWebkitFlexPack: case CSSPropertyWebkitFlexWrap: #endif @@ -4170,6 +4169,7 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue *value) case CSSPropertyWebkitMaskSize: case CSSPropertyWebkitMatchNearestMailBlockquoteColor: case CSSPropertyWebkitNbspMode: + case CSSPropertyWebkitOrder: case CSSPropertyWebkitPerspectiveOrigin: case CSSPropertyWebkitPerspectiveOriginX: case CSSPropertyWebkitPerspectiveOriginY: diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index af40173c7..60c1823e9 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -782,7 +782,7 @@ void Document::setDocType(PassRefPtr<DocumentType> docType) #if USE(LEGACY_VIEWPORT_ADAPTION) ASSERT(m_viewportArguments.type == ViewportArguments::Implicit); if (m_docType->publicId().startsWith("-//wapforum//dtd xhtml mobile 1.", /* caseSensitive */ false)) - processViewport("width=device-width, height=device-height, initial-scale=1"); + processViewport("width=device-width, height=device-height", ViewportArguments::XHTMLMobileProfile); #endif } // Doctype affects the interpretation of the stylesheets. @@ -3036,11 +3036,14 @@ void Document::processArguments(const String& features, void* data, ArgumentsCal } } -void Document::processViewport(const String& features) +void Document::processViewport(const String& features, ViewportArguments::Type origin) { ASSERT(!features.isNull()); - m_viewportArguments = ViewportArguments(ViewportArguments::ViewportMeta); + if (origin < m_viewportArguments.type) + return; + + m_viewportArguments = ViewportArguments(origin); processArguments(features, (void*)&m_viewportArguments, &setViewportFeature); updateViewportArguments(); @@ -5040,9 +5043,14 @@ void Document::initContentSecurityPolicy() contentSecurityPolicy()->copyStateFrom(m_frame->tree()->parent()->document()->contentSecurityPolicy()); } -void Document::setSecurityOrigin(PassRefPtr<SecurityOrigin> origin) +void Document::didUpdateSecurityOrigin() { - SecurityContext::setSecurityOrigin(origin); + if (!m_frame) + return; + // FIXME: We should remove DOMWindow::m_securityOrigin so that we don't need to keep them in sync. + // See <https://bugs.webkit.org/show_bug.cgi?id=75793>. + m_frame->domWindow()->setSecurityOrigin(securityOrigin()); + m_frame->script()->updateSecurityOrigin(); } bool Document::isContextThread() const diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h index 72edf436a..da5abca0b 100644 --- a/Source/WebCore/dom/Document.h +++ b/Source/WebCore/dom/Document.h @@ -834,7 +834,7 @@ public: * @param content The header value (value of the meta tag's "content" attribute) */ void processHttpEquiv(const String& equiv, const String& content); - void processViewport(const String& features); + void processViewport(const String& features, ViewportArguments::Type origin); void updateViewportArguments(); void processReferrerPolicy(const String& policy); @@ -1048,11 +1048,6 @@ public: void initSecurityContext(); void initContentSecurityPolicy(); - // Explicitly override the security origin for this document. - // Note: It is dangerous to change the security origin of a document - // that already contains content. - void setSecurityOrigin(PassRefPtr<SecurityOrigin>); - void updateURLForPushOrReplaceState(const KURL&); void statePopped(PassRefPtr<SerializedScriptValue>); @@ -1167,6 +1162,8 @@ public: protected: Document(Frame*, const KURL&, bool isXHTML, bool isHTML); + virtual void didUpdateSecurityOrigin() OVERRIDE; + void clearXMLVersion() { m_xmlVersion = String(); } private: diff --git a/Source/WebCore/dom/SecurityContext.cpp b/Source/WebCore/dom/SecurityContext.cpp index 24ceaf6f3..8002201c1 100644 --- a/Source/WebCore/dom/SecurityContext.cpp +++ b/Source/WebCore/dom/SecurityContext.cpp @@ -67,6 +67,22 @@ bool SecurityContext::isSecureTransitionTo(const KURL& url) const return securityOrigin()->canAccess(other.get()); } +void SecurityContext::enforceSandboxFlags(SandboxFlags mask) +{ + m_sandboxFlags |= mask; + + // The SandboxOrigin is stored redundantly in the security origin. + if (isSandboxed(SandboxOrigin) && securityOrigin() && !securityOrigin()->isUnique()) { + setSecurityOrigin(SecurityOrigin::createUnique()); + didUpdateSecurityOrigin(); + } +} + +void SecurityContext::didUpdateSecurityOrigin() +{ + // Subclasses can override this function if the need to do extra work when the security origin changes. +} + SandboxFlags SecurityContext::parseSandboxPolicy(const String& policy) { // http://www.w3.org/TR/html5/the-iframe-element.html#attr-iframe-sandbox diff --git a/Source/WebCore/dom/SecurityContext.h b/Source/WebCore/dom/SecurityContext.h index 7b4746d13..fc9df3e34 100644 --- a/Source/WebCore/dom/SecurityContext.h +++ b/Source/WebCore/dom/SecurityContext.h @@ -62,19 +62,22 @@ public: bool isSecureTransitionTo(const KURL&) const; - void enforceSandboxFlags(SandboxFlags mask) { m_sandboxFlags |= mask; } + void enforceSandboxFlags(SandboxFlags mask); bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; } + // Explicitly override the security origin for this security context. + // Note: It is dangerous to change the security origin of a script context + // that already contains content. + void setSecurityOrigin(PassRefPtr<SecurityOrigin>); + static SandboxFlags parseSandboxPolicy(const String& policy); protected: SecurityContext(); - ~SecurityContext(); + virtual ~SecurityContext(); + + virtual void didUpdateSecurityOrigin(); - // Explicitly override the security origin for this security context. - // Note: It is dangerous to change the security origin of a script context - // that already contains content. - void setSecurityOrigin(PassRefPtr<SecurityOrigin>); void setContentSecurityPolicy(PassOwnPtr<ContentSecurityPolicy>); void didFailToInitializeSecurityOrigin() { m_haveInitializedSecurityOrigin = false; } diff --git a/Source/WebCore/dom/ViewportArguments.h b/Source/WebCore/dom/ViewportArguments.h index 92e3172fa..93e3b8de3 100644 --- a/Source/WebCore/dom/ViewportArguments.h +++ b/Source/WebCore/dom/ViewportArguments.h @@ -57,7 +57,13 @@ struct ViewportAttributes { struct ViewportArguments { enum Type { + // These are ordered in increasing importance. Implicit, +#if USE(LEGACY_VIEWPORT_ADAPTION) + XHTMLMobileProfile, + HandheldFriendlyMeta, + MobileOptimizedMeta, +#endif ViewportMeta } type; diff --git a/Source/WebCore/html/HTMLIntentElement.cpp b/Source/WebCore/html/HTMLIntentElement.cpp index aec2dbf73..c9cfb32b6 100644 --- a/Source/WebCore/html/HTMLIntentElement.cpp +++ b/Source/WebCore/html/HTMLIntentElement.cpp @@ -51,7 +51,7 @@ PassRefPtr<HTMLIntentElement> HTMLIntentElement::create(const QualifiedName& tag return adoptRef(new HTMLIntentElement(tagName, document)); } -Node::InsertionNotificationRequest HTMLIntentElement::insertedInto(Node* insertionPoint) +Node::InsertionNotificationRequest HTMLIntentElement::insertedInto(ContainerNode* insertionPoint) { HTMLElement::insertedInto(insertionPoint); diff --git a/Source/WebCore/html/HTMLIntentElement.h b/Source/WebCore/html/HTMLIntentElement.h index badb5057e..91ac2639f 100644 --- a/Source/WebCore/html/HTMLIntentElement.h +++ b/Source/WebCore/html/HTMLIntentElement.h @@ -42,7 +42,7 @@ public: private: HTMLIntentElement(const QualifiedName&, Document*); - virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE; + virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE; }; } // namespace WebCore diff --git a/Source/WebCore/html/HTMLMetaElement.cpp b/Source/WebCore/html/HTMLMetaElement.cpp index 8d7a1a3a0..cf114f67a 100644 --- a/Source/WebCore/html/HTMLMetaElement.cpp +++ b/Source/WebCore/html/HTMLMetaElement.cpp @@ -72,10 +72,15 @@ void HTMLMetaElement::process() return; if (equalIgnoringCase(name(), "viewport")) - document()->processViewport(contentValue); - - if (equalIgnoringCase(name(), "referrer")) + document()->processViewport(contentValue, ViewportArguments::ViewportMeta); + else if (equalIgnoringCase(name(), "referrer")) document()->processReferrerPolicy(contentValue); +#if USE(LEGACY_VIEWPORT_ADAPTION) + else if (equalIgnoringCase(name(), "handheldfriendly") && equalIgnoringCase(contentValue, "true")) + document()->processViewport("width=device-width", ViewportArguments::HandheldFriendlyMeta); + else if (equalIgnoringCase(name(), "mobileoptimized")) + document()->processViewport("width=device-width, initial-scale=1", ViewportArguments::MobileOptimizedMeta); +#endif // Get the document to process the tag, but only if we're actually part of DOM tree (changing a meta tag while // it's not in the tree shouldn't have any effect on the document) diff --git a/Source/WebCore/inspector/InspectorMemoryAgent.cpp b/Source/WebCore/inspector/InspectorMemoryAgent.cpp index 922545843..6095641c0 100644 --- a/Source/WebCore/inspector/InspectorMemoryAgent.cpp +++ b/Source/WebCore/inspector/InspectorMemoryAgent.cpp @@ -43,6 +43,7 @@ #include "InspectorState.h" #include "InspectorValues.h" #include "InstrumentingAgents.h" +#include "MemoryCache.h" #include "MemoryUsageSupport.h" #include "Node.h" #include "Page.h" @@ -57,12 +58,24 @@ using WebCore::TypeBuilder::Memory::ListenerCount; using WebCore::TypeBuilder::Memory::NodeCount; using WebCore::TypeBuilder::Memory::StringStatistics; +// Use a type alias instead of 'using' here which would cause a conflict on Mac. +typedef WebCore::TypeBuilder::Memory::MemoryBlock InspectorMemoryBlock; + namespace WebCore { namespace MemoryBlockName { static const char jsHeapAllocated[] = "JSHeapAllocated"; static const char jsHeapUsed[] = "JSHeapUsed"; +static const char memoryCache[] = "MemoryCache"; static const char processPrivateMemory[] = "ProcessPrivateMemory"; + +static const char cachedImages[] = "CachedImages"; +static const char cachedCssStyleSheets[] = "CachedCssStyleSheets"; +static const char cachedScripts[] = "CachedScripts"; +static const char cachedXslStyleSheets[] = "CachedXslStyleSheets"; +static const char cachedFonts[] = "CachedFonts"; +static const char renderTreeUsed[] = "RenderTreeUsed"; +static const char renderTreeAllocated[] = "RenderTreeAllocated"; } namespace { @@ -315,18 +328,18 @@ void InspectorMemoryAgent::getDOMNodeCount(ErrorString*, RefPtr<TypeBuilder::Arr strings = counterVisitor.strings(); } -static PassRefPtr<WebCore::TypeBuilder::Memory::MemoryBlock> jsHeapInfo() +static PassRefPtr<InspectorMemoryBlock> jsHeapInfo() { size_t usedJSHeapSize; size_t totalJSHeapSize; size_t jsHeapSizeLimit; ScriptGCEvent::getHeapSize(usedJSHeapSize, totalJSHeapSize, jsHeapSizeLimit); - RefPtr<WebCore::TypeBuilder::Memory::MemoryBlock> jsHeapAllocated = WebCore::TypeBuilder::Memory::MemoryBlock::create().setName(MemoryBlockName::jsHeapAllocated); + RefPtr<InspectorMemoryBlock> jsHeapAllocated = InspectorMemoryBlock::create().setName(MemoryBlockName::jsHeapAllocated); jsHeapAllocated->setSize(static_cast<int>(totalJSHeapSize)); - RefPtr<TypeBuilder::Array<WebCore::TypeBuilder::Memory::MemoryBlock> > children = TypeBuilder::Array<WebCore::TypeBuilder::Memory::MemoryBlock>::create(); - RefPtr<WebCore::TypeBuilder::Memory::MemoryBlock> jsHeapUsed = WebCore::TypeBuilder::Memory::MemoryBlock::create().setName(MemoryBlockName::jsHeapUsed); + RefPtr<TypeBuilder::Array<InspectorMemoryBlock> > children = TypeBuilder::Array<InspectorMemoryBlock>::create(); + RefPtr<InspectorMemoryBlock> jsHeapUsed = InspectorMemoryBlock::create().setName(MemoryBlockName::jsHeapUsed); jsHeapUsed->setSize(static_cast<int>(usedJSHeapSize)); children->addItem(jsHeapUsed); @@ -334,16 +347,62 @@ static PassRefPtr<WebCore::TypeBuilder::Memory::MemoryBlock> jsHeapInfo() return jsHeapAllocated.release(); } -void InspectorMemoryAgent::getProcessMemoryDistribution(ErrorString*, RefPtr<WebCore::TypeBuilder::Memory::MemoryBlock>& processMemory) +static PassRefPtr<InspectorMemoryBlock> renderTreeInfo(Page* page) +{ + ArenaSize arenaSize = page->renderTreeSize(); + + RefPtr<InspectorMemoryBlock> renderTreeAllocated = InspectorMemoryBlock::create().setName(MemoryBlockName::renderTreeAllocated); + renderTreeAllocated->setSize(static_cast<int>(arenaSize.allocated)); + + RefPtr<TypeBuilder::Array<InspectorMemoryBlock> > children = TypeBuilder::Array<InspectorMemoryBlock>::create(); + RefPtr<InspectorMemoryBlock> renderTreeUsed = InspectorMemoryBlock::create().setName(MemoryBlockName::renderTreeUsed); + renderTreeUsed->setSize(static_cast<int>(arenaSize.treeSize)); + children->addItem(renderTreeUsed); + + renderTreeAllocated->setChildren(children); + return renderTreeAllocated.release(); +} + +static void addMemoryBlockFor(TypeBuilder::Array<InspectorMemoryBlock>* array, const MemoryCache::TypeStatistic& statistic, const char* name) +{ + RefPtr<InspectorMemoryBlock> result = InspectorMemoryBlock::create().setName(name); + result->setSize(statistic.size); + array->addItem(result); +} + +static PassRefPtr<InspectorMemoryBlock> memoryCacheInfo() +{ + MemoryCache::Statistics stats = memoryCache()->getStatistics(); + int totalSize = stats.images.size + + stats.cssStyleSheets.size + + stats.scripts.size + + stats.xslStyleSheets.size + + stats.fonts.size; + RefPtr<InspectorMemoryBlock> memoryCacheStats = InspectorMemoryBlock::create().setName(MemoryBlockName::memoryCache); + memoryCacheStats->setSize(totalSize); + + RefPtr<TypeBuilder::Array<InspectorMemoryBlock> > children = TypeBuilder::Array<InspectorMemoryBlock>::create(); + addMemoryBlockFor(children.get(), stats.images, MemoryBlockName::cachedImages); + addMemoryBlockFor(children.get(), stats.cssStyleSheets, MemoryBlockName::cachedCssStyleSheets); + addMemoryBlockFor(children.get(), stats.scripts, MemoryBlockName::cachedScripts); + addMemoryBlockFor(children.get(), stats.xslStyleSheets, MemoryBlockName::cachedXslStyleSheets); + addMemoryBlockFor(children.get(), stats.fonts, MemoryBlockName::cachedFonts); + memoryCacheStats->setChildren(children); + return memoryCacheStats.release(); +} + +void InspectorMemoryAgent::getProcessMemoryDistribution(ErrorString*, RefPtr<InspectorMemoryBlock>& processMemory) { size_t privateBytes = 0; size_t sharedBytes = 0; MemoryUsageSupport::processMemorySizesInBytes(&privateBytes, &sharedBytes); - processMemory = WebCore::TypeBuilder::Memory::MemoryBlock::create().setName(MemoryBlockName::processPrivateMemory); + processMemory = InspectorMemoryBlock::create().setName(MemoryBlockName::processPrivateMemory); processMemory->setSize(static_cast<int>(privateBytes)); - RefPtr<TypeBuilder::Array<WebCore::TypeBuilder::Memory::MemoryBlock> > children = TypeBuilder::Array<WebCore::TypeBuilder::Memory::MemoryBlock>::create(); + RefPtr<TypeBuilder::Array<InspectorMemoryBlock> > children = TypeBuilder::Array<InspectorMemoryBlock>::create(); children->addItem(jsHeapInfo()); + children->addItem(memoryCacheInfo()); + children->addItem(renderTreeInfo(m_page)); // TODO: collect for all pages? processMemory->setChildren(children); } diff --git a/Source/WebCore/inspector/front-end/HeapSnapshotWorker.js b/Source/WebCore/inspector/front-end/HeapSnapshotWorker.js index ccdb5c39b..9cb4a25ec 100644 --- a/Source/WebCore/inspector/front-end/HeapSnapshotWorker.js +++ b/Source/WebCore/inspector/front-end/HeapSnapshotWorker.js @@ -49,17 +49,20 @@ WebInspector.WorkerConsole = function() } WebInspector.WorkerConsole.prototype = { - log: function() + /** @param {...*} var_args */ + log: function(var_args) { this._postMessage("log", Array.prototype.slice.call(arguments)); }, - error: function() + /** @param {...*} var_args */ + error: function(var_args) { this._postMessage("error", Array.prototype.slice.call(arguments)); }, - info: function() + /** @param {...*} var_args */ + info: function(var_args) { this._postMessage("info", Array.prototype.slice.call(arguments)); }, @@ -69,6 +72,8 @@ WebInspector.WorkerConsole.prototype = { this.log(new Error().stack); }, + /** @param {string} method */ + /** @param {Array.<*>} args */ _postMessage: function(method, args) { var rawMessage = { diff --git a/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js b/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js index 1dfb21aa4..697225c0a 100644 --- a/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js +++ b/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js @@ -201,6 +201,9 @@ WebInspector.MemoryBlockViewProperties._initialize = function() addBlock("rgba(240, 240, 250, 0.8)", "ProcessPrivateMemory", "Total"); addBlock("rgba(250, 200, 200, 0.8)", "JSHeapAllocated", "JavaScript heap"); addBlock("rgba(200, 250, 200, 0.8)", "JSHeapUsed", "Used JavaScript heap"); + addBlock("rgba(200, 170, 200, 0.8)", "MemoryCache", "Memory cache resources"); + addBlock("rgba(250, 250, 150, 0.8)", "RenderTreeAllocated", "Render tree"); + addBlock("rgba(200, 150, 150, 0.8)", "RenderTreeUsed", "Render tree used"); } WebInspector.MemoryBlockViewProperties._forMemoryBlock = function(memoryBlock) diff --git a/Source/WebCore/inspector/front-end/SettingsScreen.js b/Source/WebCore/inspector/front-end/SettingsScreen.js index aac212bf3..f4b59426d 100644 --- a/Source/WebCore/inspector/front-end/SettingsScreen.js +++ b/Source/WebCore/inspector/front-end/SettingsScreen.js @@ -603,7 +603,7 @@ WebInspector.SettingsScreen.prototype = { this._applyDeviceMetricsUserInput(); } - var tableElement = fieldsetElement.createChild("table"); + var tableElement = fieldsetElement.createChild("table", "nowrap"); var rowElement = tableElement.createChild("tr"); var cellElement = rowElement.createChild("td"); diff --git a/Source/WebCore/inspector/front-end/elementsPanel.css b/Source/WebCore/inspector/front-end/elementsPanel.css index 61024cc62..b4dcfb2cc 100644 --- a/Source/WebCore/inspector/front-end/elementsPanel.css +++ b/Source/WebCore/inspector/front-end/elementsPanel.css @@ -27,10 +27,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#elements-content.nowrap { - white-space: nowrap; -} - #elements-content { padding-left: 0; } diff --git a/Source/WebCore/inspector/front-end/inspector.css b/Source/WebCore/inspector/front-end/inspector.css index 4db6c2368..32f90548b 100644 --- a/Source/WebCore/inspector/front-end/inspector.css +++ b/Source/WebCore/inspector/front-end/inspector.css @@ -43,6 +43,10 @@ input[type="search"]:focus, input[type="text"]:focus { display: none; } +.nowrap { + white-space: nowrap; +} + #toolbar { position: absolute; top: 0; diff --git a/Source/WebCore/loader/HistoryController.cpp b/Source/WebCore/loader/HistoryController.cpp index d5df639bc..bf8d7c8e2 100644 --- a/Source/WebCore/loader/HistoryController.cpp +++ b/Source/WebCore/loader/HistoryController.cpp @@ -124,10 +124,11 @@ void HistoryController::restoreScrollPositionAndViewState() if (FrameView* view = m_frame->view()) { if (!view->wasScrolledByUser()) { - view->setScrollPosition(m_currentItem->scrollPoint()); Page* page = m_frame->page(); if (page && page->mainFrame() == m_frame && m_currentItem->pageScaleFactor()) page->setPageScaleFactor(m_currentItem->pageScaleFactor(), m_currentItem->scrollPoint()); + else + view->setScrollPosition(m_currentItem->scrollPoint()); } } } diff --git a/Source/WebCore/platform/Decimal.cpp b/Source/WebCore/platform/Decimal.cpp index d2dd8329c..5969e3b77 100644 --- a/Source/WebCore/platform/Decimal.cpp +++ b/Source/WebCore/platform/Decimal.cpp @@ -168,7 +168,7 @@ UInt128& UInt128::operator/=(const uint32_t divisor) uint32_t quotient[4]; uint32_t remainder = 0; for (int i = 3; i >= 0; --i) { - const uint64_t work = makeUInt64(remainder, dividend[i]); + const uint64_t work = makeUInt64(dividend[i], remainder); remainder = static_cast<uint32_t>(work % divisor); quotient[i] = static_cast<uint32_t>(work / divisor); } diff --git a/Source/WebCore/platform/Pasteboard.h b/Source/WebCore/platform/Pasteboard.h index 4681357ae..1fb84827f 100644 --- a/Source/WebCore/platform/Pasteboard.h +++ b/Source/WebCore/platform/Pasteboard.h @@ -53,10 +53,6 @@ OBJC_CLASS NSArray; typedef struct HWND__* HWND; #endif -#if PLATFORM(CHROMIUM) -#include "PasteboardPrivate.h" -#endif - namespace WebCore { #if PLATFORM(MAC) @@ -123,9 +119,6 @@ private: bool m_selectionMode; #endif -#if PLATFORM(CHROMIUM) - PasteboardPrivate p; -#endif }; } // namespace WebCore diff --git a/Source/WebCore/platform/chromium/ChromiumDataObject.cpp b/Source/WebCore/platform/chromium/ChromiumDataObject.cpp index 876ec4379..50383b68e 100644 --- a/Source/WebCore/platform/chromium/ChromiumDataObject.cpp +++ b/Source/WebCore/platform/chromium/ChromiumDataObject.cpp @@ -36,16 +36,21 @@ #include "DataTransferItem.h" #include "ExceptionCode.h" #include "ExceptionCodePlaceholder.h" -#include "PlatformSupport.h" + +#include <public/Platform.h> +#include <public/WebClipboard.h> namespace WebCore { PassRefPtr<ChromiumDataObject> ChromiumDataObject::createFromPasteboard() { RefPtr<ChromiumDataObject> dataObject = create(); - uint64_t sequenceNumber = PlatformSupport::clipboardSequenceNumber(currentPasteboardBuffer()); + uint64_t sequenceNumber = WebKit::Platform::current()->clipboard()->sequenceNumber(currentPasteboardBuffer()); bool ignored; - HashSet<String> types = PlatformSupport::clipboardReadAvailableTypes(currentPasteboardBuffer(), &ignored); + WebKit::WebVector<WebKit::WebString> webTypes = WebKit::Platform::current()->clipboard()->readAvailableTypes(currentPasteboardBuffer(), &ignored); + HashSet<String> types; + for (size_t i = 0; i < webTypes.size(); ++i) + types.add(webTypes[i]); for (HashSet<String>::const_iterator it = types.begin(); it != types.end(); ++it) dataObject->m_itemList.append(ChromiumDataObjectItem::createFromPasteboard(*it, sequenceNumber)); return dataObject.release(); diff --git a/Source/WebCore/platform/chromium/ChromiumDataObjectItem.cpp b/Source/WebCore/platform/chromium/ChromiumDataObjectItem.cpp index 5db3603d4..9d19631be 100644 --- a/Source/WebCore/platform/chromium/ChromiumDataObjectItem.cpp +++ b/Source/WebCore/platform/chromium/ChromiumDataObjectItem.cpp @@ -40,10 +40,12 @@ #include "ClipboardUtilitiesChromium.h" #include "DataTransferItem.h" #include "File.h" -#include "PlatformSupport.h" #include "SharedBuffer.h" #include "StringCallback.h" +#include <public/Platform.h> +#include <public/WebClipboard.h> + namespace WebCore { PassRefPtr<ChromiumDataObjectItem> ChromiumDataObjectItem::createFromString(const String& type, const String& data) @@ -141,7 +143,7 @@ PassRefPtr<Blob> ChromiumDataObjectItem::getAsFile() const // method to the blob registry; that way the data is only copied over // into the renderer when it's actually read, not when the blob is // initially constructed). - RefPtr<SharedBuffer> data = PlatformSupport::clipboardReadImage(PasteboardPrivate::StandardBuffer); + RefPtr<SharedBuffer> data = static_cast<PassRefPtr<SharedBuffer> >(WebKit::Platform::current()->clipboard()->readImage(WebKit::WebClipboard::BufferStandard)); RefPtr<RawData> rawData = RawData::create(); rawData->mutableData()->append(data->data(), data->size()); OwnPtr<BlobData> blobData = BlobData::create(); @@ -165,15 +167,15 @@ String ChromiumDataObjectItem::internalGetAsString() const String data; // This is ugly but there's no real alternative. if (m_type == mimeTypeTextPlain) - data = PlatformSupport::clipboardReadPlainText(currentPasteboardBuffer()); + data = WebKit::Platform::current()->clipboard()->readPlainText(currentPasteboardBuffer()); else if (m_type == mimeTypeTextHTML) { - KURL ignoredSourceURL; + WebKit::WebURL ignoredSourceURL; unsigned ignored; - PlatformSupport::clipboardReadHTML(currentPasteboardBuffer(), &data, &ignoredSourceURL, &ignored, &ignored); + data = WebKit::Platform::current()->clipboard()->readHTML(currentPasteboardBuffer(), &ignoredSourceURL, &ignored, &ignored); } else - data = PlatformSupport::clipboardReadCustomData(currentPasteboardBuffer(), m_type); + data = WebKit::Platform::current()->clipboard()->readCustomData(currentPasteboardBuffer(), m_type); - return PlatformSupport::clipboardSequenceNumber(currentPasteboardBuffer()) == m_sequenceNumber ? data : String(); + return WebKit::Platform::current()->clipboard()->sequenceNumber(currentPasteboardBuffer()) == m_sequenceNumber ? data : String(); } bool ChromiumDataObjectItem::isFilename() const diff --git a/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.cpp b/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.cpp index c8f9035e4..f00c80ab9 100644 --- a/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.cpp +++ b/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.cpp @@ -35,13 +35,15 @@ #include "Pasteboard.h" #include "PlatformString.h" +#include <public/WebClipboard.h> + namespace WebCore { -PasteboardPrivate::ClipboardBuffer currentPasteboardBuffer() +WebKit::WebClipboard::Buffer currentPasteboardBuffer() { return Pasteboard::generalPasteboard()->isSelectionMode() ? - PasteboardPrivate::SelectionBuffer : - PasteboardPrivate::StandardBuffer; + WebKit::WebClipboard::BufferSelection : + WebKit::WebClipboard::BufferStandard; } #if OS(WINDOWS) diff --git a/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.h b/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.h index 49a483870..6f34b28fd 100644 --- a/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.h +++ b/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.h @@ -31,15 +31,14 @@ #ifndef ClipboardUtilitiesChromium_h #define ClipboardUtilitiesChromium_h -#include "PasteboardPrivate.h" - +#include <public/WebClipboard.h> #include <wtf/Forward.h> namespace WebCore { class KURL; -PasteboardPrivate::ClipboardBuffer currentPasteboardBuffer(); +WebKit::WebClipboard::Buffer currentPasteboardBuffer(); #if OS(WINDOWS) void replaceNewlinesWithWindowsStyleNewlines(String&); #endif diff --git a/Source/WebCore/platform/chromium/PasteboardChromium.cpp b/Source/WebCore/platform/chromium/PasteboardChromium.cpp index ec974b3ec..d0a0ee798 100644 --- a/Source/WebCore/platform/chromium/PasteboardChromium.cpp +++ b/Source/WebCore/platform/chromium/PasteboardChromium.cpp @@ -31,6 +31,7 @@ #include "config.h" #include "Pasteboard.h" +#include "ClipboardChromium.h" #include "ClipboardUtilitiesChromium.h" #include "Document.h" #include "DocumentFragment.h" @@ -41,7 +42,6 @@ #include "Image.h" #include "KURL.h" #include "NativeImageSkia.h" -#include "PlatformSupport.h" #include "Range.h" #include "RenderImage.h" #include "markup.h" @@ -51,6 +51,10 @@ #include "XLinkNames.h" #endif +#include <public/Platform.h> +#include <public/WebClipboard.h> +#include <public/WebDragData.h> + namespace WebCore { Pasteboard* Pasteboard::generalPasteboard() @@ -91,7 +95,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, #endif replaceNBSPWithSpace(plainText); - PlatformSupport::clipboardWriteSelection(html, url, plainText, canSmartCopyOrDelete); + WebKit::Platform::current()->clipboard()->writeHTML(html, url, plainText, canSmartCopyOrDelete); } void Pasteboard::writePlainText(const String& text) @@ -99,9 +103,9 @@ void Pasteboard::writePlainText(const String& text) #if OS(WINDOWS) String plainText(text); replaceNewlinesWithWindowsStyleNewlines(plainText); - PlatformSupport::clipboardWritePlainText(plainText); + WebKit::Platform::current()->clipboard()->writePlainText(plainText); #else - PlatformSupport::clipboardWritePlainText(text); + WebKit::Platform::current()->clipboard()->writePlainText(text); #endif } @@ -116,7 +120,7 @@ void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame) title = url.host(); } - PlatformSupport::clipboardWriteURL(url, title); + WebKit::Platform::current()->clipboard()->writeURL(url, title); } void Pasteboard::writeImage(Node* node, const KURL&, const String& title) @@ -151,47 +155,51 @@ void Pasteboard::writeImage(Node* node, const KURL&, const String& title) urlString = element->getAttribute(element->imageSourceAttributeName()); } KURL url = urlString.isEmpty() ? KURL() : node->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(urlString)); - - PlatformSupport::clipboardWriteImage(bitmap, url, title); + WebKit::WebImage webImage = bitmap->bitmap(); + WebKit::Platform::current()->clipboard()->writeImage(webImage, WebKit::WebURL(url), WebKit::WebString(title)); } void Pasteboard::writeClipboard(Clipboard* clipboard) { - PlatformSupport::clipboardWriteDataObject(clipboard); + WebKit::WebDragData dragData = static_cast<ClipboardChromium*>(clipboard)->dataObject(); + WebKit::Platform::current()->clipboard()->writeDataObject(dragData); } bool Pasteboard::canSmartReplace() { - return PlatformSupport::clipboardIsFormatAvailable(PasteboardPrivate::WebSmartPasteFormat, m_selectionMode ? PasteboardPrivate::SelectionBuffer : PasteboardPrivate::StandardBuffer); + return WebKit::Platform::current()->clipboard()->isFormatAvailable(WebKit::WebClipboard::FormatSmartPaste, m_selectionMode ? WebKit::WebClipboard::BufferSelection : WebKit::WebClipboard::BufferStandard); } String Pasteboard::plainText(Frame* frame) { - return PlatformSupport::clipboardReadPlainText(m_selectionMode ? PasteboardPrivate::SelectionBuffer : PasteboardPrivate::StandardBuffer); + return WebKit::Platform::current()->clipboard()->readPlainText(m_selectionMode ? WebKit::WebClipboard::BufferSelection : WebKit::WebClipboard::BufferStandard); } PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText) { chosePlainText = false; - PasteboardPrivate::ClipboardBuffer buffer = m_selectionMode ? PasteboardPrivate::SelectionBuffer : PasteboardPrivate::StandardBuffer; + WebKit::WebClipboard::Buffer buffer = m_selectionMode ? WebKit::WebClipboard::BufferSelection : WebKit::WebClipboard::BufferStandard; - if (PlatformSupport::clipboardIsFormatAvailable(PasteboardPrivate::HTMLFormat, buffer)) { - String markup; - KURL srcURL; + if (WebKit::Platform::current()->clipboard()->isFormatAvailable(WebKit::WebClipboard::FormatHTML, buffer)) { + WebKit::WebString markup; unsigned fragmentStart = 0; unsigned fragmentEnd = 0; - PlatformSupport::clipboardReadHTML(buffer, &markup, &srcURL, &fragmentStart, &fragmentEnd); + WebKit::WebURL url; + markup = WebKit::Platform::current()->clipboard()->readHTML(buffer, &url, &fragmentStart, &fragmentEnd); + + + // PlatformSupport::clipboardReadHTML(buffer, &markup, &srcURL, &fragmentStart, &fragmentEnd); if (!markup.isEmpty()) { RefPtr<DocumentFragment> fragment = - createFragmentFromMarkupWithContext(frame->document(), markup, fragmentStart, fragmentEnd, srcURL, DisallowScriptingContent); + createFragmentFromMarkupWithContext(frame->document(), markup, fragmentStart, fragmentEnd, KURL(url), DisallowScriptingContent); if (fragment) return fragment.release(); } } if (allowPlainText) { - String markup = PlatformSupport::clipboardReadPlainText(buffer); + String markup = WebKit::Platform::current()->clipboard()->readPlainText(buffer); if (!markup.isEmpty()) { chosePlainText = true; diff --git a/Source/WebCore/platform/chromium/PasteboardPrivate.h b/Source/WebCore/platform/chromium/PasteboardPrivate.h deleted file mode 100644 index 5f167baf3..000000000 --- a/Source/WebCore/platform/chromium/PasteboardPrivate.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2008, Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PasteboardPrivate_h -#define PasteboardPrivate_h - -namespace WebCore { - - class PasteboardPrivate { - public: - enum ClipboardFormat { - PlainTextFormat, - HTMLFormat, - BookmarkFormat, - WebSmartPasteFormat, - }; - enum ClipboardBuffer { - StandardBuffer, - SelectionBuffer, - DragBuffer, - }; - }; - -} // namespace WebCore - -#endif diff --git a/Source/WebCore/platform/chromium/PlatformSupport.h b/Source/WebCore/platform/chromium/PlatformSupport.h index c4864b88e..1cede0a0e 100644 --- a/Source/WebCore/platform/chromium/PlatformSupport.h +++ b/Source/WebCore/platform/chromium/PlatformSupport.h @@ -38,7 +38,6 @@ #include "FileSystem.h" #include "ImageSource.h" #include "LinkHash.h" -#include "PasteboardPrivate.h" #include "PluginData.h" #include <wtf/Forward.h> @@ -67,7 +66,6 @@ typedef struct HFONT__* HFONT; namespace WebCore { class AsyncFileSystem; -class Clipboard; class Color; class Cursor; class Document; @@ -94,26 +92,6 @@ struct FontRenderStyle; class PlatformSupport { public: - // Clipboard ---------------------------------------------------------- - static uint64_t clipboardSequenceNumber(PasteboardPrivate::ClipboardBuffer); - - static bool clipboardIsFormatAvailable(PasteboardPrivate::ClipboardFormat, PasteboardPrivate::ClipboardBuffer); - static HashSet<String> clipboardReadAvailableTypes(PasteboardPrivate::ClipboardBuffer, bool* containsFilenames); - - static String clipboardReadPlainText(PasteboardPrivate::ClipboardBuffer); - static void clipboardReadHTML(PasteboardPrivate::ClipboardBuffer, String*, KURL*, unsigned* fragmentStart, unsigned* fragmentEnd); - static PassRefPtr<SharedBuffer> clipboardReadImage(PasteboardPrivate::ClipboardBuffer); - static String clipboardReadCustomData(PasteboardPrivate::ClipboardBuffer, const String& type); - - // Only the clipboardRead functions take a buffer argument because - // Chromium currently uses a different technique to write to alternate - // clipboard buffers. - static void clipboardWriteSelection(const String&, const KURL&, const String&, bool); - static void clipboardWritePlainText(const String&); - static void clipboardWriteURL(const KURL&, const String&); - static void clipboardWriteImage(NativeImagePtr, const KURL&, const String&); - static void clipboardWriteDataObject(Clipboard*); - // Cookies ------------------------------------------------------------ static void setCookies(const Document*, const KURL&, const String& value); static String cookies(const Document*, const KURL&); diff --git a/Source/WebCore/platform/geoclue/GeolocationProviderGeoclue.cpp b/Source/WebCore/platform/geoclue/GeolocationProviderGeoclue.cpp new file mode 100644 index 000000000..e53760490 --- /dev/null +++ b/Source/WebCore/platform/geoclue/GeolocationProviderGeoclue.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "GeolocationProviderGeoclue.h" + +#if ENABLE(GEOLOCATION) + +#include <wtf/gobject/GOwnPtr.h> + +using namespace WebCore; + +static void getPositionCallback(GeocluePosition* position, GeocluePositionFields fields, int timestamp, double latitude, double longitude, double altitude, GeoclueAccuracy* accuracy, GError* error, GeolocationProviderGeoclue* provider) +{ + if (error) { + provider->errorOccurred(error->message); + g_error_free(error); + return; + } + provider->positionChanged(position, fields, timestamp, latitude, longitude, altitude, accuracy); +} + +static void positionChangedCallback(GeocluePosition* position, GeocluePositionFields fields, int timestamp, double latitude, double longitude, double altitude, GeoclueAccuracy* accuracy, GeolocationProviderGeoclue* provider) +{ + provider->positionChanged(position, fields, timestamp, latitude, longitude, altitude, accuracy); +} + +static void createGeocluePositionCallback(GeoclueMasterClient*, GeocluePosition* position, GError *error, GeolocationProviderGeoclue* provider) +{ + if (error) { + provider->errorOccurred(error->message); + g_error_free(error); + return; + } + provider->initializeGeocluePosition(position); +} + +static void geoclueClientSetRequirementsCallback(GeoclueMasterClient* client, GError* error, GeolocationProviderGeoclue* provider) +{ + if (error) { + provider->errorOccurred(error->message); + g_error_free(error); + } +} + +static void createGeoclueClientCallback(GeoclueMaster*, GeoclueMasterClient* client, char*, GError* error, GeolocationProviderGeoclue* provider) +{ + if (error) { + provider->errorOccurred(error->message); + g_error_free(error); + return; + } + provider->initializeGeoclueClient(client); +} + +GeolocationProviderGeoclue::GeolocationProviderGeoclue(GeolocationProviderGeoclueClient* client) + : m_client(client) + , m_geoclueClient(0) + , m_geocluePosition(0) + , m_latitude(0) + , m_longitude(0) + , m_altitude(0) + , m_accuracy(0) + , m_altitudeAccuracy(0) + , m_timestamp(0) + , m_enableHighAccuracy(false) + , m_isUpdating(false) +{ + ASSERT(m_client); +} + +GeolocationProviderGeoclue::~GeolocationProviderGeoclue() +{ +} + +void GeolocationProviderGeoclue::startUpdating() +{ + ASSERT(!m_geoclueClient); + + GRefPtr<GeoclueMaster> master = adoptGRef(geoclue_master_get_default()); + geoclue_master_create_client_async(master.get(), reinterpret_cast<GeoclueCreateClientCallback>(createGeoclueClientCallback), this); + m_isUpdating = true; +} + +void GeolocationProviderGeoclue::stopUpdating() +{ + m_geocluePosition.clear(); + m_geoclueClient.clear(); + m_isUpdating = false; +} + +void GeolocationProviderGeoclue::setEnableHighAccuracy(bool enable) +{ + m_enableHighAccuracy = enable; + + // If we're already updating we should report the new requirements in order + // to change to a more suitable provider if needed. If not, return. + if (!m_isUpdating) + return; + + updateClientRequirements(); +} + +void GeolocationProviderGeoclue::initializeGeoclueClient(GeoclueMasterClient* geoclueClient) +{ + ASSERT(GEOCLUE_IS_MASTER_CLIENT(geoclueClient)); + + // Store the GeoclueMasterClient object as created by GeoClue. + m_geoclueClient = adoptGRef(geoclueClient); + + // Set the requirement for the client and ask it to create a position associated to it. + updateClientRequirements(); + geoclue_master_client_create_position_async(m_geoclueClient.get(), reinterpret_cast<CreatePositionCallback>(createGeocluePositionCallback), this); +} + +void GeolocationProviderGeoclue::initializeGeocluePosition(GeocluePosition* geocluePosition) +{ + ASSERT(GEOCLUE_IS_POSITION(geocluePosition)); + + // Stores the GeocluePosition object associated with the GeoclueMasterClient. + m_geocluePosition = adoptGRef(geocluePosition); + + // Get the initial position and keep updated of further changes. + geoclue_position_get_position_async(m_geocluePosition.get(), reinterpret_cast<GeocluePositionCallback>(getPositionCallback), this); + g_signal_connect(m_geocluePosition.get(), "position-changed", G_CALLBACK(positionChangedCallback), this); +} + +void GeolocationProviderGeoclue::updateClientRequirements() +{ + if (!m_geoclueClient) + return; + + GeoclueAccuracyLevel accuracyLevel = m_enableHighAccuracy ? GEOCLUE_ACCURACY_LEVEL_DETAILED : GEOCLUE_ACCURACY_LEVEL_LOCALITY; + geoclue_master_client_set_requirements_async(m_geoclueClient.get(), accuracyLevel, 0, false, GEOCLUE_RESOURCE_ALL, reinterpret_cast<GeoclueSetRequirementsCallback>(geoclueClientSetRequirementsCallback), this); +} + +void GeolocationProviderGeoclue::positionChanged(GeocluePosition* position, GeocluePositionFields fields, int timestamp, double latitude, double longitude, double altitude, GeoclueAccuracy* accuracy) +{ + if (!(fields & GEOCLUE_POSITION_FIELDS_LATITUDE && fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) { + errorOccurred("Position could not be determined."); + return; + } + + m_timestamp = timestamp; + m_latitude = latitude; + m_longitude = longitude; + m_altitude = altitude; + + geoclue_accuracy_get_details(accuracy, 0, &m_accuracy, &m_altitudeAccuracy); + + m_client->notifyPositionChanged(m_timestamp, m_latitude, m_longitude, m_altitude, m_accuracy, m_altitudeAccuracy); +} + +void GeolocationProviderGeoclue::errorOccurred(const char* message) +{ + m_client->notifyErrorOccurred(message); +} + +#endif // ENABLE(GEOLOCATION) diff --git a/Source/WebCore/platform/geoclue/GeolocationProviderGeoclue.h b/Source/WebCore/platform/geoclue/GeolocationProviderGeoclue.h new file mode 100644 index 000000000..4a77431a4 --- /dev/null +++ b/Source/WebCore/platform/geoclue/GeolocationProviderGeoclue.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * 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 library 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 library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef GeolocationProviderGeoclue_h +#define GeolocationProviderGeoclue_h + +#if ENABLE(GEOLOCATION) + +#include "GeolocationProviderGeoclueClient.h" +#include <geoclue/geoclue-master.h> +#include <geoclue/geoclue-position.h> +#include <wtf/gobject/GRefPtr.h> + +namespace WebCore { + +class GeolocationProviderGeoclue { +public: + GeolocationProviderGeoclue(GeolocationProviderGeoclueClient*); + ~GeolocationProviderGeoclue(); + + void startUpdating(); + void stopUpdating(); + void setEnableHighAccuracy(bool); + + // To be used from signal callbacks. + void initializeGeoclueClient(GeoclueMasterClient*); + void initializeGeocluePosition(GeocluePosition*); + void updateClientRequirements(); + void positionChanged(GeocluePosition*, GeocluePositionFields, int, double, double, double, GeoclueAccuracy*); + void errorOccurred(const char*); + +private: + GeolocationProviderGeoclueClient* m_client; + + GRefPtr<GeoclueMasterClient> m_geoclueClient; + GRefPtr<GeocluePosition> m_geocluePosition; + + double m_latitude; + double m_longitude; + double m_altitude; + double m_accuracy; + double m_altitudeAccuracy; + int m_timestamp; + + bool m_enableHighAccuracy; + bool m_isUpdating; +}; + +} // namespace WebCore + +#endif // ENABLE(GEOLOCATION) + +#endif // GeolocationProviderGeoclue_h diff --git a/Source/WebCore/platform/geoclue/GeolocationProviderGeoclueClient.h b/Source/WebCore/platform/geoclue/GeolocationProviderGeoclueClient.h new file mode 100644 index 000000000..ea69e255d --- /dev/null +++ b/Source/WebCore/platform/geoclue/GeolocationProviderGeoclueClient.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * 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 library 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 library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef GeolocationProviderGeoclueClient_h +#define GeolocationProviderGeoclueClient_h + +#if ENABLE(GEOLOCATION) + +namespace WebCore { + +class GeolocationProviderGeoclueClient { +public: + virtual void notifyPositionChanged(int timestamp, double latitude, double longitude, double altitude, double accuracy, double altitudeAccuracy) = 0; + virtual void notifyErrorOccurred(const char* message) = 0; +}; + +} // namespace WebCore + +#endif // ENABLE(GEOLOCATION) + +#endif // GeolocationProviderGeoclueClient_h diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp index 7a804b0a1..a78a747a6 100644 --- a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp @@ -6,6 +6,7 @@ * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org> * Copyright (C) 2010, 2011 Igalia S.L. * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2012, Intel Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -526,8 +527,16 @@ void GraphicsContext::clip(const FloatRect& rect) cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height()); cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING); + // The rectangular clip function is traditionally not expected to + // antialias. If we don't force antialiased clipping here, + // edge fringe artifacts may occur at the layer edges + // when a transformation is applied to the GraphicsContext + // while drawing the transformed layer. + cairo_antialias_t savedAntialiasRule = cairo_get_antialias(cr); + cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); cairo_clip(cr); cairo_set_fill_rule(cr, savedFillRule); + cairo_set_antialias(cr, savedAntialiasRule); m_data->clip(rect); } diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index 1de6e10f2..642a1a5c4 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -591,71 +591,51 @@ void GraphicsContext::strokePath(const Path& path) fillPathStroke(p, pathStroker, platformPath, pen.brush()); } -static inline void drawRepeatPattern(QPainter* p, QPixmap* image, const FloatRect& rect, const bool repeatX, const bool repeatY) +static inline void drawRepeatPattern(QPainter* p, PassRefPtr<Pattern> pattern, const FloatRect& rect) { + ASSERT(pattern); + + AffineTransform affine; + const QBrush brush = pattern->createPlatformPattern(affine); + if (brush.style() != Qt::TexturePattern) + return; + + const bool repeatX = pattern->repeatX(); + const bool repeatY = pattern->repeatY(); // Patterns must be painted so that the top left of the first image is anchored at // the origin of the coordinate space - if (image) { - int w = image->width(); - int h = image->height(); - int startX, startY; - QRect r(static_cast<int>(rect.x()), static_cast<int>(rect.y()), static_cast<int>(rect.width()), static_cast<int>(rect.height())); - - // startX, startY is the coordinate of the first image we need to put on the left-top of the rect - if (repeatX && repeatY) { - // repeat - // startX, startY is at the left top side of the left-top of the rect - startX = r.x() >=0 ? r.x() - (r.x() % w) : r.x() - (w - qAbs(r.x()) % w); - startY = r.y() >=0 ? r.y() - (r.y() % h) : r.y() - (h - qAbs(r.y()) % h); - } else { - if (!repeatX && !repeatY) { - // no-repeat - // only draw the image once at orgin once, check if need to draw - QRect imageRect(0, 0, w, h); - if (imageRect.intersects(r)) { - startX = 0; - startY = 0; - } else - return; - } else if (repeatX && !repeatY) { - // repeat-x - // startY is fixed, but startX change based on the left-top of the rect - QRect imageRect(r.x(), 0, r.width(), h); - if (imageRect.intersects(r)) { - startX = r.x() >=0 ? r.x() - (r.x() % w) : r.x() - (w - qAbs(r.x()) % w); - startY = 0; - } else - return; - } else { - // repeat-y - // startX is fixed, but startY change based on the left-top of the rect - QRect imageRect(0, r.y(), w, r.height()); - if (imageRect.intersects(r)) { - startX = 0; - startY = r.y() >=0 ? r.y() - (r.y() % h) : r.y() - (h - qAbs(r.y()) % h); - } else - return; - } - } - int x = startX; - int y = startY; - do { - // repeat Y - do { - // repeat X - QRect imageRect(x, y, w, h); - QRect intersectRect = imageRect.intersected(r); - QPoint destStart(intersectRect.x(), intersectRect.y()); - QRect sourceRect(intersectRect.x() - imageRect.x(), intersectRect.y() - imageRect.y(), intersectRect.width(), intersectRect.height()); - - p->drawPixmap(destStart, *image, sourceRect); - x += w; - } while (repeatX && x < r.x() + r.width()); - x = startX; - y += h; - } while (repeatY && y < r.y() + r.height()); + QRectF targetRect(rect); + const int w = brush.texture().width(); + const int h = brush.texture().height(); + + ASSERT(p); + QRegion oldClip; + if (p->hasClipping()) + oldClip = p->clipRegion(); + + // The only type of transforms supported for the brush are translations. + ASSERT(!brush.transform().isRotating()); + + QRectF clip = targetRect; + QRectF patternRect = brush.transform().mapRect(QRectF(0, 0, w, h)); + if (!repeatX) { + clip.setLeft(patternRect.left()); + clip.setWidth(patternRect.width()); } + if (!repeatY) { + clip.setTop(patternRect.top()); + clip.setHeight(patternRect.height()); + } + if (!repeatX || !repeatY) + p->setClipRect(clip); + + p->fillRect(targetRect, brush); + + if (!oldClip.isEmpty()) + p->setClipRegion(oldClip); + else if (!repeatX || !repeatY) + p->setClipping(false); } void GraphicsContext::fillRect(const FloatRect& rect) @@ -668,14 +648,13 @@ void GraphicsContext::fillRect(const FloatRect& rect) ShadowBlur* shadow = shadowBlur(); if (m_state.fillPattern) { - QPixmap* image = m_state.fillPattern->tileImage()->nativeImageForCurrentFrame(); GraphicsContext* shadowContext = hasShadow() ? shadow->beginShadowLayer(this, normalizedRect) : 0; if (shadowContext) { QPainter* shadowPainter = shadowContext->platformContext(); - drawRepeatPattern(shadowPainter, image, normalizedRect, m_state.fillPattern->repeatX(), m_state.fillPattern->repeatY()); + drawRepeatPattern(shadowPainter, m_state.fillPattern, normalizedRect); shadow->endShadowLayer(this); } - drawRepeatPattern(p, image, normalizedRect, m_state.fillPattern->repeatX(), m_state.fillPattern->repeatY()); + drawRepeatPattern(p, m_state.fillPattern, normalizedRect); } else if (m_state.fillGradient) { QBrush brush(*m_state.fillGradient->platformGradient()); brush.setTransform(m_state.fillGradient->gradientSpaceTransform()); diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp index 8877bfe34..0ea33600f 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp @@ -21,11 +21,51 @@ #include "TextureMapperBackingStore.h" #include "GraphicsLayer.h" +#include "GraphicsSurface.h" #include "ImageBuffer.h" #include "TextureMapper.h" +#if USE(GRAPHICS_SURFACE) +#include "TextureMapperGL.h" +#endif + namespace WebCore { +#if USE(GRAPHICS_SURFACE) +void TextureMapperSurfaceBackingStore::setGraphicsSurface(uint32_t graphicsSurfaceToken, const IntSize& surfaceSize) +{ + if (graphicsSurfaceToken != m_backBufferGraphicsSurfaceData.m_graphicsSurfaceToken) { + GraphicsSurface::Flags surfaceFlags = GraphicsSurface::SupportsTextureTarget + | GraphicsSurface::SupportsSharing; + m_backBufferGraphicsSurfaceData.setSurface(GraphicsSurface::create(surfaceSize, surfaceFlags, graphicsSurfaceToken)); + m_graphicsSurfaceSize = surfaceSize; + } + + std::swap(m_backBufferGraphicsSurfaceData, m_frontBufferGraphicsSurfaceData); +} + +PassRefPtr<BitmapTexture> TextureMapperSurfaceBackingStore::texture() const +{ + // FIXME: Instead of just returning an empty texture, we should wrap the texture contents into a BitmapTexture. + RefPtr<BitmapTexture> emptyTexture; + return emptyTexture; +} + +void TextureMapperSurfaceBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask) +{ + TransformationMatrix adjustedTransform = transform; + adjustedTransform.multiply(TransformationMatrix::rectToRect(FloatRect(FloatPoint::zero(), m_graphicsSurfaceSize), targetRect)); +#if OS(DARWIN) + // This is specific to the Mac implementation of GraphicsSurface. IOSurface requires GL_TEXTURE_RECTANGLE_ARB to be used. + static_cast<TextureMapperGL*>(textureMapper)->drawTextureRectangleARB(m_frontBufferGraphicsSurfaceData.m_textureID, 0, m_graphicsSurfaceSize, targetRect, adjustedTransform, opacity, mask); +#else + UNUSED_PARAM(textureMapper); + UNUSED_PARAM(opacity); + UNUSED_PARAM(mask); +#endif +} +#endif + void TextureMapperTile::updateContents(TextureMapper* textureMapper, Image* image, const IntRect& dirtyRect) { IntRect targetRect = enclosingIntRect(m_rect); diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h index 37a365036..691cc9ab3 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h @@ -21,6 +21,7 @@ #define TextureMapperBackingStore_h #include "FloatRect.h" +#include "GraphicsSurface.h" #include "Image.h" #include "TextureMapper.h" #include "TextureMapperPlatformLayer.h" @@ -38,6 +39,39 @@ public: virtual ~TextureMapperBackingStore() { } }; +#if USE(GRAPHICS_SURFACE) +struct GraphicsSurfaceData { + void setSurface(PassRefPtr<GraphicsSurface> surface) + { + m_graphicsSurface = surface; + m_graphicsSurfaceToken = m_graphicsSurface->exportToken(); + m_textureID = m_graphicsSurface->getTextureID(); + } + + GraphicsSurfaceData() + : m_textureID(0) + , m_graphicsSurfaceToken(0) + { } + + uint32_t m_textureID; + uint32_t m_graphicsSurfaceToken; + RefPtr<WebCore::GraphicsSurface> m_graphicsSurface; +}; + +class TextureMapperSurfaceBackingStore : public TextureMapperBackingStore { +public: + static PassRefPtr<TextureMapperSurfaceBackingStore> create() { return adoptRef(new TextureMapperSurfaceBackingStore); } + void setGraphicsSurface(uint32_t graphicsSurfaceToken, const IntSize& surfaceSize); + virtual PassRefPtr<BitmapTexture> texture() const; + virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float, BitmapTexture*); + virtual ~TextureMapperSurfaceBackingStore() { } +private: + IntSize m_graphicsSurfaceSize; + GraphicsSurfaceData m_frontBufferGraphicsSurfaceData; + GraphicsSurfaceData m_backBufferGraphicsSurfaceData; +}; +#endif + class TextureMapperTile { public: inline PassRefPtr<BitmapTexture> texture() const { return m_texture; } diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp index 660334a67..e27a6da62 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp @@ -21,6 +21,7 @@ #include "TextureMapperGL.h" #include "GraphicsContext.h" +#include "GraphicsSurface.h" #include "Image.h" #include "TextureMapperShaderManager.h" #include "Timer.h" @@ -366,6 +367,34 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const FloatRect& drawTexture(textureGL.id(), textureGL.isOpaque() ? 0 : SupportsBlending, textureGL.size(), targetRect, matrix, opacity, mask); } +void TextureMapperGL::drawTextureRectangleARB(uint32_t texture, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture) +{ + RefPtr<TextureMapperShaderProgram> shaderInfo; + if (maskTexture) + shaderInfo = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::RectOpacityAndMask); + else + shaderInfo = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::RectSimple); + GL_CMD(glUseProgram(shaderInfo->id())); + + GL_CMD(glEnableVertexAttribArray(shaderInfo->vertexAttrib())); + GL_CMD(glActiveTexture(GL_TEXTURE0)); + GL_CMD(glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture)); + GL_CMD(glUniform1i(shaderInfo->sourceTextureVariable(), 0)); + + const GLfloat m4src[] = { + targetRect.width(), 0, 0, 0, + 0, (flags & ShouldFlipTexture) ? -targetRect.height() : targetRect.height(), 0, 0, + 0, 0, 1, 0, + 0, (flags & ShouldFlipTexture) ? 1 : 0, 0, 1}; + + GL_CMD(glUniformMatrix4fv(shaderInfo->sourceMatrixVariable(), 1, GL_FALSE, m4src)); + + shaderInfo->prepare(opacity, maskTexture); + + bool needsBlending = (flags & SupportsBlending) || opacity < 0.99 || maskTexture; + drawRect(targetRect, modelViewMatrix, shaderInfo.get(), GL_TRIANGLE_FAN, needsBlending); +} + void TextureMapperGL::drawTexture(uint32_t texture, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture) { RefPtr<TextureMapperShaderProgram> shaderInfo; diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h index 627eae822..4d3ddeff1 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h @@ -52,6 +52,7 @@ public: virtual void drawBorder(const Color&, float borderWidth, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix = TransformationMatrix()) OVERRIDE; virtual void drawTexture(const BitmapTexture&, const FloatRect&, const TransformationMatrix&, float opacity, const BitmapTexture* maskTexture) OVERRIDE; virtual void drawTexture(uint32_t texture, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture); + virtual void drawTextureRectangleARB(uint32_t texture, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture); virtual void bindSurface(BitmapTexture* surface) OVERRIDE; virtual void beginClip(const TransformationMatrix&, const FloatRect&) OVERRIDE; virtual void beginPainting(PaintFlags = 0) OVERRIDE; diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp index 56fa74224..e8bfba1bf 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp @@ -55,6 +55,20 @@ static const char* fragmentShaderSourceOpacityAndMask = } ); +static const char* fragmentShaderSourceRectOpacityAndMask = + FRAGMENT_SHADER( + uniform sampler2DRect SourceTexture, MaskTexture; + uniform lowp float Opacity; + varying highp vec2 OutTexCoordSource, OutTexCoordMask; + void main(void) + { + lowp vec4 color = texture2DRect(SourceTexture, OutTexCoordSource); + lowp vec4 maskColor = texture2DRect(MaskTexture, OutTexCoordMask); + lowp float fragmentAlpha = Opacity * maskColor.a; + gl_FragColor = vec4(color.rgb * fragmentAlpha, color.a * fragmentAlpha); + } + ); + static const char* vertexShaderSourceOpacityAndMask = VERTEX_SHADER( uniform mat4 InMatrix, InSourceMatrix; @@ -80,6 +94,18 @@ static const char* fragmentShaderSourceSimple = } ); +static const char* fragmentShaderSourceRectSimple = + FRAGMENT_SHADER( + uniform sampler2DRect SourceTexture; + uniform lowp float Opacity; + varying highp vec2 OutTexCoordSource; + void main(void) + { + lowp vec4 color = texture2DRect(SourceTexture, OutTexCoordSource); + gl_FragColor = vec4(color.rgb * Opacity, color.a * Opacity); + } + ); + static const char* vertexShaderSourceSimple = VERTEX_SHADER( uniform mat4 InMatrix, InSourceMatrix; @@ -131,9 +157,15 @@ PassRefPtr<TextureMapperShaderProgram> TextureMapperShaderManager::getShaderProg case Simple: program = TextureMapperShaderProgramSimple::create(); break; + case RectSimple: + program = TextureMapperShaderProgramRectSimple::create(); + break; case OpacityAndMask: program = TextureMapperShaderProgramOpacityAndMask::create(); break; + case RectOpacityAndMask: + program = TextureMapperShaderProgramRectOpacityAndMask::create(); + break; case SolidColor: program = TextureMapperShaderProgramSolidColor::create(); break; @@ -186,10 +218,13 @@ TextureMapperShaderProgram::~TextureMapperShaderProgram() PassRefPtr<TextureMapperShaderProgramSimple> TextureMapperShaderProgramSimple::create() { - return adoptRef(new TextureMapperShaderProgramSimple()); + RefPtr<TextureMapperShaderProgramSimple> program = adoptRef(new TextureMapperShaderProgramSimple()); + // Avoid calling virtual functions in constructor. + program->initialize(); + return program.release(); } -TextureMapperShaderProgramSimple::TextureMapperShaderProgramSimple() +void TextureMapperShaderProgramSimple::initialize() { initializeProgram(); getUniformLocation(m_sourceMatrixVariable, "InSourceMatrix"); @@ -215,10 +250,13 @@ void TextureMapperShaderProgramSimple::prepare(float opacity, const BitmapTextur PassRefPtr<TextureMapperShaderProgramSolidColor> TextureMapperShaderProgramSolidColor::create() { - return adoptRef(new TextureMapperShaderProgramSolidColor()); + RefPtr<TextureMapperShaderProgramSolidColor> program = adoptRef(new TextureMapperShaderProgramSolidColor()); + // Avoid calling virtual functions in constructor. + program->initialize(); + return program.release(); } -TextureMapperShaderProgramSolidColor::TextureMapperShaderProgramSolidColor() +void TextureMapperShaderProgramSolidColor::initialize() { initializeProgram(); getUniformLocation(m_matrixVariable, "InMatrix"); @@ -235,12 +273,28 @@ const char* TextureMapperShaderProgramSolidColor::fragmentShaderSource() const return fragmentShaderSourceSolidColor; } +PassRefPtr<TextureMapperShaderProgramRectSimple> TextureMapperShaderProgramRectSimple::create() +{ + RefPtr<TextureMapperShaderProgramRectSimple> program = adoptRef(new TextureMapperShaderProgramRectSimple()); + // Avoid calling virtual functions in constructor. + program->initialize(); + return program.release(); +} + +const char* TextureMapperShaderProgramRectSimple::fragmentShaderSource() const +{ + return fragmentShaderSourceRectSimple; +} + PassRefPtr<TextureMapperShaderProgramOpacityAndMask> TextureMapperShaderProgramOpacityAndMask::create() { - return adoptRef(new TextureMapperShaderProgramOpacityAndMask()); + RefPtr<TextureMapperShaderProgramOpacityAndMask> program = adoptRef(new TextureMapperShaderProgramOpacityAndMask()); + // Avoid calling virtual functions in constructor. + program->initialize(); + return program.release(); } -TextureMapperShaderProgramOpacityAndMask::TextureMapperShaderProgramOpacityAndMask() +void TextureMapperShaderProgramOpacityAndMask::initialize() { initializeProgram(); getUniformLocation(m_matrixVariable, "InMatrix"); @@ -273,6 +327,19 @@ void TextureMapperShaderProgramOpacityAndMask::prepare(float opacity, const Bitm glActiveTexture(GL_TEXTURE0); } +PassRefPtr<TextureMapperShaderProgramRectOpacityAndMask> TextureMapperShaderProgramRectOpacityAndMask::create() +{ + RefPtr<TextureMapperShaderProgramRectOpacityAndMask> program = adoptRef(new TextureMapperShaderProgramRectOpacityAndMask()); + // Avoid calling virtual functions in constructor. + program->initialize(); + return program.release(); +} + +const char* TextureMapperShaderProgramRectOpacityAndMask::fragmentShaderSource() const +{ + return fragmentShaderSourceRectOpacityAndMask; +} + TextureMapperShaderManager::TextureMapperShaderManager() { ASSERT(initializeOpenGLShims()); diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h index 16221acda..681855c3b 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h @@ -56,6 +56,7 @@ public: protected: void getUniformLocation(GLint& var, const char* name); void initializeProgram(); + virtual void initialize() { } virtual const char* vertexShaderSource() const = 0; virtual const char* fragmentShaderSource() const = 0; @@ -103,10 +104,24 @@ public: static PassRefPtr<TextureMapperShaderProgramSimple> create(); virtual void prepare(float opacity, const BitmapTexture*); +protected: + virtual void initialize(); + private: virtual const char* vertexShaderSource() const; virtual const char* fragmentShaderSource() const; - TextureMapperShaderProgramSimple(); + TextureMapperShaderProgramSimple() { } + + friend class TextureMapperShaderProgramRectSimple; +}; + +class TextureMapperShaderProgramRectSimple : public TextureMapperShaderProgramSimple { +public: + static PassRefPtr<TextureMapperShaderProgramRectSimple> create(); + +private: + virtual const char* fragmentShaderSource() const; + TextureMapperShaderProgramRectSimple() { } }; class TextureMapperShaderProgramOpacityAndMask : public TextureMapperShaderProgram { @@ -115,12 +130,26 @@ public: virtual void prepare(float opacity, const BitmapTexture*); GLint maskTextureVariable() const { return m_maskTextureVariable; } +protected: + virtual void initialize(); + private: static int m_classID; virtual const char* vertexShaderSource() const; virtual const char* fragmentShaderSource() const; - TextureMapperShaderProgramOpacityAndMask(); + TextureMapperShaderProgramOpacityAndMask() { } GLint m_maskTextureVariable; + + friend class TextureMapperShaderProgramRectOpacityAndMask; +}; + +class TextureMapperShaderProgramRectOpacityAndMask : public TextureMapperShaderProgramOpacityAndMask { +public: + static PassRefPtr<TextureMapperShaderProgramRectOpacityAndMask> create(); + +private: + virtual const char* fragmentShaderSource() const; + TextureMapperShaderProgramRectOpacityAndMask() { } }; class TextureMapperShaderProgramSolidColor : public TextureMapperShaderProgram { @@ -128,21 +157,25 @@ public: static PassRefPtr<TextureMapperShaderProgramSolidColor> create(); GLint colorVariable() const { return m_colorVariable; } +protected: + virtual void initialize(); + private: virtual const char* vertexShaderSource() const; virtual const char* fragmentShaderSource() const; - TextureMapperShaderProgramSolidColor(); + TextureMapperShaderProgramSolidColor() { } GLint m_colorVariable; }; - class TextureMapperShaderManager { public: enum ShaderType { Invalid = 0, // HashMaps do not like 0 as a key. Simple, + RectSimple, OpacityAndMask, - SolidColor, + RectOpacityAndMask, + SolidColor }; TextureMapperShaderManager(); diff --git a/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp b/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp index bfb24140b..dbb7b74dd 100644 --- a/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp +++ b/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp @@ -49,8 +49,8 @@ QNetworkRequest ResourceRequest::toNetworkRequest(NetworkingContext *context) co const HTTPHeaderMap &headers = httpHeaderFields(); for (HTTPHeaderMap::const_iterator it = headers.begin(), end = headers.end(); it != end; ++it) { - QByteArray name = QString(it->first).toAscii(); - QByteArray value = QString(it->second).toAscii(); + QByteArray name = QString(it->first).toLatin1(); + QByteArray value = QString(it->second).toLatin1(); // QNetworkRequest::setRawHeader() would remove the header if the value is null // Make sure to set an empty header instead of null header. if (!value.isNull()) diff --git a/Source/WebCore/platform/text/qt/TextBreakIteratorInternalICUQt.cpp b/Source/WebCore/platform/text/qt/TextBreakIteratorInternalICUQt.cpp index f18fd370a..7945d45d0 100644 --- a/Source/WebCore/platform/text/qt/TextBreakIteratorInternalICUQt.cpp +++ b/Source/WebCore/platform/text/qt/TextBreakIteratorInternalICUQt.cpp @@ -27,7 +27,7 @@ namespace WebCore { -Q_GLOBAL_STATIC_WITH_INITIALIZER(QByteArray, cachedSystemLocale, {*x = QLocale::system().name().toLatin1();}) +Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, cachedSystemLocale, (QLocale::system().name().toLatin1())) const char* currentSearchLocaleID() { diff --git a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp index 7fae3c40f..d6165e092 100644 --- a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp +++ b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp @@ -150,6 +150,15 @@ static bool childDoesNotAffectWidthOrFlexing(RenderObject* child) return child->isPositioned() || child->style()->visibility() == COLLAPSE; } +void RenderDeprecatedFlexibleBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyle) +{ + RenderStyle* oldStyle = style(); + if (oldStyle && !oldStyle->lineClamp().isNone() && newStyle->lineClamp().isNone()) + clearLineClamp(); + + RenderBlock::styleWillChange(diff, newStyle); +} + void RenderDeprecatedFlexibleBox::calcHorizontalPrefWidths() { for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { @@ -975,6 +984,25 @@ void RenderDeprecatedFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool } } +void RenderDeprecatedFlexibleBox::clearLineClamp() +{ + FlexBoxIterator iterator(this); + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { + if (childDoesNotAffectWidthOrFlexing(child)) + continue; + + if ((child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())) + || (child->style()->height().isAuto() && child->isBlockFlow())) { + child->setChildNeedsLayout(true); + + if (child->isRenderBlock()) { + toRenderBlock(child)->markPositionedObjectsForLayout(); + toRenderBlock(child)->clearTruncation(); + } + } + } +} + void RenderDeprecatedFlexibleBox::placeChild(RenderBox* child, const LayoutPoint& location) { LayoutRect oldRect = child->frameRect(); diff --git a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.h b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.h index d0ca6fcbf..32f518199 100644 --- a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.h +++ b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.h @@ -40,6 +40,8 @@ public: void calcHorizontalPrefWidths(); void calcVerticalPrefWidths(); + virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle) OVERRIDE; + virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageHeight = 0); void layoutHorizontalBox(bool relayoutChildren); void layoutVerticalBox(bool relayoutChildren); @@ -64,6 +66,7 @@ protected: private: void applyLineClamp(FlexBoxIterator&, bool relayoutChildren); + void clearLineClamp(); }; } // namespace WebCore diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp index 51c37dd49..e62554062 100644 --- a/Source/WebCore/rendering/RenderFlexibleBox.cpp +++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp @@ -42,21 +42,21 @@ namespace WebCore { // Normally, -1 and 0 are not valid in a HashSet, but these are relatively likely flex-order values. Instead, // we make the two smallest int values invalid flex-order values (in the css parser code we clamp them to // int min + 2). -struct RenderFlexibleBox::FlexOrderHashTraits : WTF::GenericHashTraits<int> { +struct RenderFlexibleBox::OrderHashTraits : WTF::GenericHashTraits<int> { static const bool emptyValueIsZero = false; static int emptyValue() { return std::numeric_limits<int>::min(); } static void constructDeletedValue(int& slot) { slot = std::numeric_limits<int>::min() + 1; } static bool isDeletedValue(int value) { return value == std::numeric_limits<int>::min() + 1; } }; -class RenderFlexibleBox::FlexOrderIterator { +class RenderFlexibleBox::OrderIterator { public: - FlexOrderIterator(RenderFlexibleBox* flexibleBox, const FlexOrderHashSet& flexOrderValues) + OrderIterator(RenderFlexibleBox* flexibleBox, const OrderHashSet& orderValues) : m_flexibleBox(flexibleBox) , m_currentChild(0) , m_orderValuesIterator(0) { - copyToVector(flexOrderValues, m_orderValues); + copyToVector(orderValues, m_orderValues); std::sort(m_orderValues.begin(), m_orderValues.end()); first(); } @@ -85,7 +85,7 @@ public: m_currentChild = m_flexibleBox->firstChildBox(); } else m_currentChild = m_currentChild->nextSiblingBox(); - } while (!m_currentChild || m_currentChild->style()->flexOrder() != *m_orderValuesIterator); + } while (!m_currentChild || m_currentChild->style()->order() != *m_orderValuesIterator); return m_currentChild; } @@ -264,9 +264,9 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit) } WTF::Vector<LineContext> lineContexts; - FlexOrderHashSet flexOrderValues; - computeMainAxisPreferredSizes(relayoutChildren, flexOrderValues); - FlexOrderIterator flexIterator(this, flexOrderValues); + OrderHashSet orderValues; + computeMainAxisPreferredSizes(relayoutChildren, orderValues); + OrderIterator flexIterator(this, orderValues); layoutFlexItems(flexIterator, lineContexts); LayoutUnit oldClientAfterEdge = clientLogicalBottom(); @@ -296,7 +296,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit) setNeedsLayout(false); } -void RenderFlexibleBox::repositionLogicalHeightDependentFlexItems(FlexOrderIterator& iterator, WTF::Vector<LineContext>& lineContexts, LayoutUnit& oldClientAfterEdge) +void RenderFlexibleBox::repositionLogicalHeightDependentFlexItems(OrderIterator& iterator, WTF::Vector<LineContext>& lineContexts, LayoutUnit& oldClientAfterEdge) { LayoutUnit crossAxisStartEdge = lineContexts.isEmpty() ? ZERO_LAYOUT_UNIT : lineContexts[0].crossAxisOffset; packFlexLines(iterator, lineContexts); @@ -620,7 +620,7 @@ LayoutUnit RenderFlexibleBox::computeAvailableFreeSpace(LayoutUnit preferredMain return contentExtent - preferredMainAxisExtent; } -void RenderFlexibleBox::layoutFlexItems(FlexOrderIterator& iterator, WTF::Vector<LineContext>& lineContexts) +void RenderFlexibleBox::layoutFlexItems(OrderIterator& iterator, WTF::Vector<LineContext>& lineContexts) { OrderedFlexItemList orderedChildren; LayoutUnit preferredMainAxisExtent; @@ -746,12 +746,12 @@ LayoutUnit RenderFlexibleBox::marginBoxAscentForChild(RenderBox* child) return ascent + flowAwareMarginBeforeForChild(child); } -void RenderFlexibleBox::computeMainAxisPreferredSizes(bool relayoutChildren, FlexOrderHashSet& flexOrderValues) +void RenderFlexibleBox::computeMainAxisPreferredSizes(bool relayoutChildren, OrderHashSet& orderValues) { LayoutUnit flexboxAvailableContentExtent = mainAxisContentExtent(); RenderView* renderView = view(); for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { - flexOrderValues.add(child->style()->flexOrder()); + orderValues.add(child->style()->order()); if (child->isPositioned()) continue; @@ -804,7 +804,7 @@ LayoutUnit RenderFlexibleBox::adjustChildSizeForMinAndMax(RenderBox* child, Layo return childSize; } -bool RenderFlexibleBox::computeNextFlexLine(FlexOrderIterator& iterator, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, LayoutUnit& minMaxAppliedMainAxisExtent) +bool RenderFlexibleBox::computeNextFlexLine(OrderIterator& iterator, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, LayoutUnit& minMaxAppliedMainAxisExtent) { orderedChildren.clear(); preferredMainAxisExtent = 0; @@ -1094,7 +1094,7 @@ static LayoutUnit linePackingSpaceBetweenChildren(LayoutUnit availableFreeSpace, return 0; } -void RenderFlexibleBox::packFlexLines(FlexOrderIterator& iterator, WTF::Vector<LineContext>& lineContexts) +void RenderFlexibleBox::packFlexLines(OrderIterator& iterator, WTF::Vector<LineContext>& lineContexts) { if (!isMultiline() || style()->flexLinePack() == LinePackStart) return; @@ -1139,7 +1139,7 @@ void RenderFlexibleBox::adjustAlignmentForChild(RenderBox* child, LayoutUnit del child->repaintDuringLayoutIfMoved(oldRect); } -void RenderFlexibleBox::alignChildren(FlexOrderIterator& iterator, const WTF::Vector<LineContext>& lineContexts) +void RenderFlexibleBox::alignChildren(OrderIterator& iterator, const WTF::Vector<LineContext>& lineContexts) { // Keep track of the space between the baseline edge and the after edge of the box for each line. WTF::Vector<LayoutUnit> minMarginAfterBaselines; @@ -1231,7 +1231,7 @@ void RenderFlexibleBox::applyStretchAlignmentToChild(RenderBox* child, LayoutUni } } -void RenderFlexibleBox::flipForRightToLeftColumn(FlexOrderIterator& iterator) +void RenderFlexibleBox::flipForRightToLeftColumn(OrderIterator& iterator) { if (style()->isLeftToRightDirection() || !isColumnFlow()) return; @@ -1246,7 +1246,7 @@ void RenderFlexibleBox::flipForRightToLeftColumn(FlexOrderIterator& iterator) } } -void RenderFlexibleBox::flipForWrapReverse(FlexOrderIterator& iterator, const WTF::Vector<LineContext>& lineContexts, LayoutUnit crossAxisStartEdge) +void RenderFlexibleBox::flipForWrapReverse(OrderIterator& iterator, const WTF::Vector<LineContext>& lineContexts, LayoutUnit crossAxisStartEdge) { LayoutUnit contentExtent = crossAxisContentExtent(); RenderBox* child = iterator.first(); diff --git a/Source/WebCore/rendering/RenderFlexibleBox.h b/Source/WebCore/rendering/RenderFlexibleBox.h index d923a53a9..fd469d328 100644 --- a/Source/WebCore/rendering/RenderFlexibleBox.h +++ b/Source/WebCore/rendering/RenderFlexibleBox.h @@ -59,10 +59,10 @@ private: NoFlipForRowReverse, }; - struct FlexOrderHashTraits; - typedef HashSet<int, DefaultHash<int>::Hash, FlexOrderHashTraits> FlexOrderHashSet; + struct OrderHashTraits; + typedef HashSet<int, DefaultHash<int>::Hash, OrderHashTraits> OrderHashSet; - class FlexOrderIterator; + class OrderIterator; typedef WTF::HashMap<const RenderBox*, LayoutUnit> InflexibleFlexItemSize; typedef WTF::Vector<RenderBox*> OrderedFlexItemList; @@ -105,20 +105,20 @@ private: LayoutUnit mainAxisScrollbarExtentForChild(RenderBox* child) const; LayoutUnit preferredMainAxisContentExtentForChild(RenderBox* child) const; - void layoutFlexItems(FlexOrderIterator&, WTF::Vector<LineContext>&); + void layoutFlexItems(OrderIterator&, WTF::Vector<LineContext>&); LayoutUnit autoMarginOffsetInMainAxis(const OrderedFlexItemList&, LayoutUnit& availableFreeSpace); void updateAutoMarginsInMainAxis(RenderBox* child, LayoutUnit autoMarginOffset); bool hasAutoMarginsInCrossAxis(RenderBox* child); bool updateAutoMarginsInCrossAxis(RenderBox* child, LayoutUnit availableAlignmentSpace); - void repositionLogicalHeightDependentFlexItems(FlexOrderIterator&, WTF::Vector<LineContext>&, LayoutUnit& oldClientAfterEdge); + void repositionLogicalHeightDependentFlexItems(OrderIterator&, WTF::Vector<LineContext>&, LayoutUnit& oldClientAfterEdge); LayoutUnit availableAlignmentSpaceForChild(LayoutUnit lineCrossAxisExtent, RenderBox*); LayoutUnit marginBoxAscentForChild(RenderBox*); - void computeMainAxisPreferredSizes(bool relayoutChildren, FlexOrderHashSet&); + void computeMainAxisPreferredSizes(bool relayoutChildren, OrderHashSet&); LayoutUnit lineBreakLength(); LayoutUnit adjustChildSizeForMinAndMax(RenderBox*, LayoutUnit childSize, LayoutUnit flexboxAvailableContentExtent); - bool computeNextFlexLine(FlexOrderIterator&, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, LayoutUnit& minMaxAppliedMainAxisExtent); + bool computeNextFlexLine(OrderIterator&, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, LayoutUnit& minMaxAppliedMainAxisExtent); LayoutUnit computeAvailableFreeSpace(LayoutUnit preferredMainAxisExtent); bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes); @@ -128,11 +128,11 @@ private: void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset, PositionedLayoutMode); void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, WTF::Vector<LineContext>&); void layoutColumnReverse(const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit crossAxisOffset, LayoutUnit availableFreeSpace); - void packFlexLines(FlexOrderIterator&, WTF::Vector<LineContext>&); - void alignChildren(FlexOrderIterator&, const WTF::Vector<LineContext>&); + void packFlexLines(OrderIterator&, WTF::Vector<LineContext>&); + void alignChildren(OrderIterator&, const WTF::Vector<LineContext>&); void applyStretchAlignmentToChild(RenderBox*, LayoutUnit lineCrossAxisExtent); - void flipForRightToLeftColumn(FlexOrderIterator&); - void flipForWrapReverse(FlexOrderIterator&, const WTF::Vector<LineContext>&, LayoutUnit crossAxisStartEdge); + void flipForRightToLeftColumn(OrderIterator&); + void flipForWrapReverse(OrderIterator&, const WTF::Vector<LineContext>&, LayoutUnit crossAxisStartEdge); }; } // namespace WebCore diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h index 3e68594e0..7b1127677 100644 --- a/Source/WebCore/rendering/style/RenderStyle.h +++ b/Source/WebCore/rendering/style/RenderStyle.h @@ -804,10 +804,10 @@ public: EBoxOrient boxOrient() const { return static_cast<EBoxOrient>(rareNonInheritedData->m_deprecatedFlexibleBox->orient); } EBoxPack boxPack() const { return static_cast<EBoxPack>(rareNonInheritedData->m_deprecatedFlexibleBox->pack); } + int order() const { return rareNonInheritedData->m_order; } float positiveFlex() const { return rareNonInheritedData->m_flexibleBox->m_positiveFlex; } float negativeFlex() const { return rareNonInheritedData->m_flexibleBox->m_negativeFlex; } Length flexPreferredSize() const { return rareNonInheritedData->m_flexibleBox->m_preferredSize; } - int flexOrder() const { return rareNonInheritedData->m_flexibleBox->m_flexOrder; } EFlexPack flexPack() const { return static_cast<EFlexPack>(rareNonInheritedData->m_flexibleBox->m_flexPack); } EAlignItems alignItems() const { return static_cast<EAlignItems>(rareNonInheritedData->m_alignItems); } EAlignItems alignSelf() const { return static_cast<EAlignItems>(rareNonInheritedData->m_alignSelf); } @@ -1249,7 +1249,7 @@ public: void setPositiveFlex(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_positiveFlex, f); } void setNegativeFlex(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_negativeFlex, f); } void setFlexPreferredSize(Length l) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_preferredSize, l); } - void setFlexOrder(int o) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexOrder, o); } + void setOrder(int o) { SET_VAR(rareNonInheritedData, m_order, o); } void setFlexPack(EFlexPack p) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexPack, p); } void setAlignItems(EAlignItems a) { SET_VAR(rareNonInheritedData, m_alignItems, a); } void setAlignSelf(EAlignItems a) { SET_VAR(rareNonInheritedData, m_alignSelf, a); } @@ -1583,7 +1583,7 @@ public: static float initialPositiveFlex() { return 1; } static float initialNegativeFlex() { return 1; } static Length initialFlexPreferredSize() { return Length(Auto); } - static int initialFlexOrder() { return 0; } + static int initialOrder() { return 0; } static EFlexPack initialFlexPack() { return PackStart; } static EAlignItems initialAlignItems() { return AlignStretch; } static EAlignItems initialAlignSelf() { return AlignAuto; } diff --git a/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp b/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp index cfe528bd9..53d7270cb 100644 --- a/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp +++ b/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp @@ -34,7 +34,6 @@ StyleFlexibleBoxData::StyleFlexibleBoxData() : m_positiveFlex(RenderStyle::initialPositiveFlex()) , m_negativeFlex(RenderStyle::initialNegativeFlex()) , m_preferredSize(RenderStyle::initialFlexPreferredSize()) - , m_flexOrder(RenderStyle::initialFlexOrder()) , m_flexPack(RenderStyle::initialFlexPack()) , m_flexDirection(RenderStyle::initialFlexDirection()) , m_flexWrap(RenderStyle::initialFlexWrap()) @@ -47,7 +46,6 @@ StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& o) , m_positiveFlex(o.m_positiveFlex) , m_negativeFlex(o.m_negativeFlex) , m_preferredSize(o.m_preferredSize) - , m_flexOrder(o.m_flexOrder) , m_flexPack(o.m_flexPack) , m_flexDirection(o.m_flexDirection) , m_flexWrap(o.m_flexWrap) @@ -58,7 +56,7 @@ StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& o) bool StyleFlexibleBoxData::operator==(const StyleFlexibleBoxData& o) const { return m_positiveFlex == o.m_positiveFlex && m_negativeFlex == o.m_negativeFlex && m_preferredSize == o.m_preferredSize - && m_flexOrder == o.m_flexOrder && m_flexPack == o.m_flexPack && m_flexDirection == o.m_flexDirection + && m_flexPack == o.m_flexPack && m_flexDirection == o.m_flexDirection && m_flexWrap == o.m_flexWrap && m_flexLinePack == o.m_flexLinePack; } diff --git a/Source/WebCore/rendering/style/StyleFlexibleBoxData.h b/Source/WebCore/rendering/style/StyleFlexibleBoxData.h index 46c08806e..5eab784dc 100644 --- a/Source/WebCore/rendering/style/StyleFlexibleBoxData.h +++ b/Source/WebCore/rendering/style/StyleFlexibleBoxData.h @@ -48,8 +48,6 @@ public: float m_negativeFlex; Length m_preferredSize; - int m_flexOrder; - unsigned m_flexPack : 3; // EFlexPack unsigned m_flexDirection : 2; // EFlexDirection unsigned m_flexWrap : 2; // EFlexWrap diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp index 28c79f30a..b4c045619 100644 --- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp +++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp @@ -50,6 +50,7 @@ StyleRareNonInheritedData::StyleRareNonInheritedData() , m_wrapMargin(RenderStyle::initialWrapMargin()) , m_wrapPadding(RenderStyle::initialWrapPadding()) , m_visitedLinkBackgroundColor(RenderStyle::initialBackgroundColor()) + , m_order(RenderStyle::initialOrder()) , m_flowThread(RenderStyle::initialFlowThread()) , m_regionThread(RenderStyle::initialRegionThread()) , m_regionOverflow(RenderStyle::initialRegionOverflow()) @@ -119,6 +120,7 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited , m_visitedLinkBorderRightColor(o.m_visitedLinkBorderRightColor) , m_visitedLinkBorderTopColor(o.m_visitedLinkBorderTopColor) , m_visitedLinkBorderBottomColor(o.m_visitedLinkBorderBottomColor) + , m_order(o.m_order) , m_flowThread(o.m_flowThread) , m_regionThread(o.m_regionThread) , m_regionOverflow(o.m_regionOverflow) @@ -194,6 +196,7 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c && m_visitedLinkBorderRightColor == o.m_visitedLinkBorderRightColor && m_visitedLinkBorderTopColor == o.m_visitedLinkBorderTopColor && m_visitedLinkBorderBottomColor == o.m_visitedLinkBorderBottomColor + && m_order == o.m_order && m_flowThread == o.m_flowThread && m_regionThread == o.m_regionThread && m_regionOverflow == o.m_regionOverflow diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h index 7b801d28d..494bb8d20 100644 --- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h +++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h @@ -146,6 +146,8 @@ public: Color m_visitedLinkBorderTopColor; Color m_visitedLinkBorderBottomColor; + int m_order; + AtomicString m_flowThread; AtomicString m_regionThread; unsigned m_regionOverflow : 1; // RegionOverflow diff --git a/Source/WebCore/rendering/svg/SVGResourcesCache.cpp b/Source/WebCore/rendering/svg/SVGResourcesCache.cpp index 87531ed3e..297c07b6a 100644 --- a/Source/WebCore/rendering/svg/SVGResourcesCache.cpp +++ b/Source/WebCore/rendering/svg/SVGResourcesCache.cpp @@ -154,6 +154,10 @@ static inline bool rendererCanHaveResources(RenderObject* renderer) void SVGResourcesCache::clientWasAddedToTree(RenderObject* renderer, const RenderStyle* newStyle) { + if (!renderer->node()) + return; + RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false); + if (!rendererCanHaveResources(renderer)) return; SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer); @@ -162,12 +166,14 @@ void SVGResourcesCache::clientWasAddedToTree(RenderObject* renderer, const Rende void SVGResourcesCache::clientWillBeRemovedFromTree(RenderObject* renderer) { + if (!renderer->node()) + return; + RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false); + if (!rendererCanHaveResources(renderer)) return; SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer); cache->removeResourcesFromRenderObject(renderer); - - RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false); } void SVGResourcesCache::clientDestroyed(RenderObject* renderer) diff --git a/Source/WebKit/CMakeLists.txt b/Source/WebKit/CMakeLists.txt index 57e0f00d3..f0ef98adf 100644 --- a/Source/WebKit/CMakeLists.txt +++ b/Source/WebKit/CMakeLists.txt @@ -11,6 +11,7 @@ SET(WebKit_INCLUDE_DIRECTORIES "${WEBCORE_DIR}/bridge/jsc" "${WEBCORE_DIR}/css" "${WEBCORE_DIR}/dom" + "${WEBCORE_DIR}/dom/default" "${WEBCORE_DIR}/editing" "${WEBCORE_DIR}/history" "${WEBCORE_DIR}/html" diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog index ae67e33ef..dba2b2546 100644 --- a/Source/WebKit/ChangeLog +++ b/Source/WebKit/ChangeLog @@ -1,3 +1,25 @@ +2012-06-01 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] EFL's LayoutTestController needs to implement deliverWebIntent + https://bugs.webkit.org/show_bug.cgi?id=86865 + + Reviewed by Adam Barth. + + Add "${WEBCORE_DIR}/dom/default" to include directories in + CMakeLists.txt. + + * CMakeLists.txt: + +2012-06-01 Sudarsana Nagineni <sudarsana.nagineni@linux.intel.com> + + [EFL] Implement PlatformStrategies + https://bugs.webkit.org/show_bug.cgi?id=86946 + + Reviewed by Carlos Garcia Campos. + + * PlatformEfl.cmake: Add PlatformStrategiesEfl file to the build + system. + 2012-05-31 Gyuyoung Kim <gyuyoung.kim@samsung.com> [CMAKE][EFL] Remove unneeded include path diff --git a/Source/WebKit/PlatformEfl.cmake b/Source/WebKit/PlatformEfl.cmake index 54663cd47..7d929efe4 100644 --- a/Source/WebKit/PlatformEfl.cmake +++ b/Source/WebKit/PlatformEfl.cmake @@ -98,6 +98,7 @@ LIST(APPEND WebKit_SOURCES efl/WebCoreSupport/InspectorClientEfl.cpp efl/WebCoreSupport/NotificationPresenterClientEfl.cpp efl/WebCoreSupport/PageClientEfl.cpp + efl/WebCoreSupport/PlatformStrategiesEfl.cpp efl/ewk/ewk_auth.cpp efl/ewk/ewk_auth_soup.cpp diff --git a/Source/WebKit/blackberry/Api/BackingStore.cpp b/Source/WebKit/blackberry/Api/BackingStore.cpp index 619c43968..ebae02db8 100644 --- a/Source/WebKit/blackberry/Api/BackingStore.cpp +++ b/Source/WebKit/blackberry/Api/BackingStore.cpp @@ -300,8 +300,17 @@ void BackingStorePrivate::resumeScreenAndBackingStoreUpdates(BackingStore::Resum m_suspendBackingStoreUpdates = false; #if USE(ACCELERATED_COMPOSITING) - if (op != BackingStore::None) + if (op != BackingStore::None) { + if (isOpenGLCompositing() && !isActive()) { + m_webPage->d->setCompositorDrawsRootLayer(true); + m_webPage->d->setNeedsOneShotDrawingSynchronization(); + m_suspendScreenUpdates = false; + BlackBerry::Platform::userInterfaceThreadMessageClient()->syncToCurrentMessage(); + return; + } + m_webPage->d->setNeedsOneShotDrawingSynchronization(); + } #endif // For the direct rendering case, there is no such operation as blit, diff --git a/Source/WebKit/blackberry/Api/WebPage.cpp b/Source/WebKit/blackberry/Api/WebPage.cpp index c9a6c5bf9..6975c9c2e 100644 --- a/Source/WebKit/blackberry/Api/WebPage.cpp +++ b/Source/WebKit/blackberry/Api/WebPage.cpp @@ -2181,6 +2181,11 @@ void WebPagePrivate::notifyPopupAutofillDialog(const Vector<String>& candidates, m_client->notifyPopupAutofillDialog(textItems, screenRect); } +void WebPagePrivate::notifyDismissAutofillDialog() +{ + m_client->notifyDismissAutofillDialog(); +} + bool WebPagePrivate::useFixedLayout() const { return true; diff --git a/Source/WebKit/blackberry/Api/WebPageClient.h b/Source/WebKit/blackberry/Api/WebPageClient.h index 8ee102852..6dfd17473 100644 --- a/Source/WebKit/blackberry/Api/WebPageClient.h +++ b/Source/WebKit/blackberry/Api/WebPageClient.h @@ -210,6 +210,7 @@ public: virtual bool authenticationChallenge(const unsigned short* realm, unsigned int realmLength, WebString& username, WebString& password) = 0; virtual SaveCredentialType notifyShouldSaveCredential(bool isNew) = 0; virtual void notifyPopupAutofillDialog(const std::vector<std::string>&, const Platform::IntRect&) = 0; + virtual void notifyDismissAutofillDialog() = 0; virtual bool shouldPluginEnterFullScreen() = 0; virtual void didPluginEnterFullScreen() = 0; diff --git a/Source/WebKit/blackberry/Api/WebPage_p.h b/Source/WebKit/blackberry/Api/WebPage_p.h index 309bf5323..ef46c7052 100644 --- a/Source/WebKit/blackberry/Api/WebPage_p.h +++ b/Source/WebKit/blackberry/Api/WebPage_p.h @@ -202,6 +202,7 @@ public: void layoutFinished(); void setNeedTouchEvents(bool); void notifyPopupAutofillDialog(const Vector<String>&, const WebCore::IntRect&); + void notifyDismissAutofillDialog(); // Called according to our heuristic or from setLoadState depending on whether we have a virtual viewport. void zoomToInitialScaleOnLoad(); diff --git a/Source/WebKit/blackberry/ChangeLog b/Source/WebKit/blackberry/ChangeLog index 4af41fcb1..70e42b010 100644 --- a/Source/WebKit/blackberry/ChangeLog +++ b/Source/WebKit/blackberry/ChangeLog @@ -1,3 +1,57 @@ +2012-06-01 Jonathan Dong <jonathan.dong@torchmobile.com.cn> + + [BlackBerry] Add end editing handling into AutofillManager + https://bugs.webkit.org/show_bug.cgi?id=88071 + + Reviewed by Rob Buis. + + RIM PR: 160857 + Implemented EditorClientBlackBerry::textFieldDidEndEditing + to notify AutofillManager to send the dismissing autofill + dialog notification to webpage client. + + No new tests since there is no behavior changes. + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::notifyDismissAutofillDialog): + (WebKit): + * Api/WebPageClient.h: + * Api/WebPage_p.h: + (WebPagePrivate): + * WebCoreSupport/AutofillManager.cpp: + (WebCore::AutofillManager::textFieldDidEndEditing): + (WebCore): + * WebCoreSupport/AutofillManager.h: + (AutofillManager): + * WebCoreSupport/EditorClientBlackBerry.cpp: + (WebCore::EditorClientBlackBerry::textFieldDidEndEditing): + +2012-05-31 Jacky Jiang <zhajiang@rim.com> + + [BlackBerry] Bridge Apps - Apps do not redraw correctly after orientation change + https://bugs.webkit.org/show_bug.cgi?id=88033 + + Reviewed by Rob Buis. + Patch by Jacky Jiang <zhajiang@rim.com> + + PR: 142961 + When bridge apps were in carousel mode, the backing store was inactive + as its memory had been released. When we rotated the device, we would + call WebPagPrivate:setViewportSize and resume screen and backing store + to render and blit visible contents. As backing store was inactive and + the window usage was GLES2Usage, we were neither doing backing store + rendering nor direct rendering. Therefore, we drew layers directly + based on the invalid texture contents when blitting contents if + accelerated compositing was enabled. + This patch forces compositing mode to let the accelerated compositing + layer take care of the rendering which can update texture contents + before drawing when backing store is inactive and is openGL compositing. + + Reviewed internally by George Staikos and Arvid Nilsson. + + * Api/BackingStore.cpp: + (BlackBerry::WebKit::BackingStorePrivate::resumeScreenAndBackingStoreUpdates): + 2012-05-31 Hajime Morrita <morrita@chromium.org> REGRESSION(r117572): editing/spelling/spellcheck-async-remove-frame.html crashes on Mac diff --git a/Source/WebKit/blackberry/WebCoreSupport/AutofillManager.cpp b/Source/WebKit/blackberry/WebCoreSupport/AutofillManager.cpp index e3fc27d32..44a05f2f4 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/AutofillManager.cpp +++ b/Source/WebKit/blackberry/WebCoreSupport/AutofillManager.cpp @@ -51,6 +51,11 @@ void AutofillManager::didChangeInTextField(HTMLInputElement* element) m_webPagePrivate->notifyPopupAutofillDialog(candidates, element->screenRect()); } +void AutofillManager::textFieldDidEndEditing(HTMLInputElement*) +{ + m_webPagePrivate->notifyDismissAutofillDialog(); +} + void AutofillManager::autofillTextField(const String& value) { if (!m_element) diff --git a/Source/WebKit/blackberry/WebCoreSupport/AutofillManager.h b/Source/WebKit/blackberry/WebCoreSupport/AutofillManager.h index 397f17f65..53b637a9d 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/AutofillManager.h +++ b/Source/WebKit/blackberry/WebCoreSupport/AutofillManager.h @@ -41,6 +41,7 @@ public: static PassRefPtr<AutofillManager> create(BlackBerry::WebKit::WebPagePrivate*); void didChangeInTextField(HTMLInputElement*); + void textFieldDidEndEditing(HTMLInputElement*); void autofillTextField(const WTF::String&); void saveTextFields(HTMLFormElement*); diff --git a/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.cpp b/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.cpp index d1ed4f4df..7c03e0841 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.cpp +++ b/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.cpp @@ -507,9 +507,10 @@ void EditorClientBlackBerry::textFieldDidBeginEditing(Element*) notImplemented(); } -void EditorClientBlackBerry::textFieldDidEndEditing(Element*) +void EditorClientBlackBerry::textFieldDidEndEditing(Element* element) { - notImplemented(); + if (HTMLInputElement* inputElement = element->toInputElement()) + m_webPagePrivate->m_autofillManager->textFieldDidEndEditing(inputElement); } void EditorClientBlackBerry::textDidChangeInTextField(Element* element) diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog index 09ed0651b..994e3e675 100644 --- a/Source/WebKit/chromium/ChangeLog +++ b/Source/WebKit/chromium/ChangeLog @@ -1,3 +1,32 @@ +2012-06-01 Mark Pilgrim <pilgrim@chromium.org> + + [Chromium] Call clipboard methods directly + https://bugs.webkit.org/show_bug.cgi?id=88038 + + Reviewed by Adam Barth. + + Part of a refactoring series. See tracking bug 82948. + + * src/AssertMatchingEnums.cpp: + * src/PlatformSupport.cpp: + (WebCore::getCookieJar): + +2012-06-01 Peter Beverloo <peter@chromium.org> + + Unreviewed. Rolled DEPS. + + * DEPS: + +2012-06-01 Yoshifumi Inoue <yosin@chromium.org> + + [Platform][Decimal] UInt128::operator/= calls makeUInt128 with wrong argument order + https://bugs.webkit.org/show_bug.cgi?id=88044 + + Reviewed by Kent Tamura. + + * tests/DecimalTest.cpp: + (TEST_F): Add a new test for multiplication. + 2012-05-31 Hajime Morrita <morrita@chromium.org> REGRESSION(r117572): editing/spelling/spellcheck-async-remove-frame.html crashes on Mac diff --git a/Source/WebKit/chromium/DEPS b/Source/WebKit/chromium/DEPS index 67371f99f..31b09c2f9 100644 --- a/Source/WebKit/chromium/DEPS +++ b/Source/WebKit/chromium/DEPS @@ -32,7 +32,7 @@ vars = { 'chromium_svn': 'http://src.chromium.org/svn/trunk/src', - 'chromium_rev': '139747' + 'chromium_rev': '140000' } deps = { diff --git a/Source/WebKit/chromium/src/AssertMatchingEnums.cpp b/Source/WebKit/chromium/src/AssertMatchingEnums.cpp index 94985b20c..c323d10ab 100644 --- a/Source/WebKit/chromium/src/AssertMatchingEnums.cpp +++ b/Source/WebKit/chromium/src/AssertMatchingEnums.cpp @@ -59,7 +59,6 @@ #include "MediaStreamSource.h" #include "NotificationClient.h" #include "PageVisibilityState.h" -#include "PasteboardPrivate.h" #include "PeerConnection00.h" #include "PlatformCursor.h" #include "ReferrerPolicy.h" @@ -268,14 +267,6 @@ COMPILE_ASSERT_MATCHING_ENUM(WebApplicationCacheHost::UpdateReadyEvent, Applicat COMPILE_ASSERT_MATCHING_ENUM(WebApplicationCacheHost::CachedEvent, ApplicationCacheHost::CACHED_EVENT); COMPILE_ASSERT_MATCHING_ENUM(WebApplicationCacheHost::ObsoleteEvent, ApplicationCacheHost::OBSOLETE_EVENT); -COMPILE_ASSERT_MATCHING_ENUM(WebClipboard::FormatPlainText, PasteboardPrivate::PlainTextFormat); -COMPILE_ASSERT_MATCHING_ENUM(WebClipboard::FormatHTML, PasteboardPrivate::HTMLFormat); -COMPILE_ASSERT_MATCHING_ENUM(WebClipboard::FormatBookmark, PasteboardPrivate::BookmarkFormat); -COMPILE_ASSERT_MATCHING_ENUM(WebClipboard::FormatSmartPaste, PasteboardPrivate::WebSmartPasteFormat); - -COMPILE_ASSERT_MATCHING_ENUM(WebClipboard::BufferStandard, PasteboardPrivate::StandardBuffer); -COMPILE_ASSERT_MATCHING_ENUM(WebClipboard::BufferSelection, PasteboardPrivate::SelectionBuffer); - COMPILE_ASSERT_MATCHING_ENUM(WebCursorInfo::TypePointer, PlatformCursor::TypePointer); COMPILE_ASSERT_MATCHING_ENUM(WebCursorInfo::TypeCross, PlatformCursor::TypeCross); COMPILE_ASSERT_MATCHING_ENUM(WebCursorInfo::TypeHand, PlatformCursor::TypeHand); diff --git a/Source/WebKit/chromium/src/PlatformSupport.cpp b/Source/WebKit/chromium/src/PlatformSupport.cpp index b6266fea1..cfaf097ef 100644 --- a/Source/WebKit/chromium/src/PlatformSupport.cpp +++ b/Source/WebKit/chromium/src/PlatformSupport.cpp @@ -80,7 +80,6 @@ #include "AsyncFileSystemChromium.h" #include "BitmapImage.h" -#include "ClipboardChromium.h" #include "Cookie.h" #include "Document.h" #include "FrameView.h" @@ -94,7 +93,6 @@ #include "Worker.h" #include "WorkerContextProxy.h" -#include <public/WebClipboard.h> #include <public/WebCookie.h> #include <public/WebCookieJar.h> #include <public/WebMimeRegistry.h> @@ -141,96 +139,6 @@ static WebCookieJar* getCookieJar(const Document* document) return cookieJar; } -// Clipboard ------------------------------------------------------------------ - -uint64_t PlatformSupport::clipboardSequenceNumber(PasteboardPrivate::ClipboardBuffer buffer) -{ - return webKitPlatformSupport()->clipboard()->sequenceNumber( - static_cast<WebClipboard::Buffer>(buffer)); -} - -bool PlatformSupport::clipboardIsFormatAvailable( - PasteboardPrivate::ClipboardFormat format, - PasteboardPrivate::ClipboardBuffer buffer) -{ - return webKitPlatformSupport()->clipboard()->isFormatAvailable( - static_cast<WebClipboard::Format>(format), - static_cast<WebClipboard::Buffer>(buffer)); -} - -HashSet<String> PlatformSupport::clipboardReadAvailableTypes( - PasteboardPrivate::ClipboardBuffer buffer, bool* containsFilenames) -{ - WebVector<WebString> result = webKitPlatformSupport()->clipboard()->readAvailableTypes( - static_cast<WebClipboard::Buffer>(buffer), containsFilenames); - HashSet<String> types; - for (size_t i = 0; i < result.size(); ++i) - types.add(result[i]); - return types; -} - -String PlatformSupport::clipboardReadPlainText( - PasteboardPrivate::ClipboardBuffer buffer) -{ - return webKitPlatformSupport()->clipboard()->readPlainText( - static_cast<WebClipboard::Buffer>(buffer)); -} - -void PlatformSupport::clipboardReadHTML( - PasteboardPrivate::ClipboardBuffer buffer, - String* htmlText, KURL* sourceURL, unsigned* fragmentStart, unsigned* fragmentEnd) -{ - WebURL url; - *htmlText = webKitPlatformSupport()->clipboard()->readHTML( - static_cast<WebClipboard::Buffer>(buffer), &url, fragmentStart, fragmentEnd); - *sourceURL = url; -} - -PassRefPtr<SharedBuffer> PlatformSupport::clipboardReadImage( - PasteboardPrivate::ClipboardBuffer buffer) -{ - return webKitPlatformSupport()->clipboard()->readImage(static_cast<WebClipboard::Buffer>(buffer)); -} - -String PlatformSupport::clipboardReadCustomData( - PasteboardPrivate::ClipboardBuffer buffer, const String& type) -{ - return webKitPlatformSupport()->clipboard()->readCustomData(static_cast<WebClipboard::Buffer>(buffer), type); -} - -void PlatformSupport::clipboardWriteSelection(const String& htmlText, - const KURL& sourceURL, - const String& plainText, - bool writeSmartPaste) -{ - webKitPlatformSupport()->clipboard()->writeHTML( - htmlText, sourceURL, plainText, writeSmartPaste); -} - -void PlatformSupport::clipboardWritePlainText(const String& plainText) -{ - webKitPlatformSupport()->clipboard()->writePlainText(plainText); -} - -void PlatformSupport::clipboardWriteURL(const KURL& url, const String& title) -{ - webKitPlatformSupport()->clipboard()->writeURL(url, title); -} - -void PlatformSupport::clipboardWriteImage(NativeImagePtr image, - const KURL& sourceURL, - const String& title) -{ - WebImage webImage(image->bitmap()); - webKitPlatformSupport()->clipboard()->writeImage(webImage, sourceURL, title); -} - -void PlatformSupport::clipboardWriteDataObject(Clipboard* clipboard) -{ - WebDragData data = static_cast<ClipboardChromium*>(clipboard)->dataObject(); - webKitPlatformSupport()->clipboard()->writeDataObject(data); -} - // Cookies -------------------------------------------------------------------- void PlatformSupport::setCookies(const Document* document, const KURL& url, diff --git a/Source/WebKit/chromium/tests/DecimalTest.cpp b/Source/WebKit/chromium/tests/DecimalTest.cpp index db69edd38..18457fdf4 100644 --- a/Source/WebKit/chromium/tests/DecimalTest.cpp +++ b/Source/WebKit/chromium/tests/DecimalTest.cpp @@ -646,6 +646,7 @@ TEST_F(DecimalTest, Multiplication) EXPECT_EQ(encode(2, 0, Negative), Decimal(-1) * Decimal(2)); EXPECT_EQ(encode(99, 0, Positive), Decimal(99) * Decimal(1)); EXPECT_EQ(encode(2500, 0, Positive), Decimal(-50) * Decimal(-50)); + EXPECT_EQ(encode(1, 21, Positive), encode(UINT64_C(10000000000), 0, Positive) * encode(UINT64_C(100000000000), 0, Positive)); } TEST_F(DecimalTest, MultiplicationBigExponent) diff --git a/Source/WebKit/efl/ChangeLog b/Source/WebKit/efl/ChangeLog index ec4f3151d..f3777612a 100644 --- a/Source/WebKit/efl/ChangeLog +++ b/Source/WebKit/efl/ChangeLog @@ -1,3 +1,138 @@ +2012-06-01 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] EFL port does not enable WEB_INTENTS_TAG flag + https://bugs.webkit.org/show_bug.cgi?id=86866 + + Reviewed by Adam Barth. + + Implement registerIntentService() in EFL's FrameLoaderClient. + Emit a "intent,service,register" signal on the frame when a new Web + Intent service registers. + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore): + (WebCore::FrameLoaderClientEfl::registerIntentService): + * WebCoreSupport/FrameLoaderClientEfl.h: + (FrameLoaderClientEfl): + * ewk/ewk_frame.cpp: + (ewk_frame_intent_service_register): + * ewk/ewk_frame.h: + * ewk/ewk_frame_private.h: + +2012-06-01 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] ewk_intent_data_get() is not needed and can be removed + https://bugs.webkit.org/show_bug.cgi?id=88072 + + Reviewed by Adam Barth. + + Remove ewk_intent_data_get() method from Ewk_Intent. Intent data is + serialized and does not need to be publicly exposed. The browser only + needs action and type to match with services. + + * ewk/ewk_intent.cpp: + (_Ewk_Intent): + (ewk_intent_action_get): + (ewk_intent_type_get): + (ewk_intent_service_get): + (ewk_intent_free): + * ewk/ewk_intent.h: + +2012-06-01 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] EFL's LayoutTestController needs to implement deliverWebIntent + https://bugs.webkit.org/show_bug.cgi?id=86865 + + Reviewed by Adam Barth. + + Add method on Ewk_Frame to deliver an intent. + Add helper function to DumpRenderTreeSupportEfl to deliver a Web + Intent. + + * WebCoreSupport/DumpRenderTreeSupportEfl.cpp: + (DumpRenderTreeSupportEfl::deliverWebIntent): + * WebCoreSupport/DumpRenderTreeSupportEfl.h: + * ewk/ewk_frame.cpp: + (ewk_frame_intent_deliver): + * ewk/ewk_frame.h: + +2012-06-01 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r119228. + http://trac.webkit.org/changeset/119228 + https://bugs.webkit.org/show_bug.cgi?id=88098 + + Caused the EFL debug bot to crash. (Requested by rakuco on + #webkit). + + * ewk/ewk_main.cpp: + (ewk_init): + +2012-06-01 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] [DRT] editing/execCommand/paste-and-match-style-event.html crashes + https://bugs.webkit.org/show_bug.cgi?id=86961 + + Reviewed by Csaba Osztrogonác. + + Call ecore_x_init() in ewk_init() to initialize the ecore_x library. + This avoids crashing upong calling WebCore::systemBeep() which uses + ecore_x_bell() internally. + + * ewk/ewk_main.cpp: + (ewk_init): + +2012-06-01 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com> + + [EFL] New signals in ewk_view to enable global history delegate functionality + https://bugs.webkit.org/show_bug.cgi?id=86343 + + Reviewed by Kenneth Rohde Christiansen. + + Global history delegate is an interface for WebKit clients to manage their own global history store. + The new ewk_view signals do the following: + 1) report that a navigation happened within the view and give the navigation details. + 2) report that view performed a client redirect and give source and destination uris. + 3) report that view performed a server redirect and give source and destination uris. + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::updateGlobalHistoryRedirectLinks): implementation added. + (WebCore::FrameLoaderClientEfl::updateGlobalHistory): implementation added. + * ewk/ewk_view.h: Added new signals and data types. + +2012-06-01 Sudarsana Nagineni <sudarsana.nagineni@linux.intel.com> + + [EFL] Implement PlatformStrategies + https://bugs.webkit.org/show_bug.cgi?id=86946 + + Reviewed by Carlos Garcia Campos. + + Enable PLATFORM_STRATEGIES for EFL platform. + + * WebCoreSupport/PlatformStrategiesEfl.cpp: Added, code was moved + from platform/PluginDataEfl. + (PlatformStrategiesEfl::initialize): Initialize platform strategies. + (PlatformStrategiesEfl::PlatformStrategiesEfl): + (PlatformStrategiesEfl::createCookiesStrategy): Return this. + (PlatformStrategiesEfl::createPluginStrategy): Ditto. + (PlatformStrategiesEfl::createVisitedLinkStrategy): Ditto. + (PlatformStrategiesEfl::createPasteboardStrategy): Return 0, since + PasteboardStrategy is only used by mac code for now. + (PlatformStrategiesEfl::notifyCookiesChanged): + (PlatformStrategiesEfl::refreshPlugins): Refresh the plugin + database. Code executes only when NETSCAPE_PLUGIN_API is ON. + (PlatformStrategiesEfl::getPluginInfo): Initialize plugins and + populate the given vector with plugins information. Code executes + only when NETSCAPE_PLUGIN_API is ON. + (PlatformStrategiesEfl::isLinkVisited): Return whether the given + hash is a visited link of the page group. + (PlatformStrategiesEfl::addVisitedLink): Add the given hash to the + page group visited links. + * WebCoreSupport/PlatformStrategiesEfl.h: Added. + (PlatformStrategiesEfl): + * ewk/ewk_main.cpp: Initialize PlatformStrategiesEfl. + (_ewk_init_body): + 2012-05-31 Alexander Shalamov <alexander.shalamov@intel.com> [EFL] <input type="number"> is not a spinbutton diff --git a/Source/WebKit/efl/WebCoreSupport/DumpRenderTreeSupportEfl.cpp b/Source/WebKit/efl/WebCoreSupport/DumpRenderTreeSupportEfl.cpp index 7e2127ab2..b45aef113 100644 --- a/Source/WebKit/efl/WebCoreSupport/DumpRenderTreeSupportEfl.cpp +++ b/Source/WebKit/efl/WebCoreSupport/DumpRenderTreeSupportEfl.cpp @@ -690,6 +690,21 @@ WebCore::MessagePortChannelArray* DumpRenderTreeSupportEfl::intentMessagePorts(c #endif } +void DumpRenderTreeSupportEfl::deliverWebIntent(Evas_Object* ewkFrame, JSStringRef action, JSStringRef type, JSStringRef data) +{ +#if ENABLE(WEB_INTENTS) + RefPtr<WebCore::SerializedScriptValue> serializedData = WebCore::SerializedScriptValue::create(String(data->ustring().impl())); + WebCore::ExceptionCode ec = 0; + WebCore::MessagePortArray ports; + RefPtr<WebCore::Intent> coreIntent = WebCore::Intent::create(String(action->ustring().impl()), String(type->ustring().impl()), serializedData.get(), ports, ec); + if (ec) + return; + Ewk_Intent* ewkIntent = ewk_intent_new(coreIntent.get()); + ewk_frame_intent_deliver(ewkFrame, ewkIntent); + ewk_intent_free(ewkIntent); +#endif +} + void DumpRenderTreeSupportEfl::setComposition(Evas_Object* ewkView, const char* text, int start, int length) { WebCore::Page* page = EWKPrivate::corePage(ewkView); diff --git a/Source/WebKit/efl/WebCoreSupport/DumpRenderTreeSupportEfl.h b/Source/WebKit/efl/WebCoreSupport/DumpRenderTreeSupportEfl.h index c8007a213..2ae343116 100644 --- a/Source/WebKit/efl/WebCoreSupport/DumpRenderTreeSupportEfl.h +++ b/Source/WebKit/efl/WebCoreSupport/DumpRenderTreeSupportEfl.h @@ -112,6 +112,7 @@ public: // Web Intents static void sendWebIntentResponse(Ewk_Intent_Request*, JSStringRef response); static WebCore::MessagePortChannelArray* intentMessagePorts(const Ewk_Intent*); + static void deliverWebIntent(Evas_Object* ewkFrame, JSStringRef action, JSStringRef type, JSStringRef data); // TextInputController static void setComposition(Evas_Object*, const char*, int, int); diff --git a/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp b/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp index c08d3ed81..5072de236 100644 --- a/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp +++ b/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp @@ -505,6 +505,27 @@ void FrameLoaderClientEfl::restoreViewState() void FrameLoaderClientEfl::updateGlobalHistoryRedirectLinks() { + WebCore::Frame* frame = EWKPrivate::coreFrame(m_frame); + if (!frame) + return; + + WebCore::DocumentLoader* loader = frame->loader()->documentLoader(); + if (!loader) + return; + + if (!loader->clientRedirectSourceForHistory().isNull()) { + const CString& sourceURL = loader->clientRedirectSourceForHistory().utf8(); + const CString& destinationURL = loader->clientRedirectDestinationForHistory().utf8(); + Ewk_View_Redirection_Data data = { sourceURL.data(), destinationURL.data() }; + evas_object_smart_callback_call(m_view, "perform,client,redirect", &data); + } + + if (!loader->serverRedirectSourceForHistory().isNull()) { + const CString& sourceURL = loader->serverRedirectSourceForHistory().utf8(); + const CString& destinationURL = loader->serverRedirectDestinationForHistory().utf8(); + Ewk_View_Redirection_Data data = { sourceURL.data(), destinationURL.data() }; + evas_object_smart_callback_call(m_view, "perform,server,redirect", &data); + } } bool FrameLoaderClientEfl::shouldGoToHistoryItem(HistoryItem* item) const @@ -959,7 +980,32 @@ void FrameLoaderClientEfl::startDownload(const ResourceRequest& request, const S void FrameLoaderClientEfl::updateGlobalHistory() { - notImplemented(); + WebCore::Frame* frame = EWKPrivate::coreFrame(m_frame); + if (!frame) + return; + + WebCore::DocumentLoader* loader = frame->loader()->documentLoader(); + if (!loader) + return; + + const FrameLoader* frameLoader = loader->frameLoader(); + const bool isMainFrameRequest = frameLoader && (loader == frameLoader->provisionalDocumentLoader()) && frameLoader->isLoadingMainFrame(); + const CString& urlForHistory = loader->urlForHistory().string().utf8(); + const CString& title = loader->title().string().utf8(); + const CString& firstParty = loader->request().firstPartyForCookies().string().utf8(); + const CString& clientRedirectSource = loader->clientRedirectSourceForHistory().utf8(); + const CString& originalURL = loader->originalURL().string().utf8(); + const CString& httpMethod = loader->request().httpMethod().utf8(); + const CString& responseURL = loader->responseURL().string().utf8(); + const CString& mimeType = loader->response().mimeType().utf8(); + + Ewk_Frame_Resource_Request request = { originalURL.data(), firstParty.data(), httpMethod.data(), 0, m_frame, isMainFrameRequest }; + Ewk_Frame_Resource_Response response = { responseURL.data(), loader->response().httpStatusCode(), 0, mimeType.data() }; + bool hasSubstituteData = loader->substituteData().isValid(); + + Ewk_View_Navigation_Data data = { urlForHistory.data(), title.data(), &request, &response, hasSubstituteData, clientRedirectSource.data() }; + + evas_object_smart_callback_call(m_view, "navigate,with,data", &data); } void FrameLoaderClientEfl::savePlatformDataToCachedFrame(CachedFrame*) @@ -1005,6 +1051,21 @@ void FrameLoaderClientEfl::dispatchIntent(PassRefPtr<WebCore::IntentRequest> int } #endif +#if ENABLE(WEB_INTENTS_TAG) +void FrameLoaderClientEfl::registerIntentService(const String& action, const String& type, const KURL& href, const String& title, const String& disposition) +{ + CString actionStr = action.utf8(); + CString typeStr = type.utf8(); + CString hrefStr = href.string().utf8(); + CString titleStr = title.utf8(); + CString dispositionStr = disposition.utf8(); + + Ewk_Intent_Service_Info serviceInfo = { actionStr.data(), typeStr.data(), hrefStr.data(), titleStr.data(), dispositionStr.data() }; + + ewk_frame_intent_service_register(m_frame, &serviceInfo); +} +#endif + PassRefPtr<FrameNetworkingContext> FrameLoaderClientEfl::createNetworkingContext() { return FrameNetworkingContextEfl::create(EWKPrivate::coreFrame(m_frame), m_frame); diff --git a/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h b/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h index c2529c5b2..63d8a4452 100644 --- a/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h +++ b/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h @@ -188,6 +188,9 @@ class FrameLoaderClientEfl : public FrameLoaderClient { #if ENABLE(WEB_INTENTS) virtual void dispatchIntent(PassRefPtr<WebCore::IntentRequest>); #endif +#if ENABLE(WEB_INTENTS_TAG) + virtual void registerIntentService(const String& action, const String& type, const KURL& href, const String& title, const String& disposition); +#endif virtual WTF::PassRefPtr<DocumentLoader> createDocumentLoader(const ResourceRequest&, const SubstituteData&); virtual void setTitle(const StringWithDirection& title, const KURL&); diff --git a/Source/WebCore/plugins/efl/PluginDataEfl.cpp b/Source/WebKit/efl/WebCoreSupport/PlatformStrategiesEfl.cpp index c21d51b19..5b40308a2 100644 --- a/Source/WebCore/plugins/efl/PluginDataEfl.cpp +++ b/Source/WebKit/efl/WebCoreSupport/PlatformStrategiesEfl.cpp @@ -5,6 +5,7 @@ Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia Copyright (C) 2009-2010 ProFUSION embedded systems Copyright (C) 2009-2011 Samsung Electronics + Copyright (C) 2012 Intel Corporation This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -23,24 +24,75 @@ */ #include "config.h" -#include "PluginData.h" +#include "PlatformStrategiesEfl.h" +#include "NotImplemented.h" +#include "Page.h" +#include "PageGroup.h" #include "PluginDatabase.h" #include "PluginPackage.h" -namespace WebCore { +using namespace WebCore; -void PluginData::initPlugins(const Page*) +void PlatformStrategiesEfl::initialize() { + DEFINE_STATIC_LOCAL(PlatformStrategiesEfl, platformStrategies, ()); + setPlatformStrategies(&platformStrategies); +} + +PlatformStrategiesEfl::PlatformStrategiesEfl() +{ +} + +// CookiesStrategy +CookiesStrategy* PlatformStrategiesEfl::createCookiesStrategy() +{ + return this; +} + +// PluginStrategy +PluginStrategy* PlatformStrategiesEfl::createPluginStrategy() +{ + return this; +} + +VisitedLinkStrategy* PlatformStrategiesEfl::createVisitedLinkStrategy() +{ + return this; +} + +PasteboardStrategy* PlatformStrategiesEfl::createPasteboardStrategy() +{ + notImplemented(); + return 0; +} + +// CookiesStrategy +void PlatformStrategiesEfl::notifyCookiesChanged() +{ +} + +void PlatformStrategiesEfl::refreshPlugins() +{ +#if ENABLE(NETSCAPE_PLUGIN_API) + PluginDatabase::installedPlugins()->refresh(); +#endif +} + +void PlatformStrategiesEfl::getPluginInfo(const Page* page, Vector<PluginInfo>& outPlugins) +{ +#if ENABLE(NETSCAPE_PLUGIN_API) + PluginDatabase::installedPlugins()->refresh(); const Vector<PluginPackage*>& plugins = PluginDatabase::installedPlugins()->plugins(); + outPlugins.resize(plugins.size()); for (size_t i = 0; i < plugins.size(); ++i) { PluginPackage* package = plugins[i]; - PluginInfo info; - info.name = package->name(); - info.file = package->fileName(); - info.desc = package->description(); + PluginInfo pluginInfo; + pluginInfo.name = package->name(); + pluginInfo.file = package->fileName(); + pluginInfo.desc = package->description(); const MIMEToDescriptionsMap& mimeToDescriptions = package->mimeToDescriptions(); MIMEToDescriptionsMap::const_iterator end = mimeToDescriptions.end(); @@ -50,17 +102,21 @@ void PluginData::initPlugins(const Page*) mime.type = it->first; mime.desc = it->second; mime.extensions = package->mimeToExtensions().get(mime.type); - - info.mimes.append(mime); + pluginInfo.mimes.append(mime); } - m_plugins.append(info); + outPlugins.append(pluginInfo); } +#endif } -void PluginData::refresh() +// VisitedLinkStrategy +bool PlatformStrategiesEfl::isLinkVisited(Page* page, LinkHash hash, const KURL&, const AtomicString&) { - PluginDatabase::installedPlugins()->refresh(); + return page->group().isLinkVisited(hash); } -}; +void PlatformStrategiesEfl::addVisitedLink(Page* page, LinkHash hash) +{ + page->group().addVisitedLinkHash(hash); +} diff --git a/Source/WebKit/efl/WebCoreSupport/PlatformStrategiesEfl.h b/Source/WebKit/efl/WebCoreSupport/PlatformStrategiesEfl.h new file mode 100644 index 000000000..d3f26b680 --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/PlatformStrategiesEfl.h @@ -0,0 +1,54 @@ +/* + Copyright (C) 2012 Intel Corporation + + 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 library 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 library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PlatformStrategiesEfl_h +#define PlatformStrategiesEfl_h + +#include "CookiesStrategy.h" +#include "PasteboardStrategy.h" +#include "PlatformStrategies.h" +#include "PluginStrategy.h" +#include "VisitedLinkStrategy.h" + +class PlatformStrategiesEfl : public WebCore::PlatformStrategies, private WebCore::CookiesStrategy, private WebCore::PluginStrategy, private WebCore::VisitedLinkStrategy { +public: + static void initialize(); + +private: + PlatformStrategiesEfl(); + + // WebCore::PlatformStrategies + virtual WebCore::CookiesStrategy* createCookiesStrategy(); + virtual WebCore::PluginStrategy* createPluginStrategy(); + virtual WebCore::VisitedLinkStrategy* createVisitedLinkStrategy(); + virtual WebCore::PasteboardStrategy* createPasteboardStrategy(); + + // WebCore::CookiesStrategy + virtual void notifyCookiesChanged(); + + // WebCore::PluginStrategy + virtual void refreshPlugins(); + virtual void getPluginInfo(const WebCore::Page*, Vector<WebCore::PluginInfo>&); + + // WebCore::VisitedLinkStrategy + virtual bool isLinkVisited(WebCore::Page*, WebCore::LinkHash, const WebCore::KURL& baseURL, const WTF::AtomicString& attributeURL); + virtual void addVisitedLink(WebCore::Page*, WebCore::LinkHash); +}; + +#endif // PlatformStrategiesEfl_h diff --git a/Source/WebKit/efl/ewk/ewk_frame.cpp b/Source/WebKit/efl/ewk/ewk_frame.cpp index c800ad62d..fd1ffd22e 100644 --- a/Source/WebKit/efl/ewk/ewk_frame.cpp +++ b/Source/WebKit/efl/ewk/ewk_frame.cpp @@ -24,6 +24,8 @@ #include "config.h" #include "ewk_frame.h" +#include "DOMWindowIntents.h" +#include "DeliveredIntent.h" #include "DocumentLoader.h" #include "DocumentMarkerController.h" #include "EventHandler.h" @@ -41,6 +43,7 @@ #include "KURL.h" #include "PlatformEvent.h" #include "PlatformKeyboardEvent.h" +#include "PlatformMessagePortChannel.h" #include "PlatformMouseEvent.h" #include "PlatformTouchEvent.h" #include "PlatformWheelEvent.h" @@ -51,6 +54,7 @@ #include "SubstituteData.h" #include "WindowsKeyboardCodes.h" #include "ewk_frame_private.h" +#include "ewk_intent_private.h" #include "ewk_private.h" #include "ewk_security_origin_private.h" #include "ewk_view_private.h" @@ -746,6 +750,30 @@ Ewk_Hit_Test* ewk_frame_hit_test_new(const Evas_Object* ewkFrame, int x, int y) return hitTest; } +void ewk_frame_intent_deliver(const Evas_Object* ewkFrame, Ewk_Intent* ewk_intent) +{ +#if ENABLE(WEB_INTENTS) + EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData); + EINA_SAFETY_ON_NULL_RETURN(smartData->frame); + + WebCore::Intent* intent = EWKPrivate::coreIntent(ewk_intent); + + OwnPtr<WebCore::MessagePortChannelArray> channels; + WebCore::MessagePortChannelArray* origChannels = intent->messagePorts(); + if (origChannels && origChannels->size()) { + channels = adoptPtr(new WebCore::MessagePortChannelArray(origChannels->size())); + for (size_t i = 0; i < origChannels->size(); ++i) + (*channels)[i] = origChannels->at(i).release(); + } + OwnPtr<WebCore::MessagePortArray> ports = WebCore::MessagePort::entanglePorts(*(smartData->frame->domWindow()->scriptExecutionContext()), channels.release()); + + OwnPtr<WebCore::DeliveredIntentClient> dummyClient; + RefPtr<WebCore::DeliveredIntent> deliveredIntent = WebCore::DeliveredIntent::create(smartData->frame, dummyClient.release(), intent->action(), intent->type(), intent->data(), ports.release(), intent->extras()); + + WebCore::DOMWindowIntents::from(smartData->frame->domWindow())->deliver(deliveredIntent.release()); +#endif +} + Eina_Bool ewk_frame_scroll_add(Evas_Object* ewkFrame, int deltaX, int deltaY) { @@ -1559,6 +1587,19 @@ void ewk_frame_intent_new(Evas_Object* ewkFrame, Ewk_Intent_Request* request) /** * @internal + * Reports an intent service registration. + * + * Emits signal: "intent,service,register" with pointer to a Ewk_Intent_Service_Info. + */ +void ewk_frame_intent_service_register(Evas_Object* ewkFrame, Ewk_Intent_Service_Info* info) +{ +#if ENABLE(WEB_INTENTS_TAG) + evas_object_smart_callback_call(ewkFrame, "intent,service,register", info); +#endif +} + +/** + * @internal * * Reports contents size changed. */ diff --git a/Source/WebKit/efl/ewk/ewk_frame.h b/Source/WebKit/efl/ewk/ewk_frame.h index dce883ee5..987a4b069 100644 --- a/Source/WebKit/efl/ewk/ewk_frame.h +++ b/Source/WebKit/efl/ewk/ewk_frame.h @@ -41,6 +41,7 @@ * contents were changed * - "icon,changed", void: frame favicon changed. * - "intent,new", Ewk_Intent_Request*: reports new intent. + * - "intent,service,register", Ewk_Intent_Service_Info*: reports new intent service registration. * - "load,committed", void: reports load committed. * - "load,document,finished", void: frame finished loading the document. * - "load,error", const Ewk_Frame_Load_Error*: reports load failed @@ -81,6 +82,7 @@ #ifndef ewk_frame_h #define ewk_frame_h +#include "ewk_intent.h" #include "ewk_security_origin.h" #include <Evas.h> @@ -182,6 +184,17 @@ struct _Ewk_Frame_Xss_Notification { Eina_Bool is_entire_page_blocked; /** < indicates if the entire page was blocked by XSSAuditor */ }; +/// Creates a type name for Ewk_Intent_Service_Info. +typedef struct _Ewk_Intent_Service_Info Ewk_Intent_Service_Info; + +struct _Ewk_Intent_Service_Info { + const char *action; /**< an opaque string indicating the behavior class the service supports. */ + const char *type; /**< a string specifying the type of payload data the service can accept. */ + const char *href; /**< service URI. */ + const char *title; /**< A human-readable title for the service. */ + const char *disposition; /**< A hint about whether the service can be run "inline" or in a new "window". */ +}; + /// Enum containing hit test data types typedef enum { EWK_HIT_TEST_RESULT_CONTEXT_DOCUMENT = 1 << 1, @@ -702,6 +715,14 @@ EAPI void ewk_frame_hit_test_free(Ewk_Hit_Test *hit_test); EAPI Ewk_Hit_Test *ewk_frame_hit_test_new(const Evas_Object *o, int x, int y); /** + * Delivers an intent to a target service page in the frame. + * + * @param o frame object to deliver the intent to. + * @param ewkIntent intent object to deliver. + */ +EAPI void ewk_frame_intent_deliver(const Evas_Object *o, Ewk_Intent *ewk_intent); + +/** * Sets a relative scroll of the given frame. * * This function does scroll @a dx and @a dy pixels diff --git a/Source/WebKit/efl/ewk/ewk_frame_private.h b/Source/WebKit/efl/ewk/ewk_frame_private.h index 6d0eb2fa3..4f5f0e40e 100644 --- a/Source/WebKit/efl/ewk/ewk_frame_private.h +++ b/Source/WebKit/efl/ewk/ewk_frame_private.h @@ -70,6 +70,7 @@ bool ewk_frame_uri_changed(Evas_Object* ewkFrame); void ewk_frame_force_layout(Evas_Object* ewkFrame); void ewk_frame_icon_changed(Evas_Object* ewkFrame); void ewk_frame_intent_new(Evas_Object* ewkFrame, Ewk_Intent_Request* request); +void ewk_frame_intent_service_register(Evas_Object* ewkFrame, Ewk_Intent_Service_Info* info); WTF::PassRefPtr<WebCore::Widget> ewk_frame_plugin_create(Evas_Object* ewkFrame, const WebCore::IntSize& pluginSize, WebCore::HTMLPlugInElement* element, const WebCore::KURL& url, const WTF::Vector<WTF::String>& paramNames, const WTF::Vector<WTF::String>& paramValues, const WTF::String& mimeType, bool loadManually); diff --git a/Source/WebKit/efl/ewk/ewk_intent.cpp b/Source/WebKit/efl/ewk/ewk_intent.cpp index e1da07f80..ef7914186 100644 --- a/Source/WebKit/efl/ewk/ewk_intent.cpp +++ b/Source/WebKit/efl/ewk/ewk_intent.cpp @@ -22,7 +22,6 @@ #include "Intent.h" #include "NotImplemented.h" -#include "SerializedScriptValue.h" #include "ewk_intent_private.h" #include "ewk_private.h" #include <KURL.h> @@ -40,7 +39,6 @@ struct _Ewk_Intent { #endif const char* action; const char* type; - const char* data; const char* service; }; @@ -60,7 +58,7 @@ const char* ewk_intent_action_get(const Ewk_Intent* intent) #if ENABLE(WEB_INTENTS) EWK_INTENT_CORE_GET_OR_RETURN(intent, core, 0); - // hide the following optimzation from outside + // hide the following optimization from outside Ewk_Intent* ewkIntent = const_cast<Ewk_Intent*>(intent); eina_stringshare_replace(&ewkIntent->action, core->action().utf8().data()); @@ -75,7 +73,7 @@ const char* ewk_intent_type_get(const Ewk_Intent* intent) #if ENABLE(WEB_INTENTS) EWK_INTENT_CORE_GET_OR_RETURN(intent, core, 0); - // hide the following optimzation from outside + // hide the following optimization from outside Ewk_Intent* ewkIntent = const_cast<Ewk_Intent*>(intent); eina_stringshare_replace(&ewkIntent->type, core->type().utf8().data()); @@ -85,22 +83,12 @@ const char* ewk_intent_type_get(const Ewk_Intent* intent) #endif } -const char* ewk_intent_data_get(const Ewk_Intent* intent) -{ -#if ENABLE(WEB_INTENTS) - notImplemented(); - return 0; -#else - return 0; -#endif -} - const char* ewk_intent_service_get(const Ewk_Intent* intent) { #if ENABLE(WEB_INTENTS) EWK_INTENT_CORE_GET_OR_RETURN(intent, core, 0); - // hide the following optimzation from outside + // hide the following optimization from outside Ewk_Intent* ewkIntent = const_cast<Ewk_Intent*>(intent); eina_stringshare_replace(&ewkIntent->service, core->service().string().utf8().data()); @@ -184,7 +172,6 @@ void ewk_intent_free(Ewk_Intent* intent) eina_stringshare_del(intent->action); eina_stringshare_del(intent->type); - eina_stringshare_del(intent->data); eina_stringshare_del(intent->service); delete intent; } diff --git a/Source/WebKit/efl/ewk/ewk_intent.h b/Source/WebKit/efl/ewk/ewk_intent.h index f4dc0a806..143deaa0b 100644 --- a/Source/WebKit/efl/ewk/ewk_intent.h +++ b/Source/WebKit/efl/ewk/ewk_intent.h @@ -56,19 +56,6 @@ EAPI const char *ewk_intent_action_get(const Ewk_Intent *intent); EAPI const char *ewk_intent_type_get(const Ewk_Intent *intent); /** - * Query data for this intent. - * - * @param intent intent item to query. - * - * @return the data pointer, that may be @c NULL. This pointer is - * guaranteed to be eina_stringshare, so whenever possible - * save yourself some cpu cycles and use - * eina_stringshare_ref() instead of eina_stringshare_add() or - * strdup(). - */ -EAPI const char *ewk_intent_data_get(const Ewk_Intent *intent); - -/** * Query service for this intent. * * @param intent intent item to query. diff --git a/Source/WebKit/efl/ewk/ewk_main.cpp b/Source/WebKit/efl/ewk/ewk_main.cpp index c205db5ec..84d2b5025 100644 --- a/Source/WebKit/efl/ewk/ewk_main.cpp +++ b/Source/WebKit/efl/ewk/ewk_main.cpp @@ -25,6 +25,7 @@ #include "Logging.h" #include "PageCache.h" #include "PageGroup.h" +#include "PlatformStrategiesEfl.h" #include "ResourceHandle.h" #include "ScriptController.h" #include "Settings.h" @@ -148,6 +149,8 @@ Eina_Bool _ewk_init_body(void) WebCore::initializeLoggingChannelsIfNecessary(); WebCore::Settings::setDefaultMinDOMTimerInterval(0.004); + PlatformStrategiesEfl::initialize(); + // Page cache capacity (in pages). Comment from Mac port: // (Research indicates that value / page drops substantially after 3 pages.) // FIXME: Calculate based on available resources diff --git a/Source/WebKit/efl/ewk/ewk_view.h b/Source/WebKit/efl/ewk/ewk_view.h index cc6503812..daed8accd 100644 --- a/Source/WebKit/efl/ewk/ewk_view.h +++ b/Source/WebKit/efl/ewk/ewk_view.h @@ -71,6 +71,9 @@ * - "menubar,visible,set", Eina_Bool: sets menubar visibility. * - "mixedcontent,displayed", void: any of the containing frames has loaded and displayed mixed content. * - "mixedcontent,run", void: any of the containing frames has loaded and run mixed content. + * - "navigate,with,data", Ewk_View_Navigation_Data*: reports that view did navigation and gives the navigation details. + * - "perform,client,redirect", Ewk_View_Redirection_Data*: reports that view performed a client redirect and gives the redirection details. + * - "perform,server,redirect", Ewk_View_Redirection_Data*: reports that view performed a server redirect and gives the redirection details. * - "protocolhandler,registration,requested", Ewk_Custom_Handler_Data: add a handler url for the given protocol. * - "onload,event", Evas_Object*: a frame onload event has been received. * - "populate,visited,links": tells the client to fill the visited links set. @@ -294,6 +297,36 @@ struct _Ewk_Download { /* to be extended */ }; +/// Creates a type name for @a _Ewk_View_Navigation_Data. +typedef struct _Ewk_View_Navigation_Data Ewk_View_Navigation_Data; + +/** + * @brief Structure containing details about a view navigation. + * + * Details of a view navigation. It is used in "navigate,with,data" signal. + */ +struct _Ewk_View_Navigation_Data { + const char *url; /**< URL for the history. */ + const char *title; /**< Title of the navigated page. */ + Ewk_Frame_Resource_Request *request; /**< Navigation request. */ + Ewk_Frame_Resource_Response *response; /**< Navigation response. */ + Eina_Bool has_substitute_data; /**< Data substitution flag. */ + const char *client_redirect_source; /**< Client redirect source URL. */ +}; + + +/// Creates a type name for @a _Ewk_View_Redirection_Data. +typedef struct _Ewk_View_Redirection_Data Ewk_View_Redirection_Data; + +/** + * @brief Structure containing details about a view redirection. + * + * Details of a client or server redirection. It is used in "perform,client,redirect" and "perform,server,redirect" signals. + */ +struct _Ewk_View_Redirection_Data { + const char *source_url; /**< Redirect source URL. */ + const char *destination_url; /**< Redirect destination URL. */ +}; /// Creates a type name for @a _Ewk_Scroll_Request. typedef struct _Ewk_Scroll_Request Ewk_Scroll_Request; /// Contains the scroll request that should be processed by subclass implementations. diff --git a/Source/WebKit/qt/ChangeLog b/Source/WebKit/qt/ChangeLog index 3980c1975..7fef898b3 100644 --- a/Source/WebKit/qt/ChangeLog +++ b/Source/WebKit/qt/ChangeLog @@ -1,3 +1,46 @@ +2012-06-01 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> + + [Qt] Move QObject bridge related tests from tst_qwebframe to tst_qobjectbridge + https://bugs.webkit.org/show_bug.cgi?id=88117 + + Reviewed by Noam Rosenthal. + + Five tests (classEnums, classConstructor, transferInvokable, findObject and + findChildren) were removed since they contained commented code since the file was + added back in 2008. The QObject bridge tests were probably inspired in similar + tests for QtScript, so many features not yet implemented were present in QtWebKit + tests but commented. + + Other minor changes: + - Moved MyEnumTestQObject near the only test function that uses it. + - Removed unnecessary Q_INVOKABLE from setBrushProperty. + - Removed some bits of dead / commented code. + + * tests/qobjectbridge/qobjectbridge.pro: Added. + * tests/qobjectbridge/tst_qobjectbridge.cpp: Copied from Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp. + Kept only the tests related to QObject bridge implementation. + * tests/qwebframe/tst_qwebframe.cpp: + (tst_QWebFrame): + (tst_QWebFrame::init): + (tst_QWebFrame::cleanup): + +2012-06-01 Thiago Marcos P. Santos <thiago.santos@intel.com> + + [Qt] Remove deprecated to/fromAscii() + https://bugs.webkit.org/show_bug.cgi?id=88086 + + Reviewed by Simon Hausmann. + + Replacing to/fromAscii with to/fromLatin1 since it + is deprecated on Qt5. + + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore): + * WebCoreSupport/InspectorServerQt.cpp: + (WebCore::InspectorServerRequestHandlerQt::tcpReadyRead): + * tests/qdeclarativewebview/tst_qdeclarativewebview.cpp: + (tst_QDeclarativeWebView::settings): + 2012-05-31 Hajime Morrita <morrita@chromium.org> REGRESSION(r117572): editing/spelling/spellcheck-async-remove-frame.html crashes on Mac diff --git a/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp b/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp index de98817df..4b9709d22 100644 --- a/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp @@ -120,7 +120,7 @@ public: QString settingKey(settingStoragePrefix + QString(name)); QString storedValueType = qsettings.value(settingKey + settingStorageTypeSuffix).toString(); QVariant storedValue = qsettings.value(settingKey); - storedValue.convert(QVariant::nameToType(storedValueType.toAscii().data())); + storedValue.convert(QVariant::nameToType(storedValueType.toLatin1().data())); return variantToSetting(storedValue); #endif // QT_NO_SETTINGS } diff --git a/Source/WebKit/qt/WebCoreSupport/InspectorServerQt.cpp b/Source/WebKit/qt/WebCoreSupport/InspectorServerQt.cpp index 23f33baf2..14f5dd734 100644 --- a/Source/WebKit/qt/WebCoreSupport/InspectorServerQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/InspectorServerQt.cpp @@ -287,7 +287,7 @@ void InspectorServerRequestHandlerQt::tcpReadyRead() if (!m_contentType.isEmpty()) responseHeader.setContentType(QString::fromLatin1(m_contentType)); - QByteArray asciiHeader = responseHeader.toString().toAscii(); + QByteArray asciiHeader = responseHeader.toString().toLatin1(); m_tcpConnection->write(asciiHeader); m_tcpConnection->write(response); diff --git a/Source/WebKit/qt/tests/qdeclarativewebview/tst_qdeclarativewebview.cpp b/Source/WebKit/qt/tests/qdeclarativewebview/tst_qdeclarativewebview.cpp index f9421e3cf..b1722a6fb 100644 --- a/Source/WebKit/qt/tests/qdeclarativewebview/tst_qdeclarativewebview.cpp +++ b/Source/WebKit/qt/tests/qdeclarativewebview/tst_qdeclarativewebview.cpp @@ -477,30 +477,30 @@ void tst_QDeclarativeWebView::settings() QVERIFY(s); QStringList settingsList; - settingsList << QString::fromAscii("autoLoadImages") - << QString::fromAscii("developerExtrasEnabled") - << QString::fromAscii("javaEnabled") - << QString::fromAscii("javascriptCanAccessClipboard") - << QString::fromAscii("javascriptCanOpenWindows") - << QString::fromAscii("javascriptEnabled") - << QString::fromAscii("linksIncludedInFocusChain") - << QString::fromAscii("localContentCanAccessRemoteUrls") - << QString::fromAscii("localStorageDatabaseEnabled") - << QString::fromAscii("offlineStorageDatabaseEnabled") - << QString::fromAscii("offlineWebApplicationCacheEnabled") - << QString::fromAscii("pluginsEnabled") - << QString::fromAscii("printElementBackgrounds") - << QString::fromAscii("privateBrowsingEnabled") - << QString::fromAscii("zoomTextOnly"); + settingsList << QString::fromLatin1("autoLoadImages") + << QString::fromLatin1("developerExtrasEnabled") + << QString::fromLatin1("javaEnabled") + << QString::fromLatin1("javascriptCanAccessClipboard") + << QString::fromLatin1("javascriptCanOpenWindows") + << QString::fromLatin1("javascriptEnabled") + << QString::fromLatin1("linksIncludedInFocusChain") + << QString::fromLatin1("localContentCanAccessRemoteUrls") + << QString::fromLatin1("localStorageDatabaseEnabled") + << QString::fromLatin1("offlineStorageDatabaseEnabled") + << QString::fromLatin1("offlineWebApplicationCacheEnabled") + << QString::fromLatin1("pluginsEnabled") + << QString::fromLatin1("printElementBackgrounds") + << QString::fromLatin1("privateBrowsingEnabled") + << QString::fromLatin1("zoomTextOnly"); // Merely tests that setting gets stored (in QWebSettings), behavioural tests are in WebKit. for (int b = 0; b <= 1; b++) { bool value = !!b; foreach (const QString& name, settingsList) - s->setProperty(name.toAscii().data(), value); + s->setProperty(name.toLatin1().data(), value); for (int i = 0; i < 2; i++) { foreach (const QString& name, settingsList) - QCOMPARE(s->property(name.toAscii().data()).toBool(), value); + QCOMPARE(s->property(name.toLatin1().data()).toBool(), value); } } } diff --git a/Source/WebKit/qt/tests/qobjectbridge/qobjectbridge.pro b/Source/WebKit/qt/tests/qobjectbridge/qobjectbridge.pro new file mode 100644 index 000000000..f434ccbc1 --- /dev/null +++ b/Source/WebKit/qt/tests/qobjectbridge/qobjectbridge.pro @@ -0,0 +1,3 @@ +include(../tests.pri) +exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc + diff --git a/Source/WebKit/qt/tests/qobjectbridge/tst_qobjectbridge.cpp b/Source/WebKit/qt/tests/qobjectbridge/tst_qobjectbridge.cpp new file mode 100644 index 000000000..32e8233ea --- /dev/null +++ b/Source/WebKit/qt/tests/qobjectbridge/tst_qobjectbridge.cpp @@ -0,0 +1,2189 @@ +/* + Copyright (C) 2008,2009 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 library 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 library; 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 <QtTest/QtTest> + +#include <qbrush.h> +#include <qwebelement.h> +#include <qwebframe.h> +#include <qwebpage.h> +#include <qwebview.h> + +struct CustomType { + QString string; +}; +Q_DECLARE_METATYPE(CustomType) + +Q_DECLARE_METATYPE(QBrush*) +Q_DECLARE_METATYPE(QObjectList) +Q_DECLARE_METATYPE(QList<int>) +Q_DECLARE_METATYPE(Qt::BrushStyle) +Q_DECLARE_METATYPE(QVariantList) +Q_DECLARE_METATYPE(QVariantMap) + +class MyQObject : public QObject { + Q_OBJECT + + Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty) + Q_PROPERTY(QVariant variantProperty READ variantProperty WRITE setVariantProperty) + Q_PROPERTY(QVariantList variantListProperty READ variantListProperty WRITE setVariantListProperty) + Q_PROPERTY(QVariantMap variantMapProperty READ variantMapProperty WRITE setVariantMapProperty) + Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty) + Q_PROPERTY(QStringList stringListProperty READ stringListProperty WRITE setStringListProperty) + Q_PROPERTY(QByteArray byteArrayProperty READ byteArrayProperty WRITE setByteArrayProperty) + Q_PROPERTY(QBrush brushProperty READ brushProperty WRITE setBrushProperty) + Q_PROPERTY(double hiddenProperty READ hiddenProperty WRITE setHiddenProperty SCRIPTABLE false) + Q_PROPERTY(int writeOnlyProperty WRITE setWriteOnlyProperty) + Q_PROPERTY(int readOnlyProperty READ readOnlyProperty) + Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut) + Q_PROPERTY(CustomType propWithCustomType READ propWithCustomType WRITE setPropWithCustomType) + Q_PROPERTY(QWebElement webElementProperty READ webElementProperty WRITE setWebElementProperty) + Q_PROPERTY(QObject* objectStarProperty READ objectStarProperty WRITE setObjectStarProperty) + Q_ENUMS(Policy Strategy) + Q_FLAGS(Ability) + +public: + enum Policy { + FooPolicy = 0, + BarPolicy, + BazPolicy + }; + + enum Strategy { + FooStrategy = 10, + BarStrategy, + BazStrategy + }; + + enum AbilityFlag { + NoAbility = 0x000, + FooAbility = 0x001, + BarAbility = 0x080, + BazAbility = 0x200, + AllAbility = FooAbility | BarAbility | BazAbility + }; + + Q_DECLARE_FLAGS(Ability, AbilityFlag) + + MyQObject(QObject* parent = 0) + : QObject(parent), + m_intValue(123), + m_variantValue(QLatin1String("foo")), + m_variantListValue(QVariantList() << QVariant(123) << QVariant(QLatin1String("foo"))), + m_stringValue(QLatin1String("bar")), + m_stringListValue(QStringList() << QLatin1String("zig") << QLatin1String("zag")), + m_brushValue(QColor(10, 20, 30, 40)), + m_hiddenValue(456.0), + m_writeOnlyValue(789), + m_readOnlyValue(987), + m_objectStar(0), + m_qtFunctionInvoked(-1) + { + m_variantMapValue.insert("a", QVariant(123)); + m_variantMapValue.insert("b", QVariant(QLatin1String("foo"))); + m_variantMapValue.insert("c", QVariant::fromValue<QObject*>(this)); + } + + ~MyQObject() { } + + int intProperty() const + { + return m_intValue; + } + void setIntProperty(int value) + { + m_intValue = value; + } + + QVariant variantProperty() const + { + return m_variantValue; + } + void setVariantProperty(const QVariant& value) + { + m_variantValue = value; + } + + QVariantList variantListProperty() const + { + return m_variantListValue; + } + void setVariantListProperty(const QVariantList& value) + { + m_variantListValue = value; + } + + QVariantMap variantMapProperty() const + { + return m_variantMapValue; + } + void setVariantMapProperty(const QVariantMap& value) + { + m_variantMapValue = value; + } + + QString stringProperty() const + { + return m_stringValue; + } + void setStringProperty(const QString& value) + { + m_stringValue = value; + } + + QStringList stringListProperty() const + { + return m_stringListValue; + } + void setStringListProperty(const QStringList& value) + { + m_stringListValue = value; + } + + QByteArray byteArrayProperty() const + { + return m_byteArrayValue; + } + void setByteArrayProperty(const QByteArray& value) + { + m_byteArrayValue = value; + } + + QBrush brushProperty() const + { + return m_brushValue; + } + void setBrushProperty(const QBrush& value) + { + m_brushValue = value; + } + + double hiddenProperty() const + { + return m_hiddenValue; + } + void setHiddenProperty(double value) + { + m_hiddenValue = value; + } + + int writeOnlyProperty() const + { + return m_writeOnlyValue; + } + void setWriteOnlyProperty(int value) + { + m_writeOnlyValue = value; + } + + int readOnlyProperty() const + { + return m_readOnlyValue; + } + + QKeySequence shortcut() const + { + return m_shortcut; + } + void setShortcut(const QKeySequence& seq) + { + m_shortcut = seq; + } + + QWebElement webElementProperty() const + { + return m_webElement; + } + void setWebElementProperty(const QWebElement& element) + { + m_webElement = element; + } + + CustomType propWithCustomType() const + { + return m_customType; + } + void setPropWithCustomType(const CustomType& c) + { + m_customType = c; + } + + QObject* objectStarProperty() const + { + return m_objectStar; + } + void setObjectStarProperty(QObject* object) + { + m_objectStar = object; + } + + + int qtFunctionInvoked() const + { + return m_qtFunctionInvoked; + } + + QVariantList qtFunctionActuals() const + { + return m_actuals; + } + + void resetQtFunctionInvoked() + { + m_qtFunctionInvoked = -1; + m_actuals.clear(); + } + + Q_INVOKABLE void myInvokable() + { + m_qtFunctionInvoked = 0; + } + Q_INVOKABLE void myInvokableWithIntArg(int arg) + { + m_qtFunctionInvoked = 1; + m_actuals << arg; + } + Q_INVOKABLE void myInvokableWithLonglongArg(qlonglong arg) + { + m_qtFunctionInvoked = 2; + m_actuals << arg; + } + Q_INVOKABLE void myInvokableWithFloatArg(float arg) + { + m_qtFunctionInvoked = 3; + m_actuals << arg; + } + Q_INVOKABLE void myInvokableWithDoubleArg(double arg) + { + m_qtFunctionInvoked = 4; + m_actuals << arg; + } + Q_INVOKABLE void myInvokableWithStringArg(const QString& arg) + { + m_qtFunctionInvoked = 5; + m_actuals << arg; + } + Q_INVOKABLE void myInvokableWithIntArgs(int arg1, int arg2) + { + m_qtFunctionInvoked = 6; + m_actuals << arg1 << arg2; + } + Q_INVOKABLE int myInvokableReturningInt() + { + m_qtFunctionInvoked = 7; + return 123; + } + Q_INVOKABLE qlonglong myInvokableReturningLongLong() + { + m_qtFunctionInvoked = 39; + return 456; + } + Q_INVOKABLE QString myInvokableReturningString() + { + m_qtFunctionInvoked = 8; + return QLatin1String("ciao"); + } + Q_INVOKABLE void myInvokableWithIntArg(int arg1, int arg2) // Overload. + { + m_qtFunctionInvoked = 9; + m_actuals << arg1 << arg2; + } + Q_INVOKABLE void myInvokableWithEnumArg(Policy policy) + { + m_qtFunctionInvoked = 10; + m_actuals << policy; + } + Q_INVOKABLE void myInvokableWithQualifiedEnumArg(MyQObject::Policy policy) + { + m_qtFunctionInvoked = 36; + m_actuals << policy; + } + Q_INVOKABLE Policy myInvokableReturningEnum() + { + m_qtFunctionInvoked = 37; + return BazPolicy; + } + Q_INVOKABLE MyQObject::Policy myInvokableReturningQualifiedEnum() + { + m_qtFunctionInvoked = 38; + return BazPolicy; + } + Q_INVOKABLE QVector<int> myInvokableReturningVectorOfInt() + { + m_qtFunctionInvoked = 11; + return QVector<int>(); + } + Q_INVOKABLE void myInvokableWithVectorOfIntArg(const QVector<int>&) + { + m_qtFunctionInvoked = 12; + } + Q_INVOKABLE QObject* myInvokableReturningQObjectStar() + { + m_qtFunctionInvoked = 13; + return this; + } + Q_INVOKABLE QObjectList myInvokableWithQObjectListArg(const QObjectList& lst) + { + m_qtFunctionInvoked = 14; + m_actuals << QVariant::fromValue(lst); + return lst; + } + Q_INVOKABLE QVariant myInvokableWithVariantArg(const QVariant& v) + { + m_qtFunctionInvoked = 15; + m_actuals << v; + return v; + } + Q_INVOKABLE QVariantMap myInvokableWithVariantMapArg(const QVariantMap& vm) + { + m_qtFunctionInvoked = 16; + m_actuals << vm; + return vm; + } + Q_INVOKABLE QList<int> myInvokableWithListOfIntArg(const QList<int>& lst) + { + m_qtFunctionInvoked = 17; + m_actuals << QVariant::fromValue(lst); + return lst; + } + Q_INVOKABLE QObject* myInvokableWithQObjectStarArg(QObject* obj) + { + m_qtFunctionInvoked = 18; + m_actuals << QVariant::fromValue(obj); + return obj; + } + Q_INVOKABLE QBrush myInvokableWithQBrushArg(const QBrush& brush) + { + m_qtFunctionInvoked = 19; + m_actuals << QVariant::fromValue(brush); + return brush; + } + Q_INVOKABLE void myInvokableWithBrushStyleArg(Qt::BrushStyle style) + { + m_qtFunctionInvoked = 43; + m_actuals << QVariant::fromValue(style); + } + Q_INVOKABLE void myInvokableWithVoidStarArg(void* arg) + { + m_qtFunctionInvoked = 44; + m_actuals << QVariant::fromValue(arg); + } + Q_INVOKABLE void myInvokableWithAmbiguousArg(int arg) + { + m_qtFunctionInvoked = 45; + m_actuals << QVariant::fromValue(arg); + } + Q_INVOKABLE void myInvokableWithAmbiguousArg(uint arg) + { + m_qtFunctionInvoked = 46; + m_actuals << QVariant::fromValue(arg); + } + Q_INVOKABLE void myInvokableWithDefaultArgs(int arg1, const QString& arg2 = QString()) + { + m_qtFunctionInvoked = 47; + m_actuals << QVariant::fromValue(arg1) << qVariantFromValue(arg2); + } + Q_INVOKABLE QObject& myInvokableReturningRef() + { + m_qtFunctionInvoked = 48; + return *this; + } + Q_INVOKABLE const QObject& myInvokableReturningConstRef() const + { + const_cast<MyQObject*>(this)->m_qtFunctionInvoked = 49; + return *this; + } + Q_INVOKABLE void myInvokableWithPointArg(const QPoint &arg) { + const_cast<MyQObject*>(this)->m_qtFunctionInvoked = 50; + m_actuals << QVariant::fromValue(arg); + } + Q_INVOKABLE void myInvokableWithPointArg(const QPointF &arg) { + const_cast<MyQObject*>(this)->m_qtFunctionInvoked = 51; + m_actuals << QVariant::fromValue(arg); + } + Q_INVOKABLE void myInvokableWithBoolArg(bool arg) { + m_qtFunctionInvoked = 52; + m_actuals << arg; + } + + void emitMySignal() + { + emit mySignal(); + } + void emitMySignalWithIntArg(int arg) + { + emit mySignalWithIntArg(arg); + } + void emitMySignal2(bool arg) + { + emit mySignal2(arg); + } + void emitMySignal2() + { + emit mySignal2(); + } + void emitMySignalWithDateTimeArg(QDateTime dt) + { + emit mySignalWithDateTimeArg(dt); + } + void emitMySignalWithRegexArg(QRegExp r) + { + emit mySignalWithRegexArg(r); + } + +public Q_SLOTS: + void mySlot() + { + m_qtFunctionInvoked = 20; + } + + void mySlotWithIntArg(int arg) + { + m_qtFunctionInvoked = 21; + m_actuals << arg; + } + + void mySlotWithDoubleArg(double arg) + { + m_qtFunctionInvoked = 22; + m_actuals << arg; + } + + void mySlotWithStringArg(const QString &arg) + { + m_qtFunctionInvoked = 23; + m_actuals << arg; + } + + void myOverloadedSlot() + { + m_qtFunctionInvoked = 24; + } + + void myOverloadedSlot(QObject* arg) + { + m_qtFunctionInvoked = 41; + m_actuals << QVariant::fromValue(arg); + } + + void myOverloadedSlot(bool arg) + { + m_qtFunctionInvoked = 25; + m_actuals << arg; + } + + void myOverloadedSlot(const QStringList &arg) + { + m_qtFunctionInvoked = 42; + m_actuals << arg; + } + + void myOverloadedSlot(double arg) + { + m_qtFunctionInvoked = 26; + m_actuals << arg; + } + + void myOverloadedSlot(float arg) + { + m_qtFunctionInvoked = 27; + m_actuals << arg; + } + + void myOverloadedSlot(int arg) + { + m_qtFunctionInvoked = 28; + m_actuals << arg; + } + + void myOverloadedSlot(const QString &arg) + { + m_qtFunctionInvoked = 29; + m_actuals << arg; + } + + void myOverloadedSlot(const QColor &arg) + { + m_qtFunctionInvoked = 30; + m_actuals << arg; + } + + void myOverloadedSlot(const QBrush &arg) + { + m_qtFunctionInvoked = 31; + m_actuals << arg; + } + + void myOverloadedSlot(const QDateTime &arg) + { + m_qtFunctionInvoked = 32; + m_actuals << arg; + } + + void myOverloadedSlot(const QDate &arg) + { + m_qtFunctionInvoked = 33; + m_actuals << arg; + } + + void myOverloadedSlot(const QRegExp &arg) + { + m_qtFunctionInvoked = 34; + m_actuals << arg; + } + + void myOverloadedSlot(const QVariant &arg) + { + m_qtFunctionInvoked = 35; + m_actuals << arg; + } + + void myOverloadedSlot(const QWebElement &arg) + { + m_qtFunctionInvoked = 36; + m_actuals << QVariant::fromValue<QWebElement>(arg); + } + +protected Q_SLOTS: + void myProtectedSlot() + { + m_qtFunctionInvoked = 36; + } + +private Q_SLOTS: + void myPrivateSlot() { } + +Q_SIGNALS: + void mySignal(); + void mySignalWithIntArg(int); + void mySignalWithDoubleArg(double); + void mySignal2(bool arg = false); + void mySignalWithDateTimeArg(QDateTime); + void mySignalWithRegexArg(QRegExp); + +private: + int m_intValue; + QVariant m_variantValue; + QVariantList m_variantListValue; + QVariantMap m_variantMapValue; + QString m_stringValue; + QStringList m_stringListValue; + QByteArray m_byteArrayValue; + QBrush m_brushValue; + double m_hiddenValue; + int m_writeOnlyValue; + int m_readOnlyValue; + QKeySequence m_shortcut; + QWebElement m_webElement; + CustomType m_customType; + QObject* m_objectStar; + int m_qtFunctionInvoked; + QVariantList m_actuals; +}; + +class MyWebElementSlotOnlyObject : public QObject { + Q_OBJECT + Q_PROPERTY(QString tagName READ tagName) +public slots: + void doSomethingWithWebElement(const QWebElement& element) + { + m_tagName = element.tagName(); + } + +public: + QString tagName() const + { + return m_tagName; + } +private: + QString m_tagName; +}; + +class MyOtherQObject : public MyQObject { +public: + MyOtherQObject(QObject* parent = 0) + : MyQObject(parent) { } +}; + +class tst_QObjectBridge : public QObject { + Q_OBJECT + +public: + tst_QObjectBridge(); + +public slots: + void init(); + void cleanup(); + +private slots: + void getSetStaticProperty(); + void getSetDynamicProperty(); + void getSetChildren(); + void callQtInvokable(); + void connectAndDisconnect(); + void overrideInvokable(); + void overloadedSlots(); + void webElementSlotOnly(); + void enumerate_data(); + void enumerate(); + void objectDeleted(); + void typeConversion(); + void arrayObjectEnumerable(); + void domCycles(); + void jsByteArray(); + void ownership(); + void nullValue(); + void qObjectWrapperWithSameIdentity(); + void introspectQtMethods_data(); + void introspectQtMethods(); + +private: + QString evalJS(const QString& s) + { + // Convert an undefined return variant to the string "undefined" + QVariant ret = evalJSV(s); + if (ret.userType() == QMetaType::Void) + return "undefined"; + return ret.toString(); + } + + QVariant evalJSV(const QString& s) + { + return m_page->mainFrame()->evaluateJavaScript(s); + } + + QString evalJS(const QString& s, QString& type) + { + return evalJSV(s, type).toString(); + } + + QVariant evalJSV(const QString& s, QString& type) + { + // As a special measure, if we get an exception we set the type to 'error' + // (in ecma, an Error object has typeof object, but qtscript has a convenience function) + // Similarly, an array is an object, but we'd prefer to have a type of 'array' + // Also, consider a QMetaType::Void QVariant to be undefined + QString escaped = s; + escaped.replace('\'', "\\'"); // Don't preescape your single quotes! + QString code("var retvalue; " + "var typevalue; " + "try { " + " retvalue = eval('%1'); " + " typevalue = typeof retvalue; " + " if (retvalue instanceof Array) " + " typevalue = 'array'; " + "} catch(e) { " + " retvalue = e.name + ': ' + e.message; " + " typevalue = 'error'; " + "}"); + evalJS(code.arg(escaped)); + + QVariant ret = evalJSV("retvalue"); + if (ret.userType() != QMetaType::Void) + type = evalJS("typevalue"); + else { + ret = QString("undefined"); + type = sUndefined; + } + evalJS("delete retvalue; delete typevalue"); + return ret; + } + + const QString sTrue; + const QString sFalse; + const QString sUndefined; + const QString sArray; + const QString sFunction; + const QString sError; + const QString sString; + const QString sObject; + const QString sNumber; + +private: + QWebView* m_view; + QWebPage* m_page; + MyQObject* m_myObject; +}; + +tst_QObjectBridge::tst_QObjectBridge() + : sTrue("true") + , sFalse("false") + , sUndefined("undefined") + , sArray("array") + , sFunction("function") + , sError("error") + , sString("string") + , sObject("object") + , sNumber("number") +{ +} + +void tst_QObjectBridge::init() +{ + m_view = new QWebView(); + m_page = m_view->page(); + m_myObject = new MyQObject(); + m_page->mainFrame()->addToJavaScriptWindowObject("myObject", m_myObject); +} + +void tst_QObjectBridge::cleanup() +{ + delete m_view; + delete m_myObject; +} + +void tst_QObjectBridge::getSetStaticProperty() +{ + m_page->mainFrame()->setHtml("<html><head><body></body></html>"); + QCOMPARE(evalJS("typeof myObject.noSuchProperty"), sUndefined); + + // initial value (set in MyQObject constructor) + { + QString type; + QVariant ret = evalJSV("myObject.intProperty", type); + QCOMPARE(type, sNumber); + QCOMPARE(ret.type(), QVariant::Double); + QCOMPARE(ret.toInt(), 123); + } + QCOMPARE(evalJS("myObject.intProperty === 123.0"), sTrue); + + { + QString type; + QVariant ret = evalJSV("myObject.variantProperty", type); + QCOMPARE(type, sString); + QCOMPARE(ret.type(), QVariant::String); + QCOMPARE(ret.toString(), QLatin1String("foo")); + } + QCOMPARE(evalJS("myObject.variantProperty == 'foo'"), sTrue); + + { + QString type; + QVariant ret = evalJSV("myObject.stringProperty", type); + QCOMPARE(type, sString); + QCOMPARE(ret.type(), QVariant::String); + QCOMPARE(ret.toString(), QLatin1String("bar")); + } + QCOMPARE(evalJS("myObject.stringProperty === 'bar'"), sTrue); + + { + QString type; + QVariant ret = evalJSV("myObject.variantListProperty", type); + QCOMPARE(type, sArray); + QCOMPARE(ret.type(), QVariant::List); + QVariantList vl = ret.value<QVariantList>(); + QCOMPARE(vl.size(), 2); + QCOMPARE(vl.at(0).toInt(), 123); + QCOMPARE(vl.at(1).toString(), QLatin1String("foo")); + } + QCOMPARE(evalJS("myObject.variantListProperty.length === 2"), sTrue); + QCOMPARE(evalJS("myObject.variantListProperty[0] === 123"), sTrue); + QCOMPARE(evalJS("myObject.variantListProperty[1] === 'foo'"), sTrue); + + { + QString type; + QVariant ret = evalJSV("myObject.variantMapProperty", type); + QCOMPARE(type, sObject); + QCOMPARE(ret.type(), QVariant::Map); + QVariantMap vm = ret.value<QVariantMap>(); + QCOMPARE(vm.size(), 3); + QCOMPARE(vm.value("a").toInt(), 123); + QCOMPARE(vm.value("b").toString(), QLatin1String("foo")); + QCOMPARE(vm.value("c").value<QObject*>(), static_cast<QObject*>(m_myObject)); + } + QCOMPARE(evalJS("myObject.variantMapProperty.a === 123"), sTrue); + QCOMPARE(evalJS("myObject.variantMapProperty.b === 'foo'"), sTrue); + QCOMPARE(evalJS("myObject.variantMapProperty.c.variantMapProperty.b === 'foo'"), sTrue); + + { + QString type; + QVariant ret = evalJSV("myObject.stringListProperty", type); + QCOMPARE(type, sArray); + QCOMPARE(ret.type(), QVariant::List); + QVariantList vl = ret.value<QVariantList>(); + QCOMPARE(vl.size(), 2); + QCOMPARE(vl.at(0).toString(), QLatin1String("zig")); + QCOMPARE(vl.at(1).toString(), QLatin1String("zag")); + } + QCOMPARE(evalJS("myObject.stringListProperty.length === 2"), sTrue); + QCOMPARE(evalJS("typeof myObject.stringListProperty[0]"), sString); + QCOMPARE(evalJS("myObject.stringListProperty[0]"), QLatin1String("zig")); + QCOMPARE(evalJS("typeof myObject.stringListProperty[1]"), sString); + QCOMPARE(evalJS("myObject.stringListProperty[1]"), QLatin1String("zag")); + + // property change in C++ should be reflected in script + m_myObject->setIntProperty(456); + QCOMPARE(evalJS("myObject.intProperty == 456"), sTrue); + m_myObject->setIntProperty(789); + QCOMPARE(evalJS("myObject.intProperty == 789"), sTrue); + + m_myObject->setVariantProperty(QLatin1String("bar")); + QCOMPARE(evalJS("myObject.variantProperty === 'bar'"), sTrue); + m_myObject->setVariantProperty(42); + QCOMPARE(evalJS("myObject.variantProperty === 42"), sTrue); + m_myObject->setVariantProperty(QVariant::fromValue(QBrush())); + + m_myObject->setStringProperty(QLatin1String("baz")); + QCOMPARE(evalJS("myObject.stringProperty === 'baz'"), sTrue); + m_myObject->setStringProperty(QLatin1String("zab")); + QCOMPARE(evalJS("myObject.stringProperty === 'zab'"), sTrue); + + // property change in script should be reflected in C++ + QCOMPARE(evalJS("myObject.intProperty = 123"), QLatin1String("123")); + QCOMPARE(evalJS("myObject.intProperty == 123"), sTrue); + QCOMPARE(m_myObject->intProperty(), 123); + QCOMPARE(evalJS("myObject.intProperty = 'ciao!';" + "myObject.intProperty == 0"), sTrue); + QCOMPARE(m_myObject->intProperty(), 0); + QCOMPARE(evalJS("myObject.intProperty = '123';" + "myObject.intProperty == 123"), sTrue); + QCOMPARE(m_myObject->intProperty(), 123); + + QCOMPARE(evalJS("myObject.stringProperty = 'ciao'"), QLatin1String("ciao")); + QCOMPARE(evalJS("myObject.stringProperty"), QLatin1String("ciao")); + QCOMPARE(m_myObject->stringProperty(), QLatin1String("ciao")); + QCOMPARE(evalJS("myObject.stringProperty = 123;" + "myObject.stringProperty"), QLatin1String("123")); + QCOMPARE(m_myObject->stringProperty(), QLatin1String("123")); + QCOMPARE(evalJS("myObject.stringProperty = null"), QString()); + QCOMPARE(evalJS("myObject.stringProperty"), QString()); + QCOMPARE(m_myObject->stringProperty(), QString()); + QCOMPARE(evalJS("myObject.stringProperty = undefined"), sUndefined); + QCOMPARE(evalJS("myObject.stringProperty"), QString()); + QCOMPARE(m_myObject->stringProperty(), QString()); + + QCOMPARE(evalJS("myObject.variantProperty = new Number(1234);" + "myObject.variantProperty").toDouble(), 1234.0); + QCOMPARE(m_myObject->variantProperty().toDouble(), 1234.0); + + QCOMPARE(evalJS("myObject.variantProperty = new Boolean(1234);" + "myObject.variantProperty"), sTrue); + QCOMPARE(m_myObject->variantProperty().toBool(), true); + + QCOMPARE(evalJS("myObject.variantProperty = null;" + "myObject.variantProperty.valueOf()"), sUndefined); + QCOMPARE(m_myObject->variantProperty(), QVariant()); + QCOMPARE(evalJS("myObject.variantProperty = undefined;" + "myObject.variantProperty.valueOf()"), sUndefined); + QCOMPARE(m_myObject->variantProperty(), QVariant()); + + QCOMPARE(evalJS("myObject.variantProperty = 'foo';" + "myObject.variantProperty.valueOf()"), QLatin1String("foo")); + QCOMPARE(m_myObject->variantProperty(), QVariant(QLatin1String("foo"))); + QCOMPARE(evalJS("myObject.variantProperty = 42;" + "myObject.variantProperty").toDouble(), 42.0); + QCOMPARE(m_myObject->variantProperty().toDouble(), 42.0); + + QCOMPARE(evalJS("myObject.variantListProperty = [1, 'two', true];" + "myObject.variantListProperty.length == 3"), sTrue); + QCOMPARE(evalJS("myObject.variantListProperty[0] === 1"), sTrue); + QCOMPARE(evalJS("myObject.variantListProperty[1]"), QLatin1String("two")); + QCOMPARE(evalJS("myObject.variantListProperty[2] === true"), sTrue); + + QCOMPARE(evalJS("myObject.stringListProperty = [1, 'two', true];" + "myObject.stringListProperty.length == 3"), sTrue); + QCOMPARE(evalJS("typeof myObject.stringListProperty[0]"), sString); + QCOMPARE(evalJS("myObject.stringListProperty[0] == '1'"), sTrue); + QCOMPARE(evalJS("typeof myObject.stringListProperty[1]"), sString); + QCOMPARE(evalJS("myObject.stringListProperty[1]"), QLatin1String("two")); + QCOMPARE(evalJS("typeof myObject.stringListProperty[2]"), sString); + QCOMPARE(evalJS("myObject.stringListProperty[2]"), QLatin1String("true")); + evalJS("myObject.webElementProperty=document.body;"); + QCOMPARE(evalJS("myObject.webElementProperty.tagName"), QLatin1String("BODY")); + + // try to delete + QCOMPARE(evalJS("delete myObject.intProperty"), sFalse); + QCOMPARE(evalJS("myObject.intProperty == 123"), sTrue); + + QCOMPARE(evalJS("delete myObject.variantProperty"), sFalse); + QCOMPARE(evalJS("myObject.variantProperty").toDouble(), 42.0); + + // custom property + QCOMPARE(evalJS("myObject.customProperty"), sUndefined); + QCOMPARE(evalJS("myObject.customProperty = 123;" + "myObject.customProperty == 123"), sTrue); + QVariant v = m_page->mainFrame()->evaluateJavaScript("myObject.customProperty"); + QCOMPARE(v.type(), QVariant::Double); + QCOMPARE(v.toInt(), 123); + + // non-scriptable property + QCOMPARE(m_myObject->hiddenProperty(), 456.0); + QCOMPARE(evalJS("myObject.hiddenProperty"), sUndefined); + QCOMPARE(evalJS("myObject.hiddenProperty = 123;" + "myObject.hiddenProperty == 123"), sTrue); + QCOMPARE(m_myObject->hiddenProperty(), 456.0); + + // write-only property + QCOMPARE(m_myObject->writeOnlyProperty(), 789); + QCOMPARE(evalJS("typeof myObject.writeOnlyProperty"), sUndefined); + QCOMPARE(evalJS("myObject.writeOnlyProperty = 123;" + "typeof myObject.writeOnlyProperty"), sUndefined); + QCOMPARE(m_myObject->writeOnlyProperty(), 123); + + // read-only property + QCOMPARE(m_myObject->readOnlyProperty(), 987); + QCOMPARE(evalJS("myObject.readOnlyProperty == 987"), sTrue); + QCOMPARE(evalJS("myObject.readOnlyProperty = 654;" + "myObject.readOnlyProperty == 987"), sTrue); + QCOMPARE(m_myObject->readOnlyProperty(), 987); + + // QObject* property + m_myObject->setObjectStarProperty(0); + QCOMPARE(m_myObject->objectStarProperty(), (QObject*)0); + QCOMPARE(evalJS("myObject.objectStarProperty == null"), sTrue); + QCOMPARE(evalJS("typeof myObject.objectStarProperty"), sObject); + QCOMPARE(evalJS("Boolean(myObject.objectStarProperty)"), sFalse); + QCOMPARE(evalJS("String(myObject.objectStarProperty) == 'null'"), sTrue); + QCOMPARE(evalJS("myObject.objectStarProperty.objectStarProperty"), + sUndefined); + m_myObject->setObjectStarProperty(this); + QCOMPARE(evalJS("myObject.objectStarProperty != null"), sTrue); + QCOMPARE(evalJS("typeof myObject.objectStarProperty"), sObject); + QCOMPARE(evalJS("Boolean(myObject.objectStarProperty)"), sTrue); + QCOMPARE(evalJS("String(myObject.objectStarProperty) != 'null'"), sTrue); +} + +void tst_QObjectBridge::getSetDynamicProperty() +{ + // initially the object does not have the property + // In WebKit, RuntimeObjects do not inherit Object, so don't have hasOwnProperty + + // QCOMPARE(evalJS("myObject.hasOwnProperty('dynamicProperty')"), sFalse); + QCOMPARE(evalJS("typeof myObject.dynamicProperty"), sUndefined); + + // add a dynamic property in C++ + QCOMPARE(m_myObject->setProperty("dynamicProperty", 123), false); + // QCOMPARE(evalJS("myObject.hasOwnProperty('dynamicProperty')"), sTrue); + QCOMPARE(evalJS("typeof myObject.dynamicProperty != 'undefined'"), sTrue); + QCOMPARE(evalJS("myObject.dynamicProperty == 123"), sTrue); + + // property change in script should be reflected in C++ + QCOMPARE(evalJS("myObject.dynamicProperty = 'foo';" + "myObject.dynamicProperty"), QLatin1String("foo")); + QCOMPARE(m_myObject->property("dynamicProperty").toString(), QLatin1String("foo")); + + // delete the property (XFAIL - can't delete properties) + QEXPECT_FAIL("", "can't delete properties", Continue); + QCOMPARE(evalJS("delete myObject.dynamicProperty"), sTrue); + /* + QCOMPARE(m_myObject->property("dynamicProperty").isValid(), false); + QCOMPARE(evalJS("typeof myObject.dynamicProperty"), sUndefined); + // QCOMPARE(evalJS("myObject.hasOwnProperty('dynamicProperty')"), sFalse); + QCOMPARE(evalJS("typeof myObject.dynamicProperty"), sUndefined); + */ +} + +void tst_QObjectBridge::getSetChildren() +{ + // initially the object does not have the child + // (again, no hasOwnProperty) + + // QCOMPARE(evalJS("myObject.hasOwnProperty('child')"), sFalse); + QCOMPARE(evalJS("typeof myObject.child"), sUndefined); + + // add a child + MyQObject* child = new MyQObject(m_myObject); + child->setObjectName("child"); +// QCOMPARE(evalJS("myObject.hasOwnProperty('child')"), sTrue); + QCOMPARE(evalJS("typeof myObject.child != 'undefined'"), sTrue); + + // add a grandchild + MyQObject* grandChild = new MyQObject(child); + grandChild->setObjectName("grandChild"); +// QCOMPARE(evalJS("myObject.child.hasOwnProperty('grandChild')"), sTrue); + QCOMPARE(evalJS("typeof myObject.child.grandChild != 'undefined'"), sTrue); + + // delete grandchild + delete grandChild; +// QCOMPARE(evalJS("myObject.child.hasOwnProperty('grandChild')"), sFalse); + QCOMPARE(evalJS("typeof myObject.child.grandChild == 'undefined'"), sTrue); + + // delete child + delete child; +// QCOMPARE(evalJS("myObject.hasOwnProperty('child')"), sFalse); + QCOMPARE(evalJS("typeof myObject.child == 'undefined'"), sTrue); +} + +Q_DECLARE_METATYPE(QVector<int>) +Q_DECLARE_METATYPE(QVector<double>) +Q_DECLARE_METATYPE(QVector<QString>) + +void tst_QObjectBridge::callQtInvokable() +{ + qRegisterMetaType<QObjectList>(); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokable()"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 0); + QCOMPARE(m_myObject->qtFunctionActuals(), QVariantList()); + + // extra arguments should silently be ignored + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokable(10, 20, 30)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 0); + QCOMPARE(m_myObject->qtFunctionActuals(), QVariantList()); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithIntArg(123)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithIntArg('123')"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithLonglongArg(123)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 2); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toLongLong(), qlonglong(123)); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithFloatArg(123.5)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 3); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDouble(), 123.5); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithDoubleArg(123.5)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 4); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDouble(), 123.5); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithDoubleArg(new Number(1234.5))"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 4); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDouble(), 1234.5); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithBoolArg(new Boolean(true))"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 52); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toBool(), true); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithStringArg('ciao')"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 5); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toString(), QLatin1String("ciao")); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithStringArg(123)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 5); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toString(), QLatin1String("123")); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithStringArg(null)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 5); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toString(), QString()); + QVERIFY(m_myObject->qtFunctionActuals().at(0).toString().isEmpty()); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithStringArg(undefined)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 5); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toString(), QString()); + QVERIFY(m_myObject->qtFunctionActuals().at(0).toString().isEmpty()); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithIntArgs(123, 456)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 6); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 2); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); + QCOMPARE(m_myObject->qtFunctionActuals().at(1).toInt(), 456); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("myObject.myInvokableReturningInt()"), QLatin1String("123")); + QCOMPARE(m_myObject->qtFunctionInvoked(), 7); + QCOMPARE(m_myObject->qtFunctionActuals(), QVariantList()); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("myObject.myInvokableReturningLongLong()"), QLatin1String("456")); + QCOMPARE(m_myObject->qtFunctionInvoked(), 39); + QCOMPARE(m_myObject->qtFunctionActuals(), QVariantList()); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("myObject.myInvokableReturningString()"), QLatin1String("ciao")); + QCOMPARE(m_myObject->qtFunctionInvoked(), 8); + QCOMPARE(m_myObject->qtFunctionActuals(), QVariantList()); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithIntArg(123, 456)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 9); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 2); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); + QCOMPARE(m_myObject->qtFunctionActuals().at(1).toInt(), 456); + + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("typeof myObject.myInvokableWithVoidStarArg(null)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 44); + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QString ret = evalJS("myObject.myInvokableWithVoidStarArg(123)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: incompatible type of argument(s) in call to myInvokableWithVoidStarArg(); candidates were\n myInvokableWithVoidStarArg(void*)")); + QCOMPARE(m_myObject->qtFunctionInvoked(), -1); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QString ret = evalJS("myObject.myInvokableWithAmbiguousArg(123)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: ambiguous call of overloaded function myInvokableWithAmbiguousArg(); candidates were\n myInvokableWithAmbiguousArg(int)\n myInvokableWithAmbiguousArg(uint)")); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QString ret = evalJS("myObject.myInvokableWithDefaultArgs(123, 'hello')", type); + QCOMPARE(type, sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 47); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 2); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); + QCOMPARE(m_myObject->qtFunctionActuals().at(1).toString(), QLatin1String("hello")); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QString ret = evalJS("myObject.myInvokableWithDefaultArgs(456)", type); + QCOMPARE(type, sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 47); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 2); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 456); + QCOMPARE(m_myObject->qtFunctionActuals().at(1).toString(), QString()); + } + + // calling function that returns (const)ref + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QString ret = evalJS("typeof myObject.myInvokableReturningRef()"); + QCOMPARE(ret, sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 48); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QString ret = evalJS("typeof myObject.myInvokableReturningConstRef()"); + QCOMPARE(ret, sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 49); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QVariant ret = evalJSV("myObject.myInvokableReturningQObjectStar()", type); + QCOMPARE(m_myObject->qtFunctionInvoked(), 13); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 0); + QCOMPARE(type, sObject); + QCOMPARE(ret.userType(), int(QMetaType::QObjectStar)); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QVariant ret = evalJSV("myObject.myInvokableWithQObjectListArg([myObject])", type); + QCOMPARE(m_myObject->qtFunctionInvoked(), 14); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(type, sArray); + QCOMPARE(ret.userType(), int(QVariant::List)); // All lists get downgraded to QVariantList + QVariantList vl = qvariant_cast<QVariantList>(ret); + QCOMPARE(vl.count(), 1); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + m_myObject->setVariantProperty(QVariant(123)); + QVariant ret = evalJSV("myObject.myInvokableWithVariantArg(myObject.variantProperty)", type); + QCOMPARE(type, sNumber); + QCOMPARE(m_myObject->qtFunctionInvoked(), 15); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0), m_myObject->variantProperty()); + QCOMPARE(ret.userType(), int(QMetaType::Double)); // all JS numbers are doubles, even though this started as an int + QCOMPARE(ret.toInt(), 123); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QVariant ret = evalJSV("myObject.myInvokableWithVariantArg(null)", type); + QCOMPARE(type, sObject); + QCOMPARE(m_myObject->qtFunctionInvoked(), 15); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0), QVariant()); + QVERIFY(!m_myObject->qtFunctionActuals().at(0).isValid()); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QVariant ret = evalJSV("myObject.myInvokableWithVariantArg(undefined)", type); + QCOMPARE(type, sObject); + QCOMPARE(m_myObject->qtFunctionInvoked(), 15); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0), QVariant()); + QVERIFY(!m_myObject->qtFunctionActuals().at(0).isValid()); + } + + /* XFAIL - variant support + m_myObject->resetQtFunctionInvoked(); + { + m_myObject->setVariantProperty(QVariant::fromValue(QBrush())); + QVariant ret = evalJS("myObject.myInvokableWithVariantArg(myObject.variantProperty)"); + QVERIFY(ret.isVariant()); + QCOMPARE(m_myObject->qtFunctionInvoked(), 15); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(ret.toVariant(), m_myObject->qtFunctionActuals().at(0)); + QCOMPARE(ret.toVariant(), m_myObject->variantProperty()); + } + */ + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QVariant ret = evalJSV("myObject.myInvokableWithVariantArg(123)", type); + QCOMPARE(type, sNumber); + QCOMPARE(m_myObject->qtFunctionInvoked(), 15); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0), QVariant(123)); + QCOMPARE(ret.userType(), int(QMetaType::Double)); + QCOMPARE(ret.toInt(), 123); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QVariant ret = evalJSV("myObject.myInvokableWithVariantMapArg({ a:123, b:'ciao' })", type); + QCOMPARE(m_myObject->qtFunctionInvoked(), 16); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + + QVariant v = m_myObject->qtFunctionActuals().at(0); + QCOMPARE(v.userType(), int(QMetaType::QVariantMap)); + + QVariantMap vmap = qvariant_cast<QVariantMap>(v); + QCOMPARE(vmap.keys().size(), 2); + QCOMPARE(vmap.keys().at(0), QLatin1String("a")); + QCOMPARE(vmap.value("a"), QVariant(123)); + QCOMPARE(vmap.keys().at(1), QLatin1String("b")); + QCOMPARE(vmap.value("b"), QVariant("ciao")); + + QCOMPARE(type, sObject); + + QCOMPARE(ret.userType(), int(QMetaType::QVariantMap)); + vmap = qvariant_cast<QVariantMap>(ret); + QCOMPARE(vmap.keys().size(), 2); + QCOMPARE(vmap.keys().at(0), QLatin1String("a")); + QCOMPARE(vmap.value("a"), QVariant(123)); + QCOMPARE(vmap.keys().at(1), QLatin1String("b")); + QCOMPARE(vmap.value("b"), QVariant("ciao")); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QVariant ret = evalJSV("myObject.myInvokableWithListOfIntArg([1, 5])", type); + QCOMPARE(m_myObject->qtFunctionInvoked(), 17); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QVariant v = m_myObject->qtFunctionActuals().at(0); + QCOMPARE(v.userType(), qMetaTypeId<QList<int> >()); + QList<int> ilst = qvariant_cast<QList<int> >(v); + QCOMPARE(ilst.size(), 2); + QCOMPARE(ilst.at(0), 1); + QCOMPARE(ilst.at(1), 5); + + QCOMPARE(type, sArray); + QCOMPARE(ret.userType(), int(QMetaType::QVariantList)); // ints get converted to doubles, so this is a qvariantlist + QVariantList vlst = qvariant_cast<QVariantList>(ret); + QCOMPARE(vlst.size(), 2); + QCOMPARE(vlst.at(0).toInt(), 1); + QCOMPARE(vlst.at(1).toInt(), 5); + } + + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QVariant ret = evalJSV("myObject.myInvokableWithQObjectStarArg(myObject)", type); + QCOMPARE(m_myObject->qtFunctionInvoked(), 18); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QVariant v = m_myObject->qtFunctionActuals().at(0); + QCOMPARE(v.userType(), int(QMetaType::QObjectStar)); + QCOMPARE(qvariant_cast<QObject*>(v), (QObject*)m_myObject); + + QCOMPARE(ret.userType(), int(QMetaType::QObjectStar)); + QCOMPARE(qvariant_cast<QObject*>(ret), (QObject*)m_myObject); + + QCOMPARE(type, sObject); + } + + m_myObject->resetQtFunctionInvoked(); + { + // no implicit conversion from integer to QObject* + QString type; + evalJS("myObject.myInvokableWithQObjectStarArg(123)", type); + QCOMPARE(type, sError); + } + + /* + m_myObject->resetQtFunctionInvoked(); + { + QString fun = evalJS("myObject.myInvokableWithQBrushArg"); + Q_ASSERT(fun.isFunction()); + QColor color(10, 20, 30, 40); + // QColor should be converted to a QBrush + QVariant ret = fun.call(QString(), QStringList() + << qScriptValueFromValue(m_engine, color)); + QCOMPARE(m_myObject->qtFunctionInvoked(), 19); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QVariant v = m_myObject->qtFunctionActuals().at(0); + QCOMPARE(v.userType(), int(QMetaType::QBrush)); + QCOMPARE(qvariant_cast<QColor>(v), color); + + QCOMPARE(qscriptvalue_cast<QColor>(ret), color); + } + */ + + // private slots should not be part of the QObject binding + QCOMPARE(evalJS("typeof myObject.myPrivateSlot"), sUndefined); + + // protected slots should be fine + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myProtectedSlot()"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 36); + + // call with too few arguments + { + QString type; + QString ret = evalJS("myObject.myInvokableWithIntArg()", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("SyntaxError: too few arguments in call to myInvokableWithIntArg(); candidates are\n myInvokableWithIntArg(int,int)\n myInvokableWithIntArg(int)")); + } + + // call function where not all types have been registered + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QString ret = evalJS("myObject.myInvokableWithBrushStyleArg(0)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: cannot call myInvokableWithBrushStyleArg(): unknown type `Qt::BrushStyle'")); + QCOMPARE(m_myObject->qtFunctionInvoked(), -1); + } + + // call function with incompatible argument type + m_myObject->resetQtFunctionInvoked(); + { + QString type; + QString ret = evalJS("myObject.myInvokableWithQBrushArg(null)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: incompatible type of argument(s) in call to myInvokableWithQBrushArg(); candidates were\n myInvokableWithQBrushArg(QBrush)")); + QCOMPARE(m_myObject->qtFunctionInvoked(), -1); + } +} + +void tst_QObjectBridge::connectAndDisconnect() +{ + // connect(function) + QCOMPARE(evalJS("typeof myObject.mySignal"), sFunction); + QCOMPARE(evalJS("typeof myObject.mySignal.connect"), sFunction); + QCOMPARE(evalJS("typeof myObject.mySignal.disconnect"), sFunction); + + { + QString type; + evalJS("myObject.mySignal.connect(123)", type); + QCOMPARE(type, sError); + } + + evalJS("myHandler = function() { window.gotSignal = true; window.signalArgs = arguments; window.slotThisObject = this; window.signalSender = __qt_sender__; }"); + + QCOMPARE(evalJS("myObject.mySignal.connect(myHandler)"), sUndefined); + + evalJS("gotSignal = false"); + evalJS("myObject.mySignal()"); + QCOMPARE(evalJS("gotSignal"), sTrue); + QCOMPARE(evalJS("signalArgs.length == 0"), sTrue); + QCOMPARE(evalJS("signalSender"), evalJS("myObject")); + QCOMPARE(evalJS("slotThisObject == window"), sTrue); + + evalJS("gotSignal = false"); + m_myObject->emitMySignal(); + QCOMPARE(evalJS("gotSignal"), sTrue); + QCOMPARE(evalJS("signalArgs.length == 0"), sTrue); + + QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myHandler)"), sUndefined); + + evalJS("gotSignal = false"); + m_myObject->emitMySignalWithIntArg(123); + QCOMPARE(evalJS("gotSignal"), sTrue); + QCOMPARE(evalJS("signalArgs.length == 1"), sTrue); + QCOMPARE(evalJS("signalArgs[0] == 123.0"), sTrue); + + QCOMPARE(evalJS("myObject.mySignal.disconnect(myHandler)"), sUndefined); + { + QString type; + evalJS("myObject.mySignal.disconnect(myHandler)", type); + QCOMPARE(type, sError); + } + + evalJS("gotSignal = false"); + QCOMPARE(evalJS("myObject.mySignal2.connect(myHandler)"), sUndefined); + m_myObject->emitMySignal2(true); + QCOMPARE(evalJS("gotSignal"), sTrue); + QCOMPARE(evalJS("signalArgs.length == 1"), sTrue); + QCOMPARE(evalJS("signalArgs[0]"), sTrue); + + QCOMPARE(evalJS("myObject.mySignal2.disconnect(myHandler)"), sUndefined); + + QCOMPARE(evalJS("typeof myObject['mySignal2()']"), sFunction); + QCOMPARE(evalJS("typeof myObject['mySignal2()'].connect"), sFunction); + QCOMPARE(evalJS("typeof myObject['mySignal2()'].disconnect"), sFunction); + + QCOMPARE(evalJS("myObject['mySignal2()'].connect(myHandler)"), sUndefined); + + evalJS("gotSignal = false"); + m_myObject->emitMySignal2(); + QCOMPARE(evalJS("gotSignal"), sTrue); + + QCOMPARE(evalJS("myObject['mySignal2()'].disconnect(myHandler)"), sUndefined); + + // connect(object, function) + evalJS("otherObject = { name:'foo' }"); + QCOMPARE(evalJS("myObject.mySignal.connect(otherObject, myHandler)"), sUndefined); + QCOMPARE(evalJS("myObject.mySignal.disconnect(otherObject, myHandler)"), sUndefined); + evalJS("gotSignal = false"); + m_myObject->emitMySignal(); + QCOMPARE(evalJS("gotSignal"), sFalse); + + { + QString type; + evalJS("myObject.mySignal.disconnect(otherObject, myHandler)", type); + QCOMPARE(type, sError); + } + + QCOMPARE(evalJS("myObject.mySignal.connect(otherObject, myHandler)"), sUndefined); + evalJS("gotSignal = false"); + m_myObject->emitMySignal(); + QCOMPARE(evalJS("gotSignal"), sTrue); + QCOMPARE(evalJS("signalArgs.length == 0"), sTrue); + QCOMPARE(evalJS("slotThisObject"), evalJS("otherObject")); + QCOMPARE(evalJS("signalSender"), evalJS("myObject")); + QCOMPARE(evalJS("slotThisObject.name"), QLatin1String("foo")); + QCOMPARE(evalJS("myObject.mySignal.disconnect(otherObject, myHandler)"), sUndefined); + + evalJS("yetAnotherObject = { name:'bar', func : function() { } }"); + QCOMPARE(evalJS("myObject.mySignal2.connect(yetAnotherObject, myHandler)"), sUndefined); + evalJS("gotSignal = false"); + m_myObject->emitMySignal2(true); + QCOMPARE(evalJS("gotSignal"), sTrue); + QCOMPARE(evalJS("signalArgs.length == 1"), sTrue); + QCOMPARE(evalJS("slotThisObject == yetAnotherObject"), sTrue); + QCOMPARE(evalJS("signalSender == myObject"), sTrue); + QCOMPARE(evalJS("slotThisObject.name"), QLatin1String("bar")); + QCOMPARE(evalJS("myObject.mySignal2.disconnect(yetAnotherObject, myHandler)"), sUndefined); + + QCOMPARE(evalJS("myObject.mySignal2.connect(myObject, myHandler)"), sUndefined); + evalJS("gotSignal = false"); + m_myObject->emitMySignal2(true); + QCOMPARE(evalJS("gotSignal"), sTrue); + QCOMPARE(evalJS("signalArgs.length == 1"), sTrue); + QCOMPARE(evalJS("slotThisObject == myObject"), sTrue); + QCOMPARE(evalJS("signalSender == myObject"), sTrue); + QCOMPARE(evalJS("myObject.mySignal2.disconnect(myObject, myHandler)"), sUndefined); + + // connect(obj, string) + QCOMPARE(evalJS("myObject.mySignal.connect(yetAnotherObject, 'func')"), sUndefined); + QCOMPARE(evalJS("myObject.mySignal.connect(myObject, 'mySlot')"), sUndefined); + QCOMPARE(evalJS("myObject.mySignal.disconnect(yetAnotherObject, 'func')"), sUndefined); + QCOMPARE(evalJS("myObject.mySignal.disconnect(myObject, 'mySlot')"), sUndefined); + + // check that emitting signals from script works + + // no arguments + QCOMPARE(evalJS("myObject.mySignal.connect(myObject.mySlot)"), sUndefined); + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("myObject.mySignal()"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 20); + QCOMPARE(evalJS("myObject.mySignal.disconnect(myObject.mySlot)"), sUndefined); + + // one argument + QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myObject.mySlotWithIntArg)"), sUndefined); + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("myObject.mySignalWithIntArg(123)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 21); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); + QCOMPARE(evalJS("myObject.mySignalWithIntArg.disconnect(myObject.mySlotWithIntArg)"), sUndefined); + + QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myObject.mySlotWithDoubleArg)"), sUndefined); + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("myObject.mySignalWithIntArg(123)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 22); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDouble(), 123.0); + QCOMPARE(evalJS("myObject.mySignalWithIntArg.disconnect(myObject.mySlotWithDoubleArg)"), sUndefined); + + QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myObject.mySlotWithStringArg)"), sUndefined); + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("myObject.mySignalWithIntArg(123)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 23); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toString(), QLatin1String("123")); + QCOMPARE(evalJS("myObject.mySignalWithIntArg.disconnect(myObject.mySlotWithStringArg)"), sUndefined); + + // connecting to overloaded slot + QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myObject.myOverloadedSlot)"), sUndefined); + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("myObject.mySignalWithIntArg(123)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 26); // double overload + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); + QCOMPARE(evalJS("myObject.mySignalWithIntArg.disconnect(myObject.myOverloadedSlot)"), sUndefined); + + QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myObject['myOverloadedSlot(int)'])"), sUndefined); + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("myObject.mySignalWithIntArg(456)"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 28); // int overload + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 456); + QCOMPARE(evalJS("myObject.mySignalWithIntArg.disconnect(myObject['myOverloadedSlot(int)'])"), sUndefined); + + // erroneous input + { + // ### QtScript adds .connect to all functions, WebKit does only to signals/slots + QString type; + QString ret = evalJS("(function() { }).connect()", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: 'undefined' is not a function")); + } + { + QString type; + QString ret = evalJS("var o = { }; o.connect = Function.prototype.connect; o.connect()", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: 'undefined' is not a function")); + } + + { + QString type; + QString ret = evalJS("(function() { }).connect(123)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: 'undefined' is not a function")); + } + { + QString type; + QString ret = evalJS("var o = { }; o.connect = Function.prototype.connect; o.connect(123)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: 'undefined' is not a function")); + } + + { + QString type; + QString ret = evalJS("myObject.myInvokable.connect(123)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.connect: MyQObject::myInvokable() is not a signal")); + } + { + QString type; + QString ret = evalJS("myObject.myInvokable.connect(function() { })", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.connect: MyQObject::myInvokable() is not a signal")); + } + + { + QString type; + QString ret = evalJS("myObject.mySignal.connect(123)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.connect: target is not a function")); + } + + { + QString type; + QString ret = evalJS("myObject.mySignal.disconnect()", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("Error: QtMetaMethod.disconnect: no arguments given")); + } + { + QString type; + QString ret = evalJS("var o = { }; o.disconnect = myObject.mySignal.disconnect; o.disconnect()", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("Error: QtMetaMethod.disconnect: no arguments given")); + } + + /* XFAIL - Function.prototype doesn't get connect/disconnect, just signals/slots + { + QString type; + QString ret = evalJS("(function() { }).disconnect(123)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.disconnect: this object is not a signal")); + } + */ + + { + QString type; + QString ret = evalJS("var o = { }; o.disconnect = myObject.myInvokable.disconnect; o.disconnect(123)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.disconnect: MyQObject::myInvokable() is not a signal")); + } + + { + QString type; + QString ret = evalJS("myObject.myInvokable.disconnect(123)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.disconnect: MyQObject::myInvokable() is not a signal")); + } + { + QString type; + QString ret = evalJS("myObject.myInvokable.disconnect(function() { })", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.disconnect: MyQObject::myInvokable() is not a signal")); + } + + { + QString type; + QString ret = evalJS("myObject.mySignal.disconnect(123)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.disconnect: target is not a function")); + } + + { + QString type; + QString ret = evalJS("myObject.mySignal.disconnect(function() { })", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("Error: QtMetaMethod.disconnect: failed to disconnect from MyQObject::mySignal()")); + } + + // when the wrapper dies, the connection stays alive + QCOMPARE(evalJS("myObject.mySignal.connect(myObject.mySlot)"), sUndefined); + m_myObject->resetQtFunctionInvoked(); + m_myObject->emitMySignal(); + QCOMPARE(m_myObject->qtFunctionInvoked(), 20); + evalJS("myObject = null"); + evalJS("gc()"); + m_myObject->resetQtFunctionInvoked(); + m_myObject->emitMySignal(); + QCOMPARE(m_myObject->qtFunctionInvoked(), 20); +} + +void tst_QObjectBridge::overrideInvokable() +{ + m_myObject->resetQtFunctionInvoked(); + QCOMPARE(evalJS("myObject.myInvokable()"), sUndefined); + QCOMPARE(m_myObject->qtFunctionInvoked(), 0); + + /* XFAIL - can't write to functions with RuntimeObject + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myInvokable = function() { window.a = 123; }"); + evalJS("myObject.myInvokable()"); + QCOMPARE(m_myObject->qtFunctionInvoked(), -1); + QCOMPARE(evalJS("window.a").toDouble(), 123.0); + + evalJS("myObject.myInvokable = function() { window.a = 456; }"); + evalJS("myObject.myInvokable()"); + QCOMPARE(m_myObject->qtFunctionInvoked(), -1); + QCOMPARE(evalJS("window.a").toDouble(), 456.0); + */ + + evalJS("delete myObject.myInvokable"); + evalJS("myObject.myInvokable()"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 0); + + /* XFAIL - ditto + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myInvokable = myObject.myInvokableWithIntArg"); + evalJS("myObject.myInvokable(123)"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 1); + */ + + evalJS("delete myObject.myInvokable"); + m_myObject->resetQtFunctionInvoked(); + // this form (with the '()') is read-only + evalJS("myObject['myInvokable()'] = function() { window.a = 123; }"); + evalJS("myObject.myInvokable()"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 0); +} + +void tst_QObjectBridge::overloadedSlots() +{ + // should pick myOverloadedSlot(double) + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myOverloadedSlot(10)"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 26); + + // should pick myOverloadedSlot(double) + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myOverloadedSlot(10.0)"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 26); + + // should pick myOverloadedSlot(QString) + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myOverloadedSlot('10')"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 29); + + // should pick myOverloadedSlot(bool) + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myOverloadedSlot(true)"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 25); + + // should pick myOverloadedSlot(QDateTime) + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myOverloadedSlot(new Date())"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 32); + + // should pick myOverloadedSlot(QRegExp) + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myOverloadedSlot(new RegExp())"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 34); + + // should pick myOverloadedSlot(QVariant) + /* XFAIL + m_myObject->resetQtFunctionInvoked(); + QString f = evalJS("myObject.myOverloadedSlot"); + f.call(QString(), QStringList() << m_engine->newVariant(QVariant("ciao"))); + QCOMPARE(m_myObject->qtFunctionInvoked(), 35); + */ + + // Should pick myOverloadedSlot(QWebElement). + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myOverloadedSlot(document.body)"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 36); + + // should pick myOverloadedSlot(QObject*) + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myOverloadedSlot(myObject)"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 41); + + // should pick myOverloadedSlot(QObject*) + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myOverloadedSlot(null)"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 41); + + // should pick myOverloadedSlot(QStringList) + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myOverloadedSlot(['hello'])"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 42); +} + +class MyEnumTestQObject : public QObject { + Q_OBJECT + Q_PROPERTY(QString p1 READ p1) + Q_PROPERTY(QString p2 READ p2) + Q_PROPERTY(QString p3 READ p3 SCRIPTABLE false) + Q_PROPERTY(QString p4 READ p4) + Q_PROPERTY(QString p5 READ p5 SCRIPTABLE false) + Q_PROPERTY(QString p6 READ p6) +public: + MyEnumTestQObject(QObject* parent = 0) + : QObject(parent) { } + + QString p1() const { return QLatin1String("p1"); } + QString p2() const { return QLatin1String("p2"); } + QString p3() const { return QLatin1String("p3"); } + QString p4() const { return QLatin1String("p4"); } + QString p5() const { return QLatin1String("p5"); } + QString p6() const { return QLatin1String("p6"); } + +public Q_SLOTS: + void mySlot() { } + void myOtherSlot() { } +Q_SIGNALS: + void mySignal(); +}; + +void tst_QObjectBridge::enumerate_data() +{ + QTest::addColumn<QStringList>("expectedNames"); + + QTest::newRow("enumerate all") + << (QStringList() + // meta-object-defined properties: + // inherited + << "objectName" + // non-inherited + << "p1" << "p2" << "p4" << "p6" + // dynamic properties + << "dp1" << "dp2" << "dp3" + // inherited signals and slots + << "destroyed(QObject*)" << "destroyed()" +#if defined(HAVE_QT5) && HAVE_QT5 + << "objectNameChanged(QString)" +#endif + << "deleteLater()" + // not included because it's private: + // << "_q_reregisterTimers(void*)" + // signals + << "mySignal()" + // slots + << "mySlot()" << "myOtherSlot()"); +} + +void tst_QObjectBridge::enumerate() +{ + QFETCH(QStringList, expectedNames); + + MyEnumTestQObject enumQObject; + // give it some dynamic properties + enumQObject.setProperty("dp1", "dp1"); + enumQObject.setProperty("dp2", "dp2"); + enumQObject.setProperty("dp3", "dp3"); + m_page->mainFrame()->addToJavaScriptWindowObject("myEnumObject", &enumQObject); + + // enumerate in script + { + evalJS("var enumeratedProperties = []"); + evalJS("for (var p in myEnumObject) { enumeratedProperties.push(p); }"); + QStringList result = evalJSV("enumeratedProperties").toStringList(); + QCOMPARE(result.size(), expectedNames.size()); + for (int i = 0; i < expectedNames.size(); ++i) + QCOMPARE(result.at(i), expectedNames.at(i)); + } +} + +void tst_QObjectBridge::objectDeleted() +{ + MyQObject* qobj = new MyQObject(); + m_page->mainFrame()->addToJavaScriptWindowObject("bar", qobj); + evalJS("bar.objectName = 'foo';"); + QCOMPARE(qobj->objectName(), QLatin1String("foo")); + evalJS("bar.intProperty = 123;"); + QCOMPARE(qobj->intProperty(), 123); + qobj->resetQtFunctionInvoked(); + evalJS("bar.myInvokable.call(bar);"); + QCOMPARE(qobj->qtFunctionInvoked(), 0); + + // do this, to ensure that we cache that it implements call + evalJS("bar()"); + + // now delete the object + delete qobj; + + QCOMPARE(evalJS("typeof bar"), sObject); + + // any attempt to access properties of the object should result in an exception + { + QString type; + QString ret = evalJS("bar.objectName", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("Error: cannot access member `objectName' of deleted QObject")); + } + { + QString type; + QString ret = evalJS("bar.objectName = 'foo'", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("Error: cannot access member `objectName' of deleted QObject")); + } + + // myInvokable is stored in member table (since we've accessed it before deletion) + { + QString type; + evalJS("bar.myInvokable", type); + QCOMPARE(type, sFunction); + } + + { + QString type; + QString ret = evalJS("bar.myInvokable.call(bar);", type); + ret = evalJS("bar.myInvokable(bar)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("Error: cannot call function of deleted QObject")); + } + // myInvokableWithIntArg is not stored in member table (since we've not accessed it) + { + QString type; + QString ret = evalJS("bar.myInvokableWithIntArg", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("Error: cannot access member `myInvokableWithIntArg' of deleted QObject")); + } + + // access from script + evalJS("window.o = bar;"); + { + QString type; + QString ret = evalJS("o.objectName", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("Error: cannot access member `objectName' of deleted QObject")); + } + { + QString type; + QString ret = evalJS("o.myInvokable()", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("Error: cannot call function of deleted QObject")); + } + { + QString type; + QString ret = evalJS("o.myInvokableWithIntArg(10)", type); + QCOMPARE(type, sError); + QCOMPARE(ret, QLatin1String("Error: cannot access member `myInvokableWithIntArg' of deleted QObject")); + } +} + +void tst_QObjectBridge::typeConversion() +{ + m_myObject->resetQtFunctionInvoked(); + + QDateTime localdt(QDate(2008, 1, 18), QTime(12, 31, 0)); + QDateTime utclocaldt = localdt.toUTC(); + QDateTime utcdt(QDate(2008, 1, 18), QTime(12, 31, 0), Qt::UTC); + + // Dates in JS (default to local) + evalJS("myObject.myOverloadedSlot(new Date(2008,0,18,12,31,0))"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 32); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDateTime().toUTC(), utclocaldt); + + m_myObject->resetQtFunctionInvoked(); + evalJS("myObject.myOverloadedSlot(new Date(Date.UTC(2008,0,18,12,31,0)))"); + QCOMPARE(m_myObject->qtFunctionInvoked(), 32); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDateTime().toUTC(), utcdt); + + // Pushing QDateTimes into JS + // Local + evalJS("function checkDate(d) {window.__date_equals = (d.toString() == new Date(2008,0,18,12,31,0))?true:false;}"); + evalJS("myObject.mySignalWithDateTimeArg.connect(checkDate)"); + m_myObject->emitMySignalWithDateTimeArg(localdt); + QCOMPARE(evalJS("window.__date_equals"), sTrue); + evalJS("delete window.__date_equals"); + m_myObject->emitMySignalWithDateTimeArg(utclocaldt); + QCOMPARE(evalJS("window.__date_equals"), sTrue); + evalJS("delete window.__date_equals"); + evalJS("myObject.mySignalWithDateTimeArg.disconnect(checkDate); delete checkDate;"); + + // UTC + evalJS("function checkDate(d) {window.__date_equals = (d.toString() == new Date(Date.UTC(2008,0,18,12,31,0)))?true:false; }"); + evalJS("myObject.mySignalWithDateTimeArg.connect(checkDate)"); + m_myObject->emitMySignalWithDateTimeArg(utcdt); + QCOMPARE(evalJS("window.__date_equals"), sTrue); + evalJS("delete window.__date_equals"); + evalJS("myObject.mySignalWithDateTimeArg.disconnect(checkDate); delete checkDate;"); + + // ### RegExps +} + +class StringListTestObject : public QObject { + Q_OBJECT +public Q_SLOTS: + QVariant stringList() + { + return QStringList() << "Q" << "t"; + }; +}; + +void tst_QObjectBridge::arrayObjectEnumerable() +{ + QWebPage page; + QWebFrame* frame = page.mainFrame(); + QObject* qobject = new StringListTestObject(); + frame->addToJavaScriptWindowObject("test", qobject, QScriptEngine::ScriptOwnership); + + const QString script("var stringArray = test.stringList();" + "var result = '';" + "for (var i in stringArray) {" + " result += stringArray[i];" + "}" + "result;"); + QCOMPARE(frame->evaluateJavaScript(script).toString(), QString::fromLatin1("Qt")); +} + +void tst_QObjectBridge::domCycles() +{ + m_view->setHtml("<html><body>"); + QVariant v = m_page->mainFrame()->evaluateJavaScript("document"); + QVERIFY(v.type() == QVariant::Map); +} + +void tst_QObjectBridge::jsByteArray() +{ + QByteArray ba("hello world"); + m_myObject->setByteArrayProperty(ba); + + // read-only property + QCOMPARE(m_myObject->byteArrayProperty(), ba); + QString type; + QVariant v = evalJSV("myObject.byteArrayProperty"); + QCOMPARE(int(v.type()), int(QVariant::ByteArray)); + + QCOMPARE(v.toByteArray(), ba); +} + +void tst_QObjectBridge::ownership() +{ + // test ownership + { + QWeakPointer<QObject> ptr = new QObject(); + QVERIFY(ptr); + { + QWebPage page; + QWebFrame* frame = page.mainFrame(); + frame->addToJavaScriptWindowObject("test", ptr.data(), QScriptEngine::ScriptOwnership); + } + QVERIFY(!ptr); + } + { + QWeakPointer<QObject> ptr = new QObject(); + QVERIFY(ptr); + QObject* before = ptr.data(); + { + QWebPage page; + QWebFrame* frame = page.mainFrame(); + frame->addToJavaScriptWindowObject("test", ptr.data(), QScriptEngine::QtOwnership); + } + QVERIFY(ptr.data() == before); + delete ptr.data(); + } + { + QObject* parent = new QObject(); + QObject* child = new QObject(parent); + QWebPage page; + QWebFrame* frame = page.mainFrame(); + frame->addToJavaScriptWindowObject("test", child, QScriptEngine::QtOwnership); + QVariant v = frame->evaluateJavaScript("test"); + QCOMPARE(qvariant_cast<QObject*>(v), child); + delete parent; + v = frame->evaluateJavaScript("test"); + QCOMPARE(qvariant_cast<QObject*>(v), (QObject *)0); + } + { + QWeakPointer<QObject> ptr = new QObject(); + QVERIFY(ptr); + { + QWebPage page; + QWebFrame* frame = page.mainFrame(); + frame->addToJavaScriptWindowObject("test", ptr.data(), QScriptEngine::AutoOwnership); + } + // no parent, so it should be like ScriptOwnership + QVERIFY(!ptr); + } + { + QObject* parent = new QObject(); + QWeakPointer<QObject> child = new QObject(parent); + QVERIFY(child); + { + QWebPage page; + QWebFrame* frame = page.mainFrame(); + frame->addToJavaScriptWindowObject("test", child.data(), QScriptEngine::AutoOwnership); + } + // has parent, so it should be like QtOwnership + QVERIFY(child); + delete parent; + } +} + +void tst_QObjectBridge::nullValue() +{ + QVariant v = m_view->page()->mainFrame()->evaluateJavaScript("null"); + QVERIFY(v.isNull()); +} + +class TestFactory : public QObject { + Q_OBJECT +public: + TestFactory() + : obj(0), counter(0) + { } + + Q_INVOKABLE QObject* getNewObject() + { + delete obj; + obj = new QObject(this); + obj->setObjectName(QLatin1String("test") + QString::number(++counter)); + return obj; + + } + + QObject* obj; + int counter; +}; + +void tst_QObjectBridge::qObjectWrapperWithSameIdentity() +{ + m_view->setHtml("<script>function triggerBug() { document.getElementById('span1').innerText = test.getNewObject().objectName; }</script>" + "<body><span id='span1'>test</span></body>"); + + QWebFrame* mainFrame = m_view->page()->mainFrame(); + QCOMPARE(mainFrame->toPlainText(), QString("test")); + + mainFrame->addToJavaScriptWindowObject("test", new TestFactory, QScriptEngine::ScriptOwnership); + + mainFrame->evaluateJavaScript("triggerBug();"); + QCOMPARE(mainFrame->toPlainText(), QString("test1")); + + mainFrame->evaluateJavaScript("triggerBug();"); + QCOMPARE(mainFrame->toPlainText(), QString("test2")); +} + +void tst_QObjectBridge::introspectQtMethods_data() +{ + QTest::addColumn<QString>("objectExpression"); + QTest::addColumn<QString>("methodName"); + QTest::addColumn<QStringList>("expectedPropertyNames"); + + QTest::newRow("myObject.mySignal") + << "myObject" << "mySignal" << (QStringList() << "connect" << "disconnect" << "length" << "name"); + QTest::newRow("myObject.mySlot") + << "myObject" << "mySlot" << (QStringList() << "connect" << "disconnect" << "length" << "name"); + QTest::newRow("myObject.myInvokable") + << "myObject" << "myInvokable" << (QStringList() << "connect" << "disconnect" << "length" << "name"); + QTest::newRow("myObject.mySignal.connect") + << "myObject.mySignal" << "connect" << (QStringList() << "length" << "name"); + QTest::newRow("myObject.mySignal.disconnect") + << "myObject.mySignal" << "disconnect" << (QStringList() << "length" << "name"); +} + +void tst_QObjectBridge::introspectQtMethods() +{ + QFETCH(QString, objectExpression); + QFETCH(QString, methodName); + QFETCH(QStringList, expectedPropertyNames); + + QString methodLookup = QString::fromLatin1("%0['%1']").arg(objectExpression).arg(methodName); + QCOMPARE(evalJSV(QString::fromLatin1("Object.getOwnPropertyNames(%0).sort()").arg(methodLookup)).toStringList(), expectedPropertyNames); + + for (int i = 0; i < expectedPropertyNames.size(); ++i) { + QString name = expectedPropertyNames.at(i); + QCOMPARE(evalJS(QString::fromLatin1("%0.hasOwnProperty('%1')").arg(methodLookup).arg(name)), sTrue); + evalJS(QString::fromLatin1("var descriptor = Object.getOwnPropertyDescriptor(%0, '%1')").arg(methodLookup).arg(name)); + QCOMPARE(evalJS("typeof descriptor"), QString::fromLatin1("object")); + QCOMPARE(evalJS("descriptor.get"), sUndefined); + QCOMPARE(evalJS("descriptor.set"), sUndefined); + QCOMPARE(evalJS(QString::fromLatin1("descriptor.value === %0['%1']").arg(methodLookup).arg(name)), sTrue); + QCOMPARE(evalJS(QString::fromLatin1("descriptor.enumerable")), sFalse); + QCOMPARE(evalJS(QString::fromLatin1("descriptor.configurable")), sFalse); + } + + QVERIFY(evalJSV("var props=[]; for (var p in myObject.deleteLater) {props.push(p);}; props.sort()").toStringList().isEmpty()); +} + +void tst_QObjectBridge::webElementSlotOnly() +{ + MyWebElementSlotOnlyObject object; + m_page->mainFrame()->setHtml("<html><head><body></body></html>"); + m_page->mainFrame()->addToJavaScriptWindowObject("myWebElementSlotObject", &object); + evalJS("myWebElementSlotObject.doSomethingWithWebElement(document.body)"); + QCOMPARE(evalJS("myWebElementSlotObject.tagName"), QString("BODY")); +} + +QTEST_MAIN(tst_QObjectBridge) +#include "tst_qobjectbridge.moc" diff --git a/Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp index 3d8a2b3ce..31d87b75a 100644 --- a/Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp +++ b/Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp @@ -22,7 +22,6 @@ #include <qwebpage.h> #include <qwebelement.h> -#include <qwidget.h> #include <qwebview.h> #include <qwebframe.h> #include <qwebhistory.h> @@ -40,549 +39,11 @@ #endif #include "../util.h" -struct CustomType { - QString string; -}; -Q_DECLARE_METATYPE(CustomType) - -Q_DECLARE_METATYPE(QBrush*) -Q_DECLARE_METATYPE(QObjectList) -Q_DECLARE_METATYPE(QList<int>) -Q_DECLARE_METATYPE(Qt::BrushStyle) -Q_DECLARE_METATYPE(QVariantList) -Q_DECLARE_METATYPE(QVariantMap) - -class MyQObject : public QObject -{ - Q_OBJECT - - Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty) - Q_PROPERTY(QVariant variantProperty READ variantProperty WRITE setVariantProperty) - Q_PROPERTY(QVariantList variantListProperty READ variantListProperty WRITE setVariantListProperty) - Q_PROPERTY(QVariantMap variantMapProperty READ variantMapProperty WRITE setVariantMapProperty) - Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty) - Q_PROPERTY(QStringList stringListProperty READ stringListProperty WRITE setStringListProperty) - Q_PROPERTY(QByteArray byteArrayProperty READ byteArrayProperty WRITE setByteArrayProperty) - Q_PROPERTY(QBrush brushProperty READ brushProperty WRITE setBrushProperty) - Q_PROPERTY(double hiddenProperty READ hiddenProperty WRITE setHiddenProperty SCRIPTABLE false) - Q_PROPERTY(int writeOnlyProperty WRITE setWriteOnlyProperty) - Q_PROPERTY(int readOnlyProperty READ readOnlyProperty) - Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut) - Q_PROPERTY(CustomType propWithCustomType READ propWithCustomType WRITE setPropWithCustomType) - Q_PROPERTY(QWebElement webElementProperty READ webElementProperty WRITE setWebElementProperty) - Q_PROPERTY(QObject* objectStarProperty READ objectStarProperty WRITE setObjectStarProperty) - Q_ENUMS(Policy Strategy) - Q_FLAGS(Ability) - -public: - enum Policy { - FooPolicy = 0, - BarPolicy, - BazPolicy - }; - - enum Strategy { - FooStrategy = 10, - BarStrategy, - BazStrategy - }; - - enum AbilityFlag { - NoAbility = 0x000, - FooAbility = 0x001, - BarAbility = 0x080, - BazAbility = 0x200, - AllAbility = FooAbility | BarAbility | BazAbility - }; - - Q_DECLARE_FLAGS(Ability, AbilityFlag) - - MyQObject(QObject* parent = 0) - : QObject(parent), - m_intValue(123), - m_variantValue(QLatin1String("foo")), - m_variantListValue(QVariantList() << QVariant(123) << QVariant(QLatin1String("foo"))), - m_stringValue(QLatin1String("bar")), - m_stringListValue(QStringList() << QLatin1String("zig") << QLatin1String("zag")), - m_brushValue(QColor(10, 20, 30, 40)), - m_hiddenValue(456.0), - m_writeOnlyValue(789), - m_readOnlyValue(987), - m_objectStar(0), - m_qtFunctionInvoked(-1) - { - m_variantMapValue.insert("a", QVariant(123)); - m_variantMapValue.insert("b", QVariant(QLatin1String("foo"))); - m_variantMapValue.insert("c", QVariant::fromValue<QObject*>(this)); - } - - ~MyQObject() { } - - int intProperty() const { - return m_intValue; - } - void setIntProperty(int value) { - m_intValue = value; - } - - QVariant variantProperty() const { - return m_variantValue; - } - void setVariantProperty(const QVariant &value) { - m_variantValue = value; - } - - QVariantList variantListProperty() const { - return m_variantListValue; - } - void setVariantListProperty(const QVariantList &value) { - m_variantListValue = value; - } - - QVariantMap variantMapProperty() const { - return m_variantMapValue; - } - void setVariantMapProperty(const QVariantMap &value) { - m_variantMapValue = value; - } - - QString stringProperty() const { - return m_stringValue; - } - void setStringProperty(const QString &value) { - m_stringValue = value; - } - - QStringList stringListProperty() const { - return m_stringListValue; - } - void setStringListProperty(const QStringList &value) { - m_stringListValue = value; - } - - QByteArray byteArrayProperty() const { - return m_byteArrayValue; - } - void setByteArrayProperty(const QByteArray &value) { - m_byteArrayValue = value; - } - - QBrush brushProperty() const { - return m_brushValue; - } - Q_INVOKABLE void setBrushProperty(const QBrush &value) { - m_brushValue = value; - } - - double hiddenProperty() const { - return m_hiddenValue; - } - void setHiddenProperty(double value) { - m_hiddenValue = value; - } - - int writeOnlyProperty() const { - return m_writeOnlyValue; - } - void setWriteOnlyProperty(int value) { - m_writeOnlyValue = value; - } - - int readOnlyProperty() const { - return m_readOnlyValue; - } - - QKeySequence shortcut() const { - return m_shortcut; - } - void setShortcut(const QKeySequence &seq) { - m_shortcut = seq; - } - - QWebElement webElementProperty() const { - return m_webElement; - } - - void setWebElementProperty(const QWebElement& element) { - m_webElement = element; - } - - CustomType propWithCustomType() const { - return m_customType; - } - void setPropWithCustomType(const CustomType &c) { - m_customType = c; - } - - QObject* objectStarProperty() const { - return m_objectStar; - } - - void setObjectStarProperty(QObject* object) { - m_objectStar = object; - } - - - int qtFunctionInvoked() const { - return m_qtFunctionInvoked; - } - - QVariantList qtFunctionActuals() const { - return m_actuals; - } - - void resetQtFunctionInvoked() { - m_qtFunctionInvoked = -1; - m_actuals.clear(); - } - - Q_INVOKABLE void myInvokable() { - m_qtFunctionInvoked = 0; - } - Q_INVOKABLE void myInvokableWithIntArg(int arg) { - m_qtFunctionInvoked = 1; - m_actuals << arg; - } - Q_INVOKABLE void myInvokableWithLonglongArg(qlonglong arg) { - m_qtFunctionInvoked = 2; - m_actuals << arg; - } - Q_INVOKABLE void myInvokableWithFloatArg(float arg) { - m_qtFunctionInvoked = 3; - m_actuals << arg; - } - Q_INVOKABLE void myInvokableWithDoubleArg(double arg) { - m_qtFunctionInvoked = 4; - m_actuals << arg; - } - Q_INVOKABLE void myInvokableWithStringArg(const QString &arg) { - m_qtFunctionInvoked = 5; - m_actuals << arg; - } - Q_INVOKABLE void myInvokableWithIntArgs(int arg1, int arg2) { - m_qtFunctionInvoked = 6; - m_actuals << arg1 << arg2; - } - Q_INVOKABLE int myInvokableReturningInt() { - m_qtFunctionInvoked = 7; - return 123; - } - Q_INVOKABLE qlonglong myInvokableReturningLongLong() { - m_qtFunctionInvoked = 39; - return 456; - } - Q_INVOKABLE QString myInvokableReturningString() { - m_qtFunctionInvoked = 8; - return QLatin1String("ciao"); - } - Q_INVOKABLE void myInvokableWithIntArg(int arg1, int arg2) { // overload - m_qtFunctionInvoked = 9; - m_actuals << arg1 << arg2; - } - Q_INVOKABLE void myInvokableWithEnumArg(Policy policy) { - m_qtFunctionInvoked = 10; - m_actuals << policy; - } - Q_INVOKABLE void myInvokableWithQualifiedEnumArg(MyQObject::Policy policy) { - m_qtFunctionInvoked = 36; - m_actuals << policy; - } - Q_INVOKABLE Policy myInvokableReturningEnum() { - m_qtFunctionInvoked = 37; - return BazPolicy; - } - Q_INVOKABLE MyQObject::Policy myInvokableReturningQualifiedEnum() { - m_qtFunctionInvoked = 38; - return BazPolicy; - } - Q_INVOKABLE QVector<int> myInvokableReturningVectorOfInt() { - m_qtFunctionInvoked = 11; - return QVector<int>(); - } - Q_INVOKABLE void myInvokableWithVectorOfIntArg(const QVector<int> &) { - m_qtFunctionInvoked = 12; - } - Q_INVOKABLE QObject* myInvokableReturningQObjectStar() { - m_qtFunctionInvoked = 13; - return this; - } - Q_INVOKABLE QObjectList myInvokableWithQObjectListArg(const QObjectList &lst) { - m_qtFunctionInvoked = 14; - m_actuals << QVariant::fromValue(lst); - return lst; - } - Q_INVOKABLE QVariant myInvokableWithVariantArg(const QVariant &v) { - m_qtFunctionInvoked = 15; - m_actuals << v; - return v; - } - Q_INVOKABLE QVariantMap myInvokableWithVariantMapArg(const QVariantMap &vm) { - m_qtFunctionInvoked = 16; - m_actuals << vm; - return vm; - } - Q_INVOKABLE QList<int> myInvokableWithListOfIntArg(const QList<int> &lst) { - m_qtFunctionInvoked = 17; - m_actuals << QVariant::fromValue(lst); - return lst; - } - Q_INVOKABLE QObject* myInvokableWithQObjectStarArg(QObject* obj) { - m_qtFunctionInvoked = 18; - m_actuals << QVariant::fromValue(obj); - return obj; - } - Q_INVOKABLE QBrush myInvokableWithQBrushArg(const QBrush &brush) { - m_qtFunctionInvoked = 19; - m_actuals << QVariant::fromValue(brush); - return brush; - } - Q_INVOKABLE void myInvokableWithBrushStyleArg(Qt::BrushStyle style) { - m_qtFunctionInvoked = 43; - m_actuals << QVariant::fromValue(style); - } - Q_INVOKABLE void myInvokableWithVoidStarArg(void* arg) { - m_qtFunctionInvoked = 44; - m_actuals << QVariant::fromValue(arg); - } - Q_INVOKABLE void myInvokableWithAmbiguousArg(int arg) { - m_qtFunctionInvoked = 45; - m_actuals << QVariant::fromValue(arg); - } - Q_INVOKABLE void myInvokableWithAmbiguousArg(uint arg) { - m_qtFunctionInvoked = 46; - m_actuals << QVariant::fromValue(arg); - } - Q_INVOKABLE void myInvokableWithDefaultArgs(int arg1, const QString &arg2 = "") { - m_qtFunctionInvoked = 47; - m_actuals << QVariant::fromValue(arg1) << qVariantFromValue(arg2); - } - Q_INVOKABLE QObject& myInvokableReturningRef() { - m_qtFunctionInvoked = 48; - return *this; - } - Q_INVOKABLE const QObject& myInvokableReturningConstRef() const { - const_cast<MyQObject*>(this)->m_qtFunctionInvoked = 49; - return *this; - } - Q_INVOKABLE void myInvokableWithPointArg(const QPoint &arg) { - const_cast<MyQObject*>(this)->m_qtFunctionInvoked = 50; - m_actuals << QVariant::fromValue(arg); - } - Q_INVOKABLE void myInvokableWithPointArg(const QPointF &arg) { - const_cast<MyQObject*>(this)->m_qtFunctionInvoked = 51; - m_actuals << QVariant::fromValue(arg); - } - Q_INVOKABLE void myInvokableWithBoolArg(bool arg) { - m_qtFunctionInvoked = 52; - m_actuals << arg; - } - - void emitMySignal() { - emit mySignal(); - } - void emitMySignalWithIntArg(int arg) { - emit mySignalWithIntArg(arg); - } - void emitMySignal2(bool arg) { - emit mySignal2(arg); - } - void emitMySignal2() { - emit mySignal2(); - } - void emitMySignalWithDateTimeArg(QDateTime dt) { - emit mySignalWithDateTimeArg(dt); - } - void emitMySignalWithRegexArg(QRegExp r) { - emit mySignalWithRegexArg(r); - } - -public Q_SLOTS: - void mySlot() { - m_qtFunctionInvoked = 20; - } - void mySlotWithIntArg(int arg) { - m_qtFunctionInvoked = 21; - m_actuals << arg; - } - void mySlotWithDoubleArg(double arg) { - m_qtFunctionInvoked = 22; - m_actuals << arg; - } - void mySlotWithStringArg(const QString &arg) { - m_qtFunctionInvoked = 23; - m_actuals << arg; - } - - void myOverloadedSlot() { - m_qtFunctionInvoked = 24; - } - void myOverloadedSlot(QObject* arg) { - m_qtFunctionInvoked = 41; - m_actuals << QVariant::fromValue(arg); - } - void myOverloadedSlot(bool arg) { - m_qtFunctionInvoked = 25; - m_actuals << arg; - } - void myOverloadedSlot(const QStringList &arg) { - m_qtFunctionInvoked = 42; - m_actuals << arg; - } - void myOverloadedSlot(double arg) { - m_qtFunctionInvoked = 26; - m_actuals << arg; - } - void myOverloadedSlot(float arg) { - m_qtFunctionInvoked = 27; - m_actuals << arg; - } - void myOverloadedSlot(int arg) { - m_qtFunctionInvoked = 28; - m_actuals << arg; - } - void myOverloadedSlot(const QString &arg) { - m_qtFunctionInvoked = 29; - m_actuals << arg; - } - void myOverloadedSlot(const QColor &arg) { - m_qtFunctionInvoked = 30; - m_actuals << arg; - } - void myOverloadedSlot(const QBrush &arg) { - m_qtFunctionInvoked = 31; - m_actuals << arg; - } - void myOverloadedSlot(const QDateTime &arg) { - m_qtFunctionInvoked = 32; - m_actuals << arg; - } - void myOverloadedSlot(const QDate &arg) { - m_qtFunctionInvoked = 33; - m_actuals << arg; - } - void myOverloadedSlot(const QRegExp &arg) { - m_qtFunctionInvoked = 34; - m_actuals << arg; - } - void myOverloadedSlot(const QVariant &arg) { - m_qtFunctionInvoked = 35; - m_actuals << arg; - } - void myOverloadedSlot(const QWebElement &arg) { - m_qtFunctionInvoked = 36; - m_actuals << QVariant::fromValue<QWebElement>(arg); - } - - void qscript_call(int arg) { - m_qtFunctionInvoked = 40; - m_actuals << arg; - } - -protected Q_SLOTS: - void myProtectedSlot() { - m_qtFunctionInvoked = 36; - } - -private Q_SLOTS: - void myPrivateSlot() { } - -Q_SIGNALS: - void mySignal(); - void mySignalWithIntArg(int arg); - void mySignalWithDoubleArg(double arg); - void mySignal2(bool arg = false); - void mySignalWithDateTimeArg(QDateTime dt); - void mySignalWithRegexArg(QRegExp r); - -private: - int m_intValue; - QVariant m_variantValue; - QVariantList m_variantListValue; - QVariantMap m_variantMapValue; - QString m_stringValue; - QStringList m_stringListValue; - QByteArray m_byteArrayValue; - QBrush m_brushValue; - double m_hiddenValue; - int m_writeOnlyValue; - int m_readOnlyValue; - QKeySequence m_shortcut; - QWebElement m_webElement; - CustomType m_customType; - QObject* m_objectStar; - int m_qtFunctionInvoked; - QVariantList m_actuals; -}; - -class MyWebElementSlotOnlyObject : public QObject { - Q_OBJECT - Q_PROPERTY(QString tagName READ tagName) -public slots: - void doSomethingWithWebElement(const QWebElement& element) - { - m_tagName = element.tagName(); - } - -public: - QString tagName() const - { - return m_tagName; - } -private: - QString m_tagName; -}; - -class MyOtherQObject : public MyQObject -{ -public: - MyOtherQObject(QObject* parent = 0) - : MyQObject(parent) { } -}; - -class MyEnumTestQObject : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString p1 READ p1) - Q_PROPERTY(QString p2 READ p2) - Q_PROPERTY(QString p3 READ p3 SCRIPTABLE false) - Q_PROPERTY(QString p4 READ p4) - Q_PROPERTY(QString p5 READ p5 SCRIPTABLE false) - Q_PROPERTY(QString p6 READ p6) -public: - MyEnumTestQObject(QObject* parent = 0) - : QObject(parent) { } - QString p1() const { - return QLatin1String("p1"); - } - QString p2() const { - return QLatin1String("p2"); - } - QString p3() const { - return QLatin1String("p3"); - } - QString p4() const { - return QLatin1String("p4"); - } - QString p5() const { - return QLatin1String("p5"); - } - QString p6() const { - return QLatin1String("p5"); - } -public Q_SLOTS: - void mySlot() { } - void myOtherSlot() { } -Q_SIGNALS: - void mySignal(); -}; - class tst_QWebFrame : public QObject { Q_OBJECT public: - tst_QWebFrame(); - virtual ~tst_QWebFrame(); bool eventFilter(QObject* watched, QEvent* event); public slots: @@ -591,28 +52,9 @@ public slots: private slots: void horizontalScrollAfterBack(); - void getSetStaticProperty(); - void getSetDynamicProperty(); - void getSetChildren(); - void callQtInvokable(); - void connectAndDisconnect(); - void classEnums(); - void classConstructor(); - void overrideInvokable(); - void transferInvokable(); - void findChild(); - void findChildren(); - void overloadedSlots(); - void webElementSlotOnly(); - void enumerate_data(); - void enumerate(); - void objectDeleted(); - void typeConversion(); - void arrayObjectEnumerable(); void symmetricUrl(); void progressSignal(); void urlChange(); - void domCycles(); void requestedUrl(); void requestedUrlAfterSetAndLoadFailures(); void javaScriptWindowObjectCleared_data(); @@ -630,9 +72,6 @@ private slots: #endif void inputFieldFocus(); void hitTestContent(); - void jsByteArray(); - void ownership(); - void nullValue(); void baseUrl_data(); void baseUrl(); void hasSetFocus(); @@ -642,9 +81,6 @@ private slots: void scrollToAnchor(); void scrollbarsOff(); void evaluateWillCauseRepaint(); - void qObjectWrapperWithSameIdentity(); - void introspectQtMethods_data(); - void introspectQtMethods(); void setContent_data(); void setContent(); void setCacheLoadControlAttribute(); @@ -662,80 +98,12 @@ private slots: void loadInSignalHandlers(); private: - QString evalJS(const QString&s) { - // Convert an undefined return variant to the string "undefined" - QVariant ret = evalJSV(s); - if (ret.userType() == QMetaType::Void) - return "undefined"; - else - return ret.toString(); - } - QVariant evalJSV(const QString &s) { - return m_page->mainFrame()->evaluateJavaScript(s); - } - - QString evalJS(const QString&s, QString& type) { - return evalJSV(s, type).toString(); - } - QVariant evalJSV(const QString &s, QString& type) { - // As a special measure, if we get an exception we set the type to 'error' - // (in ecma, an Error object has typeof object, but qtscript has a convenience function) - // Similarly, an array is an object, but we'd prefer to have a type of 'array' - // Also, consider a QMetaType::Void QVariant to be undefined - QString escaped = s; - escaped.replace('\'', "\\'"); // Don't preescape your single quotes! - QString code("var retvalue; " - "var typevalue; " - "try { " - " retvalue = eval('%1'); " - " typevalue = typeof retvalue; " - " if (retvalue instanceof Array) " - " typevalue = 'array'; " - "} catch(e) { " - " retvalue = e.name + ': ' + e.message; " - " typevalue = 'error'; " - "}"); - evalJS(code.arg(escaped)); - - QVariant ret = evalJSV("retvalue"); - if (ret.userType() != QMetaType::Void) - type = evalJS("typevalue"); - else { - ret = QString("undefined"); - type = sUndefined; - } - evalJS("delete retvalue; delete typevalue"); - return ret; - } - - const QString sTrue; - const QString sFalse; - const QString sUndefined; - const QString sArray; - const QString sFunction; - const QString sError; - const QString sString; - const QString sObject; - const QString sNumber; - -private: QWebView* m_view; QWebPage* m_page; - MyQObject* m_myObject; QWebView* m_inputFieldsTestView; int m_inputFieldTestPaintCount; }; -tst_QWebFrame::tst_QWebFrame() - : sTrue("true"), sFalse("false"), sUndefined("undefined"), sArray("array"), sFunction("function"), sError("error"), - sString("string"), sObject("object"), sNumber("number"), m_inputFieldsTestView(0), m_inputFieldTestPaintCount(0) -{ -} - -tst_QWebFrame::~tst_QWebFrame() -{ -} - bool tst_QWebFrame::eventFilter(QObject* watched, QEvent* event) { // used on the inputFieldFocus test @@ -750,1467 +118,11 @@ void tst_QWebFrame::init() { m_view = new QWebView(); m_page = m_view->page(); - m_myObject = new MyQObject(); - m_page->mainFrame()->addToJavaScriptWindowObject("myObject", m_myObject); } void tst_QWebFrame::cleanup() { delete m_view; - delete m_myObject; -} - -void tst_QWebFrame::getSetStaticProperty() -{ - m_page->mainFrame()->setHtml("<html><head><body></body></html>"); - QCOMPARE(evalJS("typeof myObject.noSuchProperty"), sUndefined); - - // initial value (set in MyQObject constructor) - { - QString type; - QVariant ret = evalJSV("myObject.intProperty", type); - QCOMPARE(type, sNumber); - QCOMPARE(ret.type(), QVariant::Double); - QCOMPARE(ret.toInt(), 123); - } - QCOMPARE(evalJS("myObject.intProperty === 123.0"), sTrue); - - { - QString type; - QVariant ret = evalJSV("myObject.variantProperty", type); - QCOMPARE(type, sString); - QCOMPARE(ret.type(), QVariant::String); - QCOMPARE(ret.toString(), QLatin1String("foo")); - } - QCOMPARE(evalJS("myObject.variantProperty == 'foo'"), sTrue); - - { - QString type; - QVariant ret = evalJSV("myObject.stringProperty", type); - QCOMPARE(type, sString); - QCOMPARE(ret.type(), QVariant::String); - QCOMPARE(ret.toString(), QLatin1String("bar")); - } - QCOMPARE(evalJS("myObject.stringProperty === 'bar'"), sTrue); - - { - QString type; - QVariant ret = evalJSV("myObject.variantListProperty", type); - QCOMPARE(type, sArray); - QCOMPARE(ret.type(), QVariant::List); - QVariantList vl = ret.value<QVariantList>(); - QCOMPARE(vl.size(), 2); - QCOMPARE(vl.at(0).toInt(), 123); - QCOMPARE(vl.at(1).toString(), QLatin1String("foo")); - } - QCOMPARE(evalJS("myObject.variantListProperty.length === 2"), sTrue); - QCOMPARE(evalJS("myObject.variantListProperty[0] === 123"), sTrue); - QCOMPARE(evalJS("myObject.variantListProperty[1] === 'foo'"), sTrue); - - { - QString type; - QVariant ret = evalJSV("myObject.variantMapProperty", type); - QCOMPARE(type, sObject); - QCOMPARE(ret.type(), QVariant::Map); - QVariantMap vm = ret.value<QVariantMap>(); - QCOMPARE(vm.size(), 3); - QCOMPARE(vm.value("a").toInt(), 123); - QCOMPARE(vm.value("b").toString(), QLatin1String("foo")); - QCOMPARE(vm.value("c").value<QObject*>(), static_cast<QObject*>(m_myObject)); - } - QCOMPARE(evalJS("myObject.variantMapProperty.a === 123"), sTrue); - QCOMPARE(evalJS("myObject.variantMapProperty.b === 'foo'"), sTrue); - QCOMPARE(evalJS("myObject.variantMapProperty.c.variantMapProperty.b === 'foo'"), sTrue); - - { - QString type; - QVariant ret = evalJSV("myObject.stringListProperty", type); - QCOMPARE(type, sArray); - QCOMPARE(ret.type(), QVariant::List); - QVariantList vl = ret.value<QVariantList>(); - QCOMPARE(vl.size(), 2); - QCOMPARE(vl.at(0).toString(), QLatin1String("zig")); - QCOMPARE(vl.at(1).toString(), QLatin1String("zag")); - } - QCOMPARE(evalJS("myObject.stringListProperty.length === 2"), sTrue); - QCOMPARE(evalJS("typeof myObject.stringListProperty[0]"), sString); - QCOMPARE(evalJS("myObject.stringListProperty[0]"), QLatin1String("zig")); - QCOMPARE(evalJS("typeof myObject.stringListProperty[1]"), sString); - QCOMPARE(evalJS("myObject.stringListProperty[1]"), QLatin1String("zag")); - - // property change in C++ should be reflected in script - m_myObject->setIntProperty(456); - QCOMPARE(evalJS("myObject.intProperty == 456"), sTrue); - m_myObject->setIntProperty(789); - QCOMPARE(evalJS("myObject.intProperty == 789"), sTrue); - - m_myObject->setVariantProperty(QLatin1String("bar")); - QCOMPARE(evalJS("myObject.variantProperty === 'bar'"), sTrue); - m_myObject->setVariantProperty(42); - QCOMPARE(evalJS("myObject.variantProperty === 42"), sTrue); - m_myObject->setVariantProperty(QVariant::fromValue(QBrush())); -//XFAIL -// QCOMPARE(evalJS("typeof myObject.variantProperty"), sVariant); - - m_myObject->setStringProperty(QLatin1String("baz")); - QCOMPARE(evalJS("myObject.stringProperty === 'baz'"), sTrue); - m_myObject->setStringProperty(QLatin1String("zab")); - QCOMPARE(evalJS("myObject.stringProperty === 'zab'"), sTrue); - - // property change in script should be reflected in C++ - QCOMPARE(evalJS("myObject.intProperty = 123"), QLatin1String("123")); - QCOMPARE(evalJS("myObject.intProperty == 123"), sTrue); - QCOMPARE(m_myObject->intProperty(), 123); - QCOMPARE(evalJS("myObject.intProperty = 'ciao!';" - "myObject.intProperty == 0"), sTrue); - QCOMPARE(m_myObject->intProperty(), 0); - QCOMPARE(evalJS("myObject.intProperty = '123';" - "myObject.intProperty == 123"), sTrue); - QCOMPARE(m_myObject->intProperty(), 123); - - QCOMPARE(evalJS("myObject.stringProperty = 'ciao'"), QLatin1String("ciao")); - QCOMPARE(evalJS("myObject.stringProperty"), QLatin1String("ciao")); - QCOMPARE(m_myObject->stringProperty(), QLatin1String("ciao")); - QCOMPARE(evalJS("myObject.stringProperty = 123;" - "myObject.stringProperty"), QLatin1String("123")); - QCOMPARE(m_myObject->stringProperty(), QLatin1String("123")); - QCOMPARE(evalJS("myObject.stringProperty = null"), QString()); - QCOMPARE(evalJS("myObject.stringProperty"), QString()); - QCOMPARE(m_myObject->stringProperty(), QString()); - QCOMPARE(evalJS("myObject.stringProperty = undefined"), sUndefined); - QCOMPARE(evalJS("myObject.stringProperty"), QString()); - QCOMPARE(m_myObject->stringProperty(), QString()); - - QCOMPARE(evalJS("myObject.variantProperty = new Number(1234);" - "myObject.variantProperty").toDouble(), 1234.0); - QCOMPARE(m_myObject->variantProperty().toDouble(), 1234.0); - - QCOMPARE(evalJS("myObject.variantProperty = new Boolean(1234);" - "myObject.variantProperty"), sTrue); - QCOMPARE(m_myObject->variantProperty().toBool(), true); - - QCOMPARE(evalJS("myObject.variantProperty = null;" - "myObject.variantProperty.valueOf()"), sUndefined); - QCOMPARE(m_myObject->variantProperty(), QVariant()); - QCOMPARE(evalJS("myObject.variantProperty = undefined;" - "myObject.variantProperty.valueOf()"), sUndefined); - QCOMPARE(m_myObject->variantProperty(), QVariant()); - - QCOMPARE(evalJS("myObject.variantProperty = 'foo';" - "myObject.variantProperty.valueOf()"), QLatin1String("foo")); - QCOMPARE(m_myObject->variantProperty(), QVariant(QLatin1String("foo"))); - QCOMPARE(evalJS("myObject.variantProperty = 42;" - "myObject.variantProperty").toDouble(), 42.0); - QCOMPARE(m_myObject->variantProperty().toDouble(), 42.0); - - QCOMPARE(evalJS("myObject.variantListProperty = [1, 'two', true];" - "myObject.variantListProperty.length == 3"), sTrue); - QCOMPARE(evalJS("myObject.variantListProperty[0] === 1"), sTrue); - QCOMPARE(evalJS("myObject.variantListProperty[1]"), QLatin1String("two")); - QCOMPARE(evalJS("myObject.variantListProperty[2] === true"), sTrue); - - QCOMPARE(evalJS("myObject.stringListProperty = [1, 'two', true];" - "myObject.stringListProperty.length == 3"), sTrue); - QCOMPARE(evalJS("typeof myObject.stringListProperty[0]"), sString); - QCOMPARE(evalJS("myObject.stringListProperty[0] == '1'"), sTrue); - QCOMPARE(evalJS("typeof myObject.stringListProperty[1]"), sString); - QCOMPARE(evalJS("myObject.stringListProperty[1]"), QLatin1String("two")); - QCOMPARE(evalJS("typeof myObject.stringListProperty[2]"), sString); - QCOMPARE(evalJS("myObject.stringListProperty[2]"), QLatin1String("true")); - evalJS("myObject.webElementProperty=document.body;"); - QCOMPARE(evalJS("myObject.webElementProperty.tagName"), QLatin1String("BODY")); - - // try to delete - QCOMPARE(evalJS("delete myObject.intProperty"), sFalse); - QCOMPARE(evalJS("myObject.intProperty == 123"), sTrue); - - QCOMPARE(evalJS("delete myObject.variantProperty"), sFalse); - QCOMPARE(evalJS("myObject.variantProperty").toDouble(), 42.0); - - // custom property - QCOMPARE(evalJS("myObject.customProperty"), sUndefined); - QCOMPARE(evalJS("myObject.customProperty = 123;" - "myObject.customProperty == 123"), sTrue); - QVariant v = m_page->mainFrame()->evaluateJavaScript("myObject.customProperty"); - QCOMPARE(v.type(), QVariant::Double); - QCOMPARE(v.toInt(), 123); - - // non-scriptable property - QCOMPARE(m_myObject->hiddenProperty(), 456.0); - QCOMPARE(evalJS("myObject.hiddenProperty"), sUndefined); - QCOMPARE(evalJS("myObject.hiddenProperty = 123;" - "myObject.hiddenProperty == 123"), sTrue); - QCOMPARE(m_myObject->hiddenProperty(), 456.0); - - // write-only property - QCOMPARE(m_myObject->writeOnlyProperty(), 789); - QCOMPARE(evalJS("typeof myObject.writeOnlyProperty"), sUndefined); - QCOMPARE(evalJS("myObject.writeOnlyProperty = 123;" - "typeof myObject.writeOnlyProperty"), sUndefined); - QCOMPARE(m_myObject->writeOnlyProperty(), 123); - - // read-only property - QCOMPARE(m_myObject->readOnlyProperty(), 987); - QCOMPARE(evalJS("myObject.readOnlyProperty == 987"), sTrue); - QCOMPARE(evalJS("myObject.readOnlyProperty = 654;" - "myObject.readOnlyProperty == 987"), sTrue); - QCOMPARE(m_myObject->readOnlyProperty(), 987); - - // QObject* property - m_myObject->setObjectStarProperty(0); - QCOMPARE(m_myObject->objectStarProperty(), (QObject*)0); - QCOMPARE(evalJS("myObject.objectStarProperty == null"), sTrue); - QCOMPARE(evalJS("typeof myObject.objectStarProperty"), sObject); - QCOMPARE(evalJS("Boolean(myObject.objectStarProperty)"), sFalse); - QCOMPARE(evalJS("String(myObject.objectStarProperty) == 'null'"), sTrue); - QCOMPARE(evalJS("myObject.objectStarProperty.objectStarProperty"), - sUndefined); - m_myObject->setObjectStarProperty(this); - QCOMPARE(evalJS("myObject.objectStarProperty != null"), sTrue); - QCOMPARE(evalJS("typeof myObject.objectStarProperty"), sObject); - QCOMPARE(evalJS("Boolean(myObject.objectStarProperty)"), sTrue); - QCOMPARE(evalJS("String(myObject.objectStarProperty) != 'null'"), sTrue); -} - -void tst_QWebFrame::getSetDynamicProperty() -{ - // initially the object does not have the property - // In WebKit, RuntimeObjects do not inherit Object, so don't have hasOwnProperty - - //QCOMPARE(evalJS("myObject.hasOwnProperty('dynamicProperty')"), sFalse); - QCOMPARE(evalJS("typeof myObject.dynamicProperty"), sUndefined); - - // add a dynamic property in C++ - QCOMPARE(m_myObject->setProperty("dynamicProperty", 123), false); - //QCOMPARE(evalJS("myObject.hasOwnProperty('dynamicProperty')"), sTrue); - QCOMPARE(evalJS("typeof myObject.dynamicProperty != 'undefined'"), sTrue); - QCOMPARE(evalJS("myObject.dynamicProperty == 123"), sTrue); - - // property change in script should be reflected in C++ - QCOMPARE(evalJS("myObject.dynamicProperty = 'foo';" - "myObject.dynamicProperty"), QLatin1String("foo")); - QCOMPARE(m_myObject->property("dynamicProperty").toString(), QLatin1String("foo")); - - // delete the property (XFAIL - can't delete properties) - QEXPECT_FAIL("", "can't delete properties", Continue); - QCOMPARE(evalJS("delete myObject.dynamicProperty"), sTrue); - /* - QCOMPARE(m_myObject->property("dynamicProperty").isValid(), false); - QCOMPARE(evalJS("typeof myObject.dynamicProperty"), sUndefined); - // QCOMPARE(evalJS("myObject.hasOwnProperty('dynamicProperty')"), sFalse); - QCOMPARE(evalJS("typeof myObject.dynamicProperty"), sUndefined); - */ -} - -void tst_QWebFrame::getSetChildren() -{ - // initially the object does not have the child - // (again, no hasOwnProperty) - - //QCOMPARE(evalJS("myObject.hasOwnProperty('child')"), sFalse); - QCOMPARE(evalJS("typeof myObject.child"), sUndefined); - - // add a child - MyQObject* child = new MyQObject(m_myObject); - child->setObjectName("child"); -// QCOMPARE(evalJS("myObject.hasOwnProperty('child')"), sTrue); - QCOMPARE(evalJS("typeof myObject.child != 'undefined'"), sTrue); - - // add a grandchild - MyQObject* grandChild = new MyQObject(child); - grandChild->setObjectName("grandChild"); -// QCOMPARE(evalJS("myObject.child.hasOwnProperty('grandChild')"), sTrue); - QCOMPARE(evalJS("typeof myObject.child.grandChild != 'undefined'"), sTrue); - - // delete grandchild - delete grandChild; -// QCOMPARE(evalJS("myObject.child.hasOwnProperty('grandChild')"), sFalse); - QCOMPARE(evalJS("typeof myObject.child.grandChild == 'undefined'"), sTrue); - - // delete child - delete child; -// QCOMPARE(evalJS("myObject.hasOwnProperty('child')"), sFalse); - QCOMPARE(evalJS("typeof myObject.child == 'undefined'"), sTrue); -} - -Q_DECLARE_METATYPE(QVector<int>) -Q_DECLARE_METATYPE(QVector<double>) -Q_DECLARE_METATYPE(QVector<QString>) - -void tst_QWebFrame::callQtInvokable() -{ - qRegisterMetaType<QObjectList>(); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokable()"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 0); - QCOMPARE(m_myObject->qtFunctionActuals(), QVariantList()); - - // extra arguments should silently be ignored - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokable(10, 20, 30)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 0); - QCOMPARE(m_myObject->qtFunctionActuals(), QVariantList()); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithIntArg(123)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithIntArg('123')"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithLonglongArg(123)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 2); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toLongLong(), qlonglong(123)); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithFloatArg(123.5)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 3); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDouble(), 123.5); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithDoubleArg(123.5)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 4); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDouble(), 123.5); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithDoubleArg(new Number(1234.5))"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 4); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDouble(), 1234.5); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithBoolArg(new Boolean(true))"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 52); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toBool(), true); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithStringArg('ciao')"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 5); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toString(), QLatin1String("ciao")); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithStringArg(123)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 5); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toString(), QLatin1String("123")); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithStringArg(null)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 5); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toString(), QString()); - QVERIFY(m_myObject->qtFunctionActuals().at(0).toString().isEmpty()); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithStringArg(undefined)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 5); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toString(), QString()); - QVERIFY(m_myObject->qtFunctionActuals().at(0).toString().isEmpty()); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithIntArgs(123, 456)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 6); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 2); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); - QCOMPARE(m_myObject->qtFunctionActuals().at(1).toInt(), 456); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.myInvokableReturningInt()"), QLatin1String("123")); - QCOMPARE(m_myObject->qtFunctionInvoked(), 7); - QCOMPARE(m_myObject->qtFunctionActuals(), QVariantList()); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.myInvokableReturningLongLong()"), QLatin1String("456")); - QCOMPARE(m_myObject->qtFunctionInvoked(), 39); - QCOMPARE(m_myObject->qtFunctionActuals(), QVariantList()); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.myInvokableReturningString()"), QLatin1String("ciao")); - QCOMPARE(m_myObject->qtFunctionInvoked(), 8); - QCOMPARE(m_myObject->qtFunctionActuals(), QVariantList()); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithIntArg(123, 456)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 9); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 2); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); - QCOMPARE(m_myObject->qtFunctionActuals().at(1).toInt(), 456); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("typeof myObject.myInvokableWithVoidStarArg(null)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 44); - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QString ret = evalJS("myObject.myInvokableWithVoidStarArg(123)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: incompatible type of argument(s) in call to myInvokableWithVoidStarArg(); candidates were\n myInvokableWithVoidStarArg(void*)")); - QCOMPARE(m_myObject->qtFunctionInvoked(), -1); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QString ret = evalJS("myObject.myInvokableWithAmbiguousArg(123)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: ambiguous call of overloaded function myInvokableWithAmbiguousArg(); candidates were\n myInvokableWithAmbiguousArg(int)\n myInvokableWithAmbiguousArg(uint)")); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QString ret = evalJS("myObject.myInvokableWithDefaultArgs(123, 'hello')", type); - QCOMPARE(type, sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 47); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 2); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); - QCOMPARE(m_myObject->qtFunctionActuals().at(1).toString(), QLatin1String("hello")); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QString ret = evalJS("myObject.myInvokableWithDefaultArgs(456)", type); - QCOMPARE(type, sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 47); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 2); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 456); - QCOMPARE(m_myObject->qtFunctionActuals().at(1).toString(), QString()); - } - - // calling function that returns (const)ref - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QString ret = evalJS("typeof myObject.myInvokableReturningRef()"); - QCOMPARE(ret, sUndefined); - //QVERIFY(!m_engine->hasUncaughtException()); - QCOMPARE(m_myObject->qtFunctionInvoked(), 48); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QString ret = evalJS("typeof myObject.myInvokableReturningConstRef()"); - QCOMPARE(ret, sUndefined); - //QVERIFY(!m_engine->hasUncaughtException()); - QCOMPARE(m_myObject->qtFunctionInvoked(), 49); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QVariant ret = evalJSV("myObject.myInvokableReturningQObjectStar()", type); - QCOMPARE(m_myObject->qtFunctionInvoked(), 13); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 0); - QCOMPARE(type, sObject); - QCOMPARE(ret.userType(), int(QMetaType::QObjectStar)); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QVariant ret = evalJSV("myObject.myInvokableWithQObjectListArg([myObject])", type); - QCOMPARE(m_myObject->qtFunctionInvoked(), 14); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(type, sArray); - QCOMPARE(ret.userType(), int(QVariant::List)); // All lists get downgraded to QVariantList - QVariantList vl = qvariant_cast<QVariantList>(ret); - QCOMPARE(vl.count(), 1); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - m_myObject->setVariantProperty(QVariant(123)); - QVariant ret = evalJSV("myObject.myInvokableWithVariantArg(myObject.variantProperty)", type); - QCOMPARE(type, sNumber); - QCOMPARE(m_myObject->qtFunctionInvoked(), 15); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0), m_myObject->variantProperty()); - QCOMPARE(ret.userType(), int(QMetaType::Double)); // all JS numbers are doubles, even though this started as an int - QCOMPARE(ret.toInt(),123); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QVariant ret = evalJSV("myObject.myInvokableWithVariantArg(null)", type); - QCOMPARE(type, sObject); - QCOMPARE(m_myObject->qtFunctionInvoked(), 15); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0), QVariant()); - QVERIFY(!m_myObject->qtFunctionActuals().at(0).isValid()); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QVariant ret = evalJSV("myObject.myInvokableWithVariantArg(undefined)", type); - QCOMPARE(type, sObject); - QCOMPARE(m_myObject->qtFunctionInvoked(), 15); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0), QVariant()); - QVERIFY(!m_myObject->qtFunctionActuals().at(0).isValid()); - } - - /* XFAIL - variant support - m_myObject->resetQtFunctionInvoked(); - { - m_myObject->setVariantProperty(QVariant::fromValue(QBrush())); - QVariant ret = evalJS("myObject.myInvokableWithVariantArg(myObject.variantProperty)"); - QVERIFY(ret.isVariant()); - QCOMPARE(m_myObject->qtFunctionInvoked(), 15); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(ret.toVariant(), m_myObject->qtFunctionActuals().at(0)); - QCOMPARE(ret.toVariant(), m_myObject->variantProperty()); - } - */ - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QVariant ret = evalJSV("myObject.myInvokableWithVariantArg(123)", type); - QCOMPARE(type, sNumber); - QCOMPARE(m_myObject->qtFunctionInvoked(), 15); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0), QVariant(123)); - QCOMPARE(ret.userType(), int(QMetaType::Double)); - QCOMPARE(ret.toInt(),123); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QVariant ret = evalJSV("myObject.myInvokableWithVariantMapArg({ a:123, b:'ciao' })", type); - QCOMPARE(m_myObject->qtFunctionInvoked(), 16); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - - QVariant v = m_myObject->qtFunctionActuals().at(0); - QCOMPARE(v.userType(), int(QMetaType::QVariantMap)); - - QVariantMap vmap = qvariant_cast<QVariantMap>(v); - QCOMPARE(vmap.keys().size(), 2); - QCOMPARE(vmap.keys().at(0), QLatin1String("a")); - QCOMPARE(vmap.value("a"), QVariant(123)); - QCOMPARE(vmap.keys().at(1), QLatin1String("b")); - QCOMPARE(vmap.value("b"), QVariant("ciao")); - - QCOMPARE(type, sObject); - - QCOMPARE(ret.userType(), int(QMetaType::QVariantMap)); - vmap = qvariant_cast<QVariantMap>(ret); - QCOMPARE(vmap.keys().size(), 2); - QCOMPARE(vmap.keys().at(0), QLatin1String("a")); - QCOMPARE(vmap.value("a"), QVariant(123)); - QCOMPARE(vmap.keys().at(1), QLatin1String("b")); - QCOMPARE(vmap.value("b"), QVariant("ciao")); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QVariant ret = evalJSV("myObject.myInvokableWithListOfIntArg([1, 5])", type); - QCOMPARE(m_myObject->qtFunctionInvoked(), 17); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QVariant v = m_myObject->qtFunctionActuals().at(0); - QCOMPARE(v.userType(), qMetaTypeId<QList<int> >()); - QList<int> ilst = qvariant_cast<QList<int> >(v); - QCOMPARE(ilst.size(), 2); - QCOMPARE(ilst.at(0), 1); - QCOMPARE(ilst.at(1), 5); - - QCOMPARE(type, sArray); - QCOMPARE(ret.userType(), int(QMetaType::QVariantList)); // ints get converted to doubles, so this is a qvariantlist - QVariantList vlst = qvariant_cast<QVariantList>(ret); - QCOMPARE(vlst.size(), 2); - QCOMPARE(vlst.at(0).toInt(), 1); - QCOMPARE(vlst.at(1).toInt(), 5); - } - - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QVariant ret = evalJSV("myObject.myInvokableWithQObjectStarArg(myObject)", type); - QCOMPARE(m_myObject->qtFunctionInvoked(), 18); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QVariant v = m_myObject->qtFunctionActuals().at(0); - QCOMPARE(v.userType(), int(QMetaType::QObjectStar)); - QCOMPARE(qvariant_cast<QObject*>(v), (QObject*)m_myObject); - - QCOMPARE(ret.userType(), int(QMetaType::QObjectStar)); - QCOMPARE(qvariant_cast<QObject*>(ret), (QObject*)m_myObject); - - QCOMPARE(type, sObject); - } - - m_myObject->resetQtFunctionInvoked(); - { - // no implicit conversion from integer to QObject* - QString type; - evalJS("myObject.myInvokableWithQObjectStarArg(123)", type); - QCOMPARE(type, sError); - } - - /* - m_myObject->resetQtFunctionInvoked(); - { - QString fun = evalJS("myObject.myInvokableWithQBrushArg"); - Q_ASSERT(fun.isFunction()); - QColor color(10, 20, 30, 40); - // QColor should be converted to a QBrush - QVariant ret = fun.call(QString(), QStringList() - << qScriptValueFromValue(m_engine, color)); - QCOMPARE(m_myObject->qtFunctionInvoked(), 19); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QVariant v = m_myObject->qtFunctionActuals().at(0); - QCOMPARE(v.userType(), int(QMetaType::QBrush)); - QCOMPARE(qvariant_cast<QColor>(v), color); - - QCOMPARE(qscriptvalue_cast<QColor>(ret), color); - } - */ - - // private slots should not be part of the QObject binding - QCOMPARE(evalJS("typeof myObject.myPrivateSlot"), sUndefined); - - // protected slots should be fine - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myProtectedSlot()"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 36); - - // call with too few arguments - { - QString type; - QString ret = evalJS("myObject.myInvokableWithIntArg()", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("SyntaxError: too few arguments in call to myInvokableWithIntArg(); candidates are\n myInvokableWithIntArg(int,int)\n myInvokableWithIntArg(int)")); - } - - // call function where not all types have been registered - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QString ret = evalJS("myObject.myInvokableWithBrushStyleArg(0)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: cannot call myInvokableWithBrushStyleArg(): unknown type `Qt::BrushStyle'")); - QCOMPARE(m_myObject->qtFunctionInvoked(), -1); - } - - // call function with incompatible argument type - m_myObject->resetQtFunctionInvoked(); - { - QString type; - QString ret = evalJS("myObject.myInvokableWithQBrushArg(null)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: incompatible type of argument(s) in call to myInvokableWithQBrushArg(); candidates were\n myInvokableWithQBrushArg(QBrush)")); - QCOMPARE(m_myObject->qtFunctionInvoked(), -1); - } -} - -void tst_QWebFrame::connectAndDisconnect() -{ - // connect(function) - QCOMPARE(evalJS("typeof myObject.mySignal"), sFunction); - QCOMPARE(evalJS("typeof myObject.mySignal.connect"), sFunction); - QCOMPARE(evalJS("typeof myObject.mySignal.disconnect"), sFunction); - - { - QString type; - evalJS("myObject.mySignal.connect(123)", type); - QCOMPARE(type, sError); - } - - evalJS("myHandler = function() { window.gotSignal = true; window.signalArgs = arguments; window.slotThisObject = this; window.signalSender = __qt_sender__; }"); - - QCOMPARE(evalJS("myObject.mySignal.connect(myHandler)"), sUndefined); - - evalJS("gotSignal = false"); - evalJS("myObject.mySignal()"); - QCOMPARE(evalJS("gotSignal"), sTrue); - QCOMPARE(evalJS("signalArgs.length == 0"), sTrue); - QCOMPARE(evalJS("signalSender"),evalJS("myObject")); - QCOMPARE(evalJS("slotThisObject == window"), sTrue); - - evalJS("gotSignal = false"); - m_myObject->emitMySignal(); - QCOMPARE(evalJS("gotSignal"), sTrue); - QCOMPARE(evalJS("signalArgs.length == 0"), sTrue); - - QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myHandler)"), sUndefined); - - evalJS("gotSignal = false"); - m_myObject->emitMySignalWithIntArg(123); - QCOMPARE(evalJS("gotSignal"), sTrue); - QCOMPARE(evalJS("signalArgs.length == 1"), sTrue); - QCOMPARE(evalJS("signalArgs[0] == 123.0"), sTrue); - - QCOMPARE(evalJS("myObject.mySignal.disconnect(myHandler)"), sUndefined); - { - QString type; - evalJS("myObject.mySignal.disconnect(myHandler)", type); - QCOMPARE(type, sError); - } - - evalJS("gotSignal = false"); - QCOMPARE(evalJS("myObject.mySignal2.connect(myHandler)"), sUndefined); - m_myObject->emitMySignal2(true); - QCOMPARE(evalJS("gotSignal"), sTrue); - QCOMPARE(evalJS("signalArgs.length == 1"), sTrue); - QCOMPARE(evalJS("signalArgs[0]"), sTrue); - - QCOMPARE(evalJS("myObject.mySignal2.disconnect(myHandler)"), sUndefined); - - QCOMPARE(evalJS("typeof myObject['mySignal2()']"), sFunction); - QCOMPARE(evalJS("typeof myObject['mySignal2()'].connect"), sFunction); - QCOMPARE(evalJS("typeof myObject['mySignal2()'].disconnect"), sFunction); - - QCOMPARE(evalJS("myObject['mySignal2()'].connect(myHandler)"), sUndefined); - - evalJS("gotSignal = false"); - m_myObject->emitMySignal2(); - QCOMPARE(evalJS("gotSignal"), sTrue); - - QCOMPARE(evalJS("myObject['mySignal2()'].disconnect(myHandler)"), sUndefined); - - // connect(object, function) - evalJS("otherObject = { name:'foo' }"); - QCOMPARE(evalJS("myObject.mySignal.connect(otherObject, myHandler)"), sUndefined); - QCOMPARE(evalJS("myObject.mySignal.disconnect(otherObject, myHandler)"), sUndefined); - evalJS("gotSignal = false"); - m_myObject->emitMySignal(); - QCOMPARE(evalJS("gotSignal"), sFalse); - - { - QString type; - evalJS("myObject.mySignal.disconnect(otherObject, myHandler)", type); - QCOMPARE(type, sError); - } - - QCOMPARE(evalJS("myObject.mySignal.connect(otherObject, myHandler)"), sUndefined); - evalJS("gotSignal = false"); - m_myObject->emitMySignal(); - QCOMPARE(evalJS("gotSignal"), sTrue); - QCOMPARE(evalJS("signalArgs.length == 0"), sTrue); - QCOMPARE(evalJS("slotThisObject"),evalJS("otherObject")); - QCOMPARE(evalJS("signalSender"),evalJS("myObject")); - QCOMPARE(evalJS("slotThisObject.name"), QLatin1String("foo")); - QCOMPARE(evalJS("myObject.mySignal.disconnect(otherObject, myHandler)"), sUndefined); - - evalJS("yetAnotherObject = { name:'bar', func : function() { } }"); - QCOMPARE(evalJS("myObject.mySignal2.connect(yetAnotherObject, myHandler)"), sUndefined); - evalJS("gotSignal = false"); - m_myObject->emitMySignal2(true); - QCOMPARE(evalJS("gotSignal"), sTrue); - QCOMPARE(evalJS("signalArgs.length == 1"), sTrue); - QCOMPARE(evalJS("slotThisObject == yetAnotherObject"), sTrue); - QCOMPARE(evalJS("signalSender == myObject"), sTrue); - QCOMPARE(evalJS("slotThisObject.name"), QLatin1String("bar")); - QCOMPARE(evalJS("myObject.mySignal2.disconnect(yetAnotherObject, myHandler)"), sUndefined); - - QCOMPARE(evalJS("myObject.mySignal2.connect(myObject, myHandler)"), sUndefined); - evalJS("gotSignal = false"); - m_myObject->emitMySignal2(true); - QCOMPARE(evalJS("gotSignal"), sTrue); - QCOMPARE(evalJS("signalArgs.length == 1"), sTrue); - QCOMPARE(evalJS("slotThisObject == myObject"), sTrue); - QCOMPARE(evalJS("signalSender == myObject"), sTrue); - QCOMPARE(evalJS("myObject.mySignal2.disconnect(myObject, myHandler)"), sUndefined); - - // connect(obj, string) - QCOMPARE(evalJS("myObject.mySignal.connect(yetAnotherObject, 'func')"), sUndefined); - QCOMPARE(evalJS("myObject.mySignal.connect(myObject, 'mySlot')"), sUndefined); - QCOMPARE(evalJS("myObject.mySignal.disconnect(yetAnotherObject, 'func')"), sUndefined); - QCOMPARE(evalJS("myObject.mySignal.disconnect(myObject, 'mySlot')"), sUndefined); - - // check that emitting signals from script works - - // no arguments - QCOMPARE(evalJS("myObject.mySignal.connect(myObject.mySlot)"), sUndefined); - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.mySignal()"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 20); - QCOMPARE(evalJS("myObject.mySignal.disconnect(myObject.mySlot)"), sUndefined); - - // one argument - QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myObject.mySlotWithIntArg)"), sUndefined); - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.mySignalWithIntArg(123)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 21); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); - QCOMPARE(evalJS("myObject.mySignalWithIntArg.disconnect(myObject.mySlotWithIntArg)"), sUndefined); - - QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myObject.mySlotWithDoubleArg)"), sUndefined); - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.mySignalWithIntArg(123)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 22); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDouble(), 123.0); - QCOMPARE(evalJS("myObject.mySignalWithIntArg.disconnect(myObject.mySlotWithDoubleArg)"), sUndefined); - - QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myObject.mySlotWithStringArg)"), sUndefined); - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.mySignalWithIntArg(123)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 23); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toString(), QLatin1String("123")); - QCOMPARE(evalJS("myObject.mySignalWithIntArg.disconnect(myObject.mySlotWithStringArg)"), sUndefined); - - // connecting to overloaded slot - QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myObject.myOverloadedSlot)"), sUndefined); - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.mySignalWithIntArg(123)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 26); // double overload - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); - QCOMPARE(evalJS("myObject.mySignalWithIntArg.disconnect(myObject.myOverloadedSlot)"), sUndefined); - - QCOMPARE(evalJS("myObject.mySignalWithIntArg.connect(myObject['myOverloadedSlot(int)'])"), sUndefined); - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.mySignalWithIntArg(456)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 28); // int overload - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 456); - QCOMPARE(evalJS("myObject.mySignalWithIntArg.disconnect(myObject['myOverloadedSlot(int)'])"), sUndefined); - - // erroneous input - { - // ### QtScript adds .connect to all functions, WebKit does only to signals/slots - QString type; - QString ret = evalJS("(function() { }).connect()", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: 'undefined' is not a function")); - } - { - QString type; - QString ret = evalJS("var o = { }; o.connect = Function.prototype.connect; o.connect()", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: 'undefined' is not a function")); - } - - { - QString type; - QString ret = evalJS("(function() { }).connect(123)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: 'undefined' is not a function")); - } - { - QString type; - QString ret = evalJS("var o = { }; o.connect = Function.prototype.connect; o.connect(123)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: 'undefined' is not a function")); - } - - { - QString type; - QString ret = evalJS("myObject.myInvokable.connect(123)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.connect: MyQObject::myInvokable() is not a signal")); - } - { - QString type; - QString ret = evalJS("myObject.myInvokable.connect(function() { })", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.connect: MyQObject::myInvokable() is not a signal")); - } - - { - QString type; - QString ret = evalJS("myObject.mySignal.connect(123)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.connect: target is not a function")); - } - - { - QString type; - QString ret = evalJS("myObject.mySignal.disconnect()", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("Error: QtMetaMethod.disconnect: no arguments given")); - } - { - QString type; - QString ret = evalJS("var o = { }; o.disconnect = myObject.mySignal.disconnect; o.disconnect()", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("Error: QtMetaMethod.disconnect: no arguments given")); - } - - /* XFAIL - Function.prototype doesn't get connect/disconnect, just signals/slots - { - QString type; - QString ret = evalJS("(function() { }).disconnect(123)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.disconnect: this object is not a signal")); - } - */ - - { - QString type; - QString ret = evalJS("var o = { }; o.disconnect = myObject.myInvokable.disconnect; o.disconnect(123)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.disconnect: MyQObject::myInvokable() is not a signal")); - } - - { - QString type; - QString ret = evalJS("myObject.myInvokable.disconnect(123)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.disconnect: MyQObject::myInvokable() is not a signal")); - } - { - QString type; - QString ret = evalJS("myObject.myInvokable.disconnect(function() { })", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.disconnect: MyQObject::myInvokable() is not a signal")); - } - - { - QString type; - QString ret = evalJS("myObject.mySignal.disconnect(123)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("TypeError: QtMetaMethod.disconnect: target is not a function")); - } - - { - QString type; - QString ret = evalJS("myObject.mySignal.disconnect(function() { })", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("Error: QtMetaMethod.disconnect: failed to disconnect from MyQObject::mySignal()")); - } - - // when the wrapper dies, the connection stays alive - QCOMPARE(evalJS("myObject.mySignal.connect(myObject.mySlot)"), sUndefined); - m_myObject->resetQtFunctionInvoked(); - m_myObject->emitMySignal(); - QCOMPARE(m_myObject->qtFunctionInvoked(), 20); - evalJS("myObject = null"); - evalJS("gc()"); - m_myObject->resetQtFunctionInvoked(); - m_myObject->emitMySignal(); - QCOMPARE(m_myObject->qtFunctionInvoked(), 20); -} - -void tst_QWebFrame::classEnums() -{ - // We don't do the meta thing currently, unfortunately!!! - /* - QString myClass = m_engine->newQMetaObject(m_myObject->metaObject(), m_engine->undefinedValue()); - m_engine->globalObject().setProperty("MyQObject", myClass); - - QCOMPARE(static_cast<MyQObject::Policy>(evalJS("MyQObject.FooPolicy").toInt()), - MyQObject::FooPolicy); - QCOMPARE(static_cast<MyQObject::Policy>(evalJS("MyQObject.BarPolicy").toInt()), - MyQObject::BarPolicy); - QCOMPARE(static_cast<MyQObject::Policy>(evalJS("MyQObject.BazPolicy").toInt()), - MyQObject::BazPolicy); - - QCOMPARE(static_cast<MyQObject::Strategy>(evalJS("MyQObject.FooStrategy").toInt()), - MyQObject::FooStrategy); - QCOMPARE(static_cast<MyQObject::Strategy>(evalJS("MyQObject.BarStrategy").toInt()), - MyQObject::BarStrategy); - QCOMPARE(static_cast<MyQObject::Strategy>(evalJS("MyQObject.BazStrategy").toInt()), - MyQObject::BazStrategy); - - QCOMPARE(MyQObject::Ability(evalJS("MyQObject.NoAbility").toInt()), - MyQObject::NoAbility); - QCOMPARE(MyQObject::Ability(evalJS("MyQObject.FooAbility").toInt()), - MyQObject::FooAbility); - QCOMPARE(MyQObject::Ability(evalJS("MyQObject.BarAbility").toInt()), - MyQObject::BarAbility); - QCOMPARE(MyQObject::Ability(evalJS("MyQObject.BazAbility").toInt()), - MyQObject::BazAbility); - QCOMPARE(MyQObject::Ability(evalJS("MyQObject.AllAbility").toInt()), - MyQObject::AllAbility); - - // enums from Qt are inherited through prototype - QCOMPARE(static_cast<Qt::FocusPolicy>(evalJS("MyQObject.StrongFocus").toInt()), - Qt::StrongFocus); - QCOMPARE(static_cast<Qt::Key>(evalJS("MyQObject.Key_Left").toInt()), - Qt::Key_Left); - - QCOMPARE(evalJS("MyQObject.className()"), QLatin1String("MyQObject")); - - qRegisterMetaType<MyQObject::Policy>("Policy"); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.myInvokableWithEnumArg(MyQObject.BazPolicy)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 10); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), int(MyQObject::BazPolicy)); - - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.myInvokableWithQualifiedEnumArg(MyQObject.BazPolicy)"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 36); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), int(MyQObject::BazPolicy)); - - m_myObject->resetQtFunctionInvoked(); - { - QVariant ret = evalJS("myObject.myInvokableReturningEnum()"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 37); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 0); - QCOMPARE(ret.isVariant()); - } - m_myObject->resetQtFunctionInvoked(); - { - QVariant ret = evalJS("myObject.myInvokableReturningQualifiedEnum()"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 38); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 0); - QCOMPARE(ret.isNumber()); - } - */ -} - -void tst_QWebFrame::classConstructor() -{ - /* - QString myClass = qScriptValueFromQMetaObject<MyQObject>(m_engine); - m_engine->globalObject().setProperty("MyQObject", myClass); - - QString myObj = evalJS("myObj = MyQObject()"); - QObject* qobj = myObj.toQObject(); - QVERIFY(qobj != 0); - QCOMPARE(qobj->metaObject()->className(), "MyQObject"); - QCOMPARE(qobj->parent(), (QObject*)0); - - QString qobjectClass = qScriptValueFromQMetaObject<QObject>(m_engine); - m_engine->globalObject().setProperty("QObject", qobjectClass); - - QString otherObj = evalJS("otherObj = QObject(myObj)"); - QObject* qqobj = otherObj.toQObject(); - QVERIFY(qqobj != 0); - QCOMPARE(qqobj->metaObject()->className(), "QObject"); - QCOMPARE(qqobj->parent(), qobj); - - delete qobj; - */ -} - -void tst_QWebFrame::overrideInvokable() -{ - m_myObject->resetQtFunctionInvoked(); - QCOMPARE(evalJS("myObject.myInvokable()"), sUndefined); - QCOMPARE(m_myObject->qtFunctionInvoked(), 0); - - /* XFAIL - can't write to functions with RuntimeObject - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myInvokable = function() { window.a = 123; }"); - evalJS("myObject.myInvokable()"); - QCOMPARE(m_myObject->qtFunctionInvoked(), -1); - QCOMPARE(evalJS("window.a").toDouble(), 123.0); - - evalJS("myObject.myInvokable = function() { window.a = 456; }"); - evalJS("myObject.myInvokable()"); - QCOMPARE(m_myObject->qtFunctionInvoked(), -1); - QCOMPARE(evalJS("window.a").toDouble(), 456.0); - */ - - evalJS("delete myObject.myInvokable"); - evalJS("myObject.myInvokable()"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 0); - - /* XFAIL - ditto - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myInvokable = myObject.myInvokableWithIntArg"); - evalJS("myObject.myInvokable(123)"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 1); - */ - - evalJS("delete myObject.myInvokable"); - m_myObject->resetQtFunctionInvoked(); - // this form (with the '()') is read-only - evalJS("myObject['myInvokable()'] = function() { window.a = 123; }"); - evalJS("myObject.myInvokable()"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 0); -} - -void tst_QWebFrame::transferInvokable() -{ - /* XFAIL - can't put to functions with RuntimeObject - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.foozball = myObject.myInvokable"); - evalJS("myObject.foozball()"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 0); - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.foozball = myObject.myInvokableWithIntArg"); - evalJS("myObject.foozball(123)"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 1); - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myInvokable = myObject.myInvokableWithIntArg"); - evalJS("myObject.myInvokable(123)"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 1); - - MyOtherQObject other; - m_page->mainFrame()->addToJSWindowObject("myOtherObject", &other); - evalJS("myOtherObject.foo = myObject.foozball"); - other.resetQtFunctionInvoked(); - evalJS("myOtherObject.foo(456)"); - QCOMPARE(other.qtFunctionInvoked(), 1); - */ -} - -void tst_QWebFrame::findChild() -{ - /* - QObject* child = new QObject(m_myObject); - child->setObjectName(QLatin1String("myChildObject")); - - { - QString result = evalJS("myObject.findChild('noSuchChild')"); - QCOMPARE(result.isNull()); - } - - { - QString result = evalJS("myObject.findChild('myChildObject')"); - QCOMPARE(result.isQObject()); - QCOMPARE(result.toQObject(), child); - } - - delete child; - */ -} - -void tst_QWebFrame::findChildren() -{ - /* - QObject* child = new QObject(m_myObject); - child->setObjectName(QLatin1String("myChildObject")); - - { - QString result = evalJS("myObject.findChildren('noSuchChild')"); - QCOMPARE(result.isArray()); - QCOMPARE(result.property(QLatin1String("length")).toDouble(), 0.0); - } - - { - QString result = evalJS("myObject.findChildren('myChildObject')"); - QCOMPARE(result.isArray()); - QCOMPARE(result.property(QLatin1String("length")).toDouble(), 1.0); - QCOMPARE(result.property(QLatin1String("0")).toQObject(), child); - } - - QObject* namelessChild = new QObject(m_myObject); - - { - QString result = evalJS("myObject.findChildren('myChildObject')"); - QCOMPARE(result.isArray()); - QCOMPARE(result.property(QLatin1String("length")).toDouble(), 1.0); - QCOMPARE(result.property(QLatin1String("0")).toQObject(), child); - } - - QObject* anotherChild = new QObject(m_myObject); - anotherChild->setObjectName(QLatin1String("anotherChildObject")); - - { - QString result = evalJS("myObject.findChildren('anotherChildObject')"); - QCOMPARE(result.isArray()); - QCOMPARE(result.property(QLatin1String("length")).toDouble(), 1.0); - QCOMPARE(result.property(QLatin1String("0")).toQObject(), anotherChild); - } - - anotherChild->setObjectName(QLatin1String("myChildObject")); - { - QString result = evalJS("myObject.findChildren('myChildObject')"); - QCOMPARE(result.isArray()); - QCOMPARE(result.property(QLatin1String("length")).toDouble(), 2.0); - QObject* o1 = result.property(QLatin1String("0")).toQObject(); - QObject* o2 = result.property(QLatin1String("1")).toQObject(); - if (o1 != child) { - QCOMPARE(o1, anotherChild); - QCOMPARE(o2, child); - } else { - QCOMPARE(o1, child); - QCOMPARE(o2, anotherChild); - } - } - - // find all - { - QString result = evalJS("myObject.findChildren()"); - QVERIFY(result.isArray()); - int count = 3; - QCOMPARE(result.property("length"), QLatin1String(count); - for (int i = 0; i < 3; ++i) { - QObject* o = result.property(i).toQObject(); - if (o == namelessChild || o == child || o == anotherChild) - --count; - } - QVERIFY(count == 0); - } - - delete anotherChild; - delete namelessChild; - delete child; - */ -} - -void tst_QWebFrame::overloadedSlots() -{ - // should pick myOverloadedSlot(double) - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myOverloadedSlot(10)"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 26); - - // should pick myOverloadedSlot(double) - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myOverloadedSlot(10.0)"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 26); - - // should pick myOverloadedSlot(QString) - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myOverloadedSlot('10')"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 29); - - // should pick myOverloadedSlot(bool) - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myOverloadedSlot(true)"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 25); - - // should pick myOverloadedSlot(QDateTime) - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myOverloadedSlot(new Date())"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 32); - - // should pick myOverloadedSlot(QRegExp) - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myOverloadedSlot(new RegExp())"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 34); - - // should pick myOverloadedSlot(QVariant) - /* XFAIL - m_myObject->resetQtFunctionInvoked(); - QString f = evalJS("myObject.myOverloadedSlot"); - f.call(QString(), QStringList() << m_engine->newVariant(QVariant("ciao"))); - QCOMPARE(m_myObject->qtFunctionInvoked(), 35); - */ - - // Should pick myOverloadedSlot(QWebElement). - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myOverloadedSlot(document.body)"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 36); - - // should pick myOverloadedSlot(QObject*) - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myOverloadedSlot(myObject)"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 41); - - // should pick myOverloadedSlot(QObject*) - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myOverloadedSlot(null)"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 41); - - // should pick myOverloadedSlot(QStringList) - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myOverloadedSlot(['hello'])"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 42); -} - -void tst_QWebFrame::enumerate_data() -{ - QTest::addColumn<QStringList>("expectedNames"); - - QTest::newRow("enumerate all") - << (QStringList() - // meta-object-defined properties: - // inherited - << "objectName" - // non-inherited - << "p1" << "p2" << "p4" << "p6" - // dynamic properties - << "dp1" << "dp2" << "dp3" - // inherited signals and slots - << "destroyed(QObject*)" << "destroyed()" -#if defined(HAVE_QT5) && HAVE_QT5 - << "objectNameChanged(QString)" -#endif - << "deleteLater()" - // not included because it's private: - // << "_q_reregisterTimers(void*)" - // signals - << "mySignal()" - // slots - << "mySlot()" << "myOtherSlot()"); -} - -void tst_QWebFrame::enumerate() -{ - QFETCH(QStringList, expectedNames); - - MyEnumTestQObject enumQObject; - // give it some dynamic properties - enumQObject.setProperty("dp1", "dp1"); - enumQObject.setProperty("dp2", "dp2"); - enumQObject.setProperty("dp3", "dp3"); - m_page->mainFrame()->addToJavaScriptWindowObject("myEnumObject", &enumQObject); - - // enumerate in script - { - evalJS("var enumeratedProperties = []"); - evalJS("for (var p in myEnumObject) { enumeratedProperties.push(p); }"); - QStringList result = evalJSV("enumeratedProperties").toStringList(); - QCOMPARE(result.size(), expectedNames.size()); - for (int i = 0; i < expectedNames.size(); ++i) - QCOMPARE(result.at(i), expectedNames.at(i)); - } -} - -void tst_QWebFrame::objectDeleted() -{ - MyQObject* qobj = new MyQObject(); - m_page->mainFrame()->addToJavaScriptWindowObject("bar", qobj); - evalJS("bar.objectName = 'foo';"); - QCOMPARE(qobj->objectName(), QLatin1String("foo")); - evalJS("bar.intProperty = 123;"); - QCOMPARE(qobj->intProperty(), 123); - qobj->resetQtFunctionInvoked(); - evalJS("bar.myInvokable.call(bar);"); - QCOMPARE(qobj->qtFunctionInvoked(), 0); - - // do this, to ensure that we cache that it implements call - evalJS("bar()"); - - // now delete the object - delete qobj; - - QCOMPARE(evalJS("typeof bar"), sObject); - - // any attempt to access properties of the object should result in an exception - { - QString type; - QString ret = evalJS("bar.objectName", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("Error: cannot access member `objectName' of deleted QObject")); - } - { - QString type; - QString ret = evalJS("bar.objectName = 'foo'", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("Error: cannot access member `objectName' of deleted QObject")); - } - - // myInvokable is stored in member table (since we've accessed it before deletion) - { - QString type; - evalJS("bar.myInvokable", type); - QCOMPARE(type, sFunction); - } - - { - QString type; - QString ret = evalJS("bar.myInvokable.call(bar);", type); - ret = evalJS("bar.myInvokable(bar)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("Error: cannot call function of deleted QObject")); - } - // myInvokableWithIntArg is not stored in member table (since we've not accessed it) - { - QString type; - QString ret = evalJS("bar.myInvokableWithIntArg", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("Error: cannot access member `myInvokableWithIntArg' of deleted QObject")); - } - - // access from script - evalJS("window.o = bar;"); - { - QString type; - QString ret = evalJS("o.objectName", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("Error: cannot access member `objectName' of deleted QObject")); - } - { - QString type; - QString ret = evalJS("o.myInvokable()", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("Error: cannot call function of deleted QObject")); - } - { - QString type; - QString ret = evalJS("o.myInvokableWithIntArg(10)", type); - QCOMPARE(type, sError); - QCOMPARE(ret, QLatin1String("Error: cannot access member `myInvokableWithIntArg' of deleted QObject")); - } -} - -void tst_QWebFrame::typeConversion() -{ - m_myObject->resetQtFunctionInvoked(); - - QDateTime localdt(QDate(2008,1,18), QTime(12,31,0)); - QDateTime utclocaldt = localdt.toUTC(); - QDateTime utcdt(QDate(2008,1,18), QTime(12,31,0), Qt::UTC); - - // Dates in JS (default to local) - evalJS("myObject.myOverloadedSlot(new Date(2008,0,18,12,31,0))"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 32); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDateTime().toUTC(), utclocaldt); - - m_myObject->resetQtFunctionInvoked(); - evalJS("myObject.myOverloadedSlot(new Date(Date.UTC(2008,0,18,12,31,0)))"); - QCOMPARE(m_myObject->qtFunctionInvoked(), 32); - QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); - QCOMPARE(m_myObject->qtFunctionActuals().at(0).toDateTime().toUTC(), utcdt); - - // Pushing QDateTimes into JS - // Local - evalJS("function checkDate(d) {window.__date_equals = (d.toString() == new Date(2008,0,18,12,31,0))?true:false;}"); - evalJS("myObject.mySignalWithDateTimeArg.connect(checkDate)"); - m_myObject->emitMySignalWithDateTimeArg(localdt); - QCOMPARE(evalJS("window.__date_equals"), sTrue); - evalJS("delete window.__date_equals"); - m_myObject->emitMySignalWithDateTimeArg(utclocaldt); - QCOMPARE(evalJS("window.__date_equals"), sTrue); - evalJS("delete window.__date_equals"); - evalJS("myObject.mySignalWithDateTimeArg.disconnect(checkDate); delete checkDate;"); - - // UTC - evalJS("function checkDate(d) {window.__date_equals = (d.toString() == new Date(Date.UTC(2008,0,18,12,31,0)))?true:false; }"); - evalJS("myObject.mySignalWithDateTimeArg.connect(checkDate)"); - m_myObject->emitMySignalWithDateTimeArg(utcdt); - QCOMPARE(evalJS("window.__date_equals"), sTrue); - evalJS("delete window.__date_equals"); - evalJS("myObject.mySignalWithDateTimeArg.disconnect(checkDate); delete checkDate;"); - - // ### RegExps -} - -class StringListTestObject : public QObject { - Q_OBJECT -public Q_SLOTS: - QVariant stringList() - { - return QStringList() << "Q" << "t"; - }; -}; - -void tst_QWebFrame::arrayObjectEnumerable() -{ - QWebPage page; - QWebFrame* frame = page.mainFrame(); - QObject* qobject = new StringListTestObject(); - frame->addToJavaScriptWindowObject("test", qobject, QScriptEngine::ScriptOwnership); - - const QString script("var stringArray = test.stringList();" - "var result = '';" - "for (var i in stringArray) {" - " result += stringArray[i];" - "}" - "result;"); - QCOMPARE(frame->evaluateJavaScript(script).toString(), QString::fromLatin1("Qt")); } void tst_QWebFrame::symmetricUrl() @@ -2285,14 +197,6 @@ void tst_QWebFrame::urlChange() QCOMPARE(urlSpy.size(), 2); } - -void tst_QWebFrame::domCycles() -{ - m_view->setHtml("<html><body>"); - QVariant v = m_page->mainFrame()->evaluateJavaScript("document"); - QVERIFY(v.type() == QVariant::Map); -} - class FakeReply : public QNetworkReply { Q_OBJECT @@ -2756,89 +660,6 @@ void tst_QWebFrame::hitTestContent() QCOMPARE(link.attribute("target"), QString("_foo")); } -void tst_QWebFrame::jsByteArray() -{ - QByteArray ba("hello world"); - m_myObject->setByteArrayProperty(ba); - - // read-only property - QCOMPARE(m_myObject->byteArrayProperty(), ba); - QString type; - QVariant v = evalJSV("myObject.byteArrayProperty"); - QCOMPARE(int(v.type()), int(QVariant::ByteArray)); - - QCOMPARE(v.toByteArray(), ba); -} - -void tst_QWebFrame::ownership() -{ - // test ownership - { - QWeakPointer<QObject> ptr = new QObject(); - QVERIFY(ptr != 0); - { - QWebPage page; - QWebFrame* frame = page.mainFrame(); - frame->addToJavaScriptWindowObject("test", ptr.data(), QScriptEngine::ScriptOwnership); - } - QVERIFY(ptr == 0); - } - { - QWeakPointer<QObject> ptr = new QObject(); - QVERIFY(ptr != 0); - QObject* before = ptr.data(); - { - QWebPage page; - QWebFrame* frame = page.mainFrame(); - frame->addToJavaScriptWindowObject("test", ptr.data(), QScriptEngine::QtOwnership); - } - QVERIFY(ptr.data() == before); - delete ptr.data(); - } - { - QObject* parent = new QObject(); - QObject* child = new QObject(parent); - QWebPage page; - QWebFrame* frame = page.mainFrame(); - frame->addToJavaScriptWindowObject("test", child, QScriptEngine::QtOwnership); - QVariant v = frame->evaluateJavaScript("test"); - QCOMPARE(qvariant_cast<QObject*>(v), child); - delete parent; - v = frame->evaluateJavaScript("test"); - QCOMPARE(qvariant_cast<QObject*>(v), (QObject *)0); - } - { - QWeakPointer<QObject> ptr = new QObject(); - QVERIFY(ptr != 0); - { - QWebPage page; - QWebFrame* frame = page.mainFrame(); - frame->addToJavaScriptWindowObject("test", ptr.data(), QScriptEngine::AutoOwnership); - } - // no parent, so it should be like ScriptOwnership - QVERIFY(ptr == 0); - } - { - QObject* parent = new QObject(); - QWeakPointer<QObject> child = new QObject(parent); - QVERIFY(child != 0); - { - QWebPage page; - QWebFrame* frame = page.mainFrame(); - frame->addToJavaScriptWindowObject("test", child.data(), QScriptEngine::AutoOwnership); - } - // has parent, so it should be like QtOwnership - QVERIFY(child != 0); - delete parent; - } -} - -void tst_QWebFrame::nullValue() -{ - QVariant v = m_view->page()->mainFrame()->evaluateJavaScript("null"); - QVERIFY(v.isNull()); -} - void tst_QWebFrame::baseUrl_data() { QTest::addColumn<QString>("html"); @@ -3212,86 +1033,6 @@ void tst_QWebFrame::evaluateWillCauseRepaint() ::waitForSignal(view.page(), SIGNAL(repaintRequested(QRect))); } -class TestFactory : public QObject -{ - Q_OBJECT -public: - TestFactory() - : obj(0), counter(0) - {} - - Q_INVOKABLE QObject* getNewObject() - { - delete obj; - obj = new QObject(this); - obj->setObjectName(QLatin1String("test") + QString::number(++counter)); - return obj; - - } - - QObject* obj; - int counter; -}; - -void tst_QWebFrame::qObjectWrapperWithSameIdentity() -{ - m_view->setHtml("<script>function triggerBug() { document.getElementById('span1').innerText = test.getNewObject().objectName; }</script>" - "<body><span id='span1'>test</span></body>"); - - QWebFrame* mainFrame = m_view->page()->mainFrame(); - QCOMPARE(mainFrame->toPlainText(), QString("test")); - - mainFrame->addToJavaScriptWindowObject("test", new TestFactory, QScriptEngine::ScriptOwnership); - - mainFrame->evaluateJavaScript("triggerBug();"); - QCOMPARE(mainFrame->toPlainText(), QString("test1")); - - mainFrame->evaluateJavaScript("triggerBug();"); - QCOMPARE(mainFrame->toPlainText(), QString("test2")); -} - -void tst_QWebFrame::introspectQtMethods_data() -{ - QTest::addColumn<QString>("objectExpression"); - QTest::addColumn<QString>("methodName"); - QTest::addColumn<QStringList>("expectedPropertyNames"); - - QTest::newRow("myObject.mySignal") - << "myObject" << "mySignal" << (QStringList() << "connect" << "disconnect" << "length" << "name"); - QTest::newRow("myObject.mySlot") - << "myObject" << "mySlot" << (QStringList() << "connect" << "disconnect" << "length" << "name"); - QTest::newRow("myObject.myInvokable") - << "myObject" << "myInvokable" << (QStringList() << "connect" << "disconnect" << "length" << "name"); - QTest::newRow("myObject.mySignal.connect") - << "myObject.mySignal" << "connect" << (QStringList() << "length" << "name"); - QTest::newRow("myObject.mySignal.disconnect") - << "myObject.mySignal" << "disconnect" << (QStringList() << "length" << "name"); -} - -void tst_QWebFrame::introspectQtMethods() -{ - QFETCH(QString, objectExpression); - QFETCH(QString, methodName); - QFETCH(QStringList, expectedPropertyNames); - - QString methodLookup = QString::fromLatin1("%0['%1']").arg(objectExpression).arg(methodName); - QCOMPARE(evalJSV(QString::fromLatin1("Object.getOwnPropertyNames(%0).sort()").arg(methodLookup)).toStringList(), expectedPropertyNames); - - for (int i = 0; i < expectedPropertyNames.size(); ++i) { - QString name = expectedPropertyNames.at(i); - QCOMPARE(evalJS(QString::fromLatin1("%0.hasOwnProperty('%1')").arg(methodLookup).arg(name)), sTrue); - evalJS(QString::fromLatin1("var descriptor = Object.getOwnPropertyDescriptor(%0, '%1')").arg(methodLookup).arg(name)); - QCOMPARE(evalJS("typeof descriptor"), QString::fromLatin1("object")); - QCOMPARE(evalJS("descriptor.get"), sUndefined); - QCOMPARE(evalJS("descriptor.set"), sUndefined); - QCOMPARE(evalJS(QString::fromLatin1("descriptor.value === %0['%1']").arg(methodLookup).arg(name)), sTrue); - QCOMPARE(evalJS(QString::fromLatin1("descriptor.enumerable")), sFalse); - QCOMPARE(evalJS(QString::fromLatin1("descriptor.configurable")), sFalse); - } - - QVERIFY(evalJSV("var props=[]; for (var p in myObject.deleteLater) {props.push(p);}; props.sort()").toStringList().isEmpty()); -} - void tst_QWebFrame::setContent_data() { QTest::addColumn<QString>("mimeType"); @@ -3374,15 +1115,6 @@ void tst_QWebFrame::setCacheLoadControlAttribute() QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferNetwork); } -void tst_QWebFrame::webElementSlotOnly() -{ - MyWebElementSlotOnlyObject object; - m_page->mainFrame()->setHtml("<html><head><body></body></html>"); - m_page->mainFrame()->addToJavaScriptWindowObject("myWebElementSlotObject", &object); - evalJS("myWebElementSlotObject.doSomethingWithWebElement(document.body)"); - QCOMPARE(evalJS("myWebElementSlotObject.tagName"), QString("BODY")); -} - // [Qt] Fix tst_QWebFrame::setUrlWithPendingLoads() API test // https://bugs.webkit.org/show_bug.cgi?id=63237 /* diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog index 2dd830c1c..d3f245540 100644 --- a/Source/WebKit2/ChangeLog +++ b/Source/WebKit2/ChangeLog @@ -1,3 +1,173 @@ +2012-06-01 Brady Eidson <beidson@apple.com> + + <rdar://problem/11335622> and https://bugs.webkit.org/show_bug.cgi?id=88119 + REGRESSION (r99448) Zero-sized plug-ins no longer get an NPP_SetWindow call + + Followup to r119260 + + Rubber-stamped by Anders Carlsson. + + * WebProcess/Plugins/Netscape/NetscapePlugin.cpp: + (WebKit::NetscapePlugin::callSetWindow): Set the m_hasCalledSetWindow here... + (WebKit::NetscapePlugin::geometryDidChange): ...instead of here. + +2012-06-01 Brady Eidson <beidson@apple.com> + + <rdar://problem/11335622> and https://bugs.webkit.org/show_bug.cgi?id=88119 + REGRESSION (r99448) Zero-sized plug-ins no longer get an NPP_SetWindow call + + Reviewed by Oliver Hunt. + + Add a flag to NetscapePlugin to track whether or not NPP_SetWindow has ever been called. + Check this flag in geometryDidChange to make sure every plug-in gets the call at least once. + + "Everybody gets one. Tell him, Peter." + "Apparently everybody gets one." + "Bingo." + + * WebProcess/Plugins/Netscape/NetscapePlugin.cpp: + (WebKit::NetscapePlugin::NetscapePlugin): + (WebKit::NetscapePlugin::geometryDidChange): + * WebProcess/Plugins/Netscape/NetscapePlugin.h: + (NetscapePlugin): + +2012-06-01 Dinu Jacob <dinu.jacob@nokia.com> + + [WK2] WebLayerTreeRenderer::setContentsSize called synchronously + https://bugs.webkit.org/show_bug.cgi?id=88091 + + Reviewed by Noam Rosenthal. + + Do not call WebLayerTreeRenderer::setContentsSize synchronously + from LayerTreeHostProxy. + + * UIProcess/LayerTreeHostProxy.cpp: + (WebKit::LayerTreeHostProxy::setContentsSize): + +2012-06-01 Dinu Jacob <dinu.jacob@nokia.com> + + [Qt][WK2] Set QWebKitTest::isScalable default as false + https://bugs.webkit.org/show_bug.cgi?id=88095 + + Reviewed by Tor Arne Vestbø. + + Set QWebKitTest::isScalable default as false + + * UIProcess/API/qt/qwebkittest.cpp: + (QWebKitTest::isScalable): + +2012-06-01 Allan Sandfeld Jensen <allan.jensen@nokia.com> + + [Qt] Remove QtViewportInteractionEngine::pageItemSizeChanged. + https://bugs.webkit.org/show_bug.cgi?id=88082 + + Reviewed by Kenneth Rohde Christiansen. + + The function was causing flickering, and after testing it was verified + that it was no longer needed either. + + * UIProcess/qt/QtViewportInteractionEngine.cpp: + (WebKit::QtViewportInteractionEngine::QtViewportInteractionEngine): + * UIProcess/qt/QtViewportInteractionEngine.h: + (QtViewportInteractionEngine): + +2012-06-01 Dinu Jacob <dinu.jacob@nokia.com> + + [Qt][WK2] Contents not rendered in MiniBrowser for some pages + https://bugs.webkit.org/show_bug.cgi?id=87922 + + Reviewed by Kenneth Rohde Christiansen. + + Set drawing area visible contents rect if new visible contents rect is different from + the previous one. + + * UIProcess/qt/QtViewportInteractionEngine.cpp: + (WebKit::QtViewportInteractionEngine::informVisibleContentChange): + * UIProcess/qt/QtViewportInteractionEngine.h: + (QtViewportInteractionEngine): + +2012-06-01 Kenneth Rohde Christiansen <kenneth@webkit.org> + + [Qt] Move suspension to QtViewportInteractionEngine + https://bugs.webkit.org/show_bug.cgi?id=88078 + + Reviewed by Simon Hausmann. + + Next step is to take care of visibility changes. + + * UIProcess/API/qt/qquickwebview.cpp: + (QQuickWebViewFlickablePrivate::QQuickWebViewFlickablePrivate): + (QQuickWebViewFlickablePrivate::onComponentComplete): + * UIProcess/API/qt/qquickwebview_p.h: + * UIProcess/API/qt/qquickwebview_p_p.h: + (QQuickWebViewPrivate): + (QQuickWebViewFlickablePrivate): + * UIProcess/qt/QtViewportInteractionEngine.cpp: + (WebKit::ViewportUpdateDeferrer::ViewportUpdateDeferrer): + (WebKit::ViewportUpdateDeferrer::~ViewportUpdateDeferrer): + (WebKit::QtViewportInteractionEngine::suspendPageContent): + (WebKit): + (WebKit::QtViewportInteractionEngine::resumePageContent): + * UIProcess/qt/QtViewportInteractionEngine.h: + (QtViewportInteractionEngine): + +2012-06-01 Dinu Jacob <dinu.jacob@nokia.com> + + [Qt][W2] Qml Error in ViewportInfoItem.qml in MiniBrowser + https://bugs.webkit.org/show_bug.cgi?id=87999 + + Reviewed by Kenneth Rohde Christiansen. + + Return default viewport attributes rather than invalid QVariant. + + * UIProcess/API/qt/qwebkittest.cpp: + (QWebKitTest::contentsScale): + (QWebKitTest::devicePixelRatio): + (QWebKitTest::initialScale): + (QWebKitTest::minimumScale): + (QWebKitTest::maximumScale): + (QWebKitTest::isScalable): + (QWebKitTest::layoutSize): + +2012-05-31 Kenneth Rohde Christiansen <kenneth@webkit.org> + + [Qt] Clean up our viewport handling mess + https://bugs.webkit.org/show_bug.cgi?id=87977 + + Reviewed by Simon Hausmann. + + Consolidated functionality from QQuickWebViewPrivate* into + ViewportInteractionEngine that belongs there, in preparation for + renaming ViewportInteractionEngine in the future. + + Remove unneeded methods and move others to private. + + * UIProcess/API/qt/qquickwebview.cpp: + (QQuickWebViewFlickablePrivate::QQuickWebViewFlickablePrivate): + (QQuickWebViewFlickablePrivate::onComponentComplete): + (QQuickWebViewFlickablePrivate::didChangeViewportProperties): + (QQuickWebViewFlickablePrivate::updateViewportSize): + (QQuickWebViewFlickablePrivate::_q_resume): + (QQuickWebViewFlickablePrivate::pageDidRequestScroll): + * UIProcess/API/qt/qquickwebview_p.h: + * UIProcess/API/qt/qquickwebview_p_p.h: + (QQuickWebViewPrivate): + (QQuickWebViewFlickablePrivate): + * UIProcess/qt/QtViewportInteractionEngine.cpp: + (WebKit::ViewportUpdateDeferrer::~ViewportUpdateDeferrer): + (WebKit::QtViewportInteractionEngine::QtViewportInteractionEngine): + (WebKit::QtViewportInteractionEngine::viewportAttributesChanged): + (WebKit::QtViewportInteractionEngine::pageContentsSizeChanged): + (WebKit::QtViewportInteractionEngine::pageItemPositionChanged): + (WebKit::QtViewportInteractionEngine::pageContentPositionRequested): + (WebKit::QtViewportInteractionEngine::visibleContentsRect): + (WebKit): + (WebKit::QtViewportInteractionEngine::informVisibleContentChange): + (WebKit::QtViewportInteractionEngine::viewportItemSizeChanged): + * UIProcess/qt/QtViewportInteractionEngine.h: + (WebKit): + (QtViewportInteractionEngine): + 2012-05-31 Hajime Morrita <morrita@chromium.org> REGRESSION(r117572): editing/spelling/spellcheck-async-remove-frame.html crashes on Mac diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp index 5b43e337d..7fc2e8728 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp @@ -735,16 +735,6 @@ void QQuickWebViewPrivate::setContentPos(const QPointF& pos) q->setContentY(pos.y()); } -QRect QQuickWebViewPrivate::visibleContentsRect() const -{ - Q_Q(const QQuickWebView); - const QRectF visibleRect(q->boundingRect().intersected(pageView->boundingRect())); - - // We avoid using toAlignedRect() because it produces inconsistent width and height. - QRectF mappedRect(q->mapRectToWebContent(visibleRect)); - return QRect(floor(mappedRect.x()), floor(mappedRect.y()), floor(mappedRect.width()), floor(mappedRect.height())); -} - WebCore::IntSize QQuickWebViewPrivate::viewSize() const { return WebCore::IntSize(pageView->width(), pageView->height()); @@ -819,8 +809,6 @@ void QQuickWebViewLegacyPrivate::setZoomFactor(qreal factor) QQuickWebViewFlickablePrivate::QQuickWebViewFlickablePrivate(QQuickWebView* viewport) : QQuickWebViewPrivate(viewport) - , pageIsSuspended(false) - , lastCommittedScale(-1) { // Disable mouse events on the flickable web view so we do not // select text during pan gestures on platforms which send both @@ -846,89 +834,29 @@ void QQuickWebViewFlickablePrivate::onComponentComplete() { Q_Q(QQuickWebView); - interactionEngine.reset(new QtViewportInteractionEngine(q, pageView.data())); + interactionEngine.reset(new QtViewportInteractionEngine(webPageProxy.get(), q, pageView.data())); pageView->eventHandler()->setViewportInteractionEngine(interactionEngine.data()); - QObject::connect(interactionEngine.data(), SIGNAL(contentSuspendRequested()), q, SLOT(_q_suspend())); - QObject::connect(interactionEngine.data(), SIGNAL(contentResumeRequested()), q, SLOT(_q_resume())); - QObject::connect(interactionEngine.data(), SIGNAL(informVisibleContentChange(QPointF)), q, SLOT(_q_onInformVisibleContentChange(QPointF))); - - _q_resume(); - // Trigger setting of correct visibility flags after everything was allocated and initialized. _q_onVisibleChanged(); } void QQuickWebViewFlickablePrivate::didChangeViewportProperties(const WebCore::ViewportAttributes& newAttributes) { - interactionEngine->viewportAttributesChanged(newAttributes); + if (interactionEngine) + interactionEngine->viewportAttributesChanged(newAttributes); } void QQuickWebViewFlickablePrivate::updateViewportSize() { - Q_Q(QQuickWebView); - QSize viewportSize = q->boundingRect().size().toSize(); - - if (viewportSize.isEmpty() || !interactionEngine) - return; - - WebPreferences* wkPrefs = webPageProxy->pageGroup()->preferences(); - wkPrefs->setDeviceWidth(viewportSize.width()); - wkPrefs->setDeviceHeight(viewportSize.height()); - - // Let the WebProcess know about the new viewport size, so that - // it can resize the content accordingly. - webPageProxy->setViewportSize(viewportSize); - - _q_onInformVisibleContentChange(QPointF()); -} - -void QQuickWebViewFlickablePrivate::_q_onInformVisibleContentChange(const QPointF& trajectoryVector) -{ - Q_Q(QQuickWebView); - - DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); - if (!drawingArea) - return; - - QRectF accurateVisibleRect(q->boundingRect()); - accurateVisibleRect.translate(contentPos()); - - if (accurateVisibleRect == drawingArea->contentsRect()) - return; - - float scale = pageView->contentsScale(); - - if (scale != lastCommittedScale) - emit q->experimental()->test()->contentsScaleCommitted(); - lastCommittedScale = scale; - - drawingArea->setVisibleContentsRect(QRect(visibleContentsRect()), scale, trajectoryVector, FloatPoint(accurateVisibleRect.x(), accurateVisibleRect.y())); - - // Ensure that updatePaintNode is always called before painting. - pageView->update(); -} - -void QQuickWebViewFlickablePrivate::_q_suspend() -{ - pageIsSuspended = true; - webPageProxy->suspendActiveDOMObjectsAndAnimations(); -} - -void QQuickWebViewFlickablePrivate::_q_resume() -{ - if (!interactionEngine) - return; - - pageIsSuspended = false; - webPageProxy->resumeActiveDOMObjectsAndAnimations(); - - _q_onInformVisibleContentChange(QPointF()); + // FIXME: Examine why there is not an interactionEngine here in the beginning. + if (interactionEngine) + interactionEngine->viewportItemSizeChanged(); } void QQuickWebViewFlickablePrivate::pageDidRequestScroll(const QPoint& pos) { - interactionEngine->pageContentPositionRequest(pos); + interactionEngine->pageContentPositionRequested(pos); } void QQuickWebViewFlickablePrivate::didChangeContentsSize(const QSize& newSize) diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h index cf469fb1e..deb811f7b 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h @@ -205,10 +205,6 @@ private: void emitUrlChangeIfNeeded(); - Q_PRIVATE_SLOT(d_func(), void _q_suspend()); - Q_PRIVATE_SLOT(d_func(), void _q_resume()); - Q_PRIVATE_SLOT(d_func(), void _q_onInformVisibleContentChange(const QPointF&)); - Q_PRIVATE_SLOT(d_func(), void _q_onVisibleChanged()); Q_PRIVATE_SLOT(d_func(), void _q_onUrlChanged()); Q_PRIVATE_SLOT(d_func(), void _q_onReceivedResponseFromDownload(QWebDownloadItem*)); diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h index 69afc2d54..3c3cb7e9b 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h @@ -93,10 +93,6 @@ public: virtual void updateViewportSize() { } void updateTouchViewportSize(); - virtual void _q_suspend() { } - virtual void _q_resume() { } - virtual void _q_onInformVisibleContentChange(const QPointF& trajectory) { }; - virtual qreal zoomFactor() const { return 1; } virtual void setZoomFactor(qreal) { } @@ -128,8 +124,6 @@ public: QPointF contentPos() const; void setContentPos(const QPointF&); - QRect visibleContentsRect() const; - void setDialogActive(bool active) { m_dialogActive = active; } void updateIcon(); @@ -231,17 +225,11 @@ public: virtual WebKit::QtViewportInteractionEngine* viewportInteractionEngine() { return interactionEngine.data(); } virtual void updateViewportSize(); - virtual void _q_suspend(); - virtual void _q_resume(); - virtual void _q_onInformVisibleContentChange(const QPointF& trajectory); - virtual void pageDidRequestScroll(const QPoint& pos); virtual void didChangeContentsSize(const QSize& newSize); private: QScopedPointer<WebKit::QtViewportInteractionEngine> interactionEngine; - bool pageIsSuspended; - float lastCommittedScale; }; #endif // qquickwebview_p_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp b/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp index e0a441c0e..13decd7d0 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp @@ -122,47 +122,47 @@ QVariant QWebKitTest::contentsScale() const { if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) return viewport->currentCSSScale(); - return QVariant(); + return 1.0; } QVariant QWebKitTest::devicePixelRatio() const { if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) return viewport->m_devicePixelRatio; - return QVariant(); + return 1.0; } QVariant QWebKitTest::initialScale() const { if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) return viewport->m_rawAttributes.initialScale; - return QVariant(); + return 1.0; } QVariant QWebKitTest::minimumScale() const { if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) return viewport->m_minimumScale; - return QVariant(); + return 1.0; } QVariant QWebKitTest::maximumScale() const { if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) return viewport->m_maximumScale; - return QVariant(); + return 1.0; } QVariant QWebKitTest::isScalable() const { if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) return !!viewport->m_rawAttributes.userScalable; - return QVariant(); + return false; } QVariant QWebKitTest::layoutSize() const { if (QtViewportInteractionEngine* viewport = m_webViewPrivate->viewportInteractionEngine()) return QSizeF(viewport->m_rawAttributes.layoutSize); - return QVariant(); + return QSizeF(); } diff --git a/Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp b/Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp index 03a5eacad..5f787647f 100644 --- a/Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp +++ b/Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp @@ -131,7 +131,7 @@ void LayerTreeHostProxy::destroyDirectlyCompositedImage(int64_t key) void LayerTreeHostProxy::setContentsSize(const FloatSize& contentsSize) { - m_renderer->setContentsSize(contentsSize); + dispatchUpdate(bind(&WebLayerTreeRenderer::setContentsSize, m_renderer.get(), contentsSize)); } void LayerTreeHostProxy::setVisibleContentsRect(const IntRect& rect, float scale, const FloatPoint& trajectoryVector, const WebCore::FloatPoint& accurateVisibleContentsPosition) diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp index 45c6499da..053afff29 100644 --- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp +++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp @@ -22,6 +22,9 @@ #include "config.h" #include "QtViewportInteractionEngine.h" +#include "WebPageGroup.h" +#include "WebPageProxy.h" +#include "WebPreferences.h" #include "qquickwebpage_p.h" #include "qquickwebview_p.h" #include "qwebkittest_p.h" @@ -69,10 +72,8 @@ public: // There is no need to suspend content for immediate updates // only during animations or longer gestures. - if (suspendContentFlag == DeferUpdateAndSuspendContent && !engine->m_hasSuspendedContent) { - engine->m_hasSuspendedContent = true; - emit engine->contentSuspendRequested(); - } + if (suspendContentFlag == DeferUpdateAndSuspendContent) + engine->suspendPageContent(); } ~ViewportUpdateDeferrer() @@ -80,19 +81,33 @@ public: if (--(engine->m_suspendCount)) return; - if (engine->m_hasSuspendedContent) { - engine->m_hasSuspendedContent = false; - emit engine->contentResumeRequested(); - } + engine->resumePageContent(); // Make sure that tiles all around the viewport will be requested. - emit engine->informVisibleContentChange(QPointF()); + engine->informVisibleContentChange(QPointF()); } private: QtViewportInteractionEngine* const engine; }; +void QtViewportInteractionEngine::suspendPageContent() +{ + if (m_hasSuspendedContent) + return; + + m_hasSuspendedContent = true; + m_webPageProxy->suspendActiveDOMObjectsAndAnimations(); +} + +void QtViewportInteractionEngine::resumePageContent() +{ + if (!m_hasSuspendedContent) + return; + m_hasSuspendedContent = false; + m_webPageProxy->resumeActiveDOMObjectsAndAnimations(); +} + // A floating point compare with absolute error. static inline bool fuzzyCompare(qreal a, qreal b, qreal epsilon) { @@ -132,20 +147,22 @@ inline QRectF QtViewportInteractionEngine::itemRectFromCSS(const QRectF& cssRect return itemRect; } -QtViewportInteractionEngine::QtViewportInteractionEngine(QQuickWebView* viewportItem, QQuickWebPage* pageItem) - : m_viewportItem(viewportItem) +QtViewportInteractionEngine::QtViewportInteractionEngine(WebKit::WebPageProxy* proxy, QQuickWebView* viewportItem, QQuickWebPage* pageItem) + : m_webPageProxy(proxy) + , m_viewportItem(viewportItem) , m_pageItem(pageItem) + , m_allowsUserScaling(false) + , m_minimumScale(1) + , m_maximumScale(1) + , m_devicePixelRatio(1) , m_suspendCount(0) , m_hasSuspendedContent(false) , m_hadUserInteraction(false) , m_scaleAnimation(new ScaleAnimation(this)) , m_pinchStartScale(-1) + , m_lastCommittedScale(-1) , m_zoomOutScale(0.0) { - reset(); - - connect(m_pageItem, SIGNAL(widthChanged()), SLOT(pageItemSizeChanged()), Qt::DirectConnection); - connect(m_pageItem, SIGNAL(heightChanged()), SLOT(pageItemSizeChanged()), Qt::DirectConnection); connect(m_viewportItem, SIGNAL(movementStarted()), SLOT(flickMoveStarted()), Qt::DirectConnection); connect(m_viewportItem, SIGNAL(movementEnded()), SLOT(flickMoveEnded()), Qt::DirectConnection); @@ -180,18 +197,36 @@ void QtViewportInteractionEngine::viewportAttributesChanged(const WebCore::Viewp m_rawAttributes = newAttributes; WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(m_rawAttributes); - // FIXME: Resetting here can reset more than needed. For instance it will end deferrers. - // This needs to be revised at some point. - reset(); + { + // FIXME: Resetting here is wrong, it should happen only for the first + // viewport change for a given page and first when we paint the page for + // the first time. + + m_hadUserInteraction = false; + m_zoomOutScale = 0.0; + m_scaleStack.clear(); - // FIXME: Should get directly from the webPageProxy. - setDevicePixelRatio(m_rawAttributes.devicePixelRatio); + // This part below should go fully away when the above plan is implemented. - setAllowsUserScaling(!!m_rawAttributes.userScalable); - setCSSScaleBounds(m_rawAttributes.minimumScale, m_rawAttributes.maximumScale); + m_viewportItem->cancelFlick(); + m_scaleAnimation->stop(); + + m_scaleUpdateDeferrer.clear(); + m_scrollUpdateDeferrer.clear(); + m_touchUpdateDeferrer.clear(); + m_animationUpdateDeferrer.clear(); + ASSERT(!m_suspendCount); + ASSERT(!m_hasSuspendedContent); + } + + m_devicePixelRatio = m_rawAttributes.devicePixelRatio; // Should return value from the webPageProxy. + m_allowsUserScaling = !!m_rawAttributes.userScalable; + m_minimumScale = m_rawAttributes.minimumScale; + m_maximumScale = m_rawAttributes.maximumScale; if (!m_hadUserInteraction && !m_hasSuspendedContent) { + ASSERT(m_pinchStartScale == -1); // Emits contentsScaleChanged(); setCSSScale(m_rawAttributes.initialScale); } @@ -209,7 +244,7 @@ void QtViewportInteractionEngine::pageContentsSizeChanged(const QSize& newSize, float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(m_rawAttributes, viewportSize, newSize); if (!qFuzzyCompare(minimumScale, m_rawAttributes.minimumScale)) { - setCSSScaleBounds(minimumScale, m_rawAttributes.maximumScale); + m_minimumScale = minimumScale; emit m_viewportItem->experimental()->test()->viewportChanged(); if (!m_hadUserInteraction && !m_hasSuspendedContent) { @@ -300,12 +335,12 @@ void QtViewportInteractionEngine::pageItemPositionChanged() { QPointF newPosition = m_viewportItem->contentPos(); - emit informVisibleContentChange(m_lastScrollPosition - newPosition); + informVisibleContentChange(m_lastScrollPosition - newPosition); m_lastScrollPosition = newPosition; } -void QtViewportInteractionEngine::pageContentPositionRequest(const QPoint& cssPosition) +void QtViewportInteractionEngine::pageContentPositionRequested(const QPoint& cssPosition) { // Ignore the request if suspended. Can only happen due to delay in event delivery. if (m_suspendCount) @@ -506,32 +541,6 @@ QRectF QtViewportInteractionEngine::nearestValidBounds() const return endVisibleContentRect; } -void QtViewportInteractionEngine::reset() -{ - ASSERT(!m_suspendCount); - - m_hadUserInteraction = false; - - m_allowsUserScaling = false; - m_minimumScale = 1; - m_maximumScale = 1; - m_devicePixelRatio = 1; - m_pinchStartScale = -1; - m_zoomOutScale = 0.0; - - m_viewportItem->cancelFlick(); - m_scaleAnimation->stop(); - m_scaleUpdateDeferrer.clear(); - m_scrollUpdateDeferrer.clear(); - m_scaleStack.clear(); -} - -void QtViewportInteractionEngine::setCSSScaleBounds(qreal minimum, qreal maximum) -{ - m_minimumScale = minimum; - m_maximumScale = maximum; -} - void QtViewportInteractionEngine::setCSSScale(qreal scale) { ViewportUpdateDeferrer guard(this); @@ -677,19 +686,54 @@ void QtViewportInteractionEngine::pinchGestureCancelled() m_scaleUpdateDeferrer.clear(); } -/* - * This is called for all changes of item scale, width or height. - * This is called when interacting, ie. during for instance pinch-zooming. - * - * FIXME: This is currently called twice if you concurrently change width and height. - */ -void QtViewportInteractionEngine::pageItemSizeChanged() +QRect QtViewportInteractionEngine::visibleContentsRect() const { - if (m_suspendCount) + const QRectF visibleRect(m_viewportItem->boundingRect().intersected(m_pageItem->boundingRect())); + + // We avoid using toAlignedRect() because it produces inconsistent width and height. + QRectF mappedRect(m_viewportItem->mapRectToWebContent(visibleRect)); + return QRect(floor(mappedRect.x()), floor(mappedRect.y()), floor(mappedRect.width()), floor(mappedRect.height())); +} + +void QtViewportInteractionEngine::informVisibleContentChange(const QPointF& trajectoryVector) +{ + DrawingAreaProxy* drawingArea = m_webPageProxy->drawingArea(); + if (!drawingArea) return; - ViewportUpdateDeferrer guard(this); - setPageItemRectVisible(nearestValidBounds()); + if (m_lastVisibleContentsRect == visibleContentsRect()) + return; + + qreal scale = m_pageItem->contentsScale(); + + if (scale != m_lastCommittedScale) + emit m_viewportItem->experimental()->test()->contentsScaleCommitted(); + m_lastCommittedScale = scale; + m_lastVisibleContentsRect = visibleContentsRect(); + + drawingArea->setVisibleContentsRect(visibleContentsRect(), scale, trajectoryVector, m_viewportItem->contentPos()); + + // Ensure that updatePaintNode is always called before painting. + m_pageItem->update(); +} + +void QtViewportInteractionEngine::viewportItemSizeChanged() +{ + QSize viewportSize = m_viewportItem->boundingRect().size().toSize(); + + if (viewportSize.isEmpty()) + return; + + // FIXME: This is wrong, add QML api! + WebPreferences* wkPrefs = m_webPageProxy->pageGroup()->preferences(); + wkPrefs->setDeviceWidth(viewportSize.width()); + wkPrefs->setDeviceHeight(viewportSize.height()); + + // Let the WebProcess know about the new viewport size, so that + // it can resize the content accordingly. + m_webPageProxy->setViewportSize(viewportSize); + + informVisibleContentChange(QPointF()); } void QtViewportInteractionEngine::scaleContent(const QPointF& centerInCSSCoordinates, qreal cssScale) diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h index b7595e569..b25c160c8 100644 --- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h +++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h @@ -40,34 +40,16 @@ class QWebKitTest; namespace WebKit { +class WebPageProxy; class ViewportUpdateDeferrer; class QtViewportInteractionEngine : public QObject { Q_OBJECT public: - QtViewportInteractionEngine(QQuickWebView*, QQuickWebPage*); + QtViewportInteractionEngine(WebPageProxy*, QQuickWebView*, QQuickWebPage*); ~QtViewportInteractionEngine(); - void reset(); - - bool hadUserInteraction() const { return m_hadUserInteraction; } - - void setCSSScaleBounds(qreal minimum, qreal maximum); - void setCSSScale(qreal); - - qreal currentCSSScale() const; - - void setAllowsUserScaling(bool allow) { m_allowsUserScaling = allow; } - void setDevicePixelRatio(qreal ratio) { m_devicePixelRatio = ratio; } - - void setPageItemRectVisible(const QRectF&); - void animatePageItemRectVisible(const QRectF&); - - QRectF nearestValidBounds() const; - - void pageContentPositionRequest(const QPoint& pos); - void touchBegin(); void touchEnd(); @@ -92,18 +74,15 @@ public: void zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea); void focusEditableArea(const QRectF& caretArea, const QRectF& targetArea); - void viewportAttributesChanged(const WebCore::ViewportAttributes&); - void pageContentsSizeChanged(const QSize& newSize, const QSize& viewportSize); - -Q_SIGNALS: - void contentSuspendRequested(); - void contentResumeRequested(); + void pageContentPositionRequested(const QPoint& position); + void viewportItemSizeChanged(); + void viewportAttributesChanged(const WebCore::ViewportAttributes&); void informVisibleContentChange(const QPointF& trajectory = QPointF()); + void pageContentsSizeChanged(const QSize& newSize, const QSize& viewportSize); private Q_SLOTS: - // Respond to changes of content that are not driven by us, like the page resizing itself. - void pageItemSizeChanged(); + // Respond to changes of position that are not driven by us. void pageItemPositionChanged(); void scaleAnimationStateChanged(QAbstractAnimation::State, QAbstractAnimation::State); @@ -116,6 +95,7 @@ private: friend class ViewportUpdateDeferrer; friend class ::QWebKitTest; + WebPageProxy* const m_webPageProxy; QQuickWebView* const m_viewportItem; QQuickWebPage* const m_pageItem; @@ -127,9 +107,21 @@ private: qreal innerBoundedCSSScale(qreal) const; qreal outerBoundedCSSScale(qreal) const; + void setCSSScale(qreal); + qreal currentCSSScale() const; + + void setPageItemRectVisible(const QRectF&); + void animatePageItemRectVisible(const QRectF&); + + QRect visibleContentsRect() const; + QRectF nearestValidBounds() const; + QRectF computePosRangeForPageItemAtScale(qreal itemScale) const; void scaleContent(const QPointF& centerInCSSCoordinates, qreal cssScale); + void suspendPageContent(); + void resumePageContent(); + WebCore::ViewportAttributes m_rawAttributes; bool m_allowsUserScaling; @@ -172,6 +164,8 @@ private: QPointF m_lastPinchCenterInViewportCoordinates; QPointF m_lastScrollPosition; qreal m_pinchStartScale; + qreal m_lastCommittedScale; + QRectF m_lastVisibleContentsRect; qreal m_zoomOutScale; QList<ScaleStackItem> m_scaleStack; }; diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp index 2b91038d9..4d82cff01 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp @@ -71,6 +71,7 @@ NetscapePlugin::NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule) , m_isTransparent(false) , m_inNPPNew(false) , m_shouldUseManualLoader(false) + , m_hasCalledSetWindow(false) , m_nextTimerID(0) #if PLATFORM(MAC) , m_drawingModel(static_cast<NPDrawingModel>(-1)) @@ -506,6 +507,7 @@ void NetscapePlugin::callSetWindow() m_npWindow.clipRect.bottom = m_npWindow.clipRect.top + m_clipRect.height(); NPP_SetWindow(&m_npWindow); + m_hasCalledSetWindow = true; } bool NetscapePlugin::shouldLoadSrcURL() @@ -692,11 +694,11 @@ void NetscapePlugin::geometryDidChange(const IntSize& pluginSize, const IntRect& return; } - bool shouldCallWindow = true; + bool shouldCallSetWindow = true; // If the plug-in doesn't want window relative coordinates, we don't need to call setWindow unless its size or clip rect changes. - if (wantsPluginRelativeNPWindowCoordinates() && m_pluginSize == pluginSize && m_clipRect == clipRect) - shouldCallWindow = false; + if (m_hasCalledSetWindow && wantsPluginRelativeNPWindowCoordinates() && m_pluginSize == pluginSize && m_clipRect == clipRect) + shouldCallSetWindow = false; m_pluginSize = pluginSize; m_clipRect = clipRect; @@ -707,7 +709,7 @@ void NetscapePlugin::geometryDidChange(const IntSize& pluginSize, const IntRect& platformGeometryDidChange(); - if (!shouldCallWindow) + if (!shouldCallSetWindow) return; callSetWindow(); diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h index 9194984b3..1c49c6032 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h @@ -272,6 +272,8 @@ private: bool m_isTransparent; bool m_inNPPNew; bool m_shouldUseManualLoader; + bool m_hasCalledSetWindow; + RefPtr<NetscapePluginStream> m_manualStream; Vector<bool, 8> m_popupEnabledStates; diff --git a/Source/api.pri b/Source/api.pri index ddc73578d..3b05ed184 100644 --- a/Source/api.pri +++ b/Source/api.pri @@ -42,10 +42,6 @@ haveQt(5) { # have to make sure the rpath/install_name of the libraries are relative # to the webkit build dir. - # We use private_tests to detect developer build, since the destdir will - # always be our webkit build dir. This might change as configure changes. - contains(QT_CONFIG, private_tests): CONFIG += qt_developer_build - !build_pass { # Make a more accessible copy of the module forward file # in the WebKit build directory. diff --git a/Source/cmake/OptionsEfl.cmake b/Source/cmake/OptionsEfl.cmake index 1a7514473..30f22b260 100644 --- a/Source/cmake/OptionsEfl.cmake +++ b/Source/cmake/OptionsEfl.cmake @@ -86,6 +86,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIBRATION ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIDEO ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIDEO_TRACK ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_INTENTS ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_INTENTS_TAG ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_TIMING ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WORKERS ON) diff --git a/Source/cmake/WebKitFeatures.cmake b/Source/cmake/WebKitFeatures.cmake index 2b9a7787e..34f9261a0 100644 --- a/Source/cmake/WebKitFeatures.cmake +++ b/Source/cmake/WebKitFeatures.cmake @@ -93,6 +93,7 @@ MACRO (WEBKIT_OPTION_BEGIN) WEBKIT_OPTION_DEFINE(ENABLE_WEBGL "Toggle 3D canvas (WebGL) support" OFF) WEBKIT_OPTION_DEFINE(ENABLE_WEB_AUDIO "Toggle Web Audio support" OFF) WEBKIT_OPTION_DEFINE(ENABLE_WEB_INTENTS "Toggle Web Intents support" OFF) + WEBKIT_OPTION_DEFINE(ENABLE_WEB_INTENTS_TAG "Toogle HTMLIntentElement tag support" OFF) WEBKIT_OPTION_DEFINE(ENABLE_WEB_SOCKETS "Toggle Web Sockets support" ON) WEBKIT_OPTION_DEFINE(ENABLE_WEB_TIMING "Toggle Web Timing support" OFF) WEBKIT_OPTION_DEFINE(ENABLE_WORKERS "Toggle Web Workers support" OFF) diff --git a/Source/cmakeconfig.h.cmake b/Source/cmakeconfig.h.cmake index 59b682d0a..0d41c790d 100644 --- a/Source/cmakeconfig.h.cmake +++ b/Source/cmakeconfig.h.cmake @@ -75,6 +75,7 @@ #cmakedefine01 ENABLE_WEBGL #cmakedefine01 ENABLE_WEB_AUDIO #cmakedefine01 ENABLE_WEB_INTENTS +#cmakedefine01 ENABLE_WEB_INTENTS_TAG #cmakedefine01 ENABLE_WEB_SOCKETS #cmakedefine01 ENABLE_WEB_TIMING #cmakedefine01 ENABLE_WORKERS diff --git a/Source/tests.pri b/Source/tests.pri index 3c15f29f3..5d2eb6b97 100644 --- a/Source/tests.pri +++ b/Source/tests.pri @@ -12,6 +12,7 @@ load(features) WEBKIT_TESTS_DIR = $$PWD/WebKit/qt/tests SUBDIRS += \ + $$WEBKIT_TESTS_DIR/qobjectbridge \ $$WEBKIT_TESTS_DIR/qwebframe \ $$WEBKIT_TESTS_DIR/qwebpage \ $$WEBKIT_TESTS_DIR/qwebelement \ |
