From cad810f21b803229eb11403f9209855525a25d57 Mon Sep 17 00:00:00 2001 From: Steve Block Date: Fri, 6 May 2011 11:45:16 +0100 Subject: Merge WebKit at r75315: Initial merge by git. Change-Id: I570314b346ce101c935ed22a626b48c2af266b84 --- Source/WebCore/html/HTMLPlugInImageElement.cpp | 196 +++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 Source/WebCore/html/HTMLPlugInImageElement.cpp (limited to 'Source/WebCore/html/HTMLPlugInImageElement.cpp') diff --git a/Source/WebCore/html/HTMLPlugInImageElement.cpp b/Source/WebCore/html/HTMLPlugInImageElement.cpp new file mode 100644 index 0000000..9ac5ad8 --- /dev/null +++ b/Source/WebCore/html/HTMLPlugInImageElement.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "HTMLPlugInImageElement.h" + +#include "Frame.h" +#include "FrameLoader.h" +#include "FrameLoaderClient.h" +#include "HTMLImageLoader.h" +#include "Image.h" +#include "Page.h" +#include "RenderEmbeddedObject.h" +#include "RenderImage.h" + +namespace WebCore { + +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")) + m_serviceType = mimeTypeFromDataURL(m_url); + + if (Frame* frame = document()->frame()) { + KURL completedURL = frame->loader()->completeURL(m_url); + return frame->loader()->client()->objectContentType(completedURL, m_serviceType) == ObjectContentImage; + } + + return Image::supportsType(m_serviceType); +} + +// We don't use m_url, as it may not be the final URL that the object loads, +// depending on values. +bool HTMLPlugInImageElement::allowedToLoadFrameURL(const String& url) +{ + ASSERT(document()); + ASSERT(document()->frame()); + if (document()->frame()->page()->frameCount() >= Page::maxNumberOfFrames) + return false; + + // We allow one level of self-reference because some sites depend on that. + // But we don't allow more than one. + KURL completeURL = document()->completeURL(url); + bool foundSelfReference = false; + for (Frame* frame = document()->frame(); frame; frame = frame->tree()->parent()) { + if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) { + if (foundSelfReference) + return false; + foundSelfReference = true; + } + } + return true; +} + +// We don't use m_url, or m_serviceType as they may not be the final values +// that uses depending on values. +bool HTMLPlugInImageElement::wouldLoadAsNetscapePlugin(const String& url, const String& serviceType) +{ + ASSERT(document()); + ASSERT(document()->frame()); + FrameLoader* frameLoader = document()->frame()->loader(); + ASSERT(frameLoader); + KURL completedURL; + if (!url.isEmpty()) + completedURL = frameLoader->completeURL(url); + + if (frameLoader->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin) + return true; + return false; +} + +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 HTMLPlugInImageElement::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::updateWidgetIfNecessary() +{ + document()->updateStyleIfNeeded(); + + if (!needsWidgetUpdate() || useFallbackContent() || isImageType()) + return; + + if (!renderEmbeddedObject() || renderEmbeddedObject()->pluginCrashedOrWasMissing()) + return; + + // True indicates that this code path should only create non-netscape plugins (no clue why). + updateWidget(true); +} + +void HTMLPlugInImageElement::finishParsingChildren() +{ + HTMLPlugInElement::finishParsingChildren(); + if (useFallbackContent()) + return; + + setNeedsWidgetUpdate(true); + if (inDocument()) + setNeedsStyleRecalc(); +} + +void HTMLPlugInImageElement::willMoveToNewOwnerDocument() +{ + if (m_imageLoader) + m_imageLoader->elementWillMoveToNewOwnerDocument(); + HTMLPlugInElement::willMoveToNewOwnerDocument(); +} + +void HTMLPlugInImageElement::updateWidgetCallback(Node* n) +{ + static_cast(n)->updateWidgetIfNecessary(); +} + +} // namespace WebCore -- cgit v1.1