diff options
author | Johanna Aijala <johanna.aijala@digia.com> | 2013-02-21 09:34:08 +0200 |
---|---|---|
committer | Johanna Aijala <johanna.aijala@digia.com> | 2013-02-21 09:34:53 +0200 |
commit | e6c484102e2e447f9171d9eb6799a0470910fd99 (patch) | |
tree | 7fbeb840709b78863b4ed3b4f0a66f479984caa0 | |
parent | 30400131a4c18e9a0e0895d517c620b599aaddee (diff) | |
parent | 08322b49d440e36a8c1a8b2f250a641ea1886ae3 (diff) | |
download | qtwebkit-e6c484102e2e447f9171d9eb6799a0470910fd99.tar.gz |
Merge branch 'stable' into release
Change-Id: I5f9488665e344d270d876075e4a78d472e12a66f
95 files changed, 1942 insertions, 494 deletions
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index 4e661d971..18927d19e 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -1,3 +1,88 @@ +2012-12-18 Mark Hahnenberg <mhahnenberg@apple.com> + + Restrictions on oversize CopiedBlock allocations should be relaxed + https://bugs.webkit.org/show_bug.cgi?id=105339 + + Reviewed by Filip Pizlo. + + Currently the DFG has a single branch in the inline allocation path for property/array storage where + it checks to see if the number of bytes requested will fit in the current block. This does not match + what the C++ allocation path does; it checks if the requested number of bytes is oversize, and then + if it's not, it tries to fit it in the current block. The garbage collector assumes that ALL allocations + that are greater than 16KB are in oversize blocks. Therefore, this mismatch can lead to crashes when + the collector tries to perform some operation on a CopiedBlock. + + To avoid adding an extra branch to the inline allocation path in the JIT, we should make it so that + oversize blocks are allocated on the same alignment boundaries so that there is a single mask to find + the block header of any CopiedBlock (rather than two, one for normal and one for oversize blocks), and + we should figure out if a block is oversize by some other method than just whatever the JSObject says + it is. One way we could record this info Region of the block, since we allocate a one-off Region for + oversize blocks. + + * heap/BlockAllocator.h: + (JSC::Region::isCustomSize): + (Region): + (JSC::Region::createCustomSize): + (JSC::Region::Region): + (JSC::BlockAllocator::deallocateCustomSize): + * heap/CopiedBlock.h: + (CopiedBlock): + (JSC::CopiedBlock::isOversize): + (JSC): + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::tryAllocateOversize): + (JSC::CopiedSpace::tryReallocate): + (JSC::CopiedSpace::tryReallocateOversize): + * heap/CopiedSpace.h: + (CopiedSpace): + * heap/CopiedSpaceInlines.h: + (JSC::CopiedSpace::contains): + (JSC::CopiedSpace::tryAllocate): + (JSC): + * heap/CopyVisitor.h: + (CopyVisitor): + * heap/CopyVisitorInlines.h: + (JSC::CopyVisitor::checkIfShouldCopy): + (JSC::CopyVisitor::didCopy): + * heap/SlotVisitorInlines.h: + (JSC::SlotVisitor::copyLater): + * runtime/JSObject.cpp: + (JSC::JSObject::copyButterfly): + +2012-12-17 Mark Hahnenberg <mhahnenberg@apple.com> + + Butterfly::growArrayRight shouldn't be called on null Butterfly objects + https://bugs.webkit.org/show_bug.cgi?id=105221 + + Reviewed by Filip Pizlo. + + Currently we depend upon the fact that Butterfly::growArrayRight works with null Butterfly + objects purely by coincidence. We should add a new static function that null checks the old + Butterfly object and creates a new one if it's null, or calls growArrayRight if it isn't for + use in the couple of places in JSObject that expect such behavior to work. + + * runtime/Butterfly.h: + (Butterfly): + * runtime/ButterflyInlines.h: + (JSC::Butterfly::createOrGrowArrayRight): + (JSC): + * runtime/JSObject.cpp: + (JSC::JSObject::createInitialIndexedStorage): + (JSC::JSObject::createArrayStorage): + +2013-01-02 Simon Hausmann <simon.hausmann@digia.com> + + [MinGW-w64] Centralize workaround for pow() implementation + https://bugs.webkit.org/show_bug.cgi?id=105925 + + Reviewed by Sam Weinig. + + As suggested by Sam, move the MinGW-w64 workaround into MathExtras.h + away from the JSC usage. + + * runtime/MathObject.cpp: + (JSC::mathPow): + 2012-12-17 Jonathan Liu <net147@gmail.com> Fix Math.pow implementation with MinGW-w64 diff --git a/Source/JavaScriptCore/heap/BlockAllocator.h b/Source/JavaScriptCore/heap/BlockAllocator.h index 417f81da0..90210c1fa 100644 --- a/Source/JavaScriptCore/heap/BlockAllocator.h +++ b/Source/JavaScriptCore/heap/BlockAllocator.h @@ -68,6 +68,7 @@ public: size_t blockSize() const { return m_blockSize; } bool isFull() const { return m_blocksInUse == m_totalBlocks; } bool isEmpty() const { return !m_blocksInUse; } + bool isCustomSize() const { return m_isCustomSize; } DeadBlock* allocate(); void deallocate(void*); @@ -81,6 +82,7 @@ private: size_t m_totalBlocks; size_t m_blocksInUse; size_t m_blockSize; + bool m_isCustomSize; Region* m_prev; Region* m_next; DoublyLinkedList<DeadBlock> m_deadBlocks; @@ -101,7 +103,9 @@ inline Region* Region::createCustomSize(size_t blockSize, size_t blockAlignment) PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockAlignment, OSAllocator::JSGCHeapPages); if (!static_cast<bool>(allocation)) CRASH(); - return new Region(allocation, blockSize, 1); + Region* region = new Region(allocation, blockSize, 1); + region->m_isCustomSize = true; + return region; } inline Region::Region(PageAllocationAligned& allocation, size_t blockSize, size_t totalBlocks) @@ -110,6 +114,7 @@ inline Region::Region(PageAllocationAligned& allocation, size_t blockSize, size_ , m_totalBlocks(totalBlocks) , m_blocksInUse(0) , m_blockSize(blockSize) + , m_isCustomSize(false) , m_prev(0) , m_next(0) { @@ -300,6 +305,7 @@ template<typename T> inline void BlockAllocator::deallocateCustomSize(T* block) { Region* region = block->region(); + ASSERT(region->isCustomSize()); region->deallocate(block); delete region; } diff --git a/Source/JavaScriptCore/heap/CopiedBlock.h b/Source/JavaScriptCore/heap/CopiedBlock.h index 7f585585c..cc60a0103 100644 --- a/Source/JavaScriptCore/heap/CopiedBlock.h +++ b/Source/JavaScriptCore/heap/CopiedBlock.h @@ -50,6 +50,8 @@ public: void pin(); bool isPinned(); + bool isOversize(); + unsigned liveBytes(); void reportLiveBytes(JSCell*, unsigned); void didSurviveGC(); @@ -168,6 +170,11 @@ inline bool CopiedBlock::isPinned() return m_isPinned; } +inline bool CopiedBlock::isOversize() +{ + return region()->isCustomSize(); +} + inline unsigned CopiedBlock::liveBytes() { return m_liveBytes; diff --git a/Source/JavaScriptCore/heap/CopiedSpace.cpp b/Source/JavaScriptCore/heap/CopiedSpace.cpp index e4141c1d7..b235de1dd 100644 --- a/Source/JavaScriptCore/heap/CopiedSpace.cpp +++ b/Source/JavaScriptCore/heap/CopiedSpace.cpp @@ -81,7 +81,7 @@ CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr) { ASSERT(isOversize(bytes)); - CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocateCustomSize(sizeof(CopiedBlock) + bytes, WTF::pageSize())); + CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocateCustomSize(sizeof(CopiedBlock) + bytes, CopiedBlock::blockSize)); m_oversizeBlocks.push(block); m_blockFilter.add(reinterpret_cast<Bits>(block)); m_blockSet.add(block); @@ -104,7 +104,7 @@ CheckedBoolean CopiedSpace::tryReallocate(void** ptr, size_t oldSize, size_t new void* oldPtr = *ptr; ASSERT(!m_heap->globalData()->isInitializingObject()); - if (isOversize(oldSize) || isOversize(newSize)) + if (CopiedSpace::blockFor(oldPtr)->isOversize() || isOversize(newSize)) return tryReallocateOversize(ptr, oldSize, newSize); if (m_allocator.tryReallocate(oldPtr, oldSize, newSize)) @@ -135,8 +135,8 @@ CheckedBoolean CopiedSpace::tryReallocateOversize(void** ptr, size_t oldSize, si memcpy(newPtr, oldPtr, oldSize); - if (isOversize(oldSize)) { - CopiedBlock* oldBlock = oversizeBlockFor(oldPtr); + CopiedBlock* oldBlock = CopiedSpace::blockFor(oldPtr); + if (oldBlock->isOversize()) { m_oversizeBlocks.remove(oldBlock); m_blockSet.remove(oldBlock); m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(oldBlock)); diff --git a/Source/JavaScriptCore/heap/CopiedSpace.h b/Source/JavaScriptCore/heap/CopiedSpace.h index e3727100e..65ca04ef6 100644 --- a/Source/JavaScriptCore/heap/CopiedSpace.h +++ b/Source/JavaScriptCore/heap/CopiedSpace.h @@ -82,7 +82,6 @@ public: private: static bool isOversize(size_t); - static CopiedBlock* oversizeBlockFor(void* ptr); JS_EXPORT_PRIVATE CheckedBoolean tryAllocateSlowCase(size_t, void**); CheckedBoolean tryAllocateOversize(size_t, void**); diff --git a/Source/JavaScriptCore/heap/CopiedSpaceInlines.h b/Source/JavaScriptCore/heap/CopiedSpaceInlines.h index 41f94dd74..6087cf4c2 100644 --- a/Source/JavaScriptCore/heap/CopiedSpaceInlines.h +++ b/Source/JavaScriptCore/heap/CopiedSpaceInlines.h @@ -47,9 +47,8 @@ inline bool CopiedSpace::contains(void* ptr, CopiedBlock*& result) result = block; return true; } - block = oversizeBlockFor(ptr); - result = block; - return contains(block); + result = 0; + return false; } inline void CopiedSpace::pin(CopiedBlock* block) @@ -153,7 +152,7 @@ inline CheckedBoolean CopiedSpace::tryAllocate(size_t bytes, void** outPtr) { ASSERT(!m_heap->globalData()->isInitializingObject()); - if (isOversize(bytes) || !m_allocator.tryAllocate(bytes, outPtr)) + if (!m_allocator.tryAllocate(bytes, outPtr)) return tryAllocateSlowCase(bytes, outPtr); ASSERT(*outPtr); @@ -170,11 +169,6 @@ inline bool CopiedSpace::isPinned(void* ptr) return blockFor(ptr)->m_isPinned; } -inline CopiedBlock* CopiedSpace::oversizeBlockFor(void* ptr) -{ - return reinterpret_cast<CopiedBlock*>(reinterpret_cast<size_t>(ptr) & WTF::pageMask()); -} - inline CopiedBlock* CopiedSpace::blockFor(void* ptr) { return reinterpret_cast<CopiedBlock*>(reinterpret_cast<size_t>(ptr) & s_blockMask); diff --git a/Source/JavaScriptCore/heap/CopyVisitor.h b/Source/JavaScriptCore/heap/CopyVisitor.h index c5f7272a9..da92ba5b5 100644 --- a/Source/JavaScriptCore/heap/CopyVisitor.h +++ b/Source/JavaScriptCore/heap/CopyVisitor.h @@ -45,7 +45,7 @@ public: // Low-level API for copying, appropriate for cases where the object's heap references // are discontiguous or if the object occurs frequently enough that you need to focus on // performance. Use this with care as it is easy to shoot yourself in the foot. - bool checkIfShouldCopy(void*, size_t); + bool checkIfShouldCopy(void*); void* allocateNewSpace(size_t); void didCopy(void*, size_t); diff --git a/Source/JavaScriptCore/heap/CopyVisitorInlines.h b/Source/JavaScriptCore/heap/CopyVisitorInlines.h index 1557af93d..4e087b8db 100644 --- a/Source/JavaScriptCore/heap/CopyVisitorInlines.h +++ b/Source/JavaScriptCore/heap/CopyVisitorInlines.h @@ -40,14 +40,11 @@ inline void CopyVisitor::visitCell(JSCell* cell) JSObject::copyBackingStore(cell, *this); } -inline bool CopyVisitor::checkIfShouldCopy(void* oldPtr, size_t bytes) +inline bool CopyVisitor::checkIfShouldCopy(void* oldPtr) { - if (CopiedSpace::isOversize(bytes)) + CopiedBlock* block = CopiedSpace::blockFor(oldPtr); + if (block->isOversize() || block->isPinned()) return false; - - if (CopiedSpace::blockFor(oldPtr)->isPinned()) - return false; - return true; } @@ -92,8 +89,8 @@ inline void CopyVisitor::doneCopying() inline void CopyVisitor::didCopy(void* ptr, size_t bytes) { - ASSERT(!CopiedSpace::isOversize(bytes)); CopiedBlock* block = CopiedSpace::blockFor(ptr); + ASSERT(!block->isOversize()); ASSERT(!block->isPinned()); block->didEvacuateBytes(bytes); diff --git a/Source/JavaScriptCore/heap/SlotVisitorInlines.h b/Source/JavaScriptCore/heap/SlotVisitorInlines.h index d76ac552a..3a7f2290c 100644 --- a/Source/JavaScriptCore/heap/SlotVisitorInlines.h +++ b/Source/JavaScriptCore/heap/SlotVisitorInlines.h @@ -163,12 +163,12 @@ inline void SlotVisitor::donateAndDrain() inline void SlotVisitor::copyLater(JSCell* owner, void* ptr, size_t bytes) { - if (CopiedSpace::isOversize(bytes)) { - m_shared.m_copiedSpace->pin(CopiedSpace::oversizeBlockFor(ptr)); + CopiedBlock* block = CopiedSpace::blockFor(ptr); + if (block->isOversize()) { + m_shared.m_copiedSpace->pin(block); return; } - CopiedBlock* block = CopiedSpace::blockFor(ptr); if (block->isPinned()) return; diff --git a/Source/JavaScriptCore/runtime/Butterfly.h b/Source/JavaScriptCore/runtime/Butterfly.h index 4b8d53f7e..bbbda9461 100644 --- a/Source/JavaScriptCore/runtime/Butterfly.h +++ b/Source/JavaScriptCore/runtime/Butterfly.h @@ -110,7 +110,9 @@ public: void* base(size_t preCapacity, size_t propertyCapacity) { return propertyStorage() - propertyCapacity - preCapacity; } void* base(Structure*); - + + static Butterfly* createOrGrowArrayRight(Butterfly*, JSGlobalData&, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes); + // The butterfly reallocation methods perform the reallocation itself but do not change any // of the meta-data to reflect that the reallocation occurred. Note that this set of // methods is not exhaustive and is not intended to encapsulate all possible allocation diff --git a/Source/JavaScriptCore/runtime/ButterflyInlines.h b/Source/JavaScriptCore/runtime/ButterflyInlines.h index 9167497a4..f01458950 100644 --- a/Source/JavaScriptCore/runtime/ButterflyInlines.h +++ b/Source/JavaScriptCore/runtime/ButterflyInlines.h @@ -99,6 +99,13 @@ inline Butterfly* Butterfly::growPropertyStorage(JSGlobalData& globalData, Struc globalData, oldStructure, oldStructure->outOfLineCapacity(), newPropertyCapacity); } +inline Butterfly* Butterfly::createOrGrowArrayRight(Butterfly* oldButterfly, JSGlobalData& globalData, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes) +{ + if (!oldButterfly) + return create(globalData, 0, propertyCapacity, true, IndexingHeader(), newIndexingPayloadSizeInBytes); + return oldButterfly->growArrayRight(globalData, oldStructure, propertyCapacity, hadIndexingHeader, oldIndexingPayloadSizeInBytes, newIndexingPayloadSizeInBytes); +} + inline Butterfly* Butterfly::growArrayRight(JSGlobalData& globalData, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes) { ASSERT_UNUSED(oldStructure, !indexingHeader()->preCapacity(oldStructure)); diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp index dc73e04b0..32adefd2f 100644 --- a/Source/JavaScriptCore/runtime/JSObject.cpp +++ b/Source/JavaScriptCore/runtime/JSObject.cpp @@ -110,7 +110,7 @@ ALWAYS_INLINE void JSObject::copyButterfly(CopyVisitor& visitor, Butterfly* butt indexingPayloadSizeInBytes = 0; } size_t capacityInBytes = Butterfly::totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); - if (visitor.checkIfShouldCopy(butterfly->base(preCapacity, propertyCapacity), capacityInBytes)) { + if (visitor.checkIfShouldCopy(butterfly->base(preCapacity, propertyCapacity))) { Butterfly* newButterfly = Butterfly::createUninitializedDuringCollection(visitor, preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); // Copy the properties. @@ -610,7 +610,7 @@ Butterfly* JSObject::createInitialIndexedStorage(JSGlobalData& globalData, unsig ASSERT(!structure()->needsSlowPutIndexing()); ASSERT(!indexingShouldBeSparse()); unsigned vectorLength = std::max(length, BASE_VECTOR_LEN); - Butterfly* newButterfly = m_butterfly->growArrayRight( + Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(m_butterfly, globalData, structure(), structure()->outOfLineCapacity(), false, 0, elementSize * vectorLength); newButterfly->setPublicLength(length); @@ -656,7 +656,7 @@ ArrayStorage* JSObject::createArrayStorage(JSGlobalData& globalData, unsigned le { IndexingType oldType = structure()->indexingType(); ASSERT_UNUSED(oldType, !hasIndexedProperties(oldType)); - Butterfly* newButterfly = m_butterfly->growArrayRight( + Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(m_butterfly, globalData, structure(), structure()->outOfLineCapacity(), false, 0, ArrayStorage::sizeFor(vectorLength)); if (!newButterfly) diff --git a/Source/JavaScriptCore/runtime/MathObject.cpp b/Source/JavaScriptCore/runtime/MathObject.cpp index f939b8dd4..7634487ad 100644 --- a/Source/JavaScriptCore/runtime/MathObject.cpp +++ b/Source/JavaScriptCore/runtime/MathObject.cpp @@ -232,22 +232,6 @@ static ALWAYS_INLINE double mathPow(double x, double y) ALWAYS_INLINE double mathPow(double x, double y) { -#if COMPILER(MINGW64) - // MinGW-w64 has a custom implementation for pow. - // This handles certain special cases that are different. - if ((x == 0.0 || isinf(x)) && isfinite(y)) { - double f; - if (modf(y, &f) != 0.0) - return ((x == 0.0) ^ (y > 0.0)) ? std::numeric_limits<double>::infinity() : 0.0; - } - - if (x == 2.0) { - int yInt = static_cast<int>(y); - if (y == yInt) - return ldexp(1.0, yInt); - } -#endif - return pow(x, y); } diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog index 296d4d54f..098c8de6c 100644 --- a/Source/WTF/ChangeLog +++ b/Source/WTF/ChangeLog @@ -1,3 +1,42 @@ +2013-01-05 Jonathan Liu <net147@gmail.com> + + Only enable MinGW-w64 pow() workaround if needed + https://bugs.webkit.org/show_bug.cgi?id=106099 + + Reviewed by Filip Pizlo. + + The pow() workaround is no longer needed in the latest version + of MinGW-w64. + + * wtf/MathExtras.h: + +2013-01-05 Jonathan Liu <net147@gmail.com> + + Fix compilation of MathExtras.h with MinGW-w64 + https://bugs.webkit.org/show_bug.cgi?id=106105 + + Reviewed by Simon Hausmann. + + The isfinite and isinf functions are required by wtf_pow but + not defined until after wtf_pow. Move wtf_pow to after + "using std::isfinite" and "using std::isinf" to fix compilation. + + * wtf/MathExtras.h: + (wtf_pow): + +2013-01-02 Simon Hausmann <simon.hausmann@digia.com> + + [MinGW-w64] Centralize workaround for pow() implementation + https://bugs.webkit.org/show_bug.cgi?id=105925 + + Reviewed by Sam Weinig. + + As suggested by Sam, move the MinGW-w64 workaround into MathExtras.h + away from the JSC usage. + + * wtf/MathExtras.h: + (wtf_pow): + 2012-11-30 Simon Hausmann <simon.hausmann@digia.com>, Pierre Rossi <pierre.rossi@digia.com> [Qt] Separate Qt WebKit into Qt WebKit and Qt WebKit Widgets diff --git a/Source/WTF/wtf/MathExtras.h b/Source/WTF/wtf/MathExtras.h index df1b23658..3b5025d35 100644 --- a/Source/WTF/wtf/MathExtras.h +++ b/Source/WTF/wtf/MathExtras.h @@ -347,6 +347,28 @@ using std::wtf_isnan; #endif #endif +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) +inline double wtf_pow(double x, double y) +{ + // MinGW-w64 has a custom implementation for pow. + // This handles certain special cases that are different. + if ((x == 0.0 || isinf(x)) && isfinite(y)) { + double f; + if (modf(y, &f) != 0.0) + return ((x == 0.0) ^ (y > 0.0)) ? std::numeric_limits<double>::infinity() : 0.0; + } + + if (x == 2.0) { + int yInt = static_cast<int>(y); + if (y == yInt) + return ldexp(1.0, yInt); + } + + return pow(x, y); +} +#define pow(x, y) wtf_pow(x, y) +#endif // COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + // decompose 'number' to its sign, exponent, and mantissa components. // The result is interpreted as: diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index ac0c2f769..8ee46f4b5 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,405 @@ +2013-02-19 Andras Becsi <andras.becsi@digia.com> + + [Qt] Fix compilation if Qt was configured with -no-rtti + https://bugs.webkit.org/show_bug.cgi?id=110234 + + Reviewed by Noam Rosenthal. + + Availability of dynamic_cast should be checked. + + * platform/graphics/texmap/GraphicsLayerTextureMapper.cpp: + (WebCore::GraphicsLayerTextureMapper::updateBackingStoreIfNeeded): + +2013-01-31 Allan Sandfeld Jensen <allan.jensen@digia.com> + + [Qt] Box shadows on a transparency layer is very slow + https://bugs.webkit.org/show_bug.cgi?id=107547 + + Reviewed by Noam Rosenthal. + + Include the window boundaries in the clip returned by GraphicsContext, + since QPainter may remember clips larger than the destination, but + ShadowBlur uses the clipBounds to determine the size of the shadow layer. + + * platform/graphics/qt/GraphicsContextQt.cpp: + (WebCore::GraphicsContext::clipBounds): + +2013-01-29 Allan Sandfeld Jensen <allan.jensen@digia.com> + + REGRESSION: ChildrenAffectedBy flags lost between siblings which have child elements sharing style + https://bugs.webkit.org/show_bug.cgi?id=105672 + + Reviewed by Andreas Kling. + + Change in how childrenAffectedBy bits were stored made it easier to trigger an issue where childrenAffectedBy bits + were not set due to sharing of styles between cousin elements. + + This patch fixes the issue by not sharing styles from children with parents who prevent sharing. + + Tests: fast/selectors/cousin-stylesharing-adjacent-selector.html + fast/selectors/cousin-stylesharing-last-child-selector.html + + * css/StyleResolver.cpp: + (WebCore::parentElementPreventsSharing): + (WebCore::StyleResolver::locateCousinList): + * dom/Element.cpp: + (WebCore::Element::hasFlagsSetDuringStylingOfChildren): + * dom/Element.h: + (Element): + +2013-01-25 Alexander Paschenko <alexander.pashenko@lge.com> + + [TexMap] Flickering after transitions on Apple HTML5 demo + https://bugs.webkit.org/show_bug.cgi?id=102501 + + Reviewed by Noam Rosenthal. + + The problem is caused by inconsistent state of TextureMapperLayer's transformation matrix + and opacity data during and after the end of animation. + This patch solves the problem by introducing three additional private flags + to TextureMapperLayer: + m_shouldUpdateCurrentTransformFromGraphicsLayer, + m_shouldUpdateCurrentOpacityFromGraphicsLayer, and + m_shouldUpdateCurrentFiltersFromGraphicsLayer. + The latter has been introduced in order to avoid similar future problems + with m_currentFilters. + On these flags' basis, TextureMapperLayer is able to decide whether to update + its inner state or not. + These flags themselves are set based on GraphicsLayerTextureMapper's changeMask + which indicates what details of the state have been changed since the last sync. + + No new tests - this doesn't expose any testable surface. + Eyes-only check has been made to ensure that the problem is gone now. + + * platform/graphics/texmap/TextureMapperLayer.cpp: + (WebCore::TextureMapperLayer::setAnimatedTransform): + sets m_shouldUpdateCurrentTransformFromGraphicsLayer to false and + updates m_currentTransform based on the updated state from GraphicsLayerAnimation. + (WebCore): + (WebCore::TextureMapperLayer::setAnimatedOpacity): + sets m_shouldUpdateCurrentOpacityFromGraphicsLayer to false and + updates m_currentOpacity based on the updated state from GraphicsLayerAnimation. + (WebCore::TextureMapperLayer::setAnimatedFilters): + sets m_shouldUpdateCurrentFiltersFromGraphicsLayer to false and + updates m_currentFilters based on the updated state from GraphicsLayerAnimation. + (WebCore::TextureMapperLayer::flushCompositingStateForThisLayerOnly): + sets m_shouldUpdateCurrent* flags based on GLTM's changeMask. Also illegal modification + of m_currentTransform that caused flickering has been removed from this method. + (WebCore::TextureMapperLayer::syncAnimations): updates m_currentTransform and/or + m_currentOpacity and/or m_currentFilters if corresponding flags allow to do so. + * platform/graphics/texmap/TextureMapperLayer.h: + (WebCore::TextureMapperLayer::TextureMapperLayer): aforementioned flags + get initialized in ctor. + (TextureMapperLayer): aforementioned flags are declared in the class. + +2013-01-04 John Mellor <johnme@chromium.org> + + Early out from FontCache::releaseFontData if cached font data not found. + https://bugs.webkit.org/show_bug.cgi?id=106104 + + Reviewed by Abhishek Arya. + + No tests, as no change in behavior. + + * platform/graphics/FontCache.cpp: + (WebCore::FontCache::releaseFontData): + Early out in release builds if cached font data not found. + +2013-01-02 Abhishek Arya <inferno@chromium.org> + + Crash in WebCore::Element::cloneElementWithoutChildren. + https://bugs.webkit.org/show_bug.cgi?id=105949 + + Reviewed by Ryosuke Niwa. + + RefPtr |ancestors| vector since its elements can be destroyed from mutation events + fired in CompositeEditCommand::appendNode. + + No new tests. The testcase relies on recursive DOM mutations and does not minimize. + + * editing/InsertParagraphSeparatorCommand.cpp: + (WebCore::InsertParagraphSeparatorCommand::getAncestorsInsideBlock): + (WebCore::InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock): + (WebCore::InsertParagraphSeparatorCommand::doApply): + * editing/InsertParagraphSeparatorCommand.h: + (InsertParagraphSeparatorCommand): + +2013-01-04 Abhishek Arya <inferno@chromium.org> + + Heap-use-after-free in WebCore::XMLDocumentParser::doEnd + https://bugs.webkit.org/show_bug.cgi?id=100152 + + Reviewed by Adam Barth. + + XMLDocumentParser can be blown away inside document()->styleResolverChanged() + call. Protect it with a local RefPtr in Document::explitClose. + + No new tests. The site specific dependencies are hard to minimize. + + * dom/Document.cpp: + (WebCore::Document::explicitClose): RefPtr m_parser into a local, since + it can be detached and nulled out in DocumentWriter::end(). + * xml/parser/XMLDocumentParser.cpp: + (WebCore::XMLDocumentParser::end): Bail out when we are detached. + * xml/parser/XMLDocumentParserLibxml2.cpp: + (WebCore::XMLDocumentParser::doEnd): Bail out when we are detached. + * xml/parser/XMLDocumentParserQt.cpp: + (WebCore::XMLDocumentParser::doEnd): Bail out when we are detached. + +2013-01-06 Abhishek Arya <inferno@chromium.org> + + Heap-use-after-free in DocumentLoader::stopLoading + https://bugs.webkit.org/show_bug.cgi?id=103656 + + Reviewed by Eric Seidel. + + Test: fast/dom/ready-state-change-crash.html + + * html/parser/HTMLDocumentParser.cpp: + (WebCore::HTMLDocumentParser::prepareToStopParsing): Bail out + if the parser is detached due to mutation event. + * loader/DocumentLoader.cpp: + (WebCore::DocumentLoader::stopLoading): Move the protectors for + frame and document loader to the start of the function. Call to + m_frame->loader()->stopLoading() can change document ready state + and fire mutation event which might blow the document loader from + underneath. + +2013-01-15 Allan Sandfeld Jensen <allan.jensen@digia.com> + + [Qt][CSS Shaders] Make custom filter render in Wk1 mode + https://bugs.webkit.org/show_bug.cgi?id=101532 + + Reviewed by Noam Rosenthal. + + Handle ValidatedCustomFilterOperations which are used by WebKit1. To keep the cache of compiled programs working, + the cache has been updated to use CustomFilterProgramInfo as a hash key. CustomFilterProgramInfo is an existing + class specifically designed for this purpose. + + * platform/graphics/texmap/TextureMapperGL.cpp: + (WebCore::getPassesRequiredForFilter): + (WebCore::TextureMapperGL::removeCachedCustomFilterProgram): + (WebCore::TextureMapperGL::drawUsingCustomFilter): + (WebCore::BitmapTextureGL::applyFilters): + * platform/graphics/texmap/TextureMapperGL.h: + (TextureMapperGL): + +2013-01-07 Justin Novosad <junov@google.com> + + Fixing memory read after free in CanvasRenderingContext2D::accessFont + https://bugs.webkit.org/show_bug.cgi?id=106244 + + Reviewed by Abhishek Arya. + + Using a temporary String object to hold ref count on string that is + passed by reference in CanvasRenderingContext2D::accessFont. + + Test: fast/canvas/canvas-measureText.html + + * html/canvas/CanvasRenderingContext2D.cpp: + (WebCore::CanvasRenderingContext2D::accessFont): + +2013-01-17 Poul Sysolyatin <psytonx@gmail.com> + + 32-bit build for Qt5 on Mac OS fails. + https://bugs.webkit.org/show_bug.cgi?id=107094 + + We need to define NS_BUILD_32_LIKE_64 for 32-bit build for Mac OS. + Fixed 32-bit build detection for support Qt5. + + Reviewed by Benjamin Poulain. + + * Target.pri: + +2013-01-16 Jocelyn Turcotte <jocelyn.turcotte@digia.com> + + [Qt] Use the shared HistoryItem serialization for QWebHistory + https://bugs.webkit.org/show_bug.cgi?id=106671 + + Reviewed by Allan Sandfeld Jensen. + + This allows a few things missing from the previous serialization code + to function while using commonly maintained code: + - The itemSequenceNumber and documentSequenceNumber that were needed + to properly restore same-document navigations + - The form data + - The navigation hierarchy mapping the frame tree + + * history/HistoryItem.h: + (HistoryItem): + * history/qt/HistoryItemQt.cpp: + (QDataStreamCoder): + (WebCore): + (WebCore::QDataStreamCoder::QDataStreamCoder): + (WebCore::QDataStreamCoder::encodeBytes): + (WebCore::QDataStreamCoder::encodeBool): + (WebCore::QDataStreamCoder::encodeUInt32): + (WebCore::QDataStreamCoder::encodeUInt64): + (WebCore::QDataStreamCoder::encodeInt32): + (WebCore::QDataStreamCoder::encodeInt64): + (WebCore::QDataStreamCoder::encodeFloat): + (WebCore::QDataStreamCoder::encodeDouble): + (WebCore::QDataStreamCoder::encodeString): + (WebCore::QDataStreamCoder::decodeBytes): + (WebCore::QDataStreamCoder::decodeBool): + (WebCore::QDataStreamCoder::decodeUInt32): + (WebCore::QDataStreamCoder::decodeUInt64): + (WebCore::QDataStreamCoder::decodeInt32): + (WebCore::QDataStreamCoder::decodeInt64): + (WebCore::QDataStreamCoder::decodeFloat): + (WebCore::QDataStreamCoder::decodeDouble): + (WebCore::QDataStreamCoder::decodeString): + (WebCore::HistoryItem::restoreState): + (WebCore::WebCore::HistoryItem::saveState): + +2013-01-16 Jocelyn Turcotte <jocelyn.turcotte@digia.com> + + [Qt] Crash in WebCore::CachedFrame::destroy + https://bugs.webkit.org/show_bug.cgi?id=104525 + + Reviewed by Adam Barth. + + Add an assert to increase the chances of catching this crash + early on in the future. + + * dom/Document.cpp: + (WebCore::Document::takeDOMWindowFrom): + +2013-01-14 Julien Chaffraix <jchaffraix@webkit.org> + + REGRESSION (r132591): Underpainting @ uofmchildrenshospital.org + https://bugs.webkit.org/show_bug.cgi?id=105861 + + Reviewed by David Hyatt. + + Test: fast/repaint/overhanging-float-detach-repaint.html + + The issue comes from overhanging float not contributing to their containing block's + overflow. This meant that repaint() would ignore them leading to an under-repaint. + The fix is simple: force all the overhanging floats to repaint themselves. + + * rendering/RenderObject.cpp: + (WebCore::RenderObject::destroyAndCleanupAnonymousWrappers): + +2013-01-10 Xianzhu Wang <wangxianzhu@chromium.org> + + Regression(r129944): Heap-use-after-free in WebCore::computeNonFastScrollableRegion + https://bugs.webkit.org/show_bug.cgi?id=99515 + + Reviewed by Simon Fraser. + + The object used-after-freed is a destructed FrameView that is still in the m_scrollableAreas set of the parent FrameView. Actually it has been removed from m_scrollableAreas when setParent(0), but then is added back in updateScrollableAreaSet() because its frameViewParent() is still not 0 (though parent() is already 0). + + No new tests. The heap-use-after-free doesn't always cause crash so it can't be stably tested with a test case. Memory analysis tools like asan discovered the heap-use-after-free and verified that the patch can fix the issue. + + * page/FrameView.cpp: + (WebCore::FrameView::parentFrameView): Checks if the FrameView has been removed from the parent. + +2013-01-09 Ryosuke Niwa <rniwa@webkit.org> + + [JSC] REGRESSION(r135093): A form control with name=length overrides length property on form.elements + https://bugs.webkit.org/show_bug.cgi?id=105775 + + Reviewed by Sam Weinig. + + Fixed the bug by respecting properties on ancestor classes. + + Test: fast/dom/collection-length-should-not-be-overridden.html + + * bindings/js/JSDOMBinding.h: + (WebCore::getStaticValueSlotEntryWithoutCaching): Added. + * bindings/scripts/CodeGeneratorJS.pm: + (GenerateGetOwnPropertySlotBody): Use getStaticValueSlotEntryWithoutCaching to climb up the class + hierarchy. + +2012-12-12 Allan Sandfeld Jensen <allan.jensen@digia.com> + + [Qt] Animation fails on large layers + https://bugs.webkit.org/show_bug.cgi?id=104538 + + Reviewed by Noam Rosenthal. + + The backing tiles had no upper limit defined for the non-GL backend, which could cause them + to allocate pixmaps widier or higher than what the underlying graphics systems can handle. + + On top of that GraphicsLayerTextureMapper::prepareBackingStore() would allocate an intermediate + pixmap the size of the dirty rect, which would at least on the first paint be the size of the + entire layer, again causing allocation of pixmaps with dimensions outside of platform bounds. + + This patch introduces a limit to the size of image buffer tiles, and adds an alternative path + for painting where the GraphicsLayer paints directly to the tile instead of over an intermediate + pixmap. This alternative path can also be useful later to minimize the amount of pixel copying + happening in full repaints. + + * platform/graphics/texmap/GraphicsLayerTextureMapper.cpp: + (WebCore::GraphicsLayerTextureMapper::prepareBackingStore): + * platform/graphics/texmap/GraphicsLayerTextureMapper.h: + (GraphicsLayerTextureMapper): + * platform/graphics/texmap/TextureMapper.cpp: + (WebCore::BitmapTexture::updateContents): + * platform/graphics/texmap/TextureMapper.h: + (BitmapTexture): + (TextureMapper): + * platform/graphics/texmap/TextureMapperBackingStore.cpp: + (WebCore::TextureMapperTile::updateContents): + (WebCore::TextureMapperTiledBackingStore::updateContents): + * platform/graphics/texmap/TextureMapperBackingStore.h: + (TextureMapperTile): + (TextureMapperTiledBackingStore): + * platform/graphics/texmap/TextureMapperImageBuffer.cpp: + (WebCore::BitmapTextureImageBuffer::updateContents): + (WebCore::TextureMapperImageBuffer::maxTextureSize): + * platform/graphics/texmap/TextureMapperImageBuffer.h: + (BitmapTextureImageBuffer): + +2012-12-06 Andras Becsi <andras.becsi@digia.com> + + [Qt][Mac] Fix libxslt and libxml2 config tests + https://bugs.webkit.org/show_bug.cgi?id=104164 + + Reviewed by Simon Hausmann. + + Since libxml2 is a dependency for libxslt and is not used + standalone the configurations for it should also depend on + whether XSLT is enabled. + Also avoid using pkg-config on Mac, instead use direct + include paths and add needed libraries to the linker. + + No new tests needed. + + * WebCore.pri: + +2013-01-10 Alexis Menard <alexis@webkit.org> + + ASSERT_NOT_REACHED in StylePropertySet::fontValue when accessing font style property through JS after setting style font size. + https://bugs.webkit.org/show_bug.cgi?id=88866 + + Reviewed by Alexander Pavlov. + + StylePropertySet::fontValue always assumed that it was called using + style.font after a subsequent call which set the shorthand font. The + ASSERT_NOT_REACHED assumed that all longhands of the font shorthand not + set by the shorthand itself were set to initial. While it's true when + we set the font shorthand (i.e all longhands are set to implicit initial) + it is not true when you set the longhands individually. For example setting + font-size will not set other font properties to initial. It is the behavior of all + other shorthands in WebKit. When reconstructing the shorthand other + properties tests whether the value of each longhands is initial or not + (if not then we omit the value, as we should always construct the + shortest shorthand possible) or if the value is set or not (if set then + we include it in the shorthand if not then we omit it). The comment + removed was also talking about invalid font property potentially built + by fontValue(). So far appendFontLonghandValueIfExplicit will always + construct a valid value as it takes care of adding ' ' or '/' when + needed, so the return value is parsable and correct. + + Test: fast/css/font-shorthand-from-longhands.html + + * css/StylePropertySet.cpp: + (WebCore::StylePropertySet::appendFontLonghandValueIfExplicit): + (WebCore::StylePropertySet::fontValue): + * css/StylePropertySet.h: + 2013-01-24 Kai Koehne <kai.koehne@digia.com> [Qt] Webkit debug build links against release binaries of ANGLE libEGL, libGLESv2 @@ -180,6 +582,32 @@ since BGR is not supported by QImage. (WebCore::MediaPlayerPrivateQTKit::paint): +2012-12-06 Stephen Chenney <schenney@chromium.org> + + SVG <use> element inside an svg-as-image fails + https://bugs.webkit.org/show_bug.cgi?id=104007 + + Reviewed by Eric Seidel. + + Upon redraw, SVGImage calls layout on the document it is drawing into + the image if the image, provided it believes the redraw does not need + to be delayed. Unfortunately, when an SVG <use> element is modified + (by animation, say) and regenerates its shadow tree, the destructors + invoke redraw, causing the SVGImage to call layout on something that + is in the process of being deleted. That's bad. + + This change causes SVGImage to always delay the redraw. It is the most robust + way to protect against this problem, as there may be any number of + ways to cause this issue (a node being deleted in an svg-as-image + target) and this protects against them all. + + The test case crashes in Asan Chromium. + + Test: svg/as-image/animated-use-as-image-crash.html + + * svg/graphics/SVGImageCache.cpp: + (WebCore::SVGImageCache::imageContentChanged): Always redraw on the timer. + 2012-12-03 Jocelyn Turcotte <jocelyn.turcotte@digia.com> Document::initSecurityContext() fails to call securityOrigin().grantLoadLocalResources() @@ -198,6 +626,26 @@ * loader/FrameLoader.cpp: (WebCore::FrameLoader::didBeginDocument): +2012-11-30 Florin Malita <fmalita@chromium.org> + + SVG pattern data deleted while in use + https://bugs.webkit.org/show_bug.cgi?id=103415 + + Reviewed by Dirk Schulze. + + Various calls in RenderSVGResourcePattern::applyResource() can trigger invalidations, + which may end up deleting our current pattern data (via removeAllClientsFromCache). + To avoid this, we should add the pattern data to the cache only after it is fully built. + For clarity, the patch also refactors the pattern setup code into a separate method. + + Test: svg/custom/large-image-pattern-crash.html + + * rendering/svg/RenderSVGResourcePattern.cpp: + (WebCore::RenderSVGResourcePattern::buildPattern): + (WebCore::RenderSVGResourcePattern::applyResource): + * rendering/svg/RenderSVGResourcePattern.h: + (RenderSVGResourcePattern): + 2012-11-29 Tommy Widenflycht <tommyw@google.com> Speech Recognition API: Update SpeechRecognitionEvent/Result to match the specification diff --git a/Source/WebCore/Target.pri b/Source/WebCore/Target.pri index cf1370fce..266974814 100644 --- a/Source/WebCore/Target.pri +++ b/Source/WebCore/Target.pri @@ -3253,7 +3253,7 @@ enable?(VIDEO) { platform/mac/WebWindowAnimation.mm DEFINES+=NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES - contains(CONFIG, "x86") { + isEqual(QT_ARCH, "i386") { DEFINES+=NS_BUILD_32_LIKE_64 } diff --git a/Source/WebCore/WebCore.pri b/Source/WebCore/WebCore.pri index 6c83126f0..2ac0dd7ad 100644 --- a/Source/WebCore/WebCore.pri +++ b/Source/WebCore/WebCore.pri @@ -107,17 +107,15 @@ INCLUDEPATH += $$WEBCORE_GENERATED_SOURCES_DIR enable?(XSLT) { use?(LIBXML2) { mac { - INCLUDEPATH += /usr/include/libxml2 + INCLUDEPATH += /usr/include/libxslt /usr/include/libxml2 LIBS += -lxml2 -lxslt } else { - PKGCONFIG += libxslt + PKGCONFIG += libxslt libxml-2.0 } } else { QT *= xmlpatterns } -} - -use?(LIBXML2) { +} else:!mac:use?(LIBXML2) { PKGCONFIG += libxml-2.0 } diff --git a/Source/WebCore/bindings/js/JSDOMBinding.h b/Source/WebCore/bindings/js/JSDOMBinding.h index a21959bcb..b83691ce8 100644 --- a/Source/WebCore/bindings/js/JSDOMBinding.h +++ b/Source/WebCore/bindings/js/JSDOMBinding.h @@ -46,6 +46,12 @@ #include <wtf/Noncopyable.h> #include <wtf/Vector.h> +namespace JSC { + +class HashEntry; + +} + namespace WebCore { class DOMStringList; @@ -491,6 +497,21 @@ enum ParameterDefaultPolicy { return AtomicString(propertyName.publicName()); } + template <class ThisImp> + inline const JSC::HashEntry* getStaticValueSlotEntryWithoutCaching(JSC::ExecState* exec, JSC::PropertyName propertyName) + { + const JSC::HashEntry* entry = ThisImp::s_info.propHashTable(exec)->entry(exec, propertyName); + if (!entry) // not found, forward to parent + return getStaticValueSlotEntryWithoutCaching<typename ThisImp::Base>(exec, propertyName); + return entry; + } + + template <> + inline const JSC::HashEntry* getStaticValueSlotEntryWithoutCaching<JSDOMWrapper>(JSC::ExecState*, JSC::PropertyName) + { + return 0; + } + } // namespace WebCore #endif // JSDOMBinding_h diff --git a/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm b/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm index 5b4d7acca..0578f46b4 100644 --- a/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm +++ b/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm @@ -401,7 +401,7 @@ sub GenerateGetOwnPropertySlotBody my $manualLookupGetterGeneration = sub { my $requiresManualLookup = $interface->extendedAttributes->{"IndexedGetter"} || $interface->extendedAttributes->{"NamedGetter"}; if ($requiresManualLookup) { - push(@getOwnPropertySlotImpl, " const ${namespaceMaybe}HashEntry* entry = ${className}Table.entry(exec, propertyName);\n"); + push(@getOwnPropertySlotImpl, " const ${namespaceMaybe}HashEntry* entry = getStaticValueSlotEntryWithoutCaching<$className>(exec, propertyName);\n"); push(@getOwnPropertySlotImpl, " if (entry) {\n"); push(@getOwnPropertySlotImpl, " slot.setCustom(thisObject, entry->propertyGetter());\n"); push(@getOwnPropertySlotImpl, " return true;\n"); diff --git a/Source/WebCore/css/StylePropertySet.cpp b/Source/WebCore/css/StylePropertySet.cpp index f662ccacf..ccd7d8a62 100644 --- a/Source/WebCore/css/StylePropertySet.cpp +++ b/Source/WebCore/css/StylePropertySet.cpp @@ -225,15 +225,15 @@ String StylePropertySet::borderSpacingValue(const StylePropertyShorthand& shorth return horizontalValueCSSText + ' ' + verticalValueCSSText; } -bool StylePropertySet::appendFontLonghandValueIfExplicit(CSSPropertyID propertyID, StringBuilder& result, String& commonValue) const +void StylePropertySet::appendFontLonghandValueIfExplicit(CSSPropertyID propertyID, StringBuilder& result, String& commonValue) const { int foundPropertyIndex = findPropertyIndex(propertyID); if (foundPropertyIndex == -1) - return false; // All longhands must have at least implicit values if "font" is specified. + return; // All longhands must have at least implicit values if "font" is specified. if (propertyAt(foundPropertyIndex).isImplicit()) { commonValue = String(); - return true; + return; } char prefix = '\0'; @@ -258,37 +258,32 @@ bool StylePropertySet::appendFontLonghandValueIfExplicit(CSSPropertyID propertyI result.append(value); if (!commonValue.isNull() && commonValue != value) commonValue = String(); - - return true; } String StylePropertySet::fontValue() const { - int foundPropertyIndex = findPropertyIndex(CSSPropertyFontSize); - if (foundPropertyIndex == -1) + int fontSizePropertyIndex = findPropertyIndex(CSSPropertyFontSize); + int fontFamilyPropertyIndex = findPropertyIndex(CSSPropertyFontFamily); + if (fontSizePropertyIndex == -1 || fontFamilyPropertyIndex == -1) return emptyString(); - PropertyReference fontSizeProperty = propertyAt(foundPropertyIndex); - if (fontSizeProperty.isImplicit()) + PropertyReference fontSizeProperty = propertyAt(fontSizePropertyIndex); + PropertyReference fontFamilyProperty = propertyAt(fontFamilyPropertyIndex); + if (fontSizeProperty.isImplicit() || fontFamilyProperty.isImplicit()) return emptyString(); String commonValue = fontSizeProperty.value()->cssText(); StringBuilder result; - bool success = true; - success &= appendFontLonghandValueIfExplicit(CSSPropertyFontStyle, result, commonValue); - success &= appendFontLonghandValueIfExplicit(CSSPropertyFontVariant, result, commonValue); - success &= appendFontLonghandValueIfExplicit(CSSPropertyFontWeight, result, commonValue); + appendFontLonghandValueIfExplicit(CSSPropertyFontStyle, result, commonValue); + appendFontLonghandValueIfExplicit(CSSPropertyFontVariant, result, commonValue); + appendFontLonghandValueIfExplicit(CSSPropertyFontWeight, result, commonValue); if (!result.isEmpty()) result.append(' '); result.append(fontSizeProperty.value()->cssText()); - success &= appendFontLonghandValueIfExplicit(CSSPropertyLineHeight, result, commonValue); - success &= appendFontLonghandValueIfExplicit(CSSPropertyFontFamily, result, commonValue); - if (!success) { - // An invalid "font" value has been built (should never happen, as at least implicit values - // for mandatory longhands are always found in the style), report empty value instead. - ASSERT_NOT_REACHED(); - return emptyString(); - } + appendFontLonghandValueIfExplicit(CSSPropertyLineHeight, result, commonValue); + if (!result.isEmpty()) + result.append(' '); + result.append(fontFamilyProperty.value()->cssText()); if (isInitialOrInherit(commonValue)) return commonValue; return result.toString(); diff --git a/Source/WebCore/css/StylePropertySet.h b/Source/WebCore/css/StylePropertySet.h index 456f7ef2e..40eab1d13 100644 --- a/Source/WebCore/css/StylePropertySet.h +++ b/Source/WebCore/css/StylePropertySet.h @@ -197,7 +197,7 @@ private: String get4Values(const StylePropertyShorthand&) const; String borderSpacingValue(const StylePropertyShorthand&) const; String fontValue() const; - bool appendFontLonghandValueIfExplicit(CSSPropertyID, StringBuilder& result, String& value) const; + void appendFontLonghandValueIfExplicit(CSSPropertyID, StringBuilder& result, String& value) const; bool removeShorthandProperty(CSSPropertyID); bool propertyMatches(const PropertyReference&) const; diff --git a/Source/WebCore/css/StyleResolver.cpp b/Source/WebCore/css/StyleResolver.cpp index 95a975779..b14800b31 100644 --- a/Source/WebCore/css/StyleResolver.cpp +++ b/Source/WebCore/css/StyleResolver.cpp @@ -1005,6 +1005,13 @@ inline void StyleResolver::initForStyleResolve(Element* e, RenderStyle* parentSt static const unsigned cStyleSearchThreshold = 10; static const unsigned cStyleSearchLevelThreshold = 10; +static inline bool parentElementPreventsSharing(const Element* parentElement) +{ + if (!parentElement) + return false; + return parentElement->hasFlagsSetDuringStylingOfChildren(); +} + Node* StyleResolver::locateCousinList(Element* parent, unsigned& visitedNodeCount) const { if (visitedNodeCount >= cStyleSearchThreshold * cStyleSearchLevelThreshold) @@ -1034,7 +1041,8 @@ Node* StyleResolver::locateCousinList(Element* parent, unsigned& visitedNodeCoun while (thisCousin) { while (currentNode) { ++subcount; - if (currentNode->renderStyle() == parentStyle && currentNode->lastChild()) { + if (currentNode->renderStyle() == parentStyle && currentNode->lastChild() + && currentNode->isElementNode() && !parentElementPreventsSharing(toElement(currentNode))) { // Adjust for unused reserved tries. visitedNodeCount -= cStyleSearchThreshold - subcount; return currentNode->lastChild(); @@ -1247,16 +1255,6 @@ inline StyledElement* StyleResolver::findSiblingForStyleSharing(Node* node, unsi return static_cast<StyledElement*>(node); } -static inline bool parentElementPreventsSharing(const Element* parentElement) -{ - if (!parentElement) - return false; - return parentElement->childrenAffectedByPositionalRules() - || parentElement->childrenAffectedByFirstChildRules() - || parentElement->childrenAffectedByLastChildRules() - || parentElement->childrenAffectedByDirectAdjacentRules(); -} - RenderStyle* StyleResolver::locateSharedStyle() { if (!m_styledElement || !m_parentStyle) diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index 0bb8cc019..c1c2b7b5d 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -2352,8 +2352,8 @@ void Document::close() void Document::explicitClose() { - if (m_parser) - m_parser->finish(); + if (RefPtr<DocumentParser> parser = m_parser) + parser->finish(); if (!m_frame) { // Because we have no frame, we don't know if all loading has completed, @@ -3612,6 +3612,8 @@ void Document::takeDOMWindowFrom(Document* document) ASSERT(m_frame); ASSERT(!m_domWindow); ASSERT(document->domWindow()); + // A valid DOMWindow is needed by CachedFrame for its documents. + ASSERT(!document->inPageCache()); m_domWindow = document->m_domWindow.release(); m_domWindow->didSecureTransitionTo(this); diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp index b7d0e5993..18bf57289 100644 --- a/Source/WebCore/dom/Element.cpp +++ b/Source/WebCore/dom/Element.cpp @@ -1952,6 +1952,20 @@ void Element::setChildIndex(unsigned index) rareData->setChildIndex(index); } +bool Element::hasFlagsSetDuringStylingOfChildren() const +{ + if (!hasRareData()) + return false; + return rareDataChildrenAffectedByHover() + || rareDataChildrenAffectedByActive() + || rareDataChildrenAffectedByDrag() + || rareDataChildrenAffectedByFirstChildRules() + || rareDataChildrenAffectedByLastChildRules() + || rareDataChildrenAffectedByDirectAdjacentRules() + || rareDataChildrenAffectedByForwardPositionalRules() + || rareDataChildrenAffectedByBackwardPositionalRules(); +} + bool Element::rareDataStyleAffectedByEmpty() const { ASSERT(hasRareData()); diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h index a24594f5e..b729e1db7 100644 --- a/Source/WebCore/dom/Element.h +++ b/Source/WebCore/dom/Element.h @@ -299,6 +299,8 @@ public: bool childrenAffectedByBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByBackwardPositionalRules(); } unsigned childIndex() const { return hasRareData() ? rareDataChildIndex() : 0; } + bool hasFlagsSetDuringStylingOfChildren() const; + void setStyleAffectedByEmpty(); void setChildrenAffectedByHover(bool); void setChildrenAffectedByActive(bool); diff --git a/Source/WebCore/editing/InsertParagraphSeparatorCommand.cpp b/Source/WebCore/editing/InsertParagraphSeparatorCommand.cpp index 268fa6793..72a729a84 100644 --- a/Source/WebCore/editing/InsertParagraphSeparatorCommand.cpp +++ b/Source/WebCore/editing/InsertParagraphSeparatorCommand.cpp @@ -119,7 +119,7 @@ bool InsertParagraphSeparatorCommand::shouldUseDefaultParagraphElement(Node* enc enclosingBlock->hasTagName(h5Tag); } -void InsertParagraphSeparatorCommand::getAncestorsInsideBlock(const Node* insertionNode, Element* outerBlock, Vector<Element*>& ancestors) +void InsertParagraphSeparatorCommand::getAncestorsInsideBlock(const Node* insertionNode, Element* outerBlock, Vector<RefPtr<Element> >& ancestors) { ancestors.clear(); @@ -130,7 +130,7 @@ void InsertParagraphSeparatorCommand::getAncestorsInsideBlock(const Node* insert } } -PassRefPtr<Element> InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock(const Vector<Element*>& ancestors, PassRefPtr<Element> blockToInsert) +PassRefPtr<Element> InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock(const Vector<RefPtr<Element> >& ancestors, PassRefPtr<Element> blockToInsert) { // Make clones of ancestors in between the start node and the start block. RefPtr<Element> parent = blockToInsert; @@ -239,7 +239,7 @@ void InsertParagraphSeparatorCommand::doApply() // Recreate the same structure in the new paragraph. - Vector<Element*> ancestors; + Vector<RefPtr<Element> > ancestors; getAncestorsInsideBlock(positionOutsideTabSpan(insertionPosition).deprecatedNode(), startBlock.get(), ancestors); RefPtr<Element> parent = cloneHierarchyUnderNewBlock(ancestors, blockToInsert); @@ -278,7 +278,7 @@ void InsertParagraphSeparatorCommand::doApply() // Recreate the same structure in the new paragraph. - Vector<Element*> ancestors; + Vector<RefPtr<Element> > ancestors; getAncestorsInsideBlock(positionAvoidingSpecialElementBoundary(positionOutsideTabSpan(insertionPosition)).deprecatedNode(), startBlock.get(), ancestors); appendBlockPlaceholder(cloneHierarchyUnderNewBlock(ancestors, blockToInsert)); diff --git a/Source/WebCore/editing/InsertParagraphSeparatorCommand.h b/Source/WebCore/editing/InsertParagraphSeparatorCommand.h index 9f7210824..11e14d5a8 100644 --- a/Source/WebCore/editing/InsertParagraphSeparatorCommand.h +++ b/Source/WebCore/editing/InsertParagraphSeparatorCommand.h @@ -46,8 +46,8 @@ private: void calculateStyleBeforeInsertion(const Position&); void applyStyleAfterInsertion(Node* originalEnclosingBlock); - void getAncestorsInsideBlock(const Node* insertionNode, Element* outerBlock, Vector<Element*>& ancestors); - PassRefPtr<Element> cloneHierarchyUnderNewBlock(const Vector<Element*>& ancestors, PassRefPtr<Element> blockToInsert); + void getAncestorsInsideBlock(const Node* insertionNode, Element* outerBlock, Vector<RefPtr<Element> >& ancestors); + PassRefPtr<Element> cloneHierarchyUnderNewBlock(const Vector<RefPtr<Element> >& ancestors, PassRefPtr<Element> blockToInsert); bool shouldUseDefaultParagraphElement(Node*) const; diff --git a/Source/WebCore/history/HistoryItem.h b/Source/WebCore/history/HistoryItem.h index 2472aa3fa..79c43c939 100644 --- a/Source/WebCore/history/HistoryItem.h +++ b/Source/WebCore/history/HistoryItem.h @@ -201,7 +201,7 @@ public: QVariant userData() const { return m_userData; } void setUserData(const QVariant& userData) { m_userData = userData; } - bool restoreState(QDataStream& buffer, int version); + static PassRefPtr<HistoryItem> restoreState(QDataStream& buffer, int version); QDataStream& saveState(QDataStream& out, int version) const; #endif diff --git a/Source/WebCore/history/qt/HistoryItemQt.cpp b/Source/WebCore/history/qt/HistoryItemQt.cpp index 5528eeb0c..5a54516f3 100644 --- a/Source/WebCore/history/qt/HistoryItemQt.cpp +++ b/Source/WebCore/history/qt/HistoryItemQt.cpp @@ -21,22 +21,13 @@ #include "HistoryItem.h" #include "FormData.h" +#include <wtf/Decoder.h> +#include <wtf/Encoder.h> #include <wtf/text/CString.h> -static QDataStream& operator<<(QDataStream& stream, const WebCore::IntPoint& point) -{ - stream << point.x() << point.y(); - return stream; -} +using namespace WTF; -static QDataStream& operator>>(QDataStream& stream, WebCore::IntPoint& point) -{ - int x, y; - stream >> x >> y; - point.setX(x); - point.setY(y); - return stream; -} +namespace WebCore { static QDataStream& operator<<(QDataStream& stream, const String& str) { @@ -54,117 +45,190 @@ static QDataStream& operator>>(QDataStream& stream, String& str) return stream; } -template<typename T> -QDataStream& operator<<(QDataStream& stream, const Vector<T>& data) +class QDataStreamCoder : public WTF::Encoder, public WTF::Decoder { +public: + QDataStreamCoder(QDataStream&); + +private: + virtual void encodeBytes(const uint8_t*, size_t); + virtual void encodeBool(bool); + virtual void encodeUInt32(uint32_t); + virtual void encodeUInt64(uint64_t); + virtual void encodeInt32(int32_t); + virtual void encodeInt64(int64_t); + virtual void encodeFloat(float); + virtual void encodeDouble(double); + virtual void encodeString(const String&); + + virtual bool decodeBytes(Vector<uint8_t>&); + virtual bool decodeBool(bool&); + virtual bool decodeUInt32(uint32_t&); + virtual bool decodeUInt64(uint64_t&); + virtual bool decodeInt32(int32_t&); + virtual bool decodeInt64(int64_t&); + virtual bool decodeFloat(float&); + virtual bool decodeDouble(double&); + virtual bool decodeString(String&); + + QDataStream& m_stream; +}; + +QDataStreamCoder::QDataStreamCoder(QDataStream& stream) + : m_stream(stream) { - stream << qint64(data.size()); - foreach (const T& i, data) - stream << i; - return stream; } -template<typename T> -QDataStream& operator>>(QDataStream& stream, Vector<T>& data) +void QDataStreamCoder::encodeBytes(const uint8_t* bytes, size_t size) { - data.clear(); + m_stream << qint64(size); + for (; size > 0; --size) + m_stream << bytes++; +} + +void QDataStreamCoder::encodeBool(bool value) +{ + m_stream << value; +} + +void QDataStreamCoder::encodeUInt32(uint32_t value) +{ + m_stream << value; +} + +void QDataStreamCoder::encodeUInt64(uint64_t value) +{ + m_stream << static_cast<quint64>(value); +} + +void QDataStreamCoder::encodeInt32(int32_t value) +{ + m_stream << value; +} + +void QDataStreamCoder::encodeInt64(int64_t value) +{ + m_stream << static_cast<qint64>(value); +} + +void QDataStreamCoder::encodeFloat(float value) +{ + m_stream << value; +} + +void QDataStreamCoder::encodeDouble(double value) +{ + m_stream << value; +} + +void QDataStreamCoder::encodeString(const String& value) +{ + m_stream << value; +} + +bool QDataStreamCoder::decodeBytes(Vector<uint8_t>& out) +{ + out.clear(); qint64 count; - T item; - stream >> count; - data.reserveCapacity(count); + uint8_t byte; + m_stream >> count; + out.reserveCapacity(count); for (qint64 i = 0; i < count; ++i) { - stream >> item; - data.append(item); + m_stream >> byte; + out.append(byte); } - return stream; + return m_stream.status() == QDataStream::Ok; } -bool WebCore::HistoryItem::restoreState(QDataStream& in, int version) +bool QDataStreamCoder::decodeBool(bool& out) { - // we only support version 1 for now + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} - if (version != 1) - return false; +bool QDataStreamCoder::decodeUInt32(uint32_t& out) +{ + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} - WTF::String url; - WTF::String title; - WTF::String altTitle; - WTF::String orginalUrl; - WTF::String referrer; - WTF::String target; - WTF::String parrent; - double lastVisitedTime; - bool validUserData; - WTF::String parent; - bool lastVisitWasHTTPNonGet; - bool lastVisitWasFailure; - bool isTargetItem; - int visitCount; - WTF::Vector<WTF::String> documentState; - WebCore::IntPoint scrollPoint; - qreal pageScaleFactor; - WTF::Vector<int> weeklyVisitCounts; - WTF::Vector<int> dailyVisitCounts; - // bool loadFormdata; - // WTF::String formContentType; - // WTF::Vector<char> formData; - - in >> url >> title >> altTitle >> lastVisitedTime >> orginalUrl >> referrer >> target >> parent; - in >> lastVisitWasHTTPNonGet >> lastVisitWasFailure >> isTargetItem >> visitCount >> documentState; - in >> scrollPoint >> pageScaleFactor >> dailyVisitCounts >> weeklyVisitCounts; - /*in >> loadFormdata; - if (loadFormdata) { - in >> formContentType >> formData; - // direct assigned (!) - m_formContentType = formContentType; - m_formData = FormData::create(CString(formData)); - }*/ - // use setters - adoptVisitCounts(dailyVisitCounts, weeklyVisitCounts); - setScrollPoint(scrollPoint); - setPageScaleFactor(pageScaleFactor); - setDocumentState(documentState); - setVisitCount(visitCount); - setIsTargetItem(isTargetItem); - setLastVisitWasFailure(lastVisitWasFailure); - setLastVisitWasHTTPNonGet(lastVisitWasHTTPNonGet); - setParent(parent); - setTarget(target); - setReferrer(referrer); - setOriginalURLString(orginalUrl); - setURLString(url); - setLastVisitedTime(lastVisitedTime); - setTitle(title); - setAlternateTitle(altTitle); +bool QDataStreamCoder::decodeUInt64(uint64_t& out) +{ + quint64 tmp; + m_stream >> tmp; + // quint64 is defined to "long long unsigned", incompatible with uint64_t defined as "long unsigned" on 64bits archs. + out = tmp; + return m_stream.status() == QDataStream::Ok; +} + +bool QDataStreamCoder::decodeInt32(int32_t& out) +{ + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} + +bool QDataStreamCoder::decodeInt64(int64_t& out) +{ + qint64 tmp; + m_stream >> tmp; + // qint64 is defined to "long long", incompatible with int64_t defined as "long" on 64bits archs. + out = tmp; + return m_stream.status() == QDataStream::Ok; +} + +bool QDataStreamCoder::decodeFloat(float& out) +{ + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} + +bool QDataStreamCoder::decodeDouble(double& out) +{ + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} + +bool QDataStreamCoder::decodeString(String& out) +{ + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} + +PassRefPtr<HistoryItem> HistoryItem::restoreState(QDataStream& in, int version) +{ + ASSERT(version == 2); + + String url; + String title; + String originalURL; + in >> url >> title >> originalURL; + + QDataStreamCoder decoder(in); + RefPtr<HistoryItem> item = decodeBackForwardTree(url, title, originalURL, decoder); + // decodeBackForwardTree has its own stream version. An incompatible input stream version will return null here. + if (!item) + return 0; // at the end load userData + bool validUserData; in >> validUserData; if (validUserData) { QVariant tmp; in >> tmp; - setUserData(tmp); + item->setUserData(tmp); } - return in.status() == QDataStream::Ok; + return item; } QDataStream& WebCore::HistoryItem::saveState(QDataStream& out, int version) const { - // we only support version 1 for now. - if (version != 1) - return out; - - out << urlString() << title() << alternateTitle() << lastVisitedTime(); - out << originalURLString() << referrer() << target() << parent(); - out << lastVisitWasHTTPNonGet() << lastVisitWasFailure() << isTargetItem(); - out << visitCount() << documentState() << scrollPoint(); - out << qreal(pageScaleFactor()) << dailyVisitCounts() << weeklyVisitCounts(); - /*if (m_formData) { - out << true; - out << formContentType(); - out << m_formData->flatten(); - } else { - out << false; - }*/ + ASSERT(version == 2); + + out << urlString() << title() << originalURLString(); + + QDataStreamCoder encoder(out); + encodeBackForwardTree(encoder); + // save user data if (userData().isValid()) out << true << userData(); @@ -174,3 +238,4 @@ QDataStream& WebCore::HistoryItem::saveState(QDataStream& out, int version) cons return out; } +} // namespace WebCore diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp index 3eb38a105..8899830c0 100644 --- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp +++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp @@ -2363,8 +2363,13 @@ const Font& CanvasRenderingContext2D::accessFont() { canvas()->document()->updateStyleIfNeeded(); - if (!state().m_realizedFont) - setFont(state().m_unparsedFont); + if (!state().m_realizedFont) { + // Create temporary string object to hold ref count in case + // state().m_unparsedFont in unreffed by call to realizeSaves in + // setFont. + String unparsedFont(state().m_unparsedFont); + setFont(unparsedFont); + } return state().m_font; } diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.cpp b/Source/WebCore/html/parser/HTMLDocumentParser.cpp index 935f5d057..5932bb990 100644 --- a/Source/WebCore/html/parser/HTMLDocumentParser.cpp +++ b/Source/WebCore/html/parser/HTMLDocumentParser.cpp @@ -146,6 +146,11 @@ void HTMLDocumentParser::prepareToStopParsing() if (m_scriptRunner) document()->setReadyState(Document::Interactive); + // Setting the ready state above can fire mutation event and detach us + // from underneath. In that case, just bail out. + if (isDetached()) + return; + attemptToRunDeferredScriptsAndEnd(); } diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp index 9f5f04861..74072938b 100644 --- a/Source/WebCore/loader/DocumentLoader.cpp +++ b/Source/WebCore/loader/DocumentLoader.cpp @@ -214,6 +214,9 @@ void DocumentLoader::mainReceivedError(const ResourceError& error) // but not loads initiated by child frames' data sources -- that's the WebFrame's job. void DocumentLoader::stopLoading() { + RefPtr<Frame> protectFrame(m_frame); + RefPtr<DocumentLoader> protectLoader(this); + // In some rare cases, calling FrameLoader::stopLoading could cause isLoading() to return false. // (This can happen when there's a single XMLHttpRequest currently loading and stopLoading causes it // to stop loading. Because of this, we need to save it so we don't return early. @@ -250,9 +253,6 @@ void DocumentLoader::stopLoading() // See <rdar://problem/9673866> for more details. if (m_isStopping) return; - - RefPtr<Frame> protectFrame(m_frame); - RefPtr<DocumentLoader> protectLoader(this); m_isStopping = true; diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp index dcdae213e..083b83ad5 100644 --- a/Source/WebCore/page/FrameView.cpp +++ b/Source/WebCore/page/FrameView.cpp @@ -3074,6 +3074,9 @@ bool FrameView::hasCustomScrollbars() const FrameView* FrameView::parentFrameView() const { + if (!parent()) + return 0; + if (Frame* parentFrame = m_frame->tree()->parent()) return parentFrame->view(); diff --git a/Source/WebCore/platform/graphics/FontCache.cpp b/Source/WebCore/platform/graphics/FontCache.cpp index 1ce8e3b47..729b5ad12 100644 --- a/Source/WebCore/platform/graphics/FontCache.cpp +++ b/Source/WebCore/platform/graphics/FontCache.cpp @@ -357,6 +357,8 @@ void FontCache::releaseFontData(const SimpleFontData* fontData) FontDataCache::iterator it = gFontDataCache->find(fontData->platformData()); ASSERT(it != gFontDataCache->end()); + if (it == gFontDataCache->end()) + return; ASSERT(it->value.second); if (!--it->value.second) diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index 78c682f55..e91c2d287 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -821,10 +821,10 @@ IntRect GraphicsContext::clipBounds() const QPainter* p = m_data->p(); QRectF clipRect; + clipRect = p->transform().inverted().mapRect(p->window()); + if (p->hasClipping()) - clipRect = m_data->clipBoundingRect(); - else - clipRect = p->transform().inverted().mapRect(p->window()); + clipRect = clipRect.intersected(m_data->clipBoundingRect()); return enclosingIntRect(clipRect); } diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp index b1e9cb10d..c13f892b0 100644 --- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp +++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp @@ -452,25 +452,36 @@ void GraphicsLayerTextureMapper::prepareBackingStore() if (!m_backingStore) m_backingStore = TextureMapperTiledBackingStore::create(); - // Paint the entire dirty rect into an image buffer. This ensures we only paint once. - OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(dirtyRect.size()); - GraphicsContext* context = imageBuffer->context(); - context->setImageInterpolationQuality(textureMapper->imageInterpolationQuality()); - context->setTextDrawingMode(textureMapper->textDrawingMode()); - context->translate(-dirtyRect.x(), -dirtyRect.y()); - paintGraphicsLayerContents(*context, dirtyRect); - - if (isShowingRepaintCounter()) { - incrementRepaintCount(); - drawRepaintCounter(context); - } - - RefPtr<Image> image = imageBuffer->copyImage(DontCopyBackingStore); -#if PLATFORM(QT) +#ifndef QT_NO_DYNAMIC_CAST ASSERT(dynamic_cast<TextureMapperTiledBackingStore*>(m_backingStore.get())); #endif TextureMapperTiledBackingStore* backingStore = static_cast<TextureMapperTiledBackingStore*>(m_backingStore.get()); - backingStore->updateContents(textureMapper, image.get(), m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData); + + if (isShowingRepaintCounter()) + incrementRepaintCount(); + + // Paint into an intermediate buffer to avoid painting content more than once. + bool paintOnce = true; + const IntSize maxTextureSize = textureMapper->maxTextureSize(); + // We need to paint directly if the dirty rect exceeds one of the maximum dimensions. + if (dirtyRect.width() > maxTextureSize.width() || dirtyRect.height() > maxTextureSize.height()) + paintOnce = false; + + if (paintOnce) { + OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(dirtyRect.size()); + GraphicsContext* context = imageBuffer->context(); + context->setImageInterpolationQuality(textureMapper->imageInterpolationQuality()); + context->setTextDrawingMode(textureMapper->textDrawingMode()); + context->translate(-dirtyRect.x(), -dirtyRect.y()); + paintGraphicsLayerContents(*context, dirtyRect); + + if (isShowingRepaintCounter()) + drawRepaintCounter(context); + + RefPtr<Image> image = imageBuffer->copyImage(DontCopyBackingStore); + backingStore->updateContents(textureMapper, image.get(), m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData); + } else + backingStore->updateContents(textureMapper, this, m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData); backingStore->setShowDebugBorders(isShowingDebugBorder()); backingStore->setDebugBorder(m_debugBorderColor, m_debugBorderWidth); diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h index af4940943..7051a7d97 100644 --- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h +++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h @@ -95,6 +95,7 @@ public: void setFixedToViewport(bool fixed) { m_fixedToViewport = fixed; } bool fixedToViewport() const { return m_fixedToViewport; } + void drawRepaintCounter(GraphicsContext*); private: virtual void willBeDestroyed(); void didFlushCompositingState(); @@ -102,7 +103,6 @@ private: void updateBackingStore(); void prepareBackingStore(); bool shouldHaveBackingStore() const; - void drawRepaintCounter(GraphicsContext*); void animationStartedTimerFired(Timer<GraphicsLayerTextureMapper>*); OwnPtr<TextureMapperLayer> m_layer; diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp index 7a980a9c5..43fec543c 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp @@ -20,6 +20,7 @@ #include "config.h" #include "TextureMapper.h" +#include "GraphicsLayer.h" #include "TextureMapperImageBuffer.h" #include "Timer.h" #include <wtf/CurrentTime.h> @@ -144,5 +145,23 @@ TextureMapper::TextureMapper(AccelerationMode accelerationMode) TextureMapper::~TextureMapper() { } +void BitmapTexture::updateContents(TextureMapper* textureMapper, GraphicsLayer* sourceLayer, const IntRect& targetRect, const IntPoint& offset, UpdateContentsFlag updateContentsFlag) +{ + OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(targetRect.size()); + GraphicsContext* context = imageBuffer->context(); + context->setImageInterpolationQuality(textureMapper->imageInterpolationQuality()); + context->setTextDrawingMode(textureMapper->textDrawingMode()); + + IntRect sourceRect(targetRect); + sourceRect.setLocation(offset); + context->translate(-offset.x(), -offset.y()); + sourceLayer->paintGraphicsLayerContents(*context, sourceRect); + + RefPtr<Image> image = imageBuffer->copyImage(DontCopyBackingStore); + + updateContents(image.get(), targetRect, IntPoint(), updateContentsFlag); } + +} // namespace + #endif diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.h b/Source/WebCore/platform/graphics/texmap/TextureMapper.h index 144209349..22efd5ff7 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapper.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.h @@ -49,10 +49,11 @@ namespace WebCore { class BitmapTexturePool; class CustomFilterProgram; +class GraphicsLayer; class TextureMapper; // A 2D texture that can be the target of software or GL rendering. -class BitmapTexture : public RefCounted<BitmapTexture> { +class BitmapTexture : public RefCounted<BitmapTexture> { public: enum Flag { SupportsAlpha = 0x01 @@ -75,6 +76,7 @@ public: virtual IntSize size() const = 0; virtual void updateContents(Image*, const IntRect&, const IntPoint& offset, UpdateContentsFlag) = 0; + virtual void updateContents(TextureMapper*, GraphicsLayer*, const IntRect& target, const IntPoint& offset, UpdateContentsFlag); virtual void updateContents(const void*, const IntRect& target, const IntPoint& offset, int bytesPerLine, UpdateContentsFlag) = 0; virtual bool isValid() const = 0; inline Flags flags() const { return m_flags; } @@ -151,7 +153,7 @@ public: virtual void beginPainting(PaintFlags = 0) { } virtual void endPainting() { } - virtual IntSize maxTextureSize() const { return IntSize(INT_MAX, INT_MAX); } + virtual IntSize maxTextureSize() const = 0; virtual PassRefPtr<BitmapTexture> acquireTextureFromPool(const IntSize&); diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp index 0ced83611..788bb12a1 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp @@ -80,6 +80,25 @@ void TextureMapperTile::updateContents(TextureMapper* textureMapper, Image* imag m_texture->updateContents(image, targetRect, sourceOffset, updateContentsFlag); } +void TextureMapperTile::updateContents(TextureMapper* textureMapper, GraphicsLayer* sourceLayer, const IntRect& dirtyRect, BitmapTexture::UpdateContentsFlag updateContentsFlag) +{ + IntRect targetRect = enclosingIntRect(m_rect); + targetRect.intersect(dirtyRect); + if (targetRect.isEmpty()) + return; + IntPoint sourceOffset = targetRect.location(); + + // Normalize targetRect to the texture's coordinates. + targetRect.move(-m_rect.x(), -m_rect.y()); + + if (!m_texture) { + m_texture = textureMapper->createTexture(); + m_texture->reset(targetRect.size(), BitmapTexture::SupportsAlpha); + } + + m_texture->updateContents(textureMapper, sourceLayer, targetRect, sourceOffset, updateContentsFlag); +} + void TextureMapperTile::paint(TextureMapper* textureMapper, const TransformationMatrix& transform, float opacity, BitmapTexture* mask, const unsigned exposedEdges) { if (texture().get()) @@ -197,6 +216,13 @@ void TextureMapperTiledBackingStore::updateContents(TextureMapper* textureMapper m_tiles[i].updateContents(textureMapper, image, dirtyRect, updateContentsFlag); } +void TextureMapperTiledBackingStore::updateContents(TextureMapper* textureMapper, GraphicsLayer* sourceLayer, const FloatSize& totalSize, const IntRect& dirtyRect, BitmapTexture::UpdateContentsFlag updateContentsFlag) +{ + createOrDestroyTilesIfNeeded(totalSize, textureMapper->maxTextureSize(), true); + for (size_t i = 0; i < m_tiles.size(); ++i) + m_tiles[i].updateContents(textureMapper, sourceLayer, dirtyRect, updateContentsFlag); +} + PassRefPtr<BitmapTexture> TextureMapperTiledBackingStore::texture() const { for (size_t i = 0; i < m_tiles.size(); ++i) { diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h index a704ffd23..0dd2df4b1 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h @@ -73,6 +73,7 @@ public: inline void setRect(const FloatRect& rect) { m_rect = rect; } void updateContents(TextureMapper*, Image*, const IntRect&, BitmapTexture::UpdateContentsFlag UpdateCanModifyOriginalImageData); + void updateContents(TextureMapper*, GraphicsLayer*, const IntRect&, BitmapTexture::UpdateContentsFlag UpdateCanModifyOriginalImageData); virtual void paint(TextureMapper*, const TransformationMatrix&, float, BitmapTexture*, const unsigned exposedEdges); virtual ~TextureMapperTile() { } @@ -94,6 +95,7 @@ public: virtual PassRefPtr<BitmapTexture> texture() const OVERRIDE; virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float, BitmapTexture*) OVERRIDE; void updateContents(TextureMapper*, Image*, const FloatSize&, const IntRect&, BitmapTexture::UpdateContentsFlag); + void updateContents(TextureMapper*, GraphicsLayer*, const FloatSize&, const IntRect&, BitmapTexture::UpdateContentsFlag); void setContentsToImage(Image* image) { m_image = image; } void setShowDebugBorders(bool drawsDebugBorders) { m_drawsDebugBorders = drawsDebugBorders; } diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp index cefc2b5fc..2a6f29fdf 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp @@ -818,6 +818,7 @@ static unsigned getPassesRequiredForFilter(FilterOperation::OperationType type) case FilterOperation::OPACITY: #if ENABLE(CSS_SHADERS) case FilterOperation::CUSTOM: + case FilterOperation::VALIDATED_CUSTOM: #endif return 1; case FilterOperation::BLUR: @@ -924,7 +925,7 @@ static void prepareFilterProgram(TextureMapperShaderProgram* program, const Filt #if ENABLE(CSS_SHADERS) void TextureMapperGL::removeCachedCustomFilterProgram(CustomFilterProgram* program) { - m_customFilterPrograms.remove(program); + m_customFilterPrograms.remove(program->programInfo()); } bool TextureMapperGL::drawUsingCustomFilter(BitmapTexture& target, const BitmapTexture& source, const FilterOperation& filter) @@ -939,10 +940,10 @@ bool TextureMapperGL::drawUsingCustomFilter(BitmapTexture& target, const BitmapT renderer = CustomFilterRenderer::create(m_context3D, program->programType(), customFilter->parameters(), customFilter->meshRows(), customFilter->meshColumns(), customFilter->meshBoxType(), customFilter->meshType()); RefPtr<CustomFilterCompiledProgram> compiledProgram; - CustomFilterProgramMap::iterator iter = m_customFilterPrograms.find(program.get()); + CustomFilterProgramMap::iterator iter = m_customFilterPrograms.find(program->programInfo()); if (iter == m_customFilterPrograms.end()) { compiledProgram = CustomFilterCompiledProgram::create(m_context3D, program->vertexShaderString(), program->fragmentShaderString(), program->programType()); - m_customFilterPrograms.set(program.get(), compiledProgram); + m_customFilterPrograms.set(program->programInfo(), compiledProgram); } else compiledProgram = iter->value; renderer->setCompiledProgram(compiledProgram.release()); @@ -950,9 +951,19 @@ bool TextureMapperGL::drawUsingCustomFilter(BitmapTexture& target, const BitmapT } case FilterOperation::VALIDATED_CUSTOM: { // WebKit1 uses the ValidatedCustomFilterOperation. - // FIXME: This path is not working yet as GraphicsContext3D fails to initialize. - // https://bugs.webkit.org/show_bug.cgi?id=101532 - return false; + const ValidatedCustomFilterOperation* customFilter = static_cast<const ValidatedCustomFilterOperation*>(&filter); + RefPtr<CustomFilterValidatedProgram> program = customFilter->validatedProgram(); + renderer = CustomFilterRenderer::create(m_context3D, program->programInfo().programType(), customFilter->parameters(), + customFilter->meshRows(), customFilter->meshColumns(), customFilter->meshBoxType(), customFilter->meshType()); + RefPtr<CustomFilterCompiledProgram> compiledProgram; + CustomFilterProgramMap::iterator iter = m_customFilterPrograms.find(program->programInfo()); + if (iter == m_customFilterPrograms.end()) { + compiledProgram = CustomFilterCompiledProgram::create(m_context3D, program->validatedVertexShader(), program->validatedFragmentShader(), program->programInfo().programType()); + m_customFilterPrograms.set(program->programInfo(), compiledProgram); + } else + compiledProgram = iter->value; + renderer->setCompiledProgram(compiledProgram.release()); + break; } default: ASSERT_NOT_REACHED(); @@ -1019,7 +1030,7 @@ PassRefPtr<BitmapTexture> BitmapTextureGL::applyFilters(TextureMapper* textureMa textureMapperGL->bindSurface(target.get()); const BitmapTexture& sourceTexture = useContentTexture ? contentTexture : *source; #if ENABLE(CSS_SHADERS) - if (filter->getOperationType() == FilterOperation::CUSTOM) { + if (filter->getOperationType() == FilterOperation::CUSTOM || filter->getOperationType() == FilterOperation::VALIDATED_CUSTOM) { if (textureMapperGL->drawUsingCustomFilter(*target, sourceTexture, *filter)) { // Only swap if the draw was successful. std::swap(source, target); diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h index 6646dc70a..cc556e4b1 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h @@ -22,6 +22,7 @@ #if USE(ACCELERATED_COMPOSITING) +#include "CustomFilterProgramInfo.h" #include "FloatQuad.h" #include "GraphicsContext3D.h" #include "IntSize.h" @@ -132,7 +133,7 @@ private: bool m_enableEdgeDistanceAntialiasing; #if ENABLE(CSS_SHADERS) - typedef HashMap<CustomFilterProgram*, RefPtr<CustomFilterCompiledProgram> > CustomFilterProgramMap; + typedef HashMap<CustomFilterProgramInfo, RefPtr<CustomFilterCompiledProgram> > CustomFilterProgramMap; CustomFilterProgramMap m_customFilterPrograms; #endif diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp index 48540c48d..7e9e00175 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp @@ -21,6 +21,7 @@ #include "TextureMapperImageBuffer.h" #include "FilterEffectRenderer.h" +#include "GraphicsLayer.h" #if PLATFORM(QT) #include "NativeImageQt.h" #endif @@ -29,6 +30,8 @@ #if USE(TEXTURE_MAPPER) namespace WebCore { +static const int s_maximumAllowedImageBufferDimension = 4096; + void BitmapTextureImageBuffer::updateContents(const void* data, const IntRect& targetRect, const IntPoint& sourceOffset, int bytesPerLine, UpdateContentsFlag) { #if PLATFORM(QT) @@ -54,6 +57,20 @@ void BitmapTextureImageBuffer::updateContents(const void* data, const IntRect& t #endif } +void BitmapTextureImageBuffer::updateContents(TextureMapper* textureMapper, GraphicsLayer* sourceLayer, const IntRect& targetRect, const IntPoint& sourceOffset, UpdateContentsFlag) +{ + GraphicsContext* context = m_image->context(); + + context->clearRect(targetRect); + + IntRect sourceRect(targetRect); + sourceRect.setLocation(sourceOffset); + context->save(); + context->translate(targetRect.x() - sourceOffset.x(), targetRect.y() - sourceOffset.y()); + sourceLayer->paintGraphicsLayerContents(*context, sourceRect); + context->restore(); +} + void BitmapTextureImageBuffer::didReset() { m_image = ImageBuffer::create(contentSize()); @@ -64,6 +81,11 @@ void BitmapTextureImageBuffer::updateContents(Image* image, const IntRect& targe m_image->context()->drawImage(image, ColorSpaceDeviceRGB, targetRect, IntRect(offset, targetRect.size()), CompositeCopy); } +IntSize TextureMapperImageBuffer::maxTextureSize() const +{ + return IntSize(s_maximumAllowedImageBufferDimension, s_maximumAllowedImageBufferDimension); +} + void TextureMapperImageBuffer::beginClip(const TransformationMatrix& matrix, const FloatRect& rect) { GraphicsContext* context = currentContext(); diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h index 91ff9b005..9de6d4cbd 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h @@ -35,6 +35,7 @@ public: virtual bool isValid() const { return m_image; } inline GraphicsContext* graphicsContext() { return m_image ? m_image->context() : 0; } virtual void updateContents(Image*, const IntRect&, const IntPoint&, UpdateContentsFlag); + virtual void updateContents(TextureMapper*, GraphicsLayer*, const IntRect& target, const IntPoint& offset, UpdateContentsFlag); virtual void updateContents(const void*, const IntRect& target, const IntPoint& sourceOffset, int bytesPerLine, UpdateContentsFlag); #if ENABLE(CSS_FILTERS) PassRefPtr<BitmapTexture> applyFilters(TextureMapper*, const BitmapTexture&, const FilterOperations&); @@ -65,6 +66,7 @@ public: virtual void beginClip(const TransformationMatrix&, const FloatRect&) OVERRIDE; virtual void bindSurface(BitmapTexture* surface) OVERRIDE { m_currentSurface = surface;} virtual void endClip() OVERRIDE { graphicsContext()->restore(); } + virtual IntSize maxTextureSize() const; virtual PassRefPtr<BitmapTexture> createTexture() OVERRIDE { return BitmapTextureImageBuffer::create(); } inline GraphicsContext* currentContext() diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp index d2a10aa66..9d8a21010 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp @@ -264,7 +264,25 @@ void TextureMapperLayer::paintSelfAndChildrenWithReplica(const TextureMapperPain paintSelfAndChildren(options); } +void TextureMapperLayer::setAnimatedTransform(const TransformationMatrix& matrix) +{ + m_shouldUpdateCurrentTransformFromGraphicsLayer = false; + setTransform(matrix); +} + +void TextureMapperLayer::setAnimatedOpacity(float opacity) +{ + m_shouldUpdateCurrentOpacityFromGraphicsLayer = false; + setOpacity(opacity); +} + #if ENABLE(CSS_FILTERS) +void TextureMapperLayer::setAnimatedFilters(const FilterOperations& filters) +{ + m_shouldUpdateCurrentFiltersFromGraphicsLayer = false; + setFilters(filters); +} + static bool shouldKeepContentTexture(const FilterOperations& filters) { for (size_t i = 0; i < filters.size(); ++i) { @@ -412,6 +430,17 @@ void TextureMapperLayer::flushCompositingStateSelf(GraphicsLayerTextureMapper* g if (changeMask & AnimationChange) m_animations = graphicsLayer->m_animations; + + if (changeMask & TransformChange) + m_shouldUpdateCurrentTransformFromGraphicsLayer = true; + + if (changeMask & OpacityChange) + m_shouldUpdateCurrentOpacityFromGraphicsLayer = true; + +#if ENABLE(CSS_FILTERS) + if (changeMask & FilterChange) + m_shouldUpdateCurrentFiltersFromGraphicsLayer = true; +#endif m_state.maskLayer = toTextureMapperLayer(graphicsLayer->maskLayer()); m_state.replicaLayer = toTextureMapperLayer(graphicsLayer->replicaLayer()); @@ -466,12 +495,12 @@ void TextureMapperLayer::applyAnimationsRecursively() void TextureMapperLayer::syncAnimations() { m_animations.apply(this); - if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitTransform)) + if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitTransform) && m_shouldUpdateCurrentTransformFromGraphicsLayer) setTransform(m_state.transform); - if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyOpacity)) + if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyOpacity) && m_shouldUpdateCurrentOpacityFromGraphicsLayer) setOpacity(m_state.opacity); #if ENABLE(CSS_FILTERS) - if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitFilter)) + if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitFilter) && m_shouldUpdateCurrentFiltersFromGraphicsLayer) setFilters(m_state.filters); #endif } diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h index 27a77f6fe..08c273740 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h @@ -98,6 +98,11 @@ public: , m_contentsLayer(0) , m_opacity(1) , m_centerZ(0) + , m_shouldUpdateCurrentTransformFromGraphicsLayer(true) + , m_shouldUpdateCurrentOpacityFromGraphicsLayer(true) +#if ENABLE(CSS_FILTERS) + , m_shouldUpdateCurrentFiltersFromGraphicsLayer(true) +#endif , m_textureMapper(0) { } @@ -151,10 +156,10 @@ private: void paintSelfAndChildrenWithReplica(const TextureMapperPaintOptions&); // GraphicsLayerAnimation::Client - void setAnimatedTransform(const TransformationMatrix& matrix) { setTransform(matrix); } - void setAnimatedOpacity(float opacity) { setOpacity(opacity); } + virtual void setAnimatedTransform(const TransformationMatrix& matrix) OVERRIDE; + virtual void setAnimatedOpacity(float opacity) OVERRIDE; #if ENABLE(CSS_FILTERS) - virtual void setAnimatedFilters(const FilterOperations& filters) { setFilters(filters); } + virtual void setAnimatedFilters(const FilterOperations& filters) OVERRIDE; #endif void syncAnimations(); @@ -188,6 +193,12 @@ private: float m_centerZ; String m_name; + bool m_shouldUpdateCurrentTransformFromGraphicsLayer; + bool m_shouldUpdateCurrentOpacityFromGraphicsLayer; +#if ENABLE(CSS_FILTERS) + bool m_shouldUpdateCurrentFiltersFromGraphicsLayer; +#endif + struct State { FloatPoint pos; FloatPoint3D anchorPoint; diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp index 110467ad5..b3f325e2a 100644 --- a/Source/WebCore/rendering/RenderObject.cpp +++ b/Source/WebCore/rendering/RenderObject.cpp @@ -2505,8 +2505,10 @@ void RenderObject::destroyAndCleanupAnonymousWrappers() if (destroyRoot->everHadLayout()) { if (destroyRoot->isBody()) destroyRoot->view()->repaint(); - else + else { destroyRoot->repaint(); + destroyRoot->repaintOverhangingFloats(true); + } } destroyRoot->destroy(); diff --git a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp index b3c0b0bd1..55dbb8319 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp @@ -55,20 +55,15 @@ void RenderSVGResourcePattern::removeClientFromCache(RenderObject* client, bool markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation); } -bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode) +PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsigned short resourceMode) { - ASSERT(object); - ASSERT(style); - ASSERT(context); - ASSERT(resourceMode != ApplyToDefaultMode); + PatternData* currentData = m_patternMap.get(object); + if (currentData && currentData->pattern) + return currentData; - // Be sure to synchronize all SVG properties on the patternElement _before_ processing any further. - // Otherwhise the call to collectPatternAttributes() below, may cause the SVG DOM property - // synchronization to kick in, which causes removeAllClientsFromCache() to be called, which in turn deletes our - // PatternData object! Leaving out the line below will cause svg/dynamic-updates/SVGPatternElement-svgdom* to crash. SVGPatternElement* patternElement = static_cast<SVGPatternElement*>(node()); if (!patternElement) - return false; + return 0; if (m_shouldCollectPatternAttributes) { patternElement->updateAnimatedSVGAttribute(anyQName()); @@ -78,70 +73,80 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* m_shouldCollectPatternAttributes = false; } + // If we couldn't determine the pattern content element root, stop here. + if (!m_attributes.patternContentElement()) + return 0; + + // Compute all necessary transformations to build the tile image & the pattern. + FloatRect tileBoundaries; + AffineTransform tileImageTransform; + if (!buildTileImageTransform(object, m_attributes, patternElement, tileBoundaries, tileImageTransform)) + return 0; + + AffineTransform absoluteTransformIgnoringRotation; + SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransformIgnoringRotation); + + // Ignore 2D rotation, as it doesn't affect the size of the tile. + SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation); + FloatRect absoluteTileBoundaries = absoluteTransformIgnoringRotation.mapRect(tileBoundaries); + FloatRect clampedAbsoluteTileBoundaries; + + // Scale the tile size to match the scale level of the patternTransform. + absoluteTileBoundaries.scale(static_cast<float>(m_attributes.patternTransform().xScale()), + static_cast<float>(m_attributes.patternTransform().yScale())); + + // Build tile image. + OwnPtr<ImageBuffer> tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries); + if (!tileImage) + return 0; + + RefPtr<Image> copiedImage = tileImage->copyImage(CopyBackingStore); + if (!copiedImage) + return 0; + + // Build pattern. + OwnPtr<PatternData> patternData = adoptPtr(new PatternData); + patternData->pattern = Pattern::create(copiedImage, true, true); + + // Compute pattern space transformation. + const IntSize tileImageSize = tileImage->logicalSize(); + patternData->transform.translate(tileBoundaries.x(), tileBoundaries.y()); + patternData->transform.scale(tileBoundaries.width() / tileImageSize.width(), tileBoundaries.height() / tileImageSize.height()); + + AffineTransform patternTransform = m_attributes.patternTransform(); + if (!patternTransform.isIdentity()) + patternData->transform = patternTransform * patternData->transform; + + // Account for text drawing resetting the context to non-scaled, see SVGInlineTextBox::paintTextWithShadows. + if (resourceMode & ApplyToTextMode) { + AffineTransform additionalTextTransformation; + if (shouldTransformOnTextPainting(object, additionalTextTransformation)) + patternData->transform *= additionalTextTransformation; + } + patternData->pattern->setPatternSpaceTransform(patternData->transform); + + // Various calls above may trigger invalidations in some fringe cases (ImageBuffer allocation + // failures in the SVG image cache for example). To avoid having our PatternData deleted by + // removeAllClientsFromCache(), we only make it visible in the cache at the very end. + return m_patternMap.set(object, patternData.release()).iterator->value.get(); +} + +bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode) +{ + ASSERT(object); + ASSERT(style); + ASSERT(context); + ASSERT(resourceMode != ApplyToDefaultMode); + // Spec: When the geometry of the applicable element has no width or height and objectBoundingBox is specified, // then the given effect (e.g. a gradient or a filter) will be ignored. FloatRect objectBoundingBox = object->objectBoundingBox(); if (m_attributes.patternUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty()) return false; - OwnPtr<PatternData>& patternData = m_patternMap.add(object, nullptr).iterator->value; + PatternData* patternData = buildPattern(object, resourceMode); if (!patternData) - patternData = adoptPtr(new PatternData); - - if (!patternData->pattern) { - // If we couldn't determine the pattern content element root, stop here. - if (!m_attributes.patternContentElement()) - return false; - - // Compute all necessary transformations to build the tile image & the pattern. - FloatRect tileBoundaries; - AffineTransform tileImageTransform; - if (!buildTileImageTransform(object, m_attributes, patternElement, tileBoundaries, tileImageTransform)) - return false; - - AffineTransform absoluteTransformIgnoringRotation; - SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransformIgnoringRotation); - - // Ignore 2D rotation, as it doesn't affect the size of the tile. - SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation); - FloatRect absoluteTileBoundaries = absoluteTransformIgnoringRotation.mapRect(tileBoundaries); - FloatRect clampedAbsoluteTileBoundaries; - - // Scale the tile size to match the scale level of the patternTransform. - absoluteTileBoundaries.scale(static_cast<float>(m_attributes.patternTransform().xScale()), - static_cast<float>(m_attributes.patternTransform().yScale())); - - // Build tile image. - OwnPtr<ImageBuffer> tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries); - if (!tileImage) - return false; - - RefPtr<Image> copiedImage = tileImage->copyImage(CopyBackingStore); - if (!copiedImage) - return false; - - // Build pattern. - patternData->pattern = Pattern::create(copiedImage, true, true); - if (!patternData->pattern) - return false; - - // Compute pattern space transformation. - const IntSize tileImageSize = tileImage->logicalSize(); - patternData->transform.translate(tileBoundaries.x(), tileBoundaries.y()); - patternData->transform.scale(tileBoundaries.width() / tileImageSize.width(), tileBoundaries.height() / tileImageSize.height()); - - AffineTransform patternTransform = m_attributes.patternTransform(); - if (!patternTransform.isIdentity()) - patternData->transform = patternTransform * patternData->transform; - - // Account for text drawing resetting the context to non-scaled, see SVGInlineTextBox::paintTextWithShadows. - if (resourceMode & ApplyToTextMode) { - AffineTransform additionalTextTransformation; - if (shouldTransformOnTextPainting(object, additionalTextTransformation)) - patternData->transform *= additionalTextTransformation; - } - patternData->pattern->setPatternSpaceTransform(patternData->transform); - } + return false; // Draw pattern context->save(); diff --git a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h index 9e39383bd..d4da53567 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h +++ b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h @@ -66,6 +66,8 @@ private: const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform, FloatRect& clampedAbsoluteTileBoundaries) const; + PatternData* buildPattern(RenderObject*, unsigned short resourceMode); + bool m_shouldCollectPatternAttributes : 1; PatternAttributes m_attributes; HashMap<RenderObject*, OwnPtr<PatternData> > m_patternMap; diff --git a/Source/WebCore/svg/graphics/SVGImageCache.cpp b/Source/WebCore/svg/graphics/SVGImageCache.cpp index 358f2caa8..e5ae5a7e6 100644 --- a/Source/WebCore/svg/graphics/SVGImageCache.cpp +++ b/Source/WebCore/svg/graphics/SVGImageCache.cpp @@ -90,14 +90,9 @@ void SVGImageCache::imageContentChanged() for (ImageDataMap::iterator it = m_imageDataMap.begin(); it != end; ++it) it->value.imageNeedsUpdate = true; - // If we're in the middle of layout, start redrawing dirty - // images on a timer; otherwise it's safe to draw immediately. - FrameView* frameView = m_svgImage->frameView(); - if (frameView && (frameView->needsLayout() || frameView->isInLayout())) { - if (!m_redrawTimer.isActive()) - m_redrawTimer.startOneShot(0); - } else - redraw(); + // Always redraw on a timer because this method may be invoked from destructors of things we are intending to draw. + if (!m_redrawTimer.isActive()) + m_redrawTimer.startOneShot(0); } void SVGImageCache::redraw() diff --git a/Source/WebCore/xml/parser/XMLDocumentParser.cpp b/Source/WebCore/xml/parser/XMLDocumentParser.cpp index 5aa0e0890..6b8a0abfb 100644 --- a/Source/WebCore/xml/parser/XMLDocumentParser.cpp +++ b/Source/WebCore/xml/parser/XMLDocumentParser.cpp @@ -194,6 +194,11 @@ void XMLDocumentParser::end() doEnd(); + // doEnd() call above can detach the parser and null out its document. + // In that case, we just bail out. + if (isDetached()) + return; + // doEnd() could process a script tag, thus pausing parsing. if (m_parserPaused) return; diff --git a/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp b/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp index 7813ad308..173233a89 100644 --- a/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp +++ b/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp @@ -1338,8 +1338,13 @@ void XMLDocumentParser::doEnd() document()->setParsing(false); // Make the document think it's done, so it will apply XSL stylesheets. document()->styleResolverChanged(RecalcStyleImmediately); - document()->setParsing(true); + // styleResolverChanged() call can detach the parser and null out its document. + // In that case, we just bail out. + if (isDetached()) + return; + + document()->setParsing(true); DocumentParser::stopParsing(); } #endif diff --git a/Source/WebCore/xml/parser/XMLDocumentParserQt.cpp b/Source/WebCore/xml/parser/XMLDocumentParserQt.cpp index 9473ab795..63189da29 100644 --- a/Source/WebCore/xml/parser/XMLDocumentParserQt.cpp +++ b/Source/WebCore/xml/parser/XMLDocumentParserQt.cpp @@ -204,6 +204,12 @@ void XMLDocumentParser::doEnd() document()->setTransformSource(adoptPtr(new TransformSource(m_originalSourceForTransform.toString()))); document()->setParsing(false); // Make the doc think it's done, so it will apply xsl sheets. document()->styleResolverChanged(RecalcStyleImmediately); + + // styleResolverChanged() call can detach the parser and null out its document. + // In that case, we just bail out. + if (isDetached()) + return; + document()->setParsing(true); DocumentParser::stopParsing(); } diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog index 68e6531f0..fcbb3dd08 100644 --- a/Source/WebKit/ChangeLog +++ b/Source/WebKit/ChangeLog @@ -1,3 +1,15 @@ +2013-01-17 Poul Sysolyatin <psytonx@gmail.com> + + 32-bit build for Qt5 on Mac OS fails. + https://bugs.webkit.org/show_bug.cgi?id=107094 + + We need to define NS_BUILD_32_LIKE_64 for 32-bit build for Mac OS. + Fixed 32-bit build detection for support Qt5. + + Reviewed by Benjamin Poulain. + + * WebKit1.pro: + 2012-11-30 Simon Hausmann <simon.hausmann@digia.com>, Pierre Rossi <pierre.rossi@digia.com> [Qt] Separate Qt WebKit into Qt WebKit and Qt WebKit Widgets diff --git a/Source/WebKit/WebKit1.pro b/Source/WebKit/WebKit1.pro index ea854e6c8..244735b7d 100644 --- a/Source/WebKit/WebKit1.pro +++ b/Source/WebKit/WebKit1.pro @@ -123,8 +123,7 @@ enable?(VIDEO) { $$PWD/../../WebKitLibraries/ DEFINES += NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES - - contains(CONFIG, "x86") { + isEqual(QT_ARCH, "i386") { DEFINES+=NS_BUILD_32_LIKE_64 } diff --git a/Source/WebKit/qt/Api/qwebhistory.cpp b/Source/WebKit/qt/Api/qwebhistory.cpp index a945b592b..be0905eb7 100644 --- a/Source/WebKit/qt/Api/qwebhistory.cpp +++ b/Source/WebKit/qt/Api/qwebhistory.cpp @@ -35,10 +35,7 @@ #include <QSharedData> #include <QDebug> -enum { - InitialHistoryVersion = 1, - DefaultHistoryVersion = InitialHistoryVersion -}; +static const int HistoryStreamVersion = 2; /*! \class QWebHistoryItem @@ -496,7 +493,7 @@ QDataStream& operator<<(QDataStream& target, const QWebHistory& history) { QWebHistoryPrivate* d = history.d; - int version = DefaultHistoryVersion; + int version = HistoryStreamVersion; target << version; target << history.count() << history.currentItemIndex(); @@ -521,31 +518,42 @@ QDataStream& operator<<(QDataStream& target, const QWebHistory& history) QDataStream& operator>>(QDataStream& source, QWebHistory& history) { QWebHistoryPrivate* d = history.d; + // Clear first, to have the same behavior if our version doesn't match and if the HistoryItem's version doesn't. + history.clear(); + // This version covers every field we serialize in qwebhistory.cpp and HistoryItemQt.cpp (like the HistoryItem::userData()). + // HistoryItem has its own version in the stream covering the work done in encodeBackForwardTree. + // If any of those two stream version changes, the effect should be the same and the QWebHistory should fail to restore. int version; - source >> version; + if (version != HistoryStreamVersion) { + // We do not try to decode previous history stream versions. + // Make sure that our history is cleared and mark the rest of the stream as invalid. + ASSERT(history.count() == 1); + source.setStatus(QDataStream::ReadCorruptData); + return source; + } - if (version == 1) { - int count; - int currentIndex; - source >> count >> currentIndex; - - history.clear(); - // only if there are elements - if (count) { - // after clear() is new clear HistoryItem (at the end we had to remove it) - WebCore::HistoryItem* nullItem = d->lst->currentItem(); - for (int i = 0; i < count; i++) { - WTF::PassRefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(); - item->restoreState(source, version); - d->lst->addItem(item); + int count; + int currentIndex; + source >> count >> currentIndex; + + // only if there are elements + if (count) { + // after clear() is new clear HistoryItem (at the end we had to remove it) + WebCore::HistoryItem* nullItem = d->lst->currentItem(); + for (int i = 0; i < count; i++) { + WTF::RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::restoreState(source, version); + if (!item) { + // The HistoryItem internal version might have changed, do the same as when our own version change. + history.clear(); + source.setStatus(QDataStream::ReadCorruptData); + return source; } - d->lst->removeItem(nullItem); - // Update the HistoryController. - static_cast<WebCore::BackForwardListImpl*>(history.d->lst)->page()->mainFrame()->loader()->history()->setCurrentItem(history.d->lst->entries()[currentIndex].get()); - history.goToItem(history.itemAt(currentIndex)); + d->lst->addItem(item); } + d->lst->removeItem(nullItem); + history.goToItem(history.itemAt(currentIndex)); } d->page()->updateNavigationActions(); diff --git a/Source/WebKit/qt/ChangeLog b/Source/WebKit/qt/ChangeLog index 77eea541b..608c1003a 100644 --- a/Source/WebKit/qt/ChangeLog +++ b/Source/WebKit/qt/ChangeLog @@ -1,3 +1,110 @@ +2013-01-30 Allan Sandfeld Jensen <allan.jensen@digia.com> + + [Qt][WK1] Remember denied permission for notifications + https://bugs.webkit.org/show_bug.cgi?id=107694 + + Reviewed by Jocelyn Turcotte. + + Store denied permissions. According to the specification, we should + ask the user again if he has already granted or denied permission. + + * WebCoreSupport/NotificationPresenterClientQt.cpp: + (WebCore::NotificationPresenterClientQt::requestPermission): + (WebCore::NotificationPresenterClientQt::setNotificationsAllowedForFrame): + * WebCoreSupport/NotificationPresenterClientQt.h: + (NotificationPresenterClientQt): + * WebCoreSupport/QWebPageAdapter.cpp: + (QWebPageAdapter::setNotificationsAllowedForFrame): + * WebCoreSupport/QWebPageAdapter.h: + * WidgetApi/qwebpage.cpp: + (QWebPage::setFeaturePermission): + +2013-01-21 Allan Sandfeld Jensen <allan.jensen@digia.com> + + [Qt][WK1] Permission request callbacks for non-legacy notifications + https://bugs.webkit.org/show_bug.cgi?id=107438 + + Reviewed by Jocelyn Turcotte. + + Tracks the new callbacks the same way legacy callbacks are tracked. + + No test affected yet as we are still lacking support for testing + feature permission callbacks. + + * WebCoreSupport/NotificationPresenterClientQt.cpp: + (WebCore::NotificationPresenterClientQt::requestPermission): + (WebCore::NotificationPresenterClientQt::allowNotificationForFrame): + * WebCoreSupport/NotificationPresenterClientQt.h: + (NotificationPresenterClientQt): + (CallbacksInfo): + +2013-01-21 Allan Sandfeld Jensen <allan.jensen@digia.com> + + [Qt] Crash in gmail on enabling desktop notifications + https://bugs.webkit.org/show_bug.cgi?id=106699 + + Patch by David Rosca. + Reviewed by Jocelyn Turcotte. + + Protect against callback that may be null. This also matches WebKit2 behaviour. + + * WebCoreSupport/NotificationPresenterClientQt.cpp: + (WebCore::NotificationPresenterClientQt::allowNotificationForFrame): + +2013-01-21 Jocelyn Turcotte <jocelyn.turcotte@digia.com> + + [Qt] Update the documentation about the storage of inspector settings + https://bugs.webkit.org/show_bug.cgi?id=106777 + + Reviewed by Allan Sandfeld Jensen. + + Since r76770, QSettings isn't queried anymore to persist inspector + settings like whether or not the debugger is enabled by default. + It still seems to be used for the default attach height. + + Update the documentation accordingly. + + * WidgetApi/qwebinspector.cpp: + +2013-01-16 Jocelyn Turcotte <jocelyn.turcotte@digia.com> + + [Qt] Use the shared HistoryItem serialization for QWebHistory + https://bugs.webkit.org/show_bug.cgi?id=106671 + + Reviewed by Allan Sandfeld Jensen. + + Bump the serialization version and change the code to abort the + restore of a previous stream version rather than trying to keep the + support of restoring previous versions. This is mainly to simplify + things given that HistoryItem itself aborts in that case. + + * Api/qwebhistory.cpp: + (operator<<): + (operator>>): + * tests/qwebhistory/tst_qwebhistory.cpp: + (tst_QWebHistory::serialize_2): Modify the test to cover same-document navigations. + (tst_QWebHistory::restoreIncompatibleVersion1): Add a previous version + hard-coded stream to verify that the deserialization doesn't hang or + crash. + +2013-01-16 Jocelyn Turcotte <jocelyn.turcotte@digia.com> + + [Qt] Crash in WebCore::CachedFrame::destroy + https://bugs.webkit.org/show_bug.cgi?id=104525 + + Reviewed by Adam Barth. + + Remove the call to HistoryController::setCurrentItem which is ultimately + causing the initial empty document of a page to be added to the page cache. + + This re-introduce the bug that was fixed by this line, which will be + properly fixed in a follow-up patch. + + * Api/qwebhistory.cpp: + (operator>>): + * tests/qwebhistory/tst_qwebhistory.cpp: + (tst_QWebHistory::saveAndRestore_crash_4): Cover the crash. + 2013-01-07 Michael Brüning <michael.bruning@digia.com> [Qt] Apply correct patch for the scrolling issue from bug 105014 diff --git a/Source/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.cpp b/Source/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.cpp index 2f25b8960..f6816cf16 100644 --- a/Source/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.cpp @@ -304,18 +304,56 @@ void NotificationPresenterClientQt::notificationControllerDestroyed() { } +#if ENABLE(LEGACY_NOTIFICATIONS) void NotificationPresenterClientQt::requestPermission(ScriptExecutionContext* context, PassRefPtr<VoidCallback> callback) { if (dumpNotification) printf("DESKTOP NOTIFICATION PERMISSION REQUESTED: %s\n", QString(context->securityOrigin()->toString()).toUtf8().constData()); + NotificationClient::Permission permission = checkPermission(context); + if (permission != NotificationClient::PermissionNotAllowed) { + if (callback) + callback->handleEvent(); + return; + } + QHash<ScriptExecutionContext*, CallbacksInfo >::iterator iter = m_pendingPermissionRequests.find(context); if (iter != m_pendingPermissionRequests.end()) - iter.value().m_callbacks.append(callback); + iter.value().m_voidCallbacks.append(callback); else { RefPtr<VoidCallback> cb = callback; CallbacksInfo info; info.m_frame = toFrame(context); + info.m_voidCallbacks.append(cb); + + if (toPage(context) && toFrame(context)) { + m_pendingPermissionRequests.insert(context, info); + toPage(context)->notificationsPermissionRequested(toFrame(context)); + } + } +} +#endif + +#if ENABLE(NOTIFICATIONS) +void NotificationPresenterClientQt::requestPermission(ScriptExecutionContext* context, PassRefPtr<NotificationPermissionCallback> callback) +{ + if (dumpNotification) + printf("DESKTOP NOTIFICATION PERMISSION REQUESTED: %s\n", QString(context->securityOrigin()->toString()).toUtf8().constData()); + + NotificationClient::Permission permission = checkPermission(context); + if (permission != NotificationClient::PermissionNotAllowed) { + if (callback) + callback->handleEvent(Notification::permissionString(permission)); + return; + } + + QHash<ScriptExecutionContext*, CallbacksInfo >::iterator iter = m_pendingPermissionRequests.find(context); + if (iter != m_pendingPermissionRequests.end()) + iter.value().m_callbacks.append(callback); + else { + RefPtr<NotificationPermissionCallback> cb = callback; + CallbacksInfo info; + info.m_frame = toFrame(context); info.m_callbacks.append(cb); if (toPage(context) && toFrame(context)) { @@ -324,6 +362,7 @@ void NotificationPresenterClientQt::requestPermission(ScriptExecutionContext* co } } } +#endif NotificationClient::Permission NotificationPresenterClientQt::checkPermission(ScriptExecutionContext* context) { @@ -353,9 +392,14 @@ void NotificationPresenterClientQt::cancelRequestsForPermission(ScriptExecutionC page->notificationsPermissionRequestCancelled(frame); } -void NotificationPresenterClientQt::allowNotificationForFrame(Frame* frame) +void NotificationPresenterClientQt::setNotificationsAllowedForFrame(Frame* frame, bool allowed) { - m_cachedPermissions.insert(frame->document(), NotificationClient::PermissionAllowed); + ASSERT(frame->document()); + if (!frame->document()) + return; + + NotificationClient::Permission permission = allowed ? NotificationClient::PermissionAllowed : NotificationClient::PermissionDenied; + m_cachedPermissions.insert(frame->document(), permission); QHash<ScriptExecutionContext*, CallbacksInfo>::iterator iter = m_pendingPermissionRequests.begin(); while (iter != m_pendingPermissionRequests.end()) { @@ -366,11 +410,20 @@ void NotificationPresenterClientQt::allowNotificationForFrame(Frame* frame) if (iter == m_pendingPermissionRequests.end()) return; - QList<RefPtr<VoidCallback> >& callbacks = iter.value().m_callbacks; - Q_FOREACH(const RefPtr<VoidCallback>& callback, callbacks) { +#if ENABLE(LEGACY_NOTIFICATIONS) + QList<RefPtr<VoidCallback> >& voidCallbacks = iter.value().m_voidCallbacks; + Q_FOREACH(const RefPtr<VoidCallback>& callback, voidCallbacks) { if (callback) callback->handleEvent(); } +#endif +#if ENABLE(NOTIFICATIONS) + QList<RefPtr<NotificationPermissionCallback> >& callbacks = iter.value().m_callbacks; + Q_FOREACH(const RefPtr<NotificationPermissionCallback>& callback, callbacks) { + if (callback) + callback->handleEvent(Notification::permissionString(permission)); + } +#endif m_pendingPermissionRequests.remove(iter.key()); } diff --git a/Source/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.h b/Source/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.h index 78668f35f..470c0b4c1 100644 --- a/Source/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.h +++ b/Source/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.h @@ -94,14 +94,14 @@ public: virtual void requestPermission(ScriptExecutionContext*, PassRefPtr<VoidCallback>); #endif #if ENABLE(NOTIFICATIONS) - virtual void requestPermission(ScriptExecutionContext*, PassRefPtr<NotificationPermissionCallback>) { } + virtual void requestPermission(ScriptExecutionContext*, PassRefPtr<NotificationPermissionCallback>); #endif virtual NotificationClient::Permission checkPermission(ScriptExecutionContext*); virtual void cancelRequestsForPermission(ScriptExecutionContext*); void cancel(NotificationWrapper*); - void allowNotificationForFrame(Frame*); + void setNotificationsAllowedForFrame(Frame*, bool allowed); static bool dumpNotification; @@ -131,7 +131,12 @@ private: int m_clientCount; struct CallbacksInfo { QWebFrameAdapter* m_frame; - QList<RefPtr<VoidCallback> > m_callbacks; +#if ENABLE(LEGACY_NOTIFICATIONS) + QList<RefPtr<VoidCallback> > m_voidCallbacks; +#endif +#if ENABLE(NOTIFICATIONS) + QList<RefPtr<NotificationPermissionCallback> > m_callbacks; +#endif }; QHash<ScriptExecutionContext*, CallbacksInfo > m_pendingPermissionRequests; QHash<ScriptExecutionContext*, NotificationClient::Permission> m_cachedPermissions; diff --git a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp index 5588c11bb..ae01f4b1e 100644 --- a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp +++ b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp @@ -1227,9 +1227,9 @@ QString QWebPageAdapter::contextMenuItemTagForAction(QWebPageAdapter::MenuAction } #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) -void QWebPageAdapter::allowNotificationsForFrame(QWebFrameAdapter* frame) +void QWebPageAdapter::setNotificationsAllowedForFrame(QWebFrameAdapter* frame, bool allowed) { - NotificationPresenterClientQt::notificationPresenter()->allowNotificationForFrame(frame->frame); + NotificationPresenterClientQt::notificationPresenter()->setNotificationsAllowedForFrame(frame->frame, allowed); } void QWebPageAdapter::addNotificationPresenterClient() diff --git a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h index dbba7f5b2..438a7651d 100644 --- a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h +++ b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h @@ -311,7 +311,7 @@ public: void setGeolocationEnabledForFrame(QWebFrameAdapter*, bool); #endif #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) - void allowNotificationsForFrame(QWebFrameAdapter*); + void setNotificationsAllowedForFrame(QWebFrameAdapter*, bool allowed); void addNotificationPresenterClient(); #ifndef QT_NO_SYSTEMTRAYICON bool hasSystemTrayIcon() const; diff --git a/Source/WebKit/qt/WidgetApi/qwebinspector.cpp b/Source/WebKit/qt/WidgetApi/qwebinspector.cpp index 9ae69dacf..9e3f82e69 100644 --- a/Source/WebKit/qt/WidgetApi/qwebinspector.cpp +++ b/Source/WebKit/qt/WidgetApi/qwebinspector.cpp @@ -66,11 +66,13 @@ The inspector allows the user to configure some options through its user interface (e.g. the resource tracking "Always enable" option). - These settings will be persisted automatically by QtWebKit only if - your application previously called QCoreApplication::setOrganizationName() - and QCoreApplication::setApplicationName(). - See QSettings's default constructor documentation for an explanation - of why this is necessary. + The inspector UI is itself a web page and is using HTML local storage + to persist those settings. + Since the internal QWebPage used by the inspector isn't exposed in the API, + the only way to enable those settings to be persisted is currently to enable + local storage globally through QWebSettings::globalSettings(). + + \sa QWebSettings::localStoragePath(), QWebSettings::LocalStorageEnabled */ /*! diff --git a/Source/WebKit/qt/WidgetApi/qwebpage.cpp b/Source/WebKit/qt/WidgetApi/qwebpage.cpp index f9cec3e54..a1fe49e13 100644 --- a/Source/WebKit/qt/WidgetApi/qwebpage.cpp +++ b/Source/WebKit/qt/WidgetApi/qwebpage.cpp @@ -1584,11 +1584,15 @@ bool QWebPage::shouldInterruptJavaScript() void QWebPage::setFeaturePermission(QWebFrame* frame, Feature feature, PermissionPolicy policy) { +#if !ENABLE(NOTIFICATIONS) && !ENABLE(LEGACY_NOTIFICATIONS) && !ENABLE(GEOLOCATION) + Q_UNUSED(frame); + Q_UNUSED(policy); +#endif switch (feature) { case Notifications: #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) - if (policy == PermissionGrantedByUser) - d->allowNotificationsForFrame(frame->d); + if (policy != PermissionUnknown) + d->setNotificationsAllowedForFrame(frame->d, (policy == PermissionGrantedByUser)); #endif break; case Geolocation: diff --git a/Source/WebKit/qt/tests/qgraphicswebview/resources/scrolltest_page.html b/Source/WebKit/qt/tests/qgraphicswebview/resources/scrolltest_page.html new file mode 100644 index 000000000..18fcbbebe --- /dev/null +++ b/Source/WebKit/qt/tests/qgraphicswebview/resources/scrolltest_page.html @@ -0,0 +1,6 @@ +<html> +<head><title>Scrolling test</title></head> +<body> + <div style="width: 1000px; height: 1000px; background-color: green"/> +</body> +</html> diff --git a/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp b/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp index c0d9d8ec2..4c839fec3 100644 --- a/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp +++ b/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp @@ -56,12 +56,16 @@ private Q_SLOTS: void serialize_1(); //QWebHistory countity void serialize_2(); //QWebHistory index void serialize_3(); //QWebHistoryItem + // Those tests shouldn't crash void saveAndRestore_crash_1(); void saveAndRestore_crash_2(); void saveAndRestore_crash_3(); + void saveAndRestore_crash_4(); + void popPushState_data(); void popPushState(); void clear(); + void restoreIncompatibleVersion1(); private: @@ -234,16 +238,20 @@ void tst_QWebHistory::serialize_2() QDataStream save(&tmp, QIODevice::WriteOnly); //here data will be saved QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded - int oldCurrentIndex = hist->currentItemIndex(); + // Force a "same document" navigation. + frame->load(frame->url().toString() + QLatin1String("#dummyAnchor")); + + int initialCurrentIndex = hist->currentItemIndex(); hist->back(); + hist->back(); waitForLoadFinished.exec(); hist->back(); waitForLoadFinished.exec(); //check if current index was changed (make sure that it is not last item) - QVERIFY(hist->currentItemIndex() != oldCurrentIndex); + QVERIFY(hist->currentItemIndex() != initialCurrentIndex); //save current index - oldCurrentIndex = hist->currentItemIndex(); + int oldCurrentIndex = hist->currentItemIndex(); save << *hist; QVERIFY(save.status() == QDataStream::Ok); @@ -252,6 +260,13 @@ void tst_QWebHistory::serialize_2() //check current index QCOMPARE(hist->currentItemIndex(), oldCurrentIndex); + + hist->forward(); + waitForLoadFinished.exec(); + hist->forward(); + waitForLoadFinished.exec(); + hist->forward(); + QCOMPARE(hist->currentItemIndex(), initialCurrentIndex); } /** @@ -308,7 +323,6 @@ static void restoreHistory(QWebHistory* history, QByteArray* out) load >> *history; } -/** The test shouldn't crash */ void tst_QWebHistory::saveAndRestore_crash_1() { QByteArray buffer; @@ -319,7 +333,6 @@ void tst_QWebHistory::saveAndRestore_crash_1() } } -/** The test shouldn't crash */ void tst_QWebHistory::saveAndRestore_crash_2() { QByteArray buffer; @@ -333,7 +346,6 @@ void tst_QWebHistory::saveAndRestore_crash_2() delete page2; } -/** The test shouldn't crash */ void tst_QWebHistory::saveAndRestore_crash_3() { QByteArray buffer; @@ -353,6 +365,27 @@ void tst_QWebHistory::saveAndRestore_crash_3() delete page2; } +void tst_QWebHistory::saveAndRestore_crash_4() +{ + QByteArray buffer; + saveHistory(hist, &buffer); + + QWebPage* page2 = new QWebPage(this); + // The initial crash was in PageCache. + page2->settings()->setMaximumPagesInCache(3); + + // Load the history in a new page, waiting for the load to finish. + QEventLoop waitForLoadFinished; + QObject::connect(page2, SIGNAL(loadFinished(bool)), &waitForLoadFinished, SLOT(quit()), Qt::QueuedConnection); + QDataStream load(&buffer, QIODevice::ReadOnly); + load >> *page2->history(); + waitForLoadFinished.exec(); + + delete page2; + // Give some time for the PageCache cleanup 0-timer to fire. + QTest::qWait(50); +} + void tst_QWebHistory::popPushState_data() { QTest::addColumn<QString>("script"); @@ -393,5 +426,99 @@ void tst_QWebHistory::clear() delete page2; } +// static void dumpCurrentVersion(QWebHistory* history) +// { +// QByteArray buffer; +// saveHistory(history, &buffer); +// printf(" static const char version1Dump[] = {"); +// for (int i = 0; i < buffer.size(); ++i) { +// bool newLine = !(i % 15); +// bool last = i == buffer.size() - 1; +// printf("%s0x%.2x%s", newLine ? "\n " : "", (unsigned char)buffer[i], last ? "" : ", "); +// } +// printf("};\n"); +// } + +void tst_QWebHistory::restoreIncompatibleVersion1() +{ + // Uncomment this code to generate a dump similar to the one below with the current stream version. + // dumpCurrentVersion(hist); + static const char version1Dump[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, 0x65, + 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, + 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x68, + 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x61, 0x00, + 0x67, 0x00, 0x65, 0x00, 0x31, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, + 0x2f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, + 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, + 0x31, 0x00, 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, + 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, 0x65, 0x00, + 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, + 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x68, 0x00, + 0x74, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, + 0x00, 0x65, 0x00, 0x32, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, + 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, + 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x32, + 0x00, 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, + 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, + 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, + 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x33, 0x00, 0x2e, 0x00, 0x68, 0x00, 0x74, + 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, + 0x65, 0x00, 0x33, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, + 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, + 0x00, 0x73, 0x00, 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x33, 0x00, + 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x71, + 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, + 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x70, + 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x34, 0x00, 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, + 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, + 0x00, 0x34, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, + 0x00, 0x65, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, + 0x73, 0x00, 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x34, 0x00, 0x2e, + 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x71, 0x00, + 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6f, + 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x70, 0x00, + 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, + 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, + 0x35, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, + 0x65, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, + 0x00, 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x35, 0x00, 0x2e, 0x00, + 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + QByteArray version1(version1Dump, sizeof(version1Dump)); + QDataStream stream(&version1, QIODevice::ReadOnly); + + // This should fail to load, the history should be cleared and the stream should be broken. + stream >> *hist; + QVERIFY(!hist->canGoBack()); + QVERIFY(!hist->canGoForward()); + QVERIFY(stream.status() == QDataStream::ReadCorruptData); +} + QTEST_MAIN(tst_QWebHistory) #include "tst_qwebhistory.moc" diff --git a/Source/WebKit/qt/tests/qwebview/resources/scrolltest_page.html b/Source/WebKit/qt/tests/qwebview/resources/scrolltest_page.html new file mode 100644 index 000000000..18fcbbebe --- /dev/null +++ b/Source/WebKit/qt/tests/qwebview/resources/scrolltest_page.html @@ -0,0 +1,6 @@ +<html> +<head><title>Scrolling test</title></head> +<body> + <div style="width: 1000px; height: 1000px; background-color: green"/> +</body> +</html> diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog index 64e7283e3..f6c99bedf 100644 --- a/Source/WebKit2/ChangeLog +++ b/Source/WebKit2/ChangeLog @@ -1,3 +1,133 @@ +2013-01-24 Michael Brüning <michael.bruning@digia.com> + + [Qt][WK2] Pages / resources cannot be loaded from qrc files. + https://bugs.webkit.org/show_bug.cgi?id=107031 + + Reviewed by Jocelyn Turcotte. + + Enables WebKit2 Qt applications to load files from the bundled + qrc files. This is achieved by adding a url scheme handler for + the "qrc" scheme using the application scheme handler and ignoring + all handlers for the qrc application scheme that the application might + set. + + * UIProcess/API/qt/qquickurlschemedelegate.cpp: + (QQuickQrcSchemeDelegate::QQuickQrcSchemeDelegate): + (QQuickQrcSchemeDelegate::readResourceAndSend): + * UIProcess/API/qt/qquickurlschemedelegate_p.h: + (QQuickQrcSchemeDelegate): + * UIProcess/API/qt/qquickwebview.cpp: + (QQuickWebViewPrivate::initialize): + (QQuickWebViewExperimental::schemeDelegates_Append): + (QQuickWebViewExperimental::invokeApplicationSchemeHandler): + * UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml: + * UIProcess/API/qt/tests/qmltests/common/qrctest.html: Added. + * UIProcess/API/qt/tests/qmltests/resources.qrc: + + (WebKit::NetworkResourceLoader::connectionToWebProcessDidClose): + * NetworkProcess/NetworkResourceLoader.h: + +2013-01-17 Poul Sysolyatin <psytonx@gmail.com> + + 32-bit build for Qt5 on Mac OS fails. + https://bugs.webkit.org/show_bug.cgi?id=107094 + + We need to define NS_BUILD_32_LIKE_64 for 32-bit build for Mac OS. + Fixed 32-bit build detection for support Qt5. + + Reviewed by Benjamin Poulain. + + * Target.pri: + +2013-01-09 Andras Becsi <andras.becsi@digia.com> + + [Qt][EFL][WK2] Remove redundant device pixel ratio adjustment from PageViewportController + https://bugs.webkit.org/show_bug.cgi?id=106355 + + Reviewed by Kenneth Rohde Christiansen. + + Since r137597 Qt uses the device pixel ratio of the underlying + platform window as the device pixel ratio in WebCore. + The tiles are rendered with the effective scale (scale adjusted with + the device scale factor) and the projection matrix is also adjusted + with the device pixel ratio when painting. + As a result we can follow the same approach as QtQuick and all the + coordinates in PageViewportController need to be in device independent + pixels (UI pixels) thus we do no longer need to adjust with the device + pixel ratio when calculating the viewport attributes. + This simplifies the logic significantly and increases robustness, + but does not allow to set a custom device pixel ratio different from + the factor of the underlying platform (eg. for testing purposes). + This patch is conceptually a follow-up of r137597 and fixes layout + and canvas size on retina display. + + * UIProcess/PageViewportController.cpp: + (WebKit::PageViewportController::PageViewportController): + (WebKit::PageViewportController::innerBoundedViewportScale): + (WebKit::PageViewportController::outerBoundedViewportScale): + (WebKit::PageViewportController::pixelAlignedFloatPoint): + (WebKit::PageViewportController::boundContentsPosition): + (WebKit::PageViewportController::didRenderFrame): + (WebKit::PageViewportController::pageTransitionViewportReady): + (WebKit::PageViewportController::didChangeContentsVisibility): + (WebKit::PageViewportController::syncVisibleContents): + (WebKit::PageViewportController::visibleContentsSize): + (WebKit::PageViewportController::applyScaleAfterRenderingContents): + (WebKit::PageViewportController::updateMinimumScaleToFit): + * UIProcess/PageViewportController.h: + (WebKit::PageViewportController::currentContentsScale): + (PageViewportController): + * UIProcess/efl/PageViewportControllerClientEfl.cpp: + (WebKit::PageViewportControllerClientEfl::updateViewportSize): + Adjust the viewport size with the device pixel ratio to keep previous + behaviour. + * UIProcess/qt/PageViewportControllerClientQt.cpp: + (WebKit::PageViewportControllerClientQt::focusEditableArea): + (WebKit::PageViewportControllerClientQt::zoomToAreaGestureEnded): + * UIProcess/qt/QtWebPageSGNode.cpp: + (WebKit::ContentsSGNode::clipRect): + * WebProcess/WebPage/WebPage.cpp: + (WebKit::WebPage::sendViewportAttributesChanged): + +2013-01-03 Jocelyn Turcotte <jocelyn.turcotte@digia.com> + + [Qt] Fix a crash when the QQuickWebPage is destroyed between the scene graph sync and render. + https://bugs.webkit.org/show_bug.cgi?id=106018 + + Reviewed by Simon Hausmann. + + The main and rendering threads are only guaranteed to be synchronised in + the updatePaintNode call. In every other cases, QQuickItems cannot be + safely accessed from the rendering thread. + + Do as the first patch version in + https://bugs.webkit.org/show_bug.cgi?id=104574 was doing and copy the + ratio value directly to fix the issue. + + Also add a note about the threading issue in QQuickWebPage::updatePaintNode. + + * UIProcess/API/qt/qquickwebpage.cpp: + (QQuickWebPage::updatePaintNode): + * UIProcess/qt/QtWebPageSGNode.cpp: + (WebKit::QtWebPageSGNode::QtWebPageSGNode): + * UIProcess/qt/QtWebPageSGNode.h: + (QtWebPageSGNode): + (WebKit::QtWebPageSGNode::devicePixelRatio): + (WebKit::QtWebPageSGNode::setDevicePixelRatio): + +2012-12-19 Kenneth Rohde Christiansen <kenneth@webkit.org> + + [EFL][Qt][WK2] Going back to 47-amazing-css3-animation-demos shows nothing or wrong position + https://bugs.webkit.org/show_bug.cgi?id=104414 + + Reviewed by Simon Hausmann. + + When contents size changes, make sure to apply any pending position + change if possible. + + * UIProcess/PageViewportController.cpp: + (WebKit::PageViewportController::didChangeContentsSize): + 2012-12-13 Andras Becsi <andras.becsi@digia.com> [Qt][WK2] Fix painting on Mac with retina display diff --git a/Source/WebKit2/Target.pri b/Source/WebKit2/Target.pri index 098b5b954..aeefadee7 100644 --- a/Source/WebKit2/Target.pri +++ b/Source/WebKit2/Target.pri @@ -866,6 +866,9 @@ have?(QTQUICK) { mac: { use?(QTKIT) { DEFINES += NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES + isEqual(QT_ARCH, "i386") { + DEFINES+=NS_BUILD_32_LIKE_64 + } INCLUDEPATH += \ $$PWD/../../WebKitLibraries/ HEADERS += \ diff --git a/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate.cpp b/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate.cpp index e5d63043b..19f14d5c4 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate.cpp @@ -24,6 +24,10 @@ #include "qquicknetworkreply_p.h" #include "qquicknetworkrequest_p.h" +#include <QtCore/QFile> +#include <QtCore/QFileInfo> +#include <QtCore/QMimeDatabase> + QQuickUrlSchemeDelegate::QQuickUrlSchemeDelegate(QObject* parent) : QObject(parent) , m_request(new QQuickNetworkRequest(this)) @@ -51,4 +55,27 @@ QQuickNetworkReply* QQuickUrlSchemeDelegate::reply() const return m_reply; } +QQuickQrcSchemeDelegate::QQuickQrcSchemeDelegate(const QUrl& url) + : QQuickUrlSchemeDelegate() + , m_fileName(QLatin1Char(':') + url.path()) +{ +} + +void QQuickQrcSchemeDelegate::readResourceAndSend() +{ + QFile file(m_fileName); + QFileInfo fileInfo(file); + if (fileInfo.isDir() || !file.open(QIODevice::ReadOnly | QIODevice::Unbuffered)) + return; + + QByteArray fileData(file.readAll()); + QMimeDatabase mimeDb; + QMimeType mimeType = mimeDb.mimeTypeForFileNameAndData(m_fileName, fileData); + file.close(); + + reply()->setData(fileData); + reply()->setContentType(mimeType.name()); + reply()->send(); +} + #include "moc_qquickurlschemedelegate_p.cpp" diff --git a/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate_p.h b/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate_p.h index 6ee602754..596d3c266 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate_p.h @@ -23,6 +23,7 @@ #include "qwebkitglobal.h" #include <QObject> +#include <QtCore/QUrl> #include <QtQuick/qquickitem.h> class QQuickNetworkRequest; @@ -53,6 +54,16 @@ private: QML_DECLARE_TYPE(QQuickUrlSchemeDelegate) +class QQuickQrcSchemeDelegate : public QQuickUrlSchemeDelegate { + Q_OBJECT +public: + QQuickQrcSchemeDelegate(const QUrl& url); + void readResourceAndSend(); + +private: + QString m_fileName; +}; + #endif // qquickurlschemedelegate_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp index 437d08b94..bf742ad11 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp @@ -323,6 +323,7 @@ void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pa pageClient.initialize(q_ptr, pageViewPrivate->eventHandler.data(), &undoController); webPageProxy->initializeWebPage(); + webPageProxy->registerApplicationScheme(ASCIILiteral("qrc")); q_ptr->setAcceptedMouseButtons(Qt::MouseButtonMask); q_ptr->setAcceptHoverEvents(true); @@ -1291,6 +1292,12 @@ QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QQmlListP void QQuickWebViewExperimental::schemeDelegates_Append(QQmlListProperty<QQuickUrlSchemeDelegate>* property, QQuickUrlSchemeDelegate *scheme) { + if (!scheme->scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive)) { + qWarning("WARNING: The qrc scheme is reserved to be handled internally. The handler will be ignored."); + delete scheme; + return; + } + QObject* schemeParent = property->object; scheme->setParent(schemeParent); QQuickWebViewExperimental* webViewExperimental = qobject_cast<QQuickWebViewExperimental*>(property->object->parent()); @@ -1328,6 +1335,15 @@ QQmlListProperty<QQuickUrlSchemeDelegate> QQuickWebViewExperimental::schemeDeleg void QQuickWebViewExperimental::invokeApplicationSchemeHandler(PassRefPtr<QtRefCountedNetworkRequestData> request) { RefPtr<QtRefCountedNetworkRequestData> req = request; + if (req->data().m_scheme.startsWith("qrc", false)) { + QQuickQrcSchemeDelegate qrcDelegate(QUrl(QString(req->data().m_urlString))); + qrcDelegate.request()->setNetworkRequestData(req); + qrcDelegate.reply()->setNetworkRequestData(req); + qrcDelegate.reply()->setWebViewExperimental(this); + qrcDelegate.readResourceAndSend(); + return; + } + const QObjectList children = schemeParent->children(); for (int index = 0; index < children.count(); index++) { QQuickUrlSchemeDelegate* delegate = qobject_cast<QQuickUrlSchemeDelegate*>(children.at(index)); diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml index 4fe081298..e561e1a32 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml @@ -113,5 +113,13 @@ TestWebView { verify(webView.waitForLoadSucceeded()) compare(webView.title, "title with copyright ©") } + + function test_qrcScheme() { + var testUrl = "qrc:///common/qrctest.html" + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) + compare(webView.title, "Loaded from qrc.") + + } } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/qrctest.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/qrctest.html new file mode 100644 index 000000000..98f25fb7e --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/qrctest.html @@ -0,0 +1,6 @@ +<html> +<head><title>Loaded from qrc.</title></head> +<body> +Hello. I was loaded from a qrc file. Amazing. +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/resources.qrc b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/resources.qrc index 1696aaac1..f251865ef 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/resources.qrc +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/resources.qrc @@ -1,5 +1,6 @@ <RCC> <qresource prefix="/"> <file>common/change-document-title.js</file> + <file>common/qrctest.html</file> </qresource> </RCC> diff --git a/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.cpp b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.cpp index 71c4bcbd6..0e88379bf 100644 --- a/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.cpp +++ b/Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.cpp @@ -661,7 +661,9 @@ void LayerTreeRenderer::purgeGLResources() m_surfaceBackingStores.clear(); #endif - m_rootLayer->removeAllChildren(); + if (m_rootLayer) { + m_rootLayer->removeAllChildren(); + } m_rootLayer.clear(); m_rootLayerID = InvalidWebLayerID; m_layers.clear(); diff --git a/Source/WebKit2/UIProcess/PageViewportController.cpp b/Source/WebKit2/UIProcess/PageViewportController.cpp index 8d4bc0176..05ff8b98a 100644 --- a/Source/WebKit2/UIProcess/PageViewportController.cpp +++ b/Source/WebKit2/UIProcess/PageViewportController.cpp @@ -47,9 +47,9 @@ PageViewportController::PageViewportController(WebKit::WebPageProxy* proxy, Page , m_initiallyFitToViewport(true) , m_hasSuspendedContent(false) , m_hadUserInteraction(false) - , m_effectiveScale(1) + , m_pageScaleFactor(1) , m_viewportPosIsLocked(false) - , m_effectiveScaleIsLocked(false) + , m_pageScaleFactorIsLocked(false) { // Initializing Viewport Raw Attributes to avoid random negative or infinity scale factors // if there is a race condition between the first layout and setting the viewport attributes for the first time. @@ -68,15 +68,15 @@ PageViewportController::PageViewportController(WebKit::WebPageProxy* proxy, Page float PageViewportController::innerBoundedViewportScale(float viewportScale) const { - return clampTo(viewportScale, toViewportScale(m_minimumScaleToFit), toViewportScale(m_rawAttributes.maximumScale)); + return clampTo(viewportScale, m_minimumScaleToFit, m_rawAttributes.maximumScale); } float PageViewportController::outerBoundedViewportScale(float viewportScale) const { if (m_allowsUserScaling) { // Bounded by [0.1, 10.0] like the viewport meta code in WebCore. - float hardMin = toViewportScale(std::max<float>(0.1, 0.5 * m_minimumScaleToFit)); - float hardMax = toViewportScale(std::min<float>(10, 2 * m_rawAttributes.maximumScale)); + float hardMin = std::max<float>(0.1, 0.5 * m_minimumScaleToFit); + float hardMax = std::min<float>(10, 2 * m_rawAttributes.maximumScale); return clampTo(viewportScale, hardMin, hardMax); } return innerBoundedViewportScale(viewportScale); @@ -122,6 +122,9 @@ void PageViewportController::didChangeContentsSize(const IntSize& newSize) if (minimumScaleUpdated) m_client->didChangeViewportAttributes(); + + // We might have pending position change which is now possible. + syncVisibleContents(); } void PageViewportController::didRenderFrame(const IntSize& contentsSize, const IntRect& coveredRect) @@ -142,12 +145,12 @@ void PageViewportController::didRenderFrame(const IntSize& contentsSize, const I // All position and scale changes resulting from a web process event should // go through here to be applied on the viewport to avoid showing incomplete // tiles to the user during a few milliseconds. - if (m_effectiveScaleIsLocked) { - m_client->setContentsScale(m_effectiveScale, false); - m_effectiveScaleIsLocked = false; + if (m_pageScaleFactorIsLocked) { + m_client->setContentsScale(m_pageScaleFactor, false); + m_pageScaleFactorIsLocked = false; } if (m_viewportPosIsLocked) { - FloatPoint clampedPos = clampViewportToContents(m_viewportPos, m_effectiveScale); + FloatPoint clampedPos = clampViewportToContents(m_viewportPos, m_pageScaleFactor); // There might be rendered frames not covering our requested position yet, wait for it. if (FloatRect(clampedPos, viewportSizeInContentsCoordinates()).intersects(coveredRect)) { m_client->setViewportPosition(clampedPos); @@ -161,7 +164,7 @@ void PageViewportController::pageTransitionViewportReady() if (!m_rawAttributes.layoutSize.isEmpty()) { m_hadUserInteraction = false; float initialScale = m_initiallyFitToViewport ? m_minimumScaleToFit : m_rawAttributes.initialScale; - applyScaleAfterRenderingContents(innerBoundedViewportScale(toViewportScale(initialScale))); + applyScaleAfterRenderingContents(innerBoundedViewportScale(initialScale)); } // At this point we should already have received the first viewport arguments and the requested scroll @@ -177,7 +180,7 @@ void PageViewportController::pageDidRequestScroll(const IntPoint& cssPosition) if (m_hasSuspendedContent) return; - FloatRect endVisibleContentRect(clampViewportToContents(cssPosition, m_effectiveScale), viewportSizeInContentsCoordinates()); + FloatRect endVisibleContentRect(clampViewportToContents(cssPosition, m_pageScaleFactor), viewportSizeInContentsCoordinates()); if (m_lastFrameCoveredRect.intersects(endVisibleContentRect)) m_client->setViewportPosition(endVisibleContentRect.location()); else @@ -201,8 +204,8 @@ void PageViewportController::didChangeContentsVisibility(const FloatPoint& viewp { if (!m_viewportPosIsLocked) m_viewportPos = viewportPos; - if (!m_effectiveScaleIsLocked) - m_effectiveScale = viewportScale; + if (!m_pageScaleFactorIsLocked) + m_pageScaleFactor = viewportScale; syncVisibleContents(trajectoryVector); } @@ -213,9 +216,9 @@ void PageViewportController::syncVisibleContents(const FloatPoint& trajectoryVec if (!drawingArea || m_viewportSize.isEmpty() || m_contentsSize.isEmpty()) return; - FloatRect visibleContentsRect(clampViewportToContents(m_viewportPos, m_effectiveScale), viewportSizeInContentsCoordinates()); + FloatRect visibleContentsRect(clampViewportToContents(m_viewportPos, m_pageScaleFactor), viewportSizeInContentsCoordinates()); visibleContentsRect.intersect(FloatRect(FloatPoint::zero(), m_contentsSize)); - drawingArea->setVisibleContentsRect(visibleContentsRect, m_effectiveScale, trajectoryVector); + drawingArea->setVisibleContentsRect(visibleContentsRect, m_pageScaleFactor, trajectoryVector); m_client->didChangeVisibleContents(); } @@ -240,7 +243,7 @@ void PageViewportController::didChangeViewportAttributes(const WebCore::Viewport WebCore::FloatSize PageViewportController::viewportSizeInContentsCoordinates() const { - return WebCore::FloatSize(m_viewportSize.width() / m_effectiveScale, m_viewportSize.height() / m_effectiveScale); + return WebCore::FloatSize(m_viewportSize.width() / m_pageScaleFactor, m_viewportSize.height() / m_pageScaleFactor); } void PageViewportController::suspendContent() @@ -265,8 +268,8 @@ void PageViewportController::resumeContent() void PageViewportController::applyScaleAfterRenderingContents(float scale) { - m_effectiveScale = scale; - m_effectiveScaleIsLocked = true; + m_pageScaleFactor = scale; + m_pageScaleFactorIsLocked = true; syncVisibleContents(); } @@ -282,9 +285,9 @@ bool PageViewportController::updateMinimumScaleToFit(bool userInitiatedUpdate) if (m_viewportSize.isEmpty() || m_contentsSize.isEmpty()) return false; - bool currentlyScaledToFit = fuzzyCompare(m_effectiveScale, toViewportScale(m_minimumScaleToFit), 0.001); + bool currentlyScaledToFit = fuzzyCompare(m_pageScaleFactor, m_minimumScaleToFit, 0.001); - float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(m_rawAttributes, WebCore::roundedIntSize(m_viewportSize), WebCore::roundedIntSize(m_contentsSize), devicePixelRatio()); + float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(m_rawAttributes, WebCore::roundedIntSize(m_viewportSize), WebCore::roundedIntSize(m_contentsSize), 1); if (minimumScale <= 0) return false; @@ -294,11 +297,11 @@ bool PageViewportController::updateMinimumScaleToFit(bool userInitiatedUpdate) if (!hasSuspendedContent()) { if (!m_hadUserInteraction || (userInitiatedUpdate && currentlyScaledToFit)) - applyScaleAfterRenderingContents(toViewportScale(m_minimumScaleToFit)); + applyScaleAfterRenderingContents(m_minimumScaleToFit); else { // Ensure the effective scale stays within bounds. - float boundedScale = innerBoundedViewportScale(m_effectiveScale); - if (!fuzzyCompare(boundedScale, m_effectiveScale, 0.001)) + float boundedScale = innerBoundedViewportScale(m_pageScaleFactor); + if (!fuzzyCompare(boundedScale, m_pageScaleFactor, 0.001)) applyScaleAfterRenderingContents(boundedScale); } } diff --git a/Source/WebKit2/UIProcess/PageViewportController.h b/Source/WebKit2/UIProcess/PageViewportController.h index 029228dde..dadbbbefe 100644 --- a/Source/WebKit2/UIProcess/PageViewportController.h +++ b/Source/WebKit2/UIProcess/PageViewportController.h @@ -62,7 +62,7 @@ public: float devicePixelRatio() const; float minimumContentsScale() const { return m_minimumScaleToFit; } float maximumContentsScale() const { return m_rawAttributes.maximumScale; } - float currentContentsScale() const { return fromViewportScale(m_effectiveScale); } + float currentContentsScale() const { return m_pageScaleFactor; } void setHadUserInteraction(bool didUserInteract) { m_hadUserInteraction = didUserInteract; } @@ -79,8 +79,6 @@ public: void pageDidRequestScroll(const WebCore::IntPoint& cssPosition); private: - float fromViewportScale(float scale) const { return scale / devicePixelRatio(); } - float toViewportScale(float scale) const { return scale * devicePixelRatio(); } void syncVisibleContents(const WebCore::FloatPoint &trajectoryVector = WebCore::FloatPoint::zero()); void applyScaleAfterRenderingContents(float scale); void applyPositionAfterRenderingContents(const WebCore::FloatPoint& pos); @@ -103,10 +101,10 @@ private: WebCore::FloatSize m_viewportSize; WebCore::FloatSize m_contentsSize; WebCore::IntSize m_clientContentsSize; - float m_effectiveScale; // Should always be cssScale * devicePixelRatio. + float m_pageScaleFactor; bool m_viewportPosIsLocked; - bool m_effectiveScaleIsLocked; + bool m_pageScaleFactorIsLocked; WebCore::FloatRect m_lastFrameCoveredRect; }; diff --git a/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp b/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp index b8ccd977b..c0eb16ab9 100644 --- a/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp +++ b/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp @@ -46,7 +46,7 @@ PageViewportControllerClientQt::PageViewportControllerClientQt(QQuickWebView* vi , m_lastCommittedScale(-1) , m_zoomOutScale(0) , m_isUserInteracting(false) - , m_ignoreViewportChanges(true) + , m_ignoreViewportChanges(false) { m_scaleAnimation->setDuration(kScaleAnimationDurationMillis); m_scaleAnimation->setEasingCurve(QEasingCurve::OutCubic); @@ -124,15 +124,12 @@ void PageViewportControllerClientQt::flickMoveStarted() m_controller->suspendContent(); m_lastScrollPosition = m_viewportItem->contentPos(); - - m_ignoreViewportChanges = false; } void PageViewportControllerClientQt::flickMoveEnded() { // This method is called on the end of the pan or pan kinetic animation. - m_ignoreViewportChanges = true; if (!m_isUserInteracting) m_controller->resumeContent(); } @@ -153,10 +150,12 @@ void PageViewportControllerClientQt::scaleAnimationStateChanged(QAbstractAnimati { switch (newState) { case QAbstractAnimation::Running: + m_ignoreViewportChanges = true; m_viewportItem->cancelFlick(); m_controller->suspendContent(); break; case QAbstractAnimation::Stopped: + m_ignoreViewportChanges = false; m_controller->resumeContent(); break; default: @@ -182,12 +181,12 @@ void PageViewportControllerClientQt::focusEditableArea(const QRectF& caretArea, // This can only happen as a result of a user interaction. ASSERT(m_controller->hadUserInteraction()); - const float editingFixedScale = 2 * m_controller->devicePixelRatio(); + const float editingFixedScale = 2; float targetScale = m_controller->innerBoundedViewportScale(editingFixedScale); const QRectF viewportRect = m_viewportItem->boundingRect(); qreal x; - const qreal borderOffset = 10 * m_controller->devicePixelRatio(); + const qreal borderOffset = 10; if ((targetArea.width() + borderOffset) * targetScale <= viewportRect.width()) { // Center the input field in the middle of the view, if it is smaller than // the view at the scale target. @@ -221,12 +220,12 @@ void PageViewportControllerClientQt::zoomToAreaGestureEnded(const QPointF& touch if (m_controller->hasSuspendedContent()) return; - const float margin = 10 * m_controller->devicePixelRatio(); // We want at least a little bit of margin. + const float margin = 10; // We want at least a little bit of margin. QRectF endArea = targetArea.adjusted(-margin, -margin, margin, margin); const QRectF viewportRect = m_viewportItem->boundingRect(); - qreal minViewportScale = qreal(2.5) * m_controller->devicePixelRatio(); + qreal minViewportScale = qreal(2.5); qreal targetScale = viewportRect.size().width() / endArea.size().width(); targetScale = m_controller->innerBoundedViewportScale(qMin(minViewportScale, targetScale)); qreal currentScale = m_pageItem->contentsScale(); @@ -268,7 +267,7 @@ void PageViewportControllerClientQt::zoomToAreaGestureEnded(const QPointF& touch break; case ZoomBack: { if (m_scaleStack.isEmpty()) { - targetScale = m_controller->minimumContentsScale() * m_controller->devicePixelRatio(); + targetScale = m_controller->minimumContentsScale(); endPosition.setY(hotspot.y() - viewportHotspot.y() / targetScale); endPosition.setX(0); m_zoomOutScale = 0; @@ -318,8 +317,8 @@ QRectF PageViewportControllerClientQt::nearestValidVisibleContentsRect() const void PageViewportControllerClientQt::setViewportPosition(const FloatPoint& contentsPoint) { QPointF newPosition((m_pageItem->position() + QPointF(contentsPoint)) * m_pageItem->contentsScale()); + // The contentX and contentY property changes trigger a visible rect update. m_viewportItem->setContentPos(newPosition); - updateViewportController(); } void PageViewportControllerClientQt::setContentsScale(float localScale, bool treatAsInitialValue) @@ -427,6 +426,7 @@ void PageViewportControllerClientQt::pinchGestureStarted(const QPointF& pinchCen clearRelativeZoomState(); + m_ignoreViewportChanges = true; m_controller->suspendContent(); m_lastPinchCenterInViewportCoordinates = pinchCenterInViewportCoordinates; @@ -461,6 +461,7 @@ void PageViewportControllerClientQt::pinchGestureEnded() if (!m_controller->allowsUserScaling()) return; + m_ignoreViewportChanges = false; m_pinchStartScale = -1; // This will take care of resuming the content, even if no animation was performed. diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageSGNode.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageSGNode.cpp index 7b6c1ee87..f536c4217 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPageSGNode.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebPageSGNode.cpp @@ -87,9 +87,12 @@ private: for (const QSGClipNode* clip = clipList(); clip; clip = clip->clipList()) { QMatrix4x4 clipMatrix; - if (clip->matrix()) + if (pageNode()->devicePixelRatio() != 1.0) { + clipMatrix.scale(pageNode()->devicePixelRatio()); + if (clip->matrix()) + clipMatrix *= (*clip->matrix()); + } else if (clip->matrix()) clipMatrix = *clip->matrix(); - clipMatrix.scale(pageNode()->devicePixelRatio()); QRectF currentClip; diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp index 3c256ec84..f8efcbf40 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp @@ -1018,13 +1018,13 @@ void WebPage::sendViewportAttributesChanged() // Recalculate the recommended layout size, when the available size (device pixel) changes. Settings* settings = m_page->settings(); - int minimumLayoutFallbackWidth = std::max(settings->layoutFallbackWidth(), int(m_viewportSize.width() / m_page->deviceScaleFactor())); + int minimumLayoutFallbackWidth = std::max(settings->layoutFallbackWidth(), m_viewportSize.width()); // If unset we use the viewport dimensions. This fits with the behavior of desktop browsers. int deviceWidth = (settings->deviceWidth() > 0) ? settings->deviceWidth() : m_viewportSize.width(); int deviceHeight = (settings->deviceHeight() > 0) ? settings->deviceHeight() : m_viewportSize.height(); - ViewportAttributes attr = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, deviceWidth, deviceHeight, m_page->deviceScaleFactor(), m_viewportSize); + ViewportAttributes attr = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewportSize); attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user. // This also takes care of the relayout. diff --git a/Source/qtwebkit.qdocconf b/Source/qtwebkit.qdocconf index 7c50840e8..bc3d47408 100644 --- a/Source/qtwebkit.qdocconf +++ b/Source/qtwebkit.qdocconf @@ -2,14 +2,14 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) project = QtWebKit description = "Qt WebKit API Documentation" -version = 5.0.1 +version = $QT_VERSION # Defines the name of the project. You cannot use operators (+, =, -) in # the name. Properties for this project are set using a qhp.<projectname>.property # format. qhp.projects = QtWebKit qhp.QtWebKit.file = qtwebkit.qhp -qhp.QtWebKit.namespace = org.qt-project.qtwebkit.501 +qhp.QtWebKit.namespace = org.qt-project.qtwebkit.$QT_VERSION_TAG qhp.QtWebKit.indexTitle = Qt WebKit qhp.QtWebKit.virtualFolder = qtwebkit diff --git a/Tools/ChangeLog b/Tools/ChangeLog index fb2e127de..ee62ee985 100644 --- a/Tools/ChangeLog +++ b/Tools/ChangeLog @@ -1,3 +1,85 @@ +2013-02-19 Simon Hausmann <simon.hausmann@digia.com> + + [Qt] Skip the build with a warning if certain tools cannot be found in the PATH + https://bugs.webkit.org/show_bug.cgi?id=110215 + + Reviewed by Tor Arne Vestbø. + + Check that gperf, python, ruby, perl, bison and flex are in the PATH before + continuing the build. Otherwise skip with an error message explaining which + programs are missing from the build. + + * qmake/mkspecs/features/configure.prf: + * qmake/mkspecs/features/functions.prf: + +2013-02-18 Simon Hausmann <simon.hausmann@digia.com> + + [Qt] Disable the build if certain configure checks fail + https://bugs.webkit.org/show_bug.cgi?id=110094 + + Reviewed by Tor Arne Vestbø. + + Allow for the build to be skipped (clear out SUBDIRS) if certain + configure conditions aren't met. + + * qmake/mkspecs/features/configure.prf: + +2013-01-14 Jocelyn Turcotte <jocelyn.turcotte@digia.com> + + [Qt] The Qt's configuration isn't honoured regarding the use of the system libpng and libjpeg + https://bugs.webkit.org/show_bug.cgi?id=104909 + + Reviewed by Simon Hausmann. + + To be able to build redistribuable binary packages, Qt's configure switches + -qt-libpng and -qt-libjpeg are used to avoid having the binaries trying to + dynamically link to optional system libraries. + QtWebKit is doing its own configure checks for those libraries, thus adding a + runtime dependency that might not be fulfilled if the packager's machine had + those libraries while the user's machine won't. + + Since in most cases where WebKit will want to use those system libraries, Qt will + also be using them, remove these configure tests from WebKit. + + * qmake/config.tests/libjpeg/libjpeg.cpp: Removed. + * qmake/config.tests/libjpeg/libjpeg.pro: Removed. + * qmake/config.tests/libpng/libpng.cpp: Removed. + * qmake/config.tests/libpng/libpng.pro: Removed. + * qmake/mkspecs/features/features.prf: + +2013-01-13 Jonathan Liu <net147@gmail.com> + + Fix CONFIG missing link_pkgconfig on Windows + https://bugs.webkit.org/show_bug.cgi?id=106647 + + Some libraries (e.g. libxslt, libxml2 and sqlite3) fail to link + properly on Windows because they are added to PKGCONFIG but + CONFIG does not contain link_pkgconfig. + + This is because link_pkgconfig is added in unix/default_pre.prf + which is only used for UNIX platforms. To fix this, move it to + the general default_pre.prf. + + Reviewed by Simon Hausmann. + + * qmake/mkspecs/features/default_pre.prf: + * qmake/mkspecs/features/unix/default_pre.prf: + +2012-12-06 Andras Becsi <andras.becsi@digia.com> + + [Qt][Mac] Fix libxslt and libxml2 config tests + https://bugs.webkit.org/show_bug.cgi?id=104164 + + Reviewed by Simon Hausmann. + + We should not use pkg-config on Mac instead use direct include + paths and add needed libraries to the linker options to detect + libxslt and libxml2 provided by the system. + Previously we would always fall back to qtxmlpatterns. + + * qmake/config.tests/libxml2/libxml2.pro: + * qmake/config.tests/libxslt/libxslt.pro: + 2013-01-08 Heikki Paajanen <heikki.paajanen@palm.com> [Qt] Fix libxml2 config test diff --git a/Tools/qmake/config.tests/libjpeg/libjpeg.cpp b/Tools/qmake/config.tests/libjpeg/libjpeg.cpp deleted file mode 100644 index cb44f0e73..000000000 --- a/Tools/qmake/config.tests/libjpeg/libjpeg.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) Zoltan Horvath (zoltan@webkit.org) 2012 University of Szeged. - * - * 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 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. - */ - -#include <stdio.h> -#include <jpeglib.h> - -int main(int, char**) -{ - struct jpeg_compress_struct cinfo; - jpeg_create_compress(&cinfo); - - return 0; -} diff --git a/Tools/qmake/config.tests/libjpeg/libjpeg.pro b/Tools/qmake/config.tests/libjpeg/libjpeg.pro deleted file mode 100644 index b84c3e0c4..000000000 --- a/Tools/qmake/config.tests/libjpeg/libjpeg.pro +++ /dev/null @@ -1,3 +0,0 @@ -SOURCES = libjpeg.cpp -OBJECTS_DIR = obj -LIBS += -ljpeg diff --git a/Tools/qmake/config.tests/libpng/libpng.cpp b/Tools/qmake/config.tests/libpng/libpng.cpp deleted file mode 100644 index 7fb5861ab..000000000 --- a/Tools/qmake/config.tests/libpng/libpng.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) Zoltan Horvath (zoltan@webkit.org) 2012 University of Szeged. - * - * 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 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. - */ - -#include <png.h> - -int main(int, char**) -{ - png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - - return 0; -} diff --git a/Tools/qmake/config.tests/libpng/libpng.pro b/Tools/qmake/config.tests/libpng/libpng.pro deleted file mode 100644 index 23a39a971..000000000 --- a/Tools/qmake/config.tests/libpng/libpng.pro +++ /dev/null @@ -1,3 +0,0 @@ -SOURCES = libpng.cpp -OBJECTS_DIR = obj -LIBS += -lpng diff --git a/Tools/qmake/config.tests/libxml2/libxml2.pro b/Tools/qmake/config.tests/libxml2/libxml2.pro index d5add8f17..bd72944f0 100644 --- a/Tools/qmake/config.tests/libxml2/libxml2.pro +++ b/Tools/qmake/config.tests/libxml2/libxml2.pro @@ -1,4 +1,9 @@ CONFIG -= qt SOURCES = libxml2.cpp -CONFIG += link_pkgconfig -PKGCONFIG += libxml-2.0 +mac { + INCLUDEPATH += /usr/include/libxml2 + LIBS += -lxml2 +} else { + PKGCONFIG += libxml-2.0 + CONFIG += link_pkgconfig +} diff --git a/Tools/qmake/config.tests/libxslt/libxslt.pro b/Tools/qmake/config.tests/libxslt/libxslt.pro index 6359de3c6..1943485d0 100644 --- a/Tools/qmake/config.tests/libxslt/libxslt.pro +++ b/Tools/qmake/config.tests/libxslt/libxslt.pro @@ -1,4 +1,9 @@ CONFIG -= qt SOURCES = libxslt.cpp -CONFIG += link_pkgconfig -PKGCONFIG += libxslt +mac { + INCLUDEPATH += /usr/include/libxslt /usr/include/libxml2 + LIBS += -lxslt +} else { + PKGCONFIG += libxslt + CONFIG += link_pkgconfig +} diff --git a/Tools/qmake/mkspecs/features/configure.prf b/Tools/qmake/mkspecs/features/configure.prf index 81b6f0ea1..27adbaaff 100644 --- a/Tools/qmake/mkspecs/features/configure.prf +++ b/Tools/qmake/mkspecs/features/configure.prf @@ -109,8 +109,17 @@ defineTest(finalizeConfigure) { error(Done computing defaults) } - # Sanity check that would prevent us from building the whole project altogether. - !mac:!contains(QT_CONFIG,icu): error("To build QtWebKit with Qt 5 you need to build Qt 5 with libICU support. Check for ICU support being mentioned in qtbase/config.summary.") + # Sanity checks that would prevent us from building the whole project altogether. + !mac:!contains(QT_CONFIG,icu) { + addReasonForSkippingBuild("ICU is required. To build QtWebKit with Qt 5 you need to build Qt 5 with libICU support. Check for ICU support being mentioned in qtbase/config.summary.") + } + production_build:blackberry { + addReasonForSkippingBuild("Build not supported on BB10 yet.") + } + requiredPrograms = gperf python perl bison ruby flex + for(program, requiredPrograms): \ + !programExistsInPath($$program): \ + addReasonForSkippingBuild("Missing $$program from PATH") # Detect changes to the configuration. Changes need a clean build. webkit_configured { @@ -226,7 +235,13 @@ defineTest(finalizeConfigure) { } } - log("$${EOL}WebKit is now configured for building. Just run 'make'.$${EOL}$${EOL}") + !isEmpty(skipBuildReason) { + log("$${EOL}The WebKit build was disabled for the following reasons: $$skipBuildReason $${EOL}$${EOL}") + SUBDIRS= + export(SUBDIRS) + } else { + log("$${EOL}WebKit is now configured for building. Just run 'make'.$${EOL}$${EOL}") + } configuration_changed { log(WARNING: The configuration was changed since the last build:$${EOL}$${EOL}) diff --git a/Tools/qmake/mkspecs/features/default_pre.prf b/Tools/qmake/mkspecs/features/default_pre.prf index 6b19a67b9..75acbc3a4 100644 --- a/Tools/qmake/mkspecs/features/default_pre.prf +++ b/Tools/qmake/mkspecs/features/default_pre.prf @@ -85,6 +85,9 @@ contains(QT_CONFIG, private_tests): CONFIG += qt_developer_build # Set some defaults for specific platforms CONFIG += include_webinspector +# Make sure we process the PKGCONFIG variable if applicable +!mac: CONFIG += link_pkgconfig + # By default we enable "production build", and build-webkit, which is # used by bots and developers, will disable it, to enable warnings etc. CONFIG += production_build diff --git a/Tools/qmake/mkspecs/features/features.prf b/Tools/qmake/mkspecs/features/features.prf index 2a0eb4051..6385887d2 100644 --- a/Tools/qmake/mkspecs/features/features.prf +++ b/Tools/qmake/mkspecs/features/features.prf @@ -42,10 +42,12 @@ defineTest(detectFeatures) { config_libzlib: WEBKIT_CONFIG += use_zlib config_libwebp: WEBKIT_CONFIG += use_webp - config_libjpeg: WEBKIT_CONFIG += use_libjpeg + # We can't use Qt's 3rdparty sources for libjpeg and libpng outside of qtbase, but if Qt + # is using the system libraries, use them to take advantage of the WebCore image decoders as well. + contains(QT_CONFIG, system-jpeg): WEBKIT_CONFIG += use_libjpeg else: CONFIGURE_WARNINGS += "JPEG library not found, QImageDecoder will decode JPEG images" - config_libpng: WEBKIT_CONFIG += use_libpng + contains(QT_CONFIG, system-png): WEBKIT_CONFIG += use_libpng else: CONFIGURE_WARNINGS += "PNG library not found, QImageDecoder will decode PNG images" linux-* { diff --git a/Tools/qmake/mkspecs/features/functions.prf b/Tools/qmake/mkspecs/features/functions.prf index 4477f8321..f9d2defe2 100644 --- a/Tools/qmake/mkspecs/features/functions.prf +++ b/Tools/qmake/mkspecs/features/functions.prf @@ -199,6 +199,25 @@ defineTest(haveQtModule) { return(false) } +defineTest(programExistsInPath) { + win_cmd_shell: program = $${1}.exe + else: program = $$1 + + PATH = "$$(PATH)" + paths=$$split(PATH, $$QMAKE_DIRLIST_SEP) + + GNUTOOLS_DIR=$$[QT_HOST_DATA]/../gnuwin32/bin + exists($$GNUTOOLS_DIR): paths += $$GNUTOOLS_DIR + + for(p, paths): exists($$p/$$program):return(true) + return(false) +} + +defineTest(addReasonForSkippingBuild) { + skipBuildReason = "$$skipBuildReason$${EOL} * $$1" + export(skipBuildReason) +} + defineTest(prependEach) { unset(variable) unset(prefix) diff --git a/Tools/qmake/mkspecs/features/unix/default_pre.prf b/Tools/qmake/mkspecs/features/unix/default_pre.prf index 83b7cc4a9..aafc48ceb 100644 --- a/Tools/qmake/mkspecs/features/unix/default_pre.prf +++ b/Tools/qmake/mkspecs/features/unix/default_pre.prf @@ -16,9 +16,6 @@ SBOX_CHECK = $$(_SBOX_DIR) # flag that can be used to test for either of these situations. contains(QT_CONFIG, qpa)|contains(QT_CONFIG, embedded): CONFIG += embedded -# Make sure we process the PKGCONFIG variable if applicable -!mac: CONFIG += link_pkgconfig - # Reduce linking memory pressure on 32-bit debug builds on Linux linux-g++*:CONFIG(debug, debug|release):isEqual(QT_ARCH,i386): CONFIG += use_all_in_one_files |