diff options
Diffstat (limited to 'Source/WebCore/rendering/RenderWidget.cpp')
-rw-r--r-- | Source/WebCore/rendering/RenderWidget.cpp | 135 |
1 files changed, 65 insertions, 70 deletions
diff --git a/Source/WebCore/rendering/RenderWidget.cpp b/Source/WebCore/rendering/RenderWidget.cpp index ef804b2be..b5b188823 100644 --- a/Source/WebCore/rendering/RenderWidget.cpp +++ b/Source/WebCore/rendering/RenderWidget.cpp @@ -24,18 +24,17 @@ #include "RenderWidget.h" #include "AXObjectCache.h" +#include "FloatRoundedRect.h" #include "Frame.h" #include "HTMLFrameOwnerElement.h" #include "HitTestResult.h" #include "RenderLayer.h" +#include "RenderLayerBacking.h" #include "RenderView.h" +#include "SecurityOrigin.h" #include <wtf/StackStats.h> #include <wtf/Ref.h> -#if USE(ACCELERATED_COMPOSITING) -#include "RenderLayerBacking.h" -#endif - namespace WebCore { static HashMap<const Widget*, RenderWidget*>& widgetRendererMap() @@ -48,19 +47,17 @@ unsigned WidgetHierarchyUpdatesSuspensionScope::s_widgetHierarchyUpdateSuspendCo WidgetHierarchyUpdatesSuspensionScope::WidgetToParentMap& WidgetHierarchyUpdatesSuspensionScope::widgetNewParentMap() { - DEFINE_STATIC_LOCAL(WidgetToParentMap, map, ()); + static NeverDestroyed<WidgetToParentMap> map; return map; } void WidgetHierarchyUpdatesSuspensionScope::moveWidgets() { - 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 = child->parent(); - FrameView* newParent = it->value; + auto map = WTFMove(widgetNewParentMap()); + for (auto& entry : map) { + auto& child = *entry.key; + auto* currentParent = child.parent(); + auto* newParent = entry.value; if (newParent != currentParent) { if (currentParent) currentParent->removeChild(child); @@ -70,20 +67,20 @@ void WidgetHierarchyUpdatesSuspensionScope::moveWidgets() } } -static void moveWidgetToParentSoon(Widget* child, FrameView* parent) +static void moveWidgetToParentSoon(Widget& child, FrameView* parent) { if (!WidgetHierarchyUpdatesSuspensionScope::isSuspended()) { if (parent) parent->addChild(child); else - child->removeFromParent(); + child.removeFromParent(); return; } WidgetHierarchyUpdatesSuspensionScope::scheduleWidgetToMove(child, parent); } -RenderWidget::RenderWidget(HTMLFrameOwnerElement& element, PassRef<RenderStyle> style) - : RenderReplaced(element, std::move(style)) +RenderWidget::RenderWidget(HTMLFrameOwnerElement& element, RenderStyle&& style) + : RenderReplaced(element, WTFMove(style)) , m_weakPtrFactory(this) { setInline(false); @@ -101,13 +98,14 @@ void RenderWidget::willBeDestroyed() cache->remove(this); } - setWidget(0); + setWidget(nullptr); RenderReplaced::willBeDestroyed(); } RenderWidget::~RenderWidget() { + ASSERT(!m_refCount); } // Widgets are always placed on integer boundaries, so rounding the size is actually @@ -141,10 +139,9 @@ bool RenderWidget::setWidgetGeometry(const LayoutRect& frame) if (!weakThis) return true; -#if USE(ACCELERATED_COMPOSITING) - if (boundsChanged && hasLayer() && layer()->isComposited()) + if (boundsChanged && isComposited()) layer()->backing()->updateAfterWidgetResize(); -#endif + return oldFrameRect.size() != newFrameRect.size(); } @@ -163,13 +160,13 @@ bool RenderWidget::updateWidgetGeometry() return setWidgetGeometry(absoluteContentBox); } -void RenderWidget::setWidget(PassRefPtr<Widget> widget) +void RenderWidget::setWidget(RefPtr<Widget>&& widget) { if (widget == m_widget) return; if (m_widget) { - moveWidgetToParentSoon(m_widget.get(), 0); + moveWidgetToParentSoon(*m_widget, nullptr); view().frameView().willRemoveWidgetFromRenderTree(*m_widget); widgetRendererMap().remove(m_widget.get()); m_widget = nullptr; @@ -195,7 +192,7 @@ void RenderWidget::setWidget(PassRefPtr<Widget> widget) repaint(); } } - moveWidgetToParentSoon(m_widget.get(), &view().frameView()); + moveWidgetToParentSoon(*m_widget, &view().frameView()); } } @@ -220,32 +217,37 @@ void RenderWidget::styleDidChange(StyleDifference diff, const RenderStyle* oldSt void RenderWidget::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { - LayoutPoint adjustedPaintOffset = paintOffset + location(); + if (paintInfo.requireSecurityOriginAccessForWidgets) { + if (auto contentDocument = frameOwnerElement().contentDocument()) { + if (!document().securityOrigin().canAccess(contentDocument->securityOrigin())) + return; + } + } + IntPoint contentPaintOffset = roundedIntPoint(paintOffset + location() + contentBoxRect().location()); // 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 paintLocation(roundToInt(adjustedPaintOffset.x() + borderLeft() + paddingLeft()), - roundToInt(adjustedPaintOffset.y() + borderTop() + paddingTop())); LayoutRect paintRect = paintInfo.rect; - LayoutSize widgetPaintOffset = paintLocation - widgetLocation; + IntPoint widgetLocation = m_widget->frameRect().location(); + IntSize widgetPaintOffset = contentPaintOffset - widgetLocation; // When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer, // not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing. if (!widgetPaintOffset.isZero()) { - paintInfo.context->translate(widgetPaintOffset); + paintInfo.context().translate(widgetPaintOffset); paintRect.move(-widgetPaintOffset); } - m_widget->paint(paintInfo.context, pixelSnappedIntRect(paintRect)); + // FIXME: Remove repaintrect enclosing/integral snapping when RenderWidget becomes device pixel snapped. + m_widget->paint(paintInfo.context(), snappedIntRect(paintRect), paintInfo.requireSecurityOriginAccessForWidgets ? Widget::SecurityOriginPaintPolicy::AccessibleOriginOnly : Widget::SecurityOriginPaintPolicy::AnyOrigin); if (!widgetPaintOffset.isZero()) - paintInfo.context->translate(-widgetPaintOffset); + paintInfo.context().translate(-widgetPaintOffset); - if (m_widget->isFrameView()) { - FrameView* frameView = toFrameView(m_widget.get()); - bool runOverlapTests = !frameView->useSlowRepaintsIfNotOverlapped() || frameView->hasCompositedContentIncludingDescendants(); + if (is<FrameView>(*m_widget)) { + FrameView& frameView = downcast<FrameView>(*m_widget); + bool runOverlapTests = !frameView.useSlowRepaintsIfNotOverlapped(); if (paintInfo.overlapTestRequests && runOverlapTests) { - ASSERT(!paintInfo.overlapTestRequests->contains(this)); + ASSERT(!paintInfo.overlapTestRequests->contains(this) || (paintInfo.overlapTestRequests->get(this) == m_widget->frameRect())); paintInfo.overlapTestRequests->set(this, m_widget->frameRect()); } } @@ -258,7 +260,7 @@ void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) LayoutPoint adjustedPaintOffset = paintOffset + location(); - if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection)) + if (hasVisibleBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection)) paintBoxDecorations(paintInfo, adjustedPaintOffset); if (paintInfo.phase == PaintPhaseMask) { @@ -272,11 +274,6 @@ void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) if (paintInfo.phase != PaintPhaseForeground) return; -#if PLATFORM(MAC) - if (style().highlight() != nullAtom && !paintInfo.context->paintingDisabled()) - paintCustomHighlight(paintOffset, style().highlight(), true); -#endif - if (style().hasBorderRadius()) { LayoutRect borderRect = LayoutRect(adjustedPaintOffset, size()); @@ -284,53 +281,53 @@ void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) return; // Push a clip if we have a border radius, since we want to round the foreground content that gets painted. - paintInfo.context->save(); - RoundedRect roundedInnerRect = style().getRoundedInnerBorderFor(borderRect, - paddingTop() + borderTop(), paddingBottom() + borderBottom(), paddingLeft() + borderLeft(), paddingRight() + borderRight(), true, true); - clipRoundedInnerRect(paintInfo.context, borderRect, roundedInnerRect); + paintInfo.context().save(); + FloatRoundedRect roundedInnerRect = FloatRoundedRect(style().getRoundedInnerBorderFor(borderRect, + paddingTop() + borderTop(), paddingBottom() + borderBottom(), paddingLeft() + borderLeft(), paddingRight() + borderRight(), true, true)); + clipRoundedInnerRect(paintInfo.context(), borderRect, roundedInnerRect); } if (m_widget) paintContents(paintInfo, paintOffset); if (style().hasBorderRadius()) - paintInfo.context->restore(); + paintInfo.context().restore(); // Paint a partially transparent wash over selected widgets. if (isSelected() && !document().printing()) { // FIXME: selectionRect() is in absolute, not painting coordinates. - paintInfo.context->fillRect(pixelSnappedIntRect(selectionRect()), selectionBackgroundColor(), style().colorSpace()); + paintInfo.context().fillRect(snappedIntRect(selectionRect()), selectionBackgroundColor()); } if (hasLayer() && layer()->canResize()) - layer()->paintResizer(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect); + layer()->paintResizer(paintInfo.context(), roundedIntPoint(adjustedPaintOffset), paintInfo.rect); } void RenderWidget::setOverlapTestResult(bool isOverlapped) { ASSERT(m_widget); - ASSERT(m_widget->isFrameView()); - toFrameView(m_widget.get())->setIsOverlapped(isOverlapped); + downcast<FrameView>(*m_widget).setIsOverlapped(isOverlapped); } -void RenderWidget::updateWidgetPosition() +RenderWidget::ChildWidgetState RenderWidget::updateWidgetPosition() { if (!m_widget) - return; + return ChildWidgetState::Destroyed; WeakPtr<RenderWidget> weakThis = createWeakPtr(); bool widgetSizeChanged = updateWidgetGeometry(); - if (!weakThis) - return; + if (!weakThis || !m_widget) + return ChildWidgetState::Destroyed; // if the frame size 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->isFrameView()) { - FrameView* frameView = toFrameView(m_widget.get()); + if (is<FrameView>(*m_widget)) { + FrameView& frameView = downcast<FrameView>(*m_widget); // Check the frame's page to make sure that the frame isn't in the process of being destroyed. - if ((widgetSizeChanged || frameView->needsLayout()) && frameView->frame().page()) - frameView->layout(); + if ((widgetSizeChanged || frameView.needsLayout()) && frameView.frame().page()) + frameView.layout(); } + return ChildWidgetState::Valid; } IntRect RenderWidget::windowClipRect() const @@ -347,24 +344,24 @@ void RenderWidget::setSelectionState(SelectionState state) m_widget->setIsSelected(isSelected()); } -RenderWidget* RenderWidget::find(const Widget* widget) +RenderWidget* RenderWidget::find(const Widget& widget) { - return widgetRendererMap().get(widget); + return widgetRendererMap().get(&widget); } bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) { - if (request.allowsChildFrameContent() && widget() && widget()->isFrameView() && toFrameView(widget())->renderView()) { - FrameView* childFrameView = toFrameView(widget()); - RenderView* childRoot = childFrameView->renderView(); + if (request.allowsChildFrameContent() && is<FrameView>(widget()) && downcast<FrameView>(*widget()).renderView()) { + FrameView& childFrameView = downcast<FrameView>(*widget()); + RenderView& childRoot = *childFrameView.renderView(); LayoutPoint adjustedLocation = accumulatedOffset + location(); - LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - childFrameView->scrollOffset(); + LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - toIntSize(childFrameView.scrollPosition()); HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset); HitTestRequest newHitTestRequest(request.type() | HitTestRequest::ChildFrameHitTest); HitTestResult childFrameResult(newHitTestLocation); - bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTestLocation, childFrameResult); + bool isInsideChildFrame = childRoot.hitTest(newHitTestRequest, newHitTestLocation, childFrameResult); if (newHitTestLocation.isRectBasedTest()) result.append(childFrameResult); @@ -384,7 +381,6 @@ bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& res return inside; } -#if USE(ACCELERATED_COMPOSITING) bool RenderWidget::requiresLayer() const { return RenderReplaced::requiresLayer() || requiresAcceleratedCompositing(); @@ -400,7 +396,6 @@ bool RenderWidget::requiresAcceleratedCompositing() const return false; } -#endif bool RenderWidget::needsPreferredWidthsRecalculation() const { @@ -411,9 +406,9 @@ bool RenderWidget::needsPreferredWidthsRecalculation() const RenderBox* RenderWidget::embeddedContentBox() const { - if (!widget() || !widget()->isFrameView()) - return 0; - return toFrameView(widget())->embeddedContentBox(); + if (!is<FrameView>(widget())) + return nullptr; + return downcast<FrameView>(*widget()).embeddedContentBox(); } } // namespace WebCore |