Changeset 65681 in webkit
- Timestamp:
- Aug 19, 2010 10:19:40 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r65680 r65681 1 2010-08-19 Simon Fraser <simon.fraser@apple.com> 2 3 Reviewed by Nikolas Zimmermann. 4 5 HTMLElement::isContentEditable() can cause an updateStyleIfNeeded() to happen in the middle of layout 6 https://bugs.webkit.org/show_bug.cgi?id=21834 7 <rdar://problem/8093653&8261394> 8 9 If we're in the middle of layout, or painting, and something causes updateStyleIfNeeded() to 10 get called, then we can end up entering recalcStyle() during layout or painting. This is bad 11 because it can create/destry the renderers and RenderLayers which are in use by layout/painting. 12 This is the cause of a number of random crashers, some of which show up more frequently 13 in content which uses accelerated compositing. 14 15 The changes here: 16 1. Add an assertion in Document::updateStyleIfNeeded() that we are not laying out or painting. 17 2. Remove calls to updateStyleIfNeeded() in editing and caret painting code 18 3. Pass along information to CTM and BBox-related SVG methods to indicate whether it's safe 19 to update style. 20 21 Tested by new assertions and existing tests. 22 23 * dom/Document.cpp: 24 (WebCore::Document::updateStyleIfNeeded): New assertion that we are not mid-layout or painting. 25 (WebCore::command): Call updateStyleIfNeeded() to ensure that subsequent calls to isContentEditable() 26 return the correct result. 27 28 * dom/Element.cpp: 29 (WebCore::Element::focus): Move the supportsFocus() call to after style has been updated. 30 31 * editing/SelectionController.cpp: 32 (WebCore::SelectionController::localCaretRect): 33 (WebCore::SelectionController::caretRepaintRect): 34 (WebCore::SelectionController::paintCaret): 35 * editing/SelectionController.h: 36 (WebCore::SelectionController::localCaretRectForPainting): When painting, use localCaretRectForPainting() 37 which does not update style. Make localCaretRect() non-const so allowing it to update style without ugly casts. 38 39 * html/HTMLElement.cpp: 40 (WebCore::HTMLElement::isContentEditable): Don't call updateStyleIfNeeded() here. 41 (WebCore::HTMLElement::isContentRichlyEditable): Ditto. 42 (WebCore::HTMLElement::contentEditable): Ditto. 43 44 * page/FrameView.h: 45 (WebCore::FrameView::isMidLayout): New accessor, used for asserting. 46 47 * rendering/RenderPath.cpp: 48 (WebCore::fillAndStrokePath): Pass DisallowStyleUpdate to getScreenCTM since we are painting. 49 * rendering/RenderSVGResourceContainer.cpp: 50 (WebCore::RenderSVGResourceContainer::transformOnNonScalingStroke): This is only called when 51 painting, so use DisallowStyleUpdate. 52 53 * svg/SVGElement.cpp: 54 (WebCore::SVGElement::attributeChanged): Changes to the style attribute should not have 55 side effects, since a call to Element::getAttribute() is allowed to result in a call to 56 setAttribute() for the style attribute. To avoid updateStyleIfNeeded() during painting, 57 this must not cause SVG to do extra work. 58 59 * svg/SVGLocatable.cpp: Pass StyleUpdateStrategy down to these methods to indicate 60 whether it's OK to update style. 61 (WebCore::SVGLocatable::getBBox): 62 (WebCore::SVGLocatable::computeCTM): 63 (WebCore::SVGLocatable::getTransformToElement): 64 * svg/SVGLocatable.h: 65 (WebCore::SVGLocatable::): 66 * svg/SVGStyledLocatableElement.cpp: 67 (WebCore::SVGStyledLocatableElement::getBBox): 68 (WebCore::SVGStyledLocatableElement::getCTM): 69 (WebCore::SVGStyledLocatableElement::getScreenCTM): 70 * svg/SVGStyledLocatableElement.h: 71 * svg/SVGStyledTransformableElement.cpp: 72 (WebCore::SVGStyledTransformableElement::getCTM): 73 (WebCore::SVGStyledTransformableElement::getScreenCTM): 74 (WebCore::SVGStyledTransformableElement::getBBox): 75 * svg/SVGStyledTransformableElement.h: 76 * svg/SVGTextElement.cpp: 77 (WebCore::SVGTextElement::getBBox): 78 (WebCore::SVGTextElement::getCTM): 79 (WebCore::SVGTextElement::getScreenCTM): 80 * svg/SVGTextElement.h: 81 1 82 2010-08-19 Ryosuke Niwa <rniwa@webkit.org> 2 83 -
trunk/WebCore/dom/Document.cpp
r65468 r65681 1477 1477 void Document::updateStyleIfNeeded() 1478 1478 { 1479 ASSERT(!view() || (!view()->isInLayout() && !view()->isPainting())); 1480 1479 1481 if (!childNeedsStyleRecalc() || inPageCache()) 1480 1482 return; … … 3764 3766 if (!frame || frame->document() != document) 3765 3767 return Editor::Command(); 3768 3769 document->updateStyleIfNeeded(); 3770 3766 3771 return frame->editor()->command(commandName, 3767 3772 userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM); -
trunk/WebCore/dom/Element.cpp
r65372 r65681 1294 1294 return; 1295 1295 1296 if (!supportsFocus())1297 return;1298 1299 1296 // If the stylesheets have already been loaded we can reliably check isFocusable. 1300 1297 // If not, we continue and set the focused node on the focus controller below so … … 1305 1302 return; 1306 1303 } 1304 1305 if (!supportsFocus()) 1306 return; 1307 1307 1308 1308 RefPtr<Node> protect; -
trunk/WebCore/editing/SelectionController.cpp
r62873 r65681 953 953 } 954 954 955 IntRect SelectionController::localCaretRect() const955 IntRect SelectionController::localCaretRect() 956 956 { 957 957 if (m_needsLayout) 958 const_cast<SelectionController*>(this)->layout();958 layout(); 959 959 960 960 return m_caretRect; … … 988 988 IntRect SelectionController::caretRepaintRect() const 989 989 { 990 return absoluteBoundsForLocalRect(repaintRectForCaret(localCaretRect ()));990 return absoluteBoundsForLocalRect(repaintRectForCaret(localCaretRectForPainting())); 991 991 } 992 992 … … 1080 1080 return; 1081 1081 1082 IntRect drawingRect = localCaretRect ();1082 IntRect drawingRect = localCaretRectForPainting(); 1083 1083 drawingRect.move(tx, ty); 1084 1084 IntRect caret = intersection(drawingRect, clipRect); -
trunk/WebCore/editing/SelectionController.h
r62816 r65681 101 101 102 102 // Caret rect local to the caret's renderer 103 IntRect localCaretRect() const; 103 IntRect localCaretRect(); 104 IntRect localCaretRectForPainting() const { return m_caretRect; } 105 104 106 // Bounds of (possibly transformed) caret in absolute coords 105 107 IntRect absoluteCaretBounds(); -
trunk/WebCore/html/HTMLElement.cpp
r65372 r65681 667 667 return true; 668 668 669 // FIXME: this is a terrible thing to do here:670 // https://bugs.webkit.org/show_bug.cgi?id=21834671 document()->updateStyleIfNeeded();669 // Ideally we'd call ASSERT!needsStyleRecalc()) here, but 670 // ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion 671 // would fire in the middle of Document::setFocusedNode(). 672 672 673 673 if (!renderer()) { … … 686 686 return true; 687 687 688 document()->updateStyleIfNeeded();689 690 688 if (!renderer()) { 691 689 if (parentNode()) … … 700 698 String HTMLElement::contentEditable() const 701 699 { 702 document()->updateStyleIfNeeded();703 704 700 if (!renderer()) 705 701 return "false"; -
trunk/WebCore/page/FrameView.cpp
r65534 r65681 204 204 m_doFullRepaint = true; 205 205 m_layoutSchedulingEnabled = true; 206 m_ midLayout = false;206 m_inLayout = false; 207 207 m_layoutCount = 0; 208 208 m_nestedLayoutCount = 0; … … 601 601 void FrameView::layout(bool allowSubtree) 602 602 { 603 if (m_ midLayout)603 if (m_inLayout) 604 604 return; 605 605 … … 773 773 } 774 774 775 m_ midLayout = true;775 m_inLayout = true; 776 776 beginDeferredRepaints(); 777 777 root->layout(); 778 778 endDeferredRepaints(); 779 m_ midLayout = false;779 m_inLayout = false; 780 780 781 781 if (subtree) { -
trunk/WebCore/page/FrameView.h
r65021 r65681 89 89 void unscheduleRelayout(); 90 90 bool layoutPending() const; 91 bool isInLayout() const { return m_inLayout; } 91 92 92 93 RenderObject* layoutRoot(bool onlyDuringLayout = false) const; … … 318 319 319 320 bool m_layoutSchedulingEnabled; 320 bool m_ midLayout;321 bool m_inLayout; 321 322 int m_layoutCount; 322 323 unsigned m_nestedLayoutCount; -
trunk/WebCore/rendering/RenderPath.cpp
r64830 r65681 142 142 if (style->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE) { 143 143 SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node()); 144 AffineTransform transform = element->getScreenCTM( );144 AffineTransform transform = element->getScreenCTM(SVGLocatable::DisallowStyleUpdate); 145 145 if (!transform.isInvertible()) 146 146 return; -
trunk/WebCore/rendering/RenderSVGResourceContainer.cpp
r65310 r65681 185 185 SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node()); 186 186 AffineTransform transform = resourceTransform; 187 transform.multiply(element->getScreenCTM( ));187 transform.multiply(element->getScreenCTM(SVGLocatable::DisallowStyleUpdate)); 188 188 return transform; 189 189 } -
trunk/WebCore/svg/SVGElement.cpp
r64579 r65681 313 313 return; 314 314 315 svgAttributeChanged(attr->name()); 315 // Changes to the style attribute are processed lazily (see Element::getAttribute() and related methods), 316 // so we don't want changes to the style attribute to result in extra work here. 317 if (attr->name() != styleAttr) 318 svgAttributeChanged(attr->name()); 316 319 } 317 320 -
trunk/WebCore/svg/SVGLocatable.cpp
r64579 r65681 72 72 } 73 73 74 FloatRect SVGLocatable::getBBox(const SVGElement* element )74 FloatRect SVGLocatable::getBBox(const SVGElement* element, StyleUpdateStrategy styleUpdateStrategy) 75 75 { 76 76 ASSERT(element); 77 element->document()->updateLayoutIgnorePendingStylesheets(); 77 if (styleUpdateStrategy == AllowStyleUpdate) 78 element->document()->updateLayoutIgnorePendingStylesheets(); 78 79 79 80 // FIXME: Eventually we should support getBBox for detached elements. … … 84 85 } 85 86 86 AffineTransform SVGLocatable::computeCTM(const SVGElement* element, CTMScope mode )87 AffineTransform SVGLocatable::computeCTM(const SVGElement* element, CTMScope mode, StyleUpdateStrategy styleUpdateStrategy) 87 88 { 88 89 ASSERT(element); 89 element->document()->updateLayoutIgnorePendingStylesheets(); 90 if (styleUpdateStrategy == AllowStyleUpdate) 91 element->document()->updateLayoutIgnorePendingStylesheets(); 90 92 91 93 AffineTransform ctm; … … 109 111 } 110 112 111 AffineTransform SVGLocatable::getTransformToElement(SVGElement* target, ExceptionCode& ec ) const113 AffineTransform SVGLocatable::getTransformToElement(SVGElement* target, ExceptionCode& ec, StyleUpdateStrategy styleUpdateStrategy) const 112 114 { 113 AffineTransform ctm = getCTM( );115 AffineTransform ctm = getCTM(styleUpdateStrategy); 114 116 115 117 if (target && target->isStyledLocatable()) { 116 AffineTransform targetCTM = static_cast<SVGStyledLocatableElement*>(target)->getCTM( );118 AffineTransform targetCTM = static_cast<SVGStyledLocatableElement*>(target)->getCTM(styleUpdateStrategy); 117 119 if (!targetCTM.isInvertible()) { 118 120 ec = SVGException::SVG_MATRIX_NOT_INVERTABLE; -
trunk/WebCore/svg/SVGLocatable.h
r64579 r65681 41 41 virtual SVGElement* farthestViewportElement() const = 0; 42 42 43 virtual FloatRect getBBox() const = 0; 44 virtual AffineTransform getCTM() const = 0; 45 virtual AffineTransform getScreenCTM() const = 0; 46 AffineTransform getTransformToElement(SVGElement*, ExceptionCode&) const; 43 enum StyleUpdateStrategy { AllowStyleUpdate, DisallowStyleUpdate }; 44 45 virtual FloatRect getBBox(StyleUpdateStrategy) const = 0; 46 virtual AffineTransform getCTM(StyleUpdateStrategy) const = 0; 47 virtual AffineTransform getScreenCTM(StyleUpdateStrategy) const = 0; 48 AffineTransform getTransformToElement(SVGElement*, ExceptionCode&, StyleUpdateStrategy = AllowStyleUpdate) const; 47 49 48 50 static SVGElement* nearestViewportElement(const SVGElement*); … … 57 59 virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const { return AffineTransform(); } 58 60 59 static FloatRect getBBox(const SVGElement* );60 static AffineTransform computeCTM(const SVGElement*, CTMScope );61 static FloatRect getBBox(const SVGElement*, StyleUpdateStrategy); 62 static AffineTransform computeCTM(const SVGElement*, CTMScope, StyleUpdateStrategy); 61 63 }; 62 64 -
trunk/WebCore/svg/SVGStyledLocatableElement.cpp
r64579 r65681 51 51 } 52 52 53 FloatRect SVGStyledLocatableElement::getBBox( ) const53 FloatRect SVGStyledLocatableElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) const 54 54 { 55 return SVGLocatable::getBBox(this );55 return SVGLocatable::getBBox(this, styleUpdateStrategy); 56 56 } 57 57 58 AffineTransform SVGStyledLocatableElement::getCTM( ) const58 AffineTransform SVGStyledLocatableElement::getCTM(StyleUpdateStrategy styleUpdateStrategy) const 59 59 { 60 return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope );60 return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy); 61 61 } 62 62 63 AffineTransform SVGStyledLocatableElement::getScreenCTM( ) const63 AffineTransform SVGStyledLocatableElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) const 64 64 { 65 return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope );65 return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy); 66 66 } 67 67 -
trunk/WebCore/svg/SVGStyledLocatableElement.h
r64579 r65681 41 41 virtual SVGElement* farthestViewportElement() const; 42 42 43 virtual FloatRect getBBox( ) const;44 virtual AffineTransform getCTM( ) const;45 virtual AffineTransform getScreenCTM( ) const;43 virtual FloatRect getBBox(StyleUpdateStrategy = AllowStyleUpdate) const; 44 virtual AffineTransform getCTM(StyleUpdateStrategy = AllowStyleUpdate) const; 45 virtual AffineTransform getScreenCTM(StyleUpdateStrategy = AllowStyleUpdate) const; 46 46 47 47 virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const { return SVGLocatable::localCoordinateSpaceTransform(mode); } -
trunk/WebCore/svg/SVGStyledTransformableElement.cpp
r64579 r65681 44 44 } 45 45 46 AffineTransform SVGStyledTransformableElement::getCTM( ) const46 AffineTransform SVGStyledTransformableElement::getCTM(StyleUpdateStrategy styleUpdateStrategy) const 47 47 { 48 return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope );48 return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy); 49 49 } 50 50 51 AffineTransform SVGStyledTransformableElement::getScreenCTM( ) const51 AffineTransform SVGStyledTransformableElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) const 52 52 { 53 return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope );53 return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy); 54 54 } 55 55 … … 102 102 } 103 103 104 FloatRect SVGStyledTransformableElement::getBBox( ) const104 FloatRect SVGStyledTransformableElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) const 105 105 { 106 return SVGTransformable::getBBox(this );106 return SVGTransformable::getBBox(this, styleUpdateStrategy); 107 107 } 108 108 -
trunk/WebCore/svg/SVGStyledTransformableElement.h
r64579 r65681 39 39 virtual bool isStyledTransformable() const { return true; } 40 40 41 virtual AffineTransform getCTM( ) const;42 virtual AffineTransform getScreenCTM( ) const;41 virtual AffineTransform getCTM(StyleUpdateStrategy = AllowStyleUpdate) const; 42 virtual AffineTransform getScreenCTM(StyleUpdateStrategy = AllowStyleUpdate) const; 43 43 virtual SVGElement* nearestViewportElement() const; 44 44 virtual SVGElement* farthestViewportElement() const; … … 48 48 virtual AffineTransform* supplementalTransform(); 49 49 50 virtual FloatRect getBBox( ) const;50 virtual FloatRect getBBox(StyleUpdateStrategy = AllowStyleUpdate) const; 51 51 52 52 virtual void parseMappedAttribute(Attribute*); -
trunk/WebCore/svg/SVGTextElement.cpp
r64579 r65681 69 69 } 70 70 71 FloatRect SVGTextElement::getBBox( ) const71 FloatRect SVGTextElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) const 72 72 { 73 return SVGTransformable::getBBox(this );73 return SVGTransformable::getBBox(this, styleUpdateStrategy); 74 74 } 75 75 76 AffineTransform SVGTextElement::getCTM( ) const76 AffineTransform SVGTextElement::getCTM(StyleUpdateStrategy styleUpdateStrategy) const 77 77 { 78 return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope );78 return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy); 79 79 } 80 80 81 AffineTransform SVGTextElement::getScreenCTM( ) const81 AffineTransform SVGTextElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) const 82 82 { 83 return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope );83 return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy); 84 84 } 85 85 -
trunk/WebCore/svg/SVGTextElement.h
r64579 r65681 39 39 virtual SVGElement* farthestViewportElement() const; 40 40 41 virtual FloatRect getBBox( ) const;42 virtual AffineTransform getCTM( ) const;43 virtual AffineTransform getScreenCTM( ) const;41 virtual FloatRect getBBox(StyleUpdateStrategy = AllowStyleUpdate) const; 42 virtual AffineTransform getCTM(StyleUpdateStrategy = AllowStyleUpdate) const; 43 virtual AffineTransform getScreenCTM(StyleUpdateStrategy = AllowStyleUpdate) const; 44 44 virtual AffineTransform animatedLocalTransform() const; 45 45 virtual AffineTransform* supplementalTransform();
Note: See TracChangeset
for help on using the changeset viewer.