- Revision
- 145934
- Author
- [email protected]
- Date
- 2013-03-15 13:33:50 -0700 (Fri, 15 Mar 2013)
Log Message
RenderSnapshottedPlugIn can't be a RenderBlock (what if it's display: inline?)
https://bugs.webkit.org/show_bug.cgi?id=112432
<rdar://problem/13187211>
Reviewed by Simon Fraser and Dean Jackson.
Re-use code from PLUGIN_PROXY_FOR_VIDEO to allow RenderEmbeddedObject to lay out its children,
and make RenderSnapshottedPlugIn a RenderEmbeddedObject subclass once again. This will ensure that
RenderSnapshottedPlugIn lays itself out in the page the same as the RenderEmbeddedObject it replaces did,
preventing snapshotted plug-ins from breaking the layout when they are display: inline.
* html/HTMLPlugInElement.cpp:
(WebCore::HTMLPlugInElement::defaultEventHandler):
RenderSnapshottedPlugIn is a RenderEmbeddedObject subclass again, so we need to check
for it when we have a RenderEmbeddedObject, instead of when we don't.
* page/FrameView.cpp:
(WebCore::FrameView::updateWidget):
Ditto.
* rendering/RenderEmbeddedObject.cpp:
(WebCore::RenderEmbeddedObject::layout):
(WebCore::RenderEmbeddedObject::canHaveChildren):
Allow RenderEmbeddedObject to have and lay out children if it is a RenderSnapshottedPlugIn.
Also, preserve the code that allows children if it is a media element and PLUGIN_PROXY_FOR_VIDEO is enabled.
Don't call addWidgetToUpdate for instances which will never have a widget, like RenderSnapshottedPlugIn.
* rendering/RenderEmbeddedObject.h:
(RenderEmbeddedObject):
We need canHaveChildren() and children() and m_children now.
Add canHaveWidget(), which returns true. Subclasses can override if need be.
* rendering/RenderSnapshottedPlugIn.h: Add canHaveWidget(), which is false for RenderSnapshottedPlugIn.
* rendering/RenderSnapshottedPlugIn.cpp:
(WebCore::RenderSnapshottedPlugIn::RenderSnapshottedPlugIn):
(WebCore::RenderSnapshottedPlugIn::layout):
(WebCore::RenderSnapshottedPlugIn::getCursor):
Make RenderSnapshottedPlugIn a RenderEmbeddedObject.
(WebCore::RenderSnapshottedPlugIn::paint):
Paint our children.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (145933 => 145934)
--- trunk/Source/WebCore/ChangeLog 2013-03-15 20:24:39 UTC (rev 145933)
+++ trunk/Source/WebCore/ChangeLog 2013-03-15 20:33:50 UTC (rev 145934)
@@ -1,3 +1,47 @@
+2013-03-15 Tim Horton <[email protected]>
+
+ RenderSnapshottedPlugIn can't be a RenderBlock (what if it's display: inline?)
+ https://bugs.webkit.org/show_bug.cgi?id=112432
+ <rdar://problem/13187211>
+
+ Reviewed by Simon Fraser and Dean Jackson.
+
+ Re-use code from PLUGIN_PROXY_FOR_VIDEO to allow RenderEmbeddedObject to lay out its children,
+ and make RenderSnapshottedPlugIn a RenderEmbeddedObject subclass once again. This will ensure that
+ RenderSnapshottedPlugIn lays itself out in the page the same as the RenderEmbeddedObject it replaces did,
+ preventing snapshotted plug-ins from breaking the layout when they are display: inline.
+
+ * html/HTMLPlugInElement.cpp:
+ (WebCore::HTMLPlugInElement::defaultEventHandler):
+ RenderSnapshottedPlugIn is a RenderEmbeddedObject subclass again, so we need to check
+ for it when we have a RenderEmbeddedObject, instead of when we don't.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::updateWidget):
+ Ditto.
+
+ * rendering/RenderEmbeddedObject.cpp:
+ (WebCore::RenderEmbeddedObject::layout):
+ (WebCore::RenderEmbeddedObject::canHaveChildren):
+ Allow RenderEmbeddedObject to have and lay out children if it is a RenderSnapshottedPlugIn.
+ Also, preserve the code that allows children if it is a media element and PLUGIN_PROXY_FOR_VIDEO is enabled.
+ Don't call addWidgetToUpdate for instances which will never have a widget, like RenderSnapshottedPlugIn.
+
+ * rendering/RenderEmbeddedObject.h:
+ (RenderEmbeddedObject):
+ We need canHaveChildren() and children() and m_children now.
+ Add canHaveWidget(), which returns true. Subclasses can override if need be.
+
+ * rendering/RenderSnapshottedPlugIn.h: Add canHaveWidget(), which is false for RenderSnapshottedPlugIn.
+ * rendering/RenderSnapshottedPlugIn.cpp:
+ (WebCore::RenderSnapshottedPlugIn::RenderSnapshottedPlugIn):
+ (WebCore::RenderSnapshottedPlugIn::layout):
+ (WebCore::RenderSnapshottedPlugIn::getCursor):
+ Make RenderSnapshottedPlugIn a RenderEmbeddedObject.
+
+ (WebCore::RenderSnapshottedPlugIn::paint):
+ Paint our children.
+
2013-03-15 Hajime Morrita <[email protected]>
[Custom Elements] Any HTMLElement subclass should become a superclass of custom element
Modified: trunk/Source/WebCore/html/HTMLPlugInElement.cpp (145933 => 145934)
--- trunk/Source/WebCore/html/HTMLPlugInElement.cpp 2013-03-15 20:24:39 UTC (rev 145933)
+++ trunk/Source/WebCore/html/HTMLPlugInElement.cpp 2013-03-15 20:33:50 UTC (rev 145934)
@@ -202,12 +202,15 @@
toRenderEmbeddedObject(r)->handleUnavailablePluginIndicatorEvent(event);
return;
}
- if (displayState() < HTMLPlugInElement::Playing)
+
+ if (r->isSnapshottedPlugIn() && displayState() < PlayingWithPendingMouseClick) {
+ toRenderSnapshottedPlugIn(r)->handleEvent(event);
+ HTMLFrameOwnerElement::defaultEventHandler(event);
return;
- } else if (r && r->isSnapshottedPlugIn() && displayState() < PlayingWithPendingMouseClick) {
- toRenderSnapshottedPlugIn(r)->handleEvent(event);
- HTMLFrameOwnerElement::defaultEventHandler(event);
- return;
+ }
+
+ if (displayState() < Playing)
+ return;
}
if (!r || !r->isWidget())
Modified: trunk/Source/WebCore/page/FrameView.cpp (145933 => 145934)
--- trunk/Source/WebCore/page/FrameView.cpp 2013-03-15 20:24:39 UTC (rev 145933)
+++ trunk/Source/WebCore/page/FrameView.cpp 2013-03-15 20:33:50 UTC (rev 145934)
@@ -1388,7 +1388,7 @@
// Tell the DOM element that it needs a widget update.
Node* node = object->node();
if (node->hasTagName(objectTag) || node->hasTagName(embedTag)) {
- HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(node);
+ HTMLPlugInImageElement* pluginElement = toHTMLPlugInImageElement(node);
pluginElement->setNeedsWidgetUpdate(true);
}
@@ -2527,10 +2527,18 @@
if (embeddedObject->showsUnavailablePluginIndicator())
return;
+ if (object->isSnapshottedPlugIn()) {
+ if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag)) {
+ HTMLPlugInImageElement* pluginElement = toHTMLPlugInImageElement(ownerElement);
+ pluginElement->updateSnapshotInfo();
+ }
+ return;
+ }
+
// FIXME: This could turn into a real virtual dispatch if we defined
// updateWidget(PluginCreationOption) on HTMLElement.
if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag) || ownerElement->hasTagName(appletTag)) {
- HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(ownerElement);
+ HTMLPlugInImageElement* pluginElement = toHTMLPlugInImageElement(ownerElement);
if (pluginElement->needsWidgetUpdate())
pluginElement->updateWidget(CreateAnyWidgetType);
}
@@ -2545,11 +2553,6 @@
// Caution: it's possible the object was destroyed again, since loading a
// plugin may run any arbitrary _javascript_.
embeddedObject->updateWidgetPosition();
- } else if (object->isSnapshottedPlugIn()) {
- if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag)) {
- HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(ownerElement);
- pluginElement->updateSnapshotInfo();
- }
}
}
Modified: trunk/Source/WebCore/rendering/RenderEmbeddedObject.cpp (145933 => 145934)
--- trunk/Source/WebCore/rendering/RenderEmbeddedObject.cpp 2013-03-15 20:24:39 UTC (rev 145933)
+++ trunk/Source/WebCore/rendering/RenderEmbeddedObject.cpp 2013-03-15 20:33:50 UTC (rev 145934)
@@ -38,6 +38,7 @@
#include "HTMLNames.h"
#include "HTMLObjectElement.h"
#include "HTMLParamElement.h"
+#include "HTMLPlugInElement.h"
#include "HitTestResult.h"
#include "LocalizedStrings.h"
#include "MIMETypeRegistry.h"
@@ -278,9 +279,7 @@
StackStats::LayoutCheckPoint layoutCheckPoint;
ASSERT(needsLayout());
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
LayoutSize oldSize = contentBoxRect().size();
-#endif
updateLogicalWidth();
updateLogicalHeight();
@@ -292,19 +291,27 @@
updateLayerTransform();
- if (!widget() && frameView())
+ if (!widget() && frameView() && canHaveWidget())
frameView()->addWidgetToUpdate(this);
setNeedsLayout(false);
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (!canHaveChildren())
+ return;
+
// This code copied from RenderMedia::layout().
- RenderBox* controlsRenderer = toRenderBox(m_children.firstChild());
- if (!controlsRenderer)
+ RenderObject* child = m_children.firstChild();
+
+ if (!child)
return;
+
+ RenderBox* childBox = toRenderBox(child);
+
+ if (!childBox)
+ return;
LayoutSize newSize = contentBoxRect().size();
- if (newSize == oldSize && !controlsRenderer->needsLayout())
+ if (newSize == oldSize && !childBox->needsLayout())
return;
// When calling layout() on a child node, a parent must either push a LayoutStateMaintainter, or
@@ -312,15 +319,14 @@
// and this method will be called many times per second during playback, use a LayoutStateMaintainer:
LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
- controlsRenderer->setLocation(LayoutPoint(borderLeft(), borderTop()) + LayoutSize(paddingLeft(), paddingTop()));
- controlsRenderer->style()->setHeight(Length(newSize.height(), Fixed));
- controlsRenderer->style()->setWidth(Length(newSize.width(), Fixed));
- controlsRenderer->setNeedsLayout(true, MarkOnlyThis);
- controlsRenderer->layout();
+ 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);
statePusher.pop();
-#endif
}
void RenderEmbeddedObject::viewCleared()
@@ -459,4 +465,20 @@
return RenderPart::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;
+
+ return false;
}
+
+}
Modified: trunk/Source/WebCore/rendering/RenderEmbeddedObject.h (145933 => 145934)
--- trunk/Source/WebCore/rendering/RenderEmbeddedObject.h 2013-03-15 20:24:39 UTC (rev 145933)
+++ trunk/Source/WebCore/rendering/RenderEmbeddedObject.h 2013-03-15 20:33:50 UTC (rev 145934)
@@ -63,10 +63,8 @@
virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
const RenderObjectChildList* children() const { return &m_children; }
RenderObjectChildList* children() { return &m_children; }
-#endif
protected:
virtual void layout() OVERRIDE;
@@ -94,11 +92,11 @@
bool isInUnavailablePluginIndicator(const LayoutPoint&) const;
bool getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, Path&, FloatRect& replacementTextRect, Font&, TextRun&, float& textWidth) const;
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
- virtual bool canHaveChildren() const { return node() && toElement(node())->isMediaElement(); }
+ virtual bool canHaveChildren() const;
virtual RenderObjectChildList* virtualChildren() { return children(); }
virtual const RenderObjectChildList* virtualChildren() const { return children(); }
-#endif
+
+ virtual bool canHaveWidget() const { return true; }
bool m_hasFallbackContent; // FIXME: This belongs on HTMLObjectElement.
@@ -107,9 +105,7 @@
String m_unavailablePluginReplacementText;
bool m_unavailablePluginIndicatorIsPressed;
bool m_mouseDownWasInUnavailablePluginIndicator;
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
RenderObjectChildList m_children;
-#endif
};
inline RenderEmbeddedObject* toRenderEmbeddedObject(RenderObject* object)
Modified: trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp (145933 => 145934)
--- trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp 2013-03-15 20:24:39 UTC (rev 145933)
+++ trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp 2013-03-15 20:33:50 UTC (rev 145934)
@@ -44,7 +44,7 @@
namespace WebCore {
RenderSnapshottedPlugIn::RenderSnapshottedPlugIn(HTMLPlugInImageElement* element)
- : RenderBlock(element)
+ : RenderEmbeddedObject(element)
, m_snapshotResource(RenderImageResource::create())
{
m_snapshotResource->initialize(this);
@@ -66,7 +66,7 @@
StackStats::LayoutCheckPoint layoutCheckPoint;
LayoutSize oldSize = contentBoxRect().size();
- RenderBlock::layout();
+ RenderEmbeddedObject::layout();
LayoutSize newSize = contentBoxRect().size();
if (newSize == oldSize)
@@ -92,7 +92,20 @@
paintSnapshot(paintInfo, paintOffset);
}
- RenderBlock::paint(paintInfo, paintOffset);
+ PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
+ newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
+
+ PaintInfo paintInfoForChild(paintInfo);
+ paintInfoForChild.phase = newPhase;
+ paintInfoForChild.updatePaintingRootForChildren(this);
+
+ for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+ LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
+ if (!child->hasSelfPaintingLayer() && !child->isFloating())
+ child->paint(paintInfoForChild, childPoint);
+ }
+
+ RenderEmbeddedObject::paint(paintInfo, paintOffset);
}
void RenderSnapshottedPlugIn::paintSnapshot(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -131,7 +144,7 @@
overrideCursor = handCursor();
return SetCursor;
}
- return RenderBlock::getCursor(point, overrideCursor);
+ return RenderEmbeddedObject::getCursor(point, overrideCursor);
}
void RenderSnapshottedPlugIn::handleEvent(Event* event)
Modified: trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.h (145933 => 145934)
--- trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.h 2013-03-15 20:24:39 UTC (rev 145933)
+++ trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.h 2013-03-15 20:33:50 UTC (rev 145934)
@@ -26,7 +26,7 @@
#ifndef RenderSnapshottedPlugIn_h
#define RenderSnapshottedPlugIn_h
-#include "RenderBlock.h"
+#include "RenderEmbeddedObject.h"
#include "RenderImageResource.h"
#include "Timer.h"
@@ -34,7 +34,7 @@
class HTMLPlugInImageElement;
-class RenderSnapshottedPlugIn : public RenderBlock {
+class RenderSnapshottedPlugIn : public RenderEmbeddedObject {
public:
explicit RenderSnapshottedPlugIn(HTMLPlugInImageElement*);
virtual ~RenderSnapshottedPlugIn();
@@ -50,6 +50,8 @@
virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const OVERRIDE;
virtual bool isSnapshottedPlugIn() const OVERRIDE { return true; }
virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
+
+ virtual bool canHaveWidget() const OVERRIDE { return false; }
void paintSnapshot(PaintInfo&, const LayoutPoint&);