diff options
25 files changed, 218 insertions, 228 deletions
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 8ee46f4b5..e08750c67 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,19 @@ +2013-02-21 Levi Weintraub <leviw@chromium.org> + + ASSERTION FAILED: !object || object->isBox(), UNKNOWN in WebCore::RenderListItem::positionListMarker + https://bugs.webkit.org/show_bug.cgi?id=108699 + + Reviewed by Abhishek Arya. + + RenderListItems performs special management of its children to maintain list markers. Splitting a flow + through a list item results in assumptions made inside RenderListItem failing, so for now, avoid splitting + flows when inside one. + + Test: fast/multicol/span/list-multi-column-crash.html + + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::containingColumnsBlock): + 2013-02-19 Andras Becsi <andras.becsi@digia.com> [Qt] Fix compilation if Qt was configured with -no-rtti @@ -24,6 +40,31 @@ * platform/graphics/qt/GraphicsContextQt.cpp: (WebCore::GraphicsContext::clipBounds): +2013-01-29 Justin Novosad <junov@google.com> + + REGRESSION (r135628-135632): Double box shadow failure to render + https://bugs.webkit.org/show_bug.cgi?id=107833 + + Reviewed by Simon Fraser. + + Regression caused by http://trac.webkit.org/changeset/135629 + The regression was due to faulty occlusion logic that was assuming + that drawing the background color of a render box background layer + could be skipped when the same layer also has an opaque image attached. + In the case where the background color is drawn for the purpose of + rendering a box shadow, the shadow is typically not + completely occluded by the background image because of the shadow + blur and/or offset. This patch fixes the problem by not culling a + background draw if it is used to draw a box shadow. + + Test: fast/backgrounds/gradient-background-shadow.html + + * rendering/RenderBoxModelObject.cpp: + (WebCore::RenderBoxModelObject::paintFillLayerExtended): + Changing occlusion culling test to never cull background color + draw if it is used to draw a box shadow. This is because box shadows + can draw outside the border fill region. + 2013-01-29 Allan Sandfeld Jensen <allan.jensen@digia.com> REGRESSION: ChildrenAffectedBy flags lost between siblings which have child elements sharing style @@ -47,51 +88,6 @@ * 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. diff --git a/Source/WebCore/WebCore.pri b/Source/WebCore/WebCore.pri index 2ac0dd7ad..6c9ce5c9e 100644 --- a/Source/WebCore/WebCore.pri +++ b/Source/WebCore/WebCore.pri @@ -302,10 +302,6 @@ unix:!mac:*-g++*:QMAKE_CXXFLAGS += -fdata-sections unix:!mac:*-g++*:QMAKE_LFLAGS += -Wl,--gc-sections linux*-g++*:QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF -unix|win32-g++* { - QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui QtNetwork QtWidgets -} - contains(DEFINES, ENABLE_OPENCL=1) { LIBS += -lOpenCL diff --git a/Source/WebCore/dom/ContainerNode.cpp b/Source/WebCore/dom/ContainerNode.cpp index f3c6abd38..a8ae7c893 100644 --- a/Source/WebCore/dom/ContainerNode.cpp +++ b/Source/WebCore/dom/ContainerNode.cpp @@ -777,9 +777,9 @@ void ContainerNode::attach() void ContainerNode::detach() { - Node::detach(); detachChildren(); clearChildNeedsStyleRecalc(); + Node::detach(); } void ContainerNode::childrenChanged(bool changedByParser, Node*, Node*, int childCountDelta) diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp index 1d9dfc44d..39d295f52 100644 --- a/Source/WebCore/dom/Node.cpp +++ b/Source/WebCore/dom/Node.cpp @@ -1227,23 +1227,10 @@ void Node::detach() detachingNode = this; #endif - if (renderer()) { + if (renderer()) renderer()->destroyAndCleanupAnonymousWrappers(); -#ifndef NDEBUG - for (Node* node = this; node; node = node->traverseNextNode(this)) { - RenderObject* renderer = node->renderer(); - // RenderFlowThread and the top layer remove elements from the regular tree - // hierarchy. They will be cleaned up when we call detach on them. -#if ENABLE(DIALOG_ELEMENT) - ASSERT(!renderer || renderer->inRenderFlowThread() || (renderer->enclosingLayer()->isInTopLayerSubtree())); -#else - ASSERT(!renderer || renderer->inRenderFlowThread()); -#endif - } -#endif - } - ASSERT(!renderer()); + setRenderer(0); Document* doc = document(); if (hovered()) diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp index 5716e39d3..7fc354d16 100644 --- a/Source/WebCore/loader/FrameLoader.cpp +++ b/Source/WebCore/loader/FrameLoader.cpp @@ -739,6 +739,7 @@ bool FrameLoader::allAncestorsAreComplete() const void FrameLoader::checkCompleted() { + RefPtr<Frame> protect(m_frame); m_shouldCallCheckCompleted = false; if (m_frame->view()) @@ -769,7 +770,6 @@ void FrameLoader::checkCompleted() m_requestedHistoryItem = 0; m_frame->document()->setReadyState(Document::Complete); - RefPtr<Frame> protect(m_frame); checkCallImplicitClose(); // if we didn't do it before m_frame->navigationScheduler()->startTimer(); diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp index c13f892b0..5ba109066 100644 --- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp +++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp @@ -60,6 +60,7 @@ GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* clie , m_debugBorderWidth(0) , m_contentsLayer(0) , m_animationStartedTimer(this, &GraphicsLayerTextureMapper::animationStartedTimerFired) + , m_animationStartTime(0) { } @@ -542,7 +543,13 @@ bool GraphicsLayerTextureMapper::addAnimation(const KeyframeValueList& valueList if (valueList.property() == AnimatedPropertyWebkitTransform) listsMatch = validateTransformOperations(valueList, hasBigRotation) >= 0; - m_animations.add(GraphicsLayerAnimation(keyframesName, valueList, boxSize, anim, WTF::currentTime() - timeOffset, listsMatch)); + const double currentTime = WTF::currentTime(); + m_animations.add(GraphicsLayerAnimation(keyframesName, valueList, boxSize, anim, currentTime - timeOffset, listsMatch)); + // m_animationStartTime is the time of the first real frame of animation, now or delayed by a negative offset. + if (timeOffset > 0) + m_animationStartTime = currentTime; + else + m_animationStartTime = currentTime - timeOffset; notifyChange(TextureMapperLayer::AnimationChange); m_animationStartedTimer.startOneShot(0); return true; @@ -567,7 +574,7 @@ void GraphicsLayerTextureMapper::removeAnimation(const String& animationName) void GraphicsLayerTextureMapper::animationStartedTimerFired(Timer<GraphicsLayerTextureMapper>*) { - client()->notifyAnimationStarted(this, /* DOM time */ WTF::currentTime()); + client()->notifyAnimationStarted(this, m_animationStartTime); } void GraphicsLayerTextureMapper::setDebugBorder(const Color& color, float width) diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h index 7051a7d97..00b0fe7c1 100644 --- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h +++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h @@ -122,6 +122,7 @@ private: FloatRect m_needsDisplayRect; GraphicsLayerAnimations m_animations; Timer<GraphicsLayerTextureMapper> m_animationStartedTimer; + double m_animationStartTime; }; inline static GraphicsLayerTextureMapper* toGraphicsLayerTextureMapper(GraphicsLayer* layer) diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp index 9d8a21010..d2a10aa66 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp @@ -264,25 +264,7 @@ 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) { @@ -430,17 +412,6 @@ 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()); @@ -495,12 +466,12 @@ void TextureMapperLayer::applyAnimationsRecursively() void TextureMapperLayer::syncAnimations() { m_animations.apply(this); - if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitTransform) && m_shouldUpdateCurrentTransformFromGraphicsLayer) + if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitTransform)) setTransform(m_state.transform); - if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyOpacity) && m_shouldUpdateCurrentOpacityFromGraphicsLayer) + if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyOpacity)) setOpacity(m_state.opacity); #if ENABLE(CSS_FILTERS) - if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitFilter) && m_shouldUpdateCurrentFiltersFromGraphicsLayer) + if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitFilter)) setFilters(m_state.filters); #endif } diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h index 08c273740..27a77f6fe 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h @@ -98,11 +98,6 @@ 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) { } @@ -156,10 +151,10 @@ private: void paintSelfAndChildrenWithReplica(const TextureMapperPaintOptions&); // GraphicsLayerAnimation::Client - virtual void setAnimatedTransform(const TransformationMatrix& matrix) OVERRIDE; - virtual void setAnimatedOpacity(float opacity) OVERRIDE; + void setAnimatedTransform(const TransformationMatrix& matrix) { setTransform(matrix); } + void setAnimatedOpacity(float opacity) { setOpacity(opacity); } #if ENABLE(CSS_FILTERS) - virtual void setAnimatedFilters(const FilterOperations& filters) OVERRIDE; + virtual void setAnimatedFilters(const FilterOperations& filters) { setFilters(filters); } #endif void syncAnimations(); @@ -193,12 +188,6 @@ 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/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp index 8c6249765..4265ecdf3 100644 --- a/Source/WebCore/rendering/RenderBlock.cpp +++ b/Source/WebCore/rendering/RenderBlock.cpp @@ -530,13 +530,10 @@ RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock) || curr->isInlineBlockOrInlineTable()) return 0; - // FIXME: Table manages its own table parts, most of which are RenderBoxes. - // Multi-column code cannot handle splitting the flow in table. Disabling it - // to prevent crashes. - // Similarly, RenderButton maintains an anonymous block child and overrides - // addChild() to prevent itself from having additional direct children. This - // causes problems for split flows. - if (curr->isTable() || curr->isRenderButton()) + // FIXME: Tables, RenderButtons, and RenderListItems all do special management + // of their children that breaks when the flow is split through them. Disabling + // multi-column for them to avoid this problem. + if (curr->isTable() || curr->isRenderButton() || curr->isListItem()) return 0; RenderBlock* currBlock = toRenderBlock(curr); diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp index 33dc945e9..6c341ddb2 100644 --- a/Source/WebCore/rendering/RenderBox.cpp +++ b/Source/WebCore/rendering/RenderBox.cpp @@ -263,6 +263,7 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle if (viewStyle->writingMode() != newStyle->writingMode() && (isRootRenderer || !document()->writingModeSetOnDocumentElement())) { viewStyle->setWritingMode(newStyle->writingMode()); viewRenderer->setHorizontalWritingMode(newStyle->isHorizontalWritingMode()); + viewRenderer->markAllDescendantsWithFloatsForLayout(); if (isBodyRenderer) { document()->documentElement()->renderer()->style()->setWritingMode(newStyle->writingMode()); document()->documentElement()->renderer()->setHorizontalWritingMode(newStyle->isHorizontalWritingMode()); diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp index cd1822f3e..6d63169b5 100644 --- a/Source/WebCore/rendering/RenderBoxModelObject.cpp +++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp @@ -910,35 +910,37 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co // Paint the color first underneath all images, culled if background image occludes it. // FIXME: In the bgLayer->hasFiniteBounds() case, we could improve the culling test // by verifying whether the background image covers the entire layout rect. - if (!bgLayer->next() && !(shouldPaintBackgroundImage && bgLayer->hasOpaqueImage(this) && bgLayer->hasRepeatXY())) { + if (!bgLayer->next()) { IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect)); bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppliedToBackground(bleedAvoidance, box); - if (!boxShadowShouldBeAppliedToBackground) - backgroundRect.intersect(paintInfo.rect); - - // If we have an alpha and we are painting the root element, go ahead and blend with the base background color. - Color baseColor; - bool shouldClearBackground = false; - if (isOpaqueRoot) { - baseColor = view()->frameView()->baseBackgroundColor(); - if (!baseColor.alpha()) - shouldClearBackground = true; - } + if (boxShadowShouldBeAppliedToBackground || !shouldPaintBackgroundImage || !bgLayer->hasOpaqueImage(this) || !bgLayer->hasRepeatXY()) { + if (!boxShadowShouldBeAppliedToBackground) + backgroundRect.intersect(paintInfo.rect); + + // If we have an alpha and we are painting the root element, go ahead and blend with the base background color. + Color baseColor; + bool shouldClearBackground = false; + if (isOpaqueRoot) { + baseColor = view()->frameView()->baseBackgroundColor(); + if (!baseColor.alpha()) + shouldClearBackground = true; + } - GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAppliedToBackground); - if (boxShadowShouldBeAppliedToBackground) - applyBoxShadowForBackground(context, style()); + GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAppliedToBackground); + if (boxShadowShouldBeAppliedToBackground) + applyBoxShadowForBackground(context, style()); - if (baseColor.alpha()) { - if (bgColor.alpha()) - baseColor = baseColor.blend(bgColor); + if (baseColor.alpha()) { + if (bgColor.alpha()) + baseColor = baseColor.blend(bgColor); - context->fillRect(backgroundRect, baseColor, style()->colorSpace(), CompositeCopy); - } else if (bgColor.alpha()) { - CompositeOperator operation = shouldClearBackground ? CompositeCopy : context->compositeOperation(); - context->fillRect(backgroundRect, bgColor, style()->colorSpace(), operation); - } else if (shouldClearBackground) - context->clearRect(backgroundRect); + context->fillRect(backgroundRect, baseColor, style()->colorSpace(), CompositeCopy); + } else if (bgColor.alpha()) { + CompositeOperator operation = shouldClearBackground ? CompositeCopy : context->compositeOperation(); + context->fillRect(backgroundRect, bgColor, style()->colorSpace(), operation); + } else if (shouldClearBackground) + context->clearRect(backgroundRect); + } } // no progressive loading of the background image diff --git a/Source/WebCore/rendering/RenderFrameSet.cpp b/Source/WebCore/rendering/RenderFrameSet.cpp index 543c2d353..e4e7e24bb 100644 --- a/Source/WebCore/rendering/RenderFrameSet.cpp +++ b/Source/WebCore/rendering/RenderFrameSet.cpp @@ -131,14 +131,14 @@ void RenderFrameSet::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) LayoutPoint adjustedPaintOffset = paintOffset + location(); - int rows = frameSet()->totalRows(); - int cols = frameSet()->totalCols(); + size_t rows = m_rows.m_sizes.size(); + size_t cols = m_cols.m_sizes.size(); LayoutUnit borderThickness = frameSet()->border(); LayoutUnit yPos = 0; - for (int r = 0; r < rows; r++) { + for (size_t r = 0; r < rows; r++) { LayoutUnit xPos = 0; - for (int c = 0; c < cols; c++) { + for (size_t c = 0; c < cols; c++) { child->paint(paintInfo, adjustedPaintOffset); xPos += m_cols.m_sizes[c]; if (borderThickness && m_cols.m_allowBorder[c + 1]) { diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp index b3f325e2a..17bdafb54 100644 --- a/Source/WebCore/rendering/RenderObject.cpp +++ b/Source/WebCore/rendering/RenderObject.cpp @@ -2361,11 +2361,6 @@ void RenderObject::willBeDestroyed() remove(); - // Continuation and first-letter can generate several renderers associated with a single node. - // We only want to clear the node's renderer if we are the associated renderer. - if (node() && node()->renderer() == this) - node()->setRenderer(0); - #ifndef NDEBUG if (!documentBeingDestroyed() && view() && view()->hasRenderNamedFlowThreads()) { // After remove, the object and the associated information should not be in any flow thread. @@ -2499,18 +2494,6 @@ void RenderObject::destroyAndCleanupAnonymousWrappers() break; } - // We repaint, so that the area exposed when this object disappears gets repainted properly. - // FIXME: A RenderObject with RenderLayer should probably repaint through it as getting the - // repaint rects is O(1) through a RenderLayer (assuming it's up-to-date). - if (destroyRoot->everHadLayout()) { - if (destroyRoot->isBody()) - destroyRoot->view()->repaint(); - else { - destroyRoot->repaint(); - destroyRoot->repaintOverhangingFloats(true); - } - } - destroyRoot->destroy(); // WARNING: |this| is deleted here. diff --git a/Source/WebCore/rendering/RenderObjectChildList.cpp b/Source/WebCore/rendering/RenderObjectChildList.cpp index 202cc36b3..e2a95a207 100644 --- a/Source/WebCore/rendering/RenderObjectChildList.cpp +++ b/Source/WebCore/rendering/RenderObjectChildList.cpp @@ -48,10 +48,13 @@ void RenderObjectChildList::destroyLeftoverChildren() if (firstChild()->isListMarker() || (firstChild()->style()->styleType() == FIRST_LETTER && !firstChild()->isText())) firstChild()->remove(); // List markers are owned by their enclosing list and so don't get destroyed by this container. Similarly, first letters are destroyed by their remaining text fragment. else if (firstChild()->isRunIn() && firstChild()->node()) { + firstChild()->node()->setRenderer(0); firstChild()->node()->setNeedsStyleRecalc(); firstChild()->destroy(); } else { // Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields. + if (firstChild()->node()) + firstChild()->node()->setRenderer(0); firstChild()->destroy(); } } @@ -65,11 +68,14 @@ RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, Render toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists(); // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or - // that a positioned child got yanked). + // that a positioned child got yanked). We also repaint, so that the area exposed when the child + // disappears gets repainted properly. if (!owner->documentBeingDestroyed() && notifyRenderer && oldChild->everHadLayout()) { oldChild->setNeedsLayoutAndPrefWidthsRecalc(); // We only repaint |oldChild| if we have a RenderLayer as its visual overflow may not be tracked by its parent. - if (oldChild->hasLayer()) + if (oldChild->isBody()) + owner->view()->repaint(); + else oldChild->repaint(); } diff --git a/Source/WebCore/rendering/RenderTextFragment.cpp b/Source/WebCore/rendering/RenderTextFragment.cpp index 5d6e165d6..9f497d344 100644 --- a/Source/WebCore/rendering/RenderTextFragment.cpp +++ b/Source/WebCore/rendering/RenderTextFragment.cpp @@ -85,7 +85,10 @@ void RenderTextFragment::setText(PassRefPtr<StringImpl> text, bool force) ASSERT(!m_contentString); m_firstLetter->destroy(); m_firstLetter = 0; - ASSERT(!node() || node()->renderer() == this); + if (Node* t = node()) { + ASSERT(!t->renderer()); + t->setRenderer(this); + } } } diff --git a/Source/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h index 6be9b1c31..65ee9e58d 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h @@ -56,12 +56,19 @@ public: virtual bool isAnimatedListTearOff() const { return true; } - int removeItemFromList(SVGProperty* property, bool shouldSynchronizeWrappers) + int findItem(SVGProperty* property) const { // This should ever be called for our baseVal, as animVal can't modify the list. // It's safe to cast to ListPropertyTearOff here as all classes inheriting from us supply their own removeItemFromList() method. typedef SVGPropertyTearOff<typename SVGPropertyTraits<PropertyType>::ListItemType> ListItemTearOff; - return static_cast<ListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(static_cast<ListItemTearOff*>(property), shouldSynchronizeWrappers); + return static_cast<ListPropertyTearOff*>(m_baseVal.get())->findItem(static_cast<ListItemTearOff*>(property)); + } + + void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) + { + // This should ever be called for our baseVal, as animVal can't modify the list. + // It's safe to cast to ListPropertyTearOff here as all classes inheriting from us supply their own removeItemFromList() method. + static_cast<ListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(itemIndex, shouldSynchronizeWrappers); } void detachListWrappers(unsigned newListSize) diff --git a/Source/WebCore/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h index db910fe90..f1268f8fd 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h @@ -46,11 +46,18 @@ public: return static_cast<SVGListProperty<SVGPathSegList>*>(m_animVal.get()); } - int removeItemFromList(const RefPtr<SVGPathSeg>& segment, bool shouldSynchronizeWrappers) + int findItem(const RefPtr<SVGPathSeg>& segment) const { // This should ever be called for our baseVal, as animVal can't modify the list. ASSERT(m_baseVal); - return static_cast<SVGPathSegListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(segment, shouldSynchronizeWrappers); + return static_cast<SVGPathSegListPropertyTearOff*>(m_baseVal.get())->findItem(segment); + } + + void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) + { + // This should ever be called for our baseVal, as animVal can't modify the list. + ASSERT(m_baseVal); + static_cast<SVGPathSegListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(itemIndex, shouldSynchronizeWrappers); } static PassRefPtr<SVGAnimatedPathSegListPropertyTearOff> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGPathSegList& values) diff --git a/Source/WebCore/svg/properties/SVGListProperty.h b/Source/WebCore/svg/properties/SVGListProperty.h index 9db2f4ceb..5a202dfaf 100644 --- a/Source/WebCore/svg/properties/SVGListProperty.h +++ b/Source/WebCore/svg/properties/SVGListProperty.h @@ -221,7 +221,10 @@ public: index = m_values->size(); // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. - processIncomingListItemValue(newItem, &index); + if (!processIncomingListItemValue(newItem, &index)) { + // Inserting the item before itself is a no-op. + return newItem; + } // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list. @@ -251,7 +254,8 @@ public: ASSERT(m_values->size() == m_wrappers->size()); // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. - processIncomingListItemWrapper(newItem, &index); + if (!processIncomingListItemWrapper(newItem, &index)) + return newItem.release(); // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list. @@ -285,7 +289,10 @@ public: // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item. - processIncomingListItemValue(newItem, &index); + if (!processIncomingListItemValue(newItem, &index)) { + // Replacing the item with itself is a no-op. + return newItem; + } if (m_values->isEmpty()) { // 'newItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace. @@ -317,7 +324,8 @@ public: // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item. - processIncomingListItemWrapper(newItem, &index); + if (!processIncomingListItemWrapper(newItem, &index)) + return newItem.release(); if (m_values->isEmpty()) { ASSERT(m_wrappers->isEmpty()); @@ -461,8 +469,8 @@ protected: commitChange(); } - virtual void processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) = 0; - virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) = 0; + virtual bool processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) = 0; + virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) = 0; SVGPropertyRole m_role; bool m_ownsValues; diff --git a/Source/WebCore/svg/properties/SVGListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGListPropertyTearOff.h index c3bba4be1..a9dbec52b 100644 --- a/Source/WebCore/svg/properties/SVGListPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGListPropertyTearOff.h @@ -47,30 +47,35 @@ public: return adoptRef(new Self(animatedProperty, role, values, wrappers)); } - int removeItemFromList(ListItemTearOff* removeItem, bool shouldSynchronizeWrappers) + int findItem(ListItemTearOff* item) const { ASSERT(m_values); ASSERT(m_wrappers); - // Lookup item in cache and remove its corresponding wrapper. unsigned size = m_wrappers->size(); ASSERT(size == m_values->size()); - for (unsigned i = 0; i < size; ++i) { - RefPtr<ListItemTearOff>& item = m_wrappers->at(i); - if (item != removeItem) - continue; + for (size_t i = 0; i < size; ++i) { + if (item == m_wrappers->at(i)) + return i; + } - item->detachWrapper(); - m_wrappers->remove(i); - m_values->remove(i); + return -1; + } - if (shouldSynchronizeWrappers) - commitChange(); + void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) + { + ASSERT(m_values); + ASSERT(m_wrappers); + ASSERT(m_values->size() == m_wrappers->size()); + ASSERT(itemIndex < m_wrappers->size()); - return i; - } + RefPtr<ListItemTearOff>& item = m_wrappers->at(itemIndex); + item->detachWrapper(); + m_wrappers->remove(itemIndex); + m_values->remove(itemIndex); - return -1; + if (shouldSynchronizeWrappers) + commitChange(); } // SVGList API @@ -144,19 +149,20 @@ protected: m_animatedProperty->commitChange(); } - virtual void processIncomingListItemValue(const ListItemType&, unsigned*) + virtual bool processIncomingListItemValue(const ListItemType&, unsigned*) { ASSERT_NOT_REACHED(); + return true; } - virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) + virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) { SVGAnimatedProperty* animatedPropertyOfItem = newItem->animatedProperty(); // newItem has been created manually, it doesn't belong to any SVGElement. // (for example: "textElement.x.baseVal.appendItem(svgsvgElement.createSVGLength())") if (!animatedPropertyOfItem) - return; + return true; // newItem belongs to a SVGElement, but its associated SVGAnimatedProperty is not an animated list tear off. // (for example: "textElement.x.baseVal.appendItem(rectElement.width.baseVal)") @@ -167,25 +173,34 @@ protected: // that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. textElement.x.baseVal.getItem(0).value += 150 would // mutate the rectElement width _and_ the textElement x list. That's obviously wrong, take care of that. newItem = ListItemTearOff::create(newItem->propertyReference()); - return; + return true; } // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal. bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty; - int removedIndex = static_cast<AnimatedListPropertyTearOff*>(animatedPropertyOfItem)->removeItemFromList(newItem.get(), livesInOtherList); - ASSERT(removedIndex != -1); + AnimatedListPropertyTearOff* propertyTearOff = static_cast<AnimatedListPropertyTearOff*>(animatedPropertyOfItem); + int indexToRemove = propertyTearOff->findItem(newItem.get()); + ASSERT(indexToRemove != -1); + + // Do not remove newItem if already in this list at the target index. + if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToRemove) == *indexToModify) + return false; + + propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList); if (!indexToModify) - return; + return true; // If the item lived in our list, adjust the insertion index. if (!livesInOtherList) { unsigned& index = *indexToModify; // Spec: If the item is already in this list, note that the index of the item to (replace|insert before) is before the removal of the item. - if (static_cast<unsigned>(removedIndex) < index) + if (static_cast<unsigned>(indexToRemove) < index) --index; } + + return true; } // Back pointer to the animated property that created us diff --git a/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.cpp b/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.cpp index 2021301d6..ccef71306 100644 --- a/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.cpp +++ b/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.cpp @@ -70,7 +70,7 @@ SVGPathElement* SVGPathSegListPropertyTearOff::contextElement() const return static_cast<SVGPathElement*>(contextElement); } -void SVGPathSegListPropertyTearOff::processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) +bool SVGPathSegListPropertyTearOff::processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) { SVGPathSegWithContext* newItemWithContext = static_cast<SVGPathSegWithContext*>(newItem.get()); SVGAnimatedProperty* animatedPropertyOfItem = newItemWithContext->animatedProperty(); @@ -79,29 +79,38 @@ void SVGPathSegListPropertyTearOff::processIncomingListItemValue(const ListItemT newItemWithContext->setContextAndRole(contextElement(), m_pathSegRole); if (!animatedPropertyOfItem) - return; + return true; // newItem belongs to a SVGPathElement, but its associated SVGAnimatedProperty is not an animated list tear off. // (for example: "pathElement.pathSegList.appendItem(pathElement.createSVGPathSegClosepath())") if (!animatedPropertyOfItem->isAnimatedListTearOff()) - return; + return true; // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal. bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty; - int removedIndex = static_cast<SVGAnimatedPathSegListPropertyTearOff*>(animatedPropertyOfItem)->removeItemFromList(newItem.get(), livesInOtherList); - ASSERT(removedIndex != -1); + SVGAnimatedPathSegListPropertyTearOff* propertyTearOff = static_cast<SVGAnimatedPathSegListPropertyTearOff*>(animatedPropertyOfItem); + int indexToRemove = propertyTearOff->findItem(newItem.get()); + ASSERT(indexToRemove != -1); + + // Do not remove newItem if already in this list at the target index. + if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToRemove) == *indexToModify) + return false; + + propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList); if (!indexToModify) - return; + return true; // If the item lived in our list, adjust the insertion index. if (!livesInOtherList) { unsigned& index = *indexToModify; // Spec: If the item is already in this list, note that the index of the item to (replace|insert before) is before the removal of the item. - if (static_cast<unsigned>(removedIndex) < index) + if (static_cast<unsigned>(indexToRemove) < index) --index; } + + return true; } } diff --git a/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.h index bac9ee76d..6c22a9022 100644 --- a/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.h @@ -41,24 +41,28 @@ public: return adoptRef(new SVGPathSegListPropertyTearOff(animatedProperty, role, pathSegRole, values, wrappers)); } - int removeItemFromList(const ListItemType& removeItem, bool shouldSynchronizeWrappers) + int findItem(const ListItemType& item) const { ASSERT(m_values); + unsigned size = m_values->size(); - for (unsigned i = 0; i < size; ++i) { - ListItemType& item = m_values->at(i); - if (item != removeItem) - continue; + for (size_t i = 0; i < size; ++i) { + if (item == m_values->at(i)) + return i; + } - m_values->remove(i); + return -1; + } - if (shouldSynchronizeWrappers) - commitChange(); + void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) + { + ASSERT(m_values); + ASSERT(itemIndex < m_values->size()); - return i; - } + m_values->remove(itemIndex); - return -1; + if (shouldSynchronizeWrappers) + commitChange(); } // SVGList API @@ -149,10 +153,11 @@ private: m_values->commitChange(m_animatedProperty->contextElement(), listModification); } - virtual void processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify); - virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*) + virtual bool processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) OVERRIDE; + virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*) { ASSERT_NOT_REACHED(); + return true; } private: diff --git a/Source/WebCore/svg/properties/SVGStaticListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGStaticListPropertyTearOff.h index b39aaf3c1..4e6f5fd9f 100644 --- a/Source/WebCore/svg/properties/SVGStaticListPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGStaticListPropertyTearOff.h @@ -96,14 +96,16 @@ private: m_values->commitChange(m_contextElement.get()); } - virtual void processIncomingListItemValue(const ListItemType&, unsigned*) + virtual bool processIncomingListItemValue(const ListItemType&, unsigned*) { // no-op for static lists + return true; } - virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*) + virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*) { ASSERT_NOT_REACHED(); + return true; } private: diff --git a/Source/sync.profile b/Source/sync.profile index 4dbcb0106..55efd2667 100644 --- a/Source/sync.profile +++ b/Source/sync.profile @@ -17,7 +17,7 @@ # - any git symbolic ref resolvable from the module's repository (e.g. "refs/heads/master" to track master branch) # %dependencies = ( - "qtbase" => "refs/heads/release", - "qtdeclarative" => "refs/heads/release", - "qtjsbackend" => "refs/heads/release", + "qtbase" => "refs/heads/old/5.0", + "qtdeclarative" => "refs/heads/old/5.0", + "qtjsbackend" => "refs/heads/old/5.0", ); diff --git a/Tools/qmake/mkspecs/features/default_post.prf b/Tools/qmake/mkspecs/features/default_post.prf index 7c92a7d3c..603d9782c 100644 --- a/Tools/qmake/mkspecs/features/default_post.prf +++ b/Tools/qmake/mkspecs/features/default_post.prf @@ -36,8 +36,6 @@ CONFIG(release, debug|release): DEFINES *= NDEBUG DEFINES += $$configDefines() -DEPENDPATH += $$OUT_PWD - INCLUDEPATH += \ $${ROOT_WEBKIT_DIR}/Source \ $${ROOT_BUILD_DIR}/Source/include \ |