Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / rendering / RenderEmbeddedObject.cpp
index 94e0a64..de91014 100644 (file)
 #include "ChromeClient.h"
 #include "Cursor.h"
 #include "EventHandler.h"
-#include "Font.h"
+#include "FontCascade.h"
 #include "FontSelector.h"
 #include "Frame.h"
 #include "FrameLoaderClient.h"
 #include "GraphicsContext.h"
+#include "HTMLAppletElement.h"
 #include "HTMLEmbedElement.h"
 #include "HTMLIFrameElement.h"
 #include "HTMLNames.h"
 #include "RenderLayer.h"
 #include "RenderTheme.h"
 #include "RenderView.h"
-#include "RenderWidgetProtector.h"
 #include "Settings.h"
 #include "Text.h"
 #include "TextRun.h"
 #include <wtf/StackStats.h>
 
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-#include "HTMLMediaElement.h"
-#endif
-
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -100,9 +96,8 @@ static const Color& unavailablePluginBorderColor()
     return standard;
 }
 
-RenderEmbeddedObject::RenderEmbeddedObject(Element* element)
-    : RenderPart(element)
-    , m_hasFallbackContent(false)
+RenderEmbeddedObject::RenderEmbeddedObject(HTMLFrameOwnerElement& element, Ref<RenderStyle>&& style)
+    : RenderWidget(element, WTFMove(style))
     , m_isPluginUnavailable(false)
     , m_isUnavailablePluginIndicatorHidden(false)
     , m_unavailablePluginIndicatorIsPressed(false)
@@ -114,14 +109,19 @@ RenderEmbeddedObject::RenderEmbeddedObject(Element* element)
 
 RenderEmbeddedObject::~RenderEmbeddedObject()
 {
-    if (frameView())
-        frameView()->removeWidgetToUpdate(this);
+    view().frameView().removeEmbeddedObjectToUpdate(*this);
+}
+
+RenderPtr<RenderEmbeddedObject> RenderEmbeddedObject::createForApplet(HTMLAppletElement& applet, Ref<RenderStyle>&& style)
+{
+    auto renderer = createRenderer<RenderEmbeddedObject>(applet, WTFMove(style));
+    renderer->setInline(true);
+    return renderer;
 }
 
-#if USE(ACCELERATED_COMPOSITING)
 bool RenderEmbeddedObject::requiresLayer() const
 {
-    if (RenderPart::requiresLayer())
+    if (RenderWidget::requiresLayer())
         return true;
     
     return allowsAcceleratedCompositing();
@@ -129,10 +129,15 @@ bool RenderEmbeddedObject::requiresLayer() const
 
 bool RenderEmbeddedObject::allowsAcceleratedCompositing() const
 {
-    return widget() && widget()->isPluginViewBase() && toPluginViewBase(widget())->platformLayer();
-}
+#if PLATFORM(IOS)
+    // The timing of layer creation is different on the phone, since the plugin can only be manipulated from the main thread.
+    return is<PluginViewBase>(widget()) && downcast<PluginViewBase>(*widget()).willProvidePluginLayer();
+#else
+    return is<PluginViewBase>(widget()) && downcast<PluginViewBase>(*widget()).platformLayer();
 #endif
+}
 
+#if !PLATFORM(IOS)
 static String unavailablePluginReplacementText(RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason)
 {
     switch (pluginUnavailabilityReason) {
@@ -149,6 +154,7 @@ static String unavailablePluginReplacementText(RenderEmbeddedObject::PluginUnava
     ASSERT_NOT_REACHED();
     return String();
 }
+#endif
 
 static bool shouldUnavailablePluginMessageBeButton(Document& document, RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason)
 {
@@ -158,11 +164,19 @@ static bool shouldUnavailablePluginMessageBeButton(Document& document, RenderEmb
 
 void RenderEmbeddedObject::setPluginUnavailabilityReason(PluginUnavailabilityReason pluginUnavailabilityReason)
 {
+#if PLATFORM(IOS)
+    UNUSED_PARAM(pluginUnavailabilityReason);
+#else
     setPluginUnavailabilityReasonWithDescription(pluginUnavailabilityReason, unavailablePluginReplacementText(pluginUnavailabilityReason));
+#endif
 }
 
 void RenderEmbeddedObject::setPluginUnavailabilityReasonWithDescription(PluginUnavailabilityReason pluginUnavailabilityReason, const String& description)
 {
+#if PLATFORM(IOS)
+    UNUSED_PARAM(pluginUnavailabilityReason);
+    UNUSED_PARAM(description);
+#else
     ASSERT(!m_isPluginUnavailable);
     m_isPluginUnavailable = true;
     m_pluginUnavailabilityReason = pluginUnavailabilityReason;
@@ -171,6 +185,7 @@ void RenderEmbeddedObject::setPluginUnavailabilityReasonWithDescription(PluginUn
         m_unavailablePluginReplacementText = unavailablePluginReplacementText(pluginUnavailabilityReason);
     else
         m_unavailablePluginReplacementText = description;
+#endif
 }
 
 void RenderEmbeddedObject::setUnavailablePluginIndicatorIsPressed(bool pressed)
@@ -182,69 +197,74 @@ void RenderEmbeddedObject::setUnavailablePluginIndicatorIsPressed(bool pressed)
     repaint();
 }
 
-void RenderEmbeddedObject::paintSnapshotImage(PaintInfo& paintInfo, const LayoutPoint& paintOffset, Image* image)
+void RenderEmbeddedObject::paintSnapshotImage(PaintInfo& paintInfo, const LayoutPoint& paintOffset, Image& image)
 {
     LayoutUnit cWidth = contentWidth();
     LayoutUnit cHeight = contentHeight();
     if (!cWidth || !cHeight)
         return;
 
-    GraphicsContext* context = paintInfo.context;
+    GraphicsContext& context = paintInfo.context();
     LayoutSize contentSize(cWidth, cHeight);
     LayoutPoint contentLocation = location() + paintOffset;
     contentLocation.move(borderLeft() + paddingLeft(), borderTop() + paddingTop());
 
     LayoutRect rect(contentLocation, contentSize);
-    IntRect alignedRect = pixelSnappedIntRect(rect);
+    IntRect alignedRect = snappedIntRect(rect);
     if (alignedRect.width() <= 0 || alignedRect.height() <= 0)
         return;
 
-    bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, image, alignedRect.size());
-    context->drawImage(image, style()->colorSpace(), alignedRect, CompositeSourceOver, ImageOrientationDescription(shouldRespectImageOrientation()), useLowQualityScaling);
+    bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, &image, alignedRect.size());
+    ImageOrientationDescription orientationDescription(shouldRespectImageOrientation());
+#if ENABLE(CSS_IMAGE_ORIENTATION)
+    orientationDescription.setImageOrientationEnum(style().imageOrientation());
+#endif
+    context.drawImage(image, alignedRect, ImagePaintingOptions(orientationDescription, useLowQualityScaling));
 }
 
 void RenderEmbeddedObject::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
-    Element* element = toElement(node());
-    if (!element || !element->isPluginElement())
+    if (!is<HTMLPlugInElement>(frameOwnerElement()))
         return;
 
-    HTMLPlugInElement* plugInElement = toHTMLPlugInElement(element);
+    HTMLPlugInElement& plugInElement = downcast<HTMLPlugInElement>(frameOwnerElement());
 
-    if (plugInElement->displayState() > HTMLPlugInElement::DisplayingSnapshot) {
-        RenderPart::paintContents(paintInfo, paintOffset);
-        if (!plugInElement->isRestartedPlugin())
+    if (plugInElement.displayState() > HTMLPlugInElement::DisplayingSnapshot) {
+        RenderWidget::paintContents(paintInfo, paintOffset);
+        if (!plugInElement.isRestartedPlugin())
             return;
     }
 
-    if (!plugInElement->isPlugInImageElement())
+    if (!is<HTMLPlugInImageElement>(plugInElement))
         return;
 
-    Image* snapshot = toHTMLPlugInImageElement(plugInElement)->snapshotImage();
-    if (snapshot)
-        paintSnapshotImage(paintInfo, paintOffset, snapshot);
+    if (Image* snapshot = downcast<HTMLPlugInImageElement>(plugInElement).snapshotImage())
+        paintSnapshotImage(paintInfo, paintOffset, *snapshot);
 }
 
 void RenderEmbeddedObject::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
     Page* page = frame().page();
 
+    // The relevant repainted object heuristic is not tuned for plugin documents.
+    bool countsTowardsRelevantObjects = page && !document().isPluginDocument() && paintInfo.phase == PaintPhaseForeground;
+
     if (isPluginUnavailable()) {
-        if (page && paintInfo.phase == PaintPhaseForeground)
+        if (countsTowardsRelevantObjects)
             page->addRelevantUnpaintedObject(this, visualOverflowRect());
         RenderReplaced::paint(paintInfo, paintOffset);
         return;
     }
 
-    if (page && paintInfo.phase == PaintPhaseForeground)
+    if (countsTowardsRelevantObjects)
         page->addRelevantRepaintedObject(this, visualOverflowRect());
 
-    RenderPart::paint(paintInfo, paintOffset);
+    RenderWidget::paint(paintInfo, paintOffset);
 }
 
-static void drawReplacementArrow(GraphicsContext* context, const FloatRect& insideRect)
+static void drawReplacementArrow(GraphicsContext& context, const FloatRect& insideRect)
 {
-    GraphicsContextStateSaver stateSaver(*context);
+    GraphicsContextStateSaver stateSaver(context);
 
     FloatRect rect(insideRect);
     rect.inflate(-replacementArrowPadding);
@@ -252,9 +272,9 @@ static void drawReplacementArrow(GraphicsContext* context, const FloatRect& insi
     FloatPoint center(rect.center());
     FloatPoint arrowTip(rect.maxX(), center.y());
 
-    context->setStrokeThickness(2);
-    context->setLineCap(RoundCap);
-    context->setLineJoin(RoundJoin);
+    context.setStrokeThickness(2);
+    context.setLineCap(RoundCap);
+    context.setLineJoin(RoundJoin);
 
     Path path;
     path.moveTo(FloatPoint(rect.x(), center.y()));
@@ -262,7 +282,7 @@ static void drawReplacementArrow(GraphicsContext* context, const FloatRect& insi
     path.addLineTo(FloatPoint(center.x(), rect.y()));
     path.moveTo(arrowTip);
     path.addLineTo(FloatPoint(center.x(), rect.maxY()));
-    context->strokePath(path);
+    context.strokePath(path);
 }
 
 void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -273,16 +293,16 @@ void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, const LayoutPoint
     if (paintInfo.phase == PaintPhaseSelection)
         return;
 
-    GraphicsContext* context = paintInfo.context;
-    if (context->paintingDisabled())
+    GraphicsContext& context = paintInfo.context();
+    if (context.paintingDisabled())
         return;
 
     FloatRect contentRect;
     FloatRect indicatorRect;
     FloatRect replacementTextRect;
     FloatRect arrowRect;
-    Font font;
-    TextRun run("");
+    FontCascade font;
+    TextRun run(emptyString());
     float textWidth;
     if (!getReplacementTextGeometry(paintOffset, contentRect, indicatorRect, replacementTextRect, arrowRect, font, run, textWidth))
         return;
@@ -290,59 +310,61 @@ void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, const LayoutPoint
     Path background;
     background.addRoundedRect(indicatorRect, FloatSize(replacementTextRoundedRectRadius, replacementTextRoundedRectRadius));
 
-    GraphicsContextStateSaver stateSaver(*context);
-    context->clip(contentRect);
-    context->setFillColor(m_unavailablePluginIndicatorIsPressed ? replacementTextRoundedRectPressedColor() : replacementTextRoundedRectColor(), style()->colorSpace());
-    context->fillPath(background);
+    GraphicsContextStateSaver stateSaver(context);
+    context.clip(contentRect);
+    context.setFillColor(m_unavailablePluginIndicatorIsPressed ? replacementTextRoundedRectPressedColor() : replacementTextRoundedRectColor());
+    context.fillPath(background);
 
     Path strokePath;
     FloatRect strokeRect(indicatorRect);
     strokeRect.inflate(1);
     strokePath.addRoundedRect(strokeRect, FloatSize(replacementTextRoundedRectRadius + 1, replacementTextRoundedRectRadius + 1));
 
-    context->setStrokeColor(unavailablePluginBorderColor(), style()->colorSpace());
-    context->setStrokeThickness(2);
-    context->strokePath(strokePath);
+    context.setStrokeColor(unavailablePluginBorderColor());
+    context.setStrokeThickness(2);
+    context.strokePath(strokePath);
 
     const FontMetrics& fontMetrics = font.fontMetrics();
     float labelX = roundf(replacementTextRect.location().x() + replacementTextRoundedRectLeftTextMargin);
     float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - fontMetrics.height()) / 2 + fontMetrics.ascent() + replacementTextRoundedRectTopTextMargin);
-    context->setFillColor(replacementTextColor(), style()->colorSpace());
-    context->drawBidiText(font, run, FloatPoint(labelX, labelY));
+    context.setFillColor(replacementTextColor());
+    context.drawBidiText(font, run, FloatPoint(labelX, labelY));
 
     if (shouldUnavailablePluginMessageBeButton(document(), m_pluginUnavailabilityReason)) {
         arrowRect.inflate(-replacementArrowCirclePadding);
 
-        context->beginTransparencyLayer(1.0);
-        context->setFillColor(replacementTextColor(), style()->colorSpace());
-        context->fillEllipse(arrowRect);
+        context.beginTransparencyLayer(1.0);
+        context.setFillColor(replacementTextColor());
+        context.fillEllipse(arrowRect);
 
-        context->setCompositeOperation(CompositeClear);
+        context.setCompositeOperation(CompositeClear);
         drawReplacementArrow(context, arrowRect);
-        context->endTransparencyLayer();
+        context.endTransparencyLayer();
     }
 }
 
 void RenderEmbeddedObject::setUnavailablePluginIndicatorIsHidden(bool hidden)
 {
-    m_isUnavailablePluginIndicatorHidden = hidden;
+    if (m_isUnavailablePluginIndicatorHidden == hidden)
+        return;
 
+    m_isUnavailablePluginIndicatorHidden = hidden;
     repaint();
 }
 
-bool RenderEmbeddedObject::getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, FloatRect& indicatorRect, FloatRect& replacementTextRect, FloatRect& arrowRect, Font& font, TextRun& run, float& textWidth) const
+bool RenderEmbeddedObject::getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, FloatRect& indicatorRect, FloatRect& replacementTextRect, FloatRect& arrowRect, FontCascade& font, TextRun& run, float& textWidth) const
 {
     bool includesArrow = shouldUnavailablePluginMessageBeButton(document(), m_pluginUnavailabilityReason);
 
     contentRect = contentBoxRect();
     contentRect.moveBy(roundedIntPoint(accumulatedOffset));
 
-    FontDescription fontDescription;
+    FontCascadeDescription fontDescription;
     RenderTheme::defaultTheme()->systemFont(CSSValueWebkitSmallControl, fontDescription);
     fontDescription.setWeight(FontWeightBold);
     fontDescription.setRenderingMode(frame().settings().fontRenderingMode());
     fontDescription.setComputedSize(12);
-    font = Font(fontDescription, 0, 0);
+    font = FontCascade(fontDescription, 0, 0);
     font.update(0);
 
     run = TextRun(m_unavailablePluginReplacementText);
@@ -372,8 +394,8 @@ LayoutRect RenderEmbeddedObject::unavailablePluginIndicatorBounds(const LayoutPo
     FloatRect indicatorRect;
     FloatRect replacementTextRect;
     FloatRect arrowRect;
-    Font font;
-    TextRun run("", 0);
+    FontCascade font;
+    TextRun run(emptyString());
     float textWidth;
     if (getReplacementTextGeometry(accumulatedOffset, contentRect, indicatorRect, replacementTextRect, arrowRect, font, run, textWidth))
         return LayoutRect(indicatorRect);
@@ -388,7 +410,7 @@ bool RenderEmbeddedObject::isReplacementObscured() const
     // Check the opacity of each layer containing the element or its ancestors.
     float opacity = 1.0;
     for (RenderLayer* layer = enclosingLayer(); layer; layer = layer->parent()) {
-        opacity *= layer->renderer().style()->opacity();
+        opacity *= layer->renderer().style().opacity();
         if (opacity < 0.1)
             return true;
     }
@@ -400,12 +422,12 @@ bool RenderEmbeddedObject::isReplacementObscured() const
     if (rect.isEmpty())
         return true;
 
-    RenderView* rootRenderView = document().topDocument()->renderView();
+    RenderView* rootRenderView = document().topDocument().renderView();
     ASSERT(rootRenderView);
     if (!rootRenderView)
         return true;
 
-    IntRect rootViewRect = frameView()->convertToRootView(pixelSnappedIntRect(rect));
+    IntRect rootViewRect = view().frameView().convertToRootView(snappedIntRect(rect));
     
     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent | HitTestRequest::AllowChildFrameContent);
     HitTestResult result;
@@ -421,27 +443,27 @@ bool RenderEmbeddedObject::isReplacementObscured() const
     bool hit = false;
     location = LayoutPoint(x + width / 2, y + height / 2);
     hit = rootRenderView->hitTest(request, location, result);
-    if (!hit || result.innerNode() != node())
+    if (!hit || result.innerNode() != &frameOwnerElement())
         return true;
     
     location = LayoutPoint(x, y);
     hit = rootRenderView->hitTest(request, location, result);
-    if (!hit || result.innerNode() != node())
+    if (!hit || result.innerNode() != &frameOwnerElement())
         return true;
     
     location = LayoutPoint(x + width, y);
     hit = rootRenderView->hitTest(request, location, result);
-    if (!hit || result.innerNode() != node())
+    if (!hit || result.innerNode() != &frameOwnerElement())
         return true;
     
     location = LayoutPoint(x + width, y + height);
     hit = rootRenderView->hitTest(request, location, result);
-    if (!hit || result.innerNode() != node())
+    if (!hit || result.innerNode() != &frameOwnerElement())
         return true;
     
     location = LayoutPoint(x, y + height);
     hit = rootRenderView->hitTest(request, location, result);
-    if (!hit || result.innerNode() != node())
+    if (!hit || result.innerNode() != &frameOwnerElement())
         return true;
 
     return false;
@@ -457,7 +479,7 @@ void RenderEmbeddedObject::layout()
     updateLogicalWidth();
     updateLogicalHeight();
 
-    RenderPart::layout();
+    RenderWidget::layout();
 
     clearOverflow();
     addVisualEffectOverflow();
@@ -465,22 +487,22 @@ void RenderEmbeddedObject::layout()
     updateLayerTransform();
 
     bool wasMissingWidget = false;
-    if (!widget() && frameView() && canHaveWidget()) {
+    if (!widget() && canHaveWidget()) {
         wasMissingWidget = true;
-        frameView()->addWidgetToUpdate(this);
+        view().frameView().addEmbeddedObjectToUpdate(*this);
     }
 
-    setNeedsLayout(false);
+    clearNeedsLayout();
 
     LayoutSize newSize = contentBoxRect().size();
 
     if (!wasMissingWidget && newSize.width() >= oldSize.width() && newSize.height() >= oldSize.height()) {
-        Element* element = toElement(node());
-        if (element && element->isPluginElement() && toHTMLPlugInElement(element)->isPlugInImageElement()) {
-            HTMLPlugInImageElement* plugInImageElement = toHTMLPlugInImageElement(element);
-            if (plugInImageElement->displayState() > HTMLPlugInElement::DisplayingSnapshot && plugInImageElement->snapshotDecision() == HTMLPlugInImageElement::MaySnapshotWhenResized) {
-                plugInImageElement->setNeedsCheckForSizeChange();
-                view().frameView().addWidgetToUpdate(this);
+        HTMLFrameOwnerElement& element = frameOwnerElement();
+        if (is<HTMLPlugInImageElement>(element)) {
+            HTMLPlugInImageElement& plugInImageElement = downcast<HTMLPlugInImageElement>(element);
+            if (plugInImageElement.displayState() > HTMLPlugInElement::DisplayingSnapshot && plugInImageElement.snapshotDecision() == HTMLPlugInImageElement::MaySnapshotWhenResized) {
+                plugInImageElement.setNeedsCheckForSizeChange();
+                view().frameView().addEmbeddedObjectToUpdate(*this);
             }
         }
     }
@@ -489,72 +511,50 @@ void RenderEmbeddedObject::layout()
         return;
 
     // This code copied from RenderMedia::layout().
-    RenderObject* child = m_children.firstChild();
+    RenderObject* child = firstChild();
 
     if (!child)
         return;
 
-    RenderBox* childBox = toRenderBox(child);
+    auto& childBox = downcast<RenderBox>(*child);
 
-    if (!childBox)
-        return;
-
-    if (newSize == oldSize && !childBox->needsLayout())
+    if (newSize == oldSize && !childBox.needsLayout())
         return;
     
     // When calling layout() on a child node, a parent must either push a LayoutStateMaintainter, or
     // instantiate LayoutStateDisabler. Since using a LayoutStateMaintainer is slightly more efficient,
     // and this method will be called many times per second during playback, use a LayoutStateMaintainer:
-    LayoutStateMaintainer statePusher(&view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(view(), *this, locationOffset(), hasTransform() || hasReflection() || style().isFlippedBlocksWritingMode());
     
-    childBox->setLocation(LayoutPoint(borderLeft(), borderTop()) + LayoutSize(paddingLeft(), paddingTop()));
-    childBox->style()->setHeight(Length(newSize.height(), Fixed));
-    childBox->style()->setWidth(Length(newSize.width(), Fixed));
-    childBox->setNeedsLayout(true, MarkOnlyThis);
-    childBox->layout();
-    setChildNeedsLayout(false);
+    childBox.setLocation(LayoutPoint(borderLeft(), borderTop()) + LayoutSize(paddingLeft(), paddingTop()));
+    childBox.style().setHeight(Length(newSize.height(), Fixed));
+    childBox.style().setWidth(Length(newSize.width(), Fixed));
+    childBox.setNeedsLayout(MarkOnlyThis);
+    childBox.layout();
+    clearChildNeedsLayout();
     
     statePusher.pop();
 }
 
-void RenderEmbeddedObject::viewCleared()
-{
-    // This is required for <object> elements whose contents are rendered by WebCore (e.g. src="foo.html").
-    if (node() && widget() && widget()->isFrameView()) {
-        FrameView* view = toFrameView(widget());
-        int marginWidth = -1;
-        int marginHeight = -1;
-        if (node()->hasTagName(iframeTag)) {
-            HTMLIFrameElement* frame = toHTMLIFrameElement(node());
-            marginWidth = frame->marginWidth();
-            marginHeight = frame->marginHeight();
-        }
-        if (marginWidth != -1)
-            view->setMarginWidth(marginWidth);
-        if (marginHeight != -1)
-            view->setMarginHeight(marginHeight);
-    }
-}
-
 bool RenderEmbeddedObject::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
 {
-    if (!RenderPart::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction))
+    if (!RenderWidget::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction))
         return false;
 
-    if (!widget() || !widget()->isPluginViewBase())
+    if (!is<PluginViewBase>(widget()))
         return true;
 
-    PluginViewBase* view = toPluginViewBase(widget());
+    PluginViewBase& view = downcast<PluginViewBase>(*widget());
     IntPoint roundedPoint = locationInContainer.roundedPoint();
 
-    if (Scrollbar* horizontalScrollbar = view->horizontalScrollbar()) {
+    if (Scrollbar* horizontalScrollbar = view.horizontalScrollbar()) {
         if (horizontalScrollbar->shouldParticipateInHitTesting() && horizontalScrollbar->frameRect().contains(roundedPoint)) {
             result.setScrollbar(horizontalScrollbar);
             return true;
         }
     }
 
-    if (Scrollbar* verticalScrollbar = view->verticalScrollbar()) {
+    if (Scrollbar* verticalScrollbar = view.verticalScrollbar()) {
         if (verticalScrollbar->shouldParticipateInHitTesting() && verticalScrollbar->frameRect().contains(roundedPoint)) {
             result.setScrollbar(verticalScrollbar);
             return true;
@@ -564,37 +564,37 @@ bool RenderEmbeddedObject::nodeAtPoint(const HitTestRequest& request, HitTestRes
     return true;
 }
 
-bool RenderEmbeddedObject::scroll(ScrollDirection direction, ScrollGranularity granularity, float, Node**)
+bool RenderEmbeddedObject::scroll(ScrollDirection direction, ScrollGranularity granularity, float, Element**, RenderBox*, const IntPoint&)
 {
-    if (!widget() || !widget()->isPluginViewBase())
+    if (!is<PluginViewBase>(widget()))
         return false;
 
-    return toPluginViewBase(widget())->scroll(direction, granularity);
+    return downcast<PluginViewBase>(*widget()).scroll(direction, granularity);
 }
 
-bool RenderEmbeddedObject::logicalScroll(ScrollLogicalDirection direction, ScrollGranularity granularity, float multiplier, Node** stopNode)
+bool RenderEmbeddedObject::logicalScroll(ScrollLogicalDirection direction, ScrollGranularity granularity, float multiplier, Element** stopElement)
 {
     // Plugins don't expose a writing direction, so assuming horizontal LTR.
-    return scroll(logicalToPhysical(direction, true, false), granularity, multiplier, stopNode);
+    return scroll(logicalToPhysical(direction, true, false), granularity, multiplier, stopElement);
 }
 
 
-bool RenderEmbeddedObject::isInUnavailablePluginIndicator(const LayoutPoint& point) const
+bool RenderEmbeddedObject::isInUnavailablePluginIndicator(const FloatPoint& point) const
 {
     FloatRect contentRect;
     FloatRect indicatorRect;
     FloatRect replacementTextRect;
     FloatRect arrowRect;
-    Font font;
-    TextRun run("");
+    FontCascade font;
+    TextRun run(emptyString());
     float textWidth;
     return getReplacementTextGeometry(IntPoint(), contentRect, indicatorRect, replacementTextRect, arrowRect, font, run, textWidth)
         && indicatorRect.contains(point);
 }
 
-bool RenderEmbeddedObject::isInUnavailablePluginIndicator(MouseEvent* event) const
+bool RenderEmbeddedObject::isInUnavailablePluginIndicator(const MouseEvent& event) const
 {
-    return isInUnavailablePluginIndicator(roundedLayoutPoint(absoluteToLocal(event->absoluteLocation(), UseTransforms)));
+    return isInUnavailablePluginIndicator(absoluteToLocal(event.absoluteLocation(), UseTransforms));
 }
 
 void RenderEmbeddedObject::handleUnavailablePluginIndicatorEvent(Event* event)
@@ -602,36 +602,36 @@ void RenderEmbeddedObject::handleUnavailablePluginIndicatorEvent(Event* event)
     if (!shouldUnavailablePluginMessageBeButton(document(), m_pluginUnavailabilityReason))
         return;
 
-    if (!event->isMouseEvent())
+    if (!is<MouseEvent>(*event))
         return;
 
-    MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
-    HTMLPlugInElement* element = toHTMLPlugInElement(node());
-    if (event->type() == eventNames().mousedownEvent && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+    MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
+    HTMLPlugInElement& element = downcast<HTMLPlugInElement>(frameOwnerElement());
+    if (mouseEvent.type() == eventNames().mousedownEvent && mouseEvent.button() == LeftButton) {
         m_mouseDownWasInUnavailablePluginIndicator = isInUnavailablePluginIndicator(mouseEvent);
         if (m_mouseDownWasInUnavailablePluginIndicator) {
-            frame().eventHandler().setCapturingMouseEventsNode(element);
-            element->setIsCapturingMouseEvents(true);
+            frame().eventHandler().setCapturingMouseEventsElement(&element);
+            element.setIsCapturingMouseEvents(true);
             setUnavailablePluginIndicatorIsPressed(true);
         }
-        event->setDefaultHandled();
+        mouseEvent.setDefaultHandled();
     }
-    if (event->type() == eventNames().mouseupEvent && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+    if (mouseEvent.type() == eventNames().mouseupEvent && mouseEvent.button() == LeftButton) {
         if (m_unavailablePluginIndicatorIsPressed) {
-            frame().eventHandler().setCapturingMouseEventsNode(0);
-            element->setIsCapturingMouseEvents(false);
+            frame().eventHandler().setCapturingMouseEventsElement(nullptr);
+            element.setIsCapturingMouseEvents(false);
             setUnavailablePluginIndicatorIsPressed(false);
         }
         if (m_mouseDownWasInUnavailablePluginIndicator && isInUnavailablePluginIndicator(mouseEvent)) {
             if (Page* page = document().page())
-                page->chrome().client().unavailablePluginButtonClicked(element, m_pluginUnavailabilityReason);
+                page->chrome().client().unavailablePluginButtonClicked(&element, m_pluginUnavailabilityReason);
         }
         m_mouseDownWasInUnavailablePluginIndicator = false;
         event->setDefaultHandled();
     }
-    if (event->type() == eventNames().mousemoveEvent) {
+    if (mouseEvent.type() == eventNames().mousemoveEvent) {
         setUnavailablePluginIndicatorIsPressed(m_mouseDownWasInUnavailablePluginIndicator && isInUnavailablePluginIndicator(mouseEvent));
-        event->setDefaultHandled();
+        mouseEvent.setDefaultHandled();
     }
 }
 
@@ -641,19 +641,15 @@ CursorDirective RenderEmbeddedObject::getCursor(const LayoutPoint& point, Cursor
         cursor = handCursor();
         return SetCursor;
     }
-    return RenderPart::getCursor(point, cursor);
+    if (widget() && widget()->isPluginViewBase()) {
+        // A plug-in is responsible for setting the cursor when the pointer is over it.
+        return DoNotSetCursor;
+    }
+    return RenderWidget::getCursor(point, cursor);
 }
 
 bool RenderEmbeddedObject::canHaveChildren() const
 {
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-    if (!node())
-        return false;
-
-    if (toElement(node())->isMediaElement())
-        return true;
-#endif
-
     if (isSnapshottedPlugIn())
         return true;