diff options
Diffstat (limited to 'WebCore/html/HTMLPlugInImageElement.cpp')
-rw-r--r-- | WebCore/html/HTMLPlugInImageElement.cpp | 93 |
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 |