summaryrefslogtreecommitdiffstats
path: root/WebCore/html/HTMLPlugInImageElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/html/HTMLPlugInImageElement.cpp')
-rw-r--r--WebCore/html/HTMLPlugInImageElement.cpp93
1 files changed, 92 insertions, 1 deletions
diff --git a/WebCore/html/HTMLPlugInImageElement.cpp b/WebCore/html/HTMLPlugInImageElement.cpp
index e2898a2..75407dd 100644
--- a/WebCore/html/HTMLPlugInImageElement.cpp
+++ b/WebCore/html/HTMLPlugInImageElement.cpp
@@ -26,14 +26,30 @@
#include "FrameLoaderClient.h"
#include "HTMLImageLoader.h"
#include "Image.h"
+#include "RenderEmbeddedObject.h"
+#include "RenderImage.h"
namespace WebCore {
-HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Document* document)
+HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Document* document, bool createdByParser)
: HTMLPlugInElement(tagName, document)
+ // m_needsWidgetUpdate(!createdByParser) allows HTMLObjectElement to delay
+ // widget updates until after all children are parsed. For HTMLEmbedElement
+ // this delay is unnecessary, but it is simpler to make both classes share
+ // the same codepath in this class.
+ , m_needsWidgetUpdate(!createdByParser)
{
}
+RenderEmbeddedObject* HTMLPlugInImageElement::renderEmbeddedObject() const
+{
+ // HTMLObjectElement and HTMLEmbedElement may return arbitrary renderers
+ // when using fallback content.
+ if (!renderer() || !renderer()->isEmbeddedObject())
+ return 0;
+ return toRenderEmbeddedObject(renderer());
+}
+
bool HTMLPlugInImageElement::isImageType()
{
if (m_serviceType.isEmpty() && protocolIs(m_url, "data"))
@@ -47,6 +63,76 @@ bool HTMLPlugInImageElement::isImageType()
return Image::supportsType(m_serviceType);
}
+RenderObject* HTMLPlugInImageElement::createRenderer(RenderArena* arena, RenderStyle* style)
+{
+ // Fallback content breaks the DOM->Renderer class relationship of this
+ // class and all superclasses because createObject won't necessarily
+ // return a RenderEmbeddedObject, RenderPart or even RenderWidget.
+ if (useFallbackContent())
+ return RenderObject::createObject(this, style);
+ if (isImageType()) {
+ RenderImage* image = new (arena) RenderImage(this);
+ image->setImageResource(RenderImageResource::create());
+ return image;
+ }
+ return new (arena) RenderEmbeddedObject(this);
+}
+
+void HTMLPlugInImageElement::recalcStyle(StyleChange ch)
+{
+ // FIXME: Why is this necessary? Manual re-attach is almost always wrong.
+ if (!useFallbackContent() && needsWidgetUpdate() && renderer() && !isImageType()) {
+ detach();
+ attach();
+ }
+ HTMLPlugInElement::recalcStyle(ch);
+}
+
+void HTMLPlugInImageElement::attach()
+{
+ bool isImage = isImageType();
+
+ if (!isImage)
+ queuePostAttachCallback(&HTMLPlugInImageElement::updateWidgetCallback, this);
+
+ HTMLPlugInElement::attach();
+
+ if (isImage && renderer() && !useFallbackContent()) {
+ if (!m_imageLoader)
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader->updateFromElement();
+ }
+}
+
+void HTMLPlugInImageElement::detach()
+{
+ // FIXME: Because of the insanity that is HTMLObjectElement::recalcStyle,
+ // we can end up detaching during an attach() call, before we even have a
+ // renderer. In that case, don't mark the widget for update.
+ if (attached() && renderer() && !useFallbackContent())
+ // Update the widget the next time we attach (detaching destroys the plugin).
+ setNeedsWidgetUpdate(true);
+ HTMLPlugInElement::detach();
+}
+
+void HTMLPlugInImageElement::updateWidget()
+{
+ document()->updateStyleIfNeeded();
+ if (needsWidgetUpdate() && renderEmbeddedObject() && !useFallbackContent() && !isImageType())
+ renderEmbeddedObject()->updateWidget(true);
+}
+
+void HTMLPlugInImageElement::finishParsingChildren()
+{
+ HTMLPlugInElement::finishParsingChildren();
+ if (useFallbackContent())
+ return;
+
+ setNeedsWidgetUpdate(true);
+ if (inDocument())
+ setNeedsStyleRecalc();
+}
+
void HTMLPlugInImageElement::willMoveToNewOwnerDocument()
{
if (m_imageLoader)
@@ -54,4 +140,9 @@ void HTMLPlugInImageElement::willMoveToNewOwnerDocument()
HTMLPlugInElement::willMoveToNewOwnerDocument();
}
+void HTMLPlugInImageElement::updateWidgetCallback(Node* n)
+{
+ static_cast<HTMLPlugInImageElement*>(n)->updateWidget();
+}
+
} // namespace WebCore