Chromium Code Reviews| Index: Source/core/rendering/RenderWidget.cpp |
| diff --git a/Source/core/rendering/RenderWidget.cpp b/Source/core/rendering/RenderWidget.cpp |
| index 90b089686a84874a9d904ab5eeabd24ff94a081e..5cce8b2358bbe564be11f2d54a0d11b90d972885 100644 |
| --- a/Source/core/rendering/RenderWidget.cpp |
| +++ b/Source/core/rendering/RenderWidget.cpp |
| @@ -26,6 +26,8 @@ |
| #include "core/accessibility/AXObjectCache.h" |
| #include "core/frame/Frame.h" |
| +#include "core/html/HTMLFrameOwnerElement.h" |
| +#include "core/html/HTMLPlugInElement.h" |
| #include "core/rendering/CompositedLayerMapping.h" |
| #include "core/rendering/GraphicsContextAnnotator.h" |
| #include "core/rendering/HitTestResult.h" |
| @@ -37,57 +39,8 @@ |
| namespace WebCore { |
| -typedef HashMap<RefPtr<Widget>, FrameView*> WidgetToParentMap; |
| -static WidgetToParentMap& widgetNewParentMap() |
| -{ |
| - DEFINE_STATIC_LOCAL(WidgetToParentMap, map, ()); |
| - return map; |
| -} |
| - |
| -static unsigned s_updateSuspendCount = 0; |
| - |
| -RenderWidget::UpdateSuspendScope::UpdateSuspendScope() |
| -{ |
| - ++s_updateSuspendCount; |
| -} |
| - |
| -RenderWidget::UpdateSuspendScope::~UpdateSuspendScope() |
| -{ |
| - ASSERT(s_updateSuspendCount > 0); |
| - if (s_updateSuspendCount == 1) { |
| - WidgetToParentMap map; |
| - widgetNewParentMap().swap(map); |
| - WidgetToParentMap::iterator end = map.end(); |
| - for (WidgetToParentMap::iterator it = map.begin(); it != end; ++it) { |
| - Widget* child = it->key.get(); |
| - ScrollView* currentParent = toScrollView(child->parent()); |
| - FrameView* newParent = it->value; |
| - if (newParent != currentParent) { |
| - if (currentParent) |
| - currentParent->removeChild(child); |
| - if (newParent) |
| - newParent->addChild(child); |
| - } |
| - } |
| - } |
| - --s_updateSuspendCount; |
| -} |
| - |
| -static void moveWidgetToParentSoon(Widget* child, FrameView* parent) |
| -{ |
| - if (!s_updateSuspendCount) { |
| - if (parent) |
| - parent->addChild(child); |
| - else |
| - toScrollView(child->parent())->removeChild(child); |
| - return; |
| - } |
| - widgetNewParentMap().set(child, parent); |
| -} |
| - |
| RenderWidget::RenderWidget(Element* element) |
| : RenderReplaced(element) |
| - , m_widget(0) |
| , m_frameView(element->document().view()) |
| // Reference counting is used to prevent the widget from being |
| // destroyed while inside the Widget code, which might not be |
| @@ -107,7 +60,9 @@ void RenderWidget::willBeDestroyed() |
| cache->remove(this); |
| } |
| - setWidget(0); |
| + Element* element = toElement(node()); |
| + if (element && element->isFrameOwnerElement()) |
| + toHTMLFrameOwnerElement(element)->setWidget(0); |
| RenderReplaced::willBeDestroyed(); |
| } |
| @@ -122,7 +77,17 @@ void RenderWidget::destroy() |
| RenderWidget::~RenderWidget() |
| { |
| ASSERT(m_refCount <= 0); |
| - clearWidget(); |
| +} |
| + |
| +Widget* RenderWidget::widget() const |
| +{ |
| + // Plugin widgets are stored in their DOM node. This includes HTMLAppletElement. |
| + Element* element = toElement(node()); |
| + |
| + if (element && element->isFrameOwnerElement()) |
| + return toHTMLFrameOwnerElement(element)->widget(); |
| + |
| + return 0; |
| } |
| // Widgets are always placed on integer boundaries, so rounding the size is actually |
| @@ -138,10 +103,13 @@ bool RenderWidget::setWidgetGeometry(const LayoutRect& frame) |
| if (!node()) |
| return false; |
| + Widget* widget = this->widget(); |
| + ASSERT(widget); |
| + |
| IntRect clipRect = roundedIntRect(enclosingLayer()->childrenClipRect()); |
| IntRect newFrame = roundedIntRect(frame); |
| bool clipChanged = m_clipRect != clipRect; |
| - bool frameRectChanged = m_widget->frameRect() != newFrame; |
| + bool frameRectChanged = widget->frameRect() != newFrame; |
| if (!frameRectChanged && !clipChanged) |
| return false; |
| @@ -150,23 +118,25 @@ bool RenderWidget::setWidgetGeometry(const LayoutRect& frame) |
| RefPtr<RenderWidget> protector(this); |
| RefPtr<Node> protectedNode(node()); |
| - m_widget->setFrameRect(newFrame); |
| + widget->setFrameRect(newFrame); |
| if (clipChanged && !frameRectChanged) |
| - m_widget->clipRectChanged(); |
| + widget->clipRectChanged(); |
| if (hasLayer() && layer()->compositingState() == PaintsIntoOwnBacking) |
| layer()->compositedLayerMapping()->updateAfterWidgetResize(); |
| - bool boundsChanged = m_widget->frameRect().size() != newFrame.size(); |
| + bool boundsChanged = widget->frameRect().size() != newFrame.size(); |
| return boundsChanged; |
| } |
| bool RenderWidget::updateWidgetGeometry() |
| { |
| + Widget* widget = this->widget(); |
| + |
| LayoutRect contentBox = contentBoxRect(); |
| LayoutRect absoluteContentBox(localToAbsoluteQuad(FloatQuad(contentBox)).boundingBox()); |
| - if (m_widget->isFrameView()) { |
| + if (widget->isFrameView()) { |
| contentBox.setLocation(absoluteContentBox.location()); |
| return setWidgetGeometry(contentBox); |
| } |
| @@ -174,38 +144,6 @@ bool RenderWidget::updateWidgetGeometry() |
| return setWidgetGeometry(absoluteContentBox); |
| } |
| -void RenderWidget::setWidget(PassRefPtr<Widget> widget) |
| -{ |
| - if (widget == m_widget) |
| - return; |
| - |
| - if (m_widget) { |
| - moveWidgetToParentSoon(m_widget.get(), 0); |
| - clearWidget(); |
| - } |
| - m_widget = widget; |
| - if (m_widget) { |
| - // If we've already received a layout, apply the calculated space to the |
| - // widget immediately, but we have to have really been fully constructed (with a non-null |
| - // style pointer). |
| - if (style()) { |
| - if (!needsLayout()) |
| - updateWidgetGeometry(); |
| - |
| - if (style()->visibility() != VISIBLE) |
| - m_widget->hide(); |
| - else { |
| - m_widget->show(); |
| - repaint(); |
| - } |
| - } |
| - moveWidgetToParentSoon(m_widget.get(), m_frameView); |
| - } |
| - |
| - if (AXObjectCache* cache = document().existingAXObjectCache()) |
| - cache->childrenChanged(this); |
| -} |
| - |
| void RenderWidget::layout() |
| { |
| ASSERT(needsLayout()); |
| @@ -217,11 +155,13 @@ void RenderWidget::layout() |
| void RenderWidget::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) |
| { |
| RenderReplaced::styleDidChange(diff, oldStyle); |
| - if (m_widget) { |
| + Widget* widget = this->widget(); |
| + |
| + if (widget) { |
| if (style()->visibility() != VISIBLE) |
| - m_widget->hide(); |
| + widget->hide(); |
| else |
| - m_widget->show(); |
| + widget->show(); |
| } |
| } |
| @@ -229,9 +169,12 @@ void RenderWidget::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintO |
| { |
| LayoutPoint adjustedPaintOffset = paintOffset + location(); |
| + Widget* widget = this->widget(); |
| + ASSERT(widget); |
| + |
| // Tell the widget to paint now. This is the only time the widget is allowed |
| // to paint itself. That way it will composite properly with z-indexed layers. |
| - IntPoint widgetLocation = m_widget->frameRect().location(); |
| + IntPoint widgetLocation = widget->frameRect().location(); |
| IntPoint paintLocation(roundToInt(adjustedPaintOffset.x() + borderLeft() + paddingLeft()), |
| roundToInt(adjustedPaintOffset.y() + borderTop() + paddingTop())); |
| IntRect paintRect = paintInfo.rect; |
| @@ -243,17 +186,17 @@ void RenderWidget::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintO |
| paintInfo.context->translate(widgetPaintOffset); |
| paintRect.move(-widgetPaintOffset); |
| } |
| - m_widget->paint(paintInfo.context, paintRect); |
| + widget->paint(paintInfo.context, paintRect); |
| if (!widgetPaintOffset.isZero()) |
| paintInfo.context->translate(-widgetPaintOffset); |
| - if (m_widget->isFrameView()) { |
| - FrameView* frameView = toFrameView(m_widget.get()); |
| + if (widget->isFrameView()) { |
| + FrameView* frameView = toFrameView(widget); |
| bool runOverlapTests = !frameView->useSlowRepaintsIfNotOverlapped() || frameView->hasCompositedContent(); |
| if (paintInfo.overlapTestRequests && runOverlapTests) { |
| ASSERT(!paintInfo.overlapTestRequests->contains(this)); |
| - paintInfo.overlapTestRequests->set(this, m_widget->frameRect()); |
| + paintInfo.overlapTestRequests->set(this, widget->frameRect()); |
| } |
| } |
| } |
| @@ -294,7 +237,8 @@ void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) |
| clipRoundedInnerRect(paintInfo.context, borderRect, roundedInnerRect); |
| } |
| - if (m_widget) |
| + Widget* widget = this->widget(); |
| + if (widget) |
| paintContents(paintInfo, paintOffset); |
| if (style()->hasBorderRadius()) |
| @@ -312,9 +256,10 @@ void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) |
| void RenderWidget::setIsOverlapped(bool isOverlapped) |
| { |
| - ASSERT(m_widget); |
| - ASSERT(m_widget->isFrameView()); |
| - toFrameView(m_widget.get())->setIsOverlapped(isOverlapped); |
| + Widget* widget = this->widget(); |
| + ASSERT(widget); |
| + ASSERT(widget->isFrameView()); |
| + toFrameView(widget)->setIsOverlapped(isOverlapped); |
| } |
| void RenderWidget::deref() |
| @@ -323,17 +268,38 @@ void RenderWidget::deref() |
| postDestroy(); |
| } |
| +void RenderWidget::updateOnWidgetChange() |
| +{ |
| + Widget* widget = this->widget(); |
| + if (!widget) |
| + return; |
| + |
| + if (!style()) |
| + return; |
| + |
| + if (!needsLayout()) |
| + updateWidgetGeometry(); |
| + |
| + if (style()->visibility() != VISIBLE) { |
| + widget->hide(); |
| + } else { |
| + widget->show(); |
| + repaint(); |
|
eseidel
2013/12/24 00:02:04
Since we don't understand the unpaired repaint() h
wjmaclean
2013/12/24 00:14:32
Done.
|
| + } |
| +} |
| + |
| void RenderWidget::updateWidgetPosition() |
| { |
| - if (!m_widget || !node()) // Check the node in case destroy() has been called. |
| + Widget* widget = this->widget(); |
| + if (!widget || !node()) // Check the node in case destroy() has been called. |
| return; |
| bool boundsChanged = updateWidgetGeometry(); |
| // if the frame bounds got changed, or if view needs layout (possibly indicating |
| // content size is wrong) we have to do a layout to set the right widget size |
| - if (m_widget && m_widget->isFrameView()) { |
| - FrameView* frameView = toFrameView(m_widget.get()); |
| + if (widget && widget->isFrameView()) { |
| + FrameView* frameView = toFrameView(widget); |
| // Check the frame's page to make sure that the frame isn't in the process of being destroyed. |
| if ((boundsChanged || frameView->needsLayout()) && frameView->frame().page()) |
| frameView->layout(); |
| @@ -342,14 +308,10 @@ void RenderWidget::updateWidgetPosition() |
| void RenderWidget::widgetPositionsUpdated() |
| { |
| - if (!m_widget) |
| + Widget* widget = this->widget(); |
| + if (!widget) |
| return; |
| - m_widget->widgetPositionsUpdated(); |
| -} |
| - |
| -void RenderWidget::clearWidget() |
| -{ |
| - m_widget = 0; |
| + widget->widgetPositionsUpdated(); |
| } |
| bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) |