18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 22bde8e466a4451c7319e3a072d118917957d6554Steve Block * Copyright (C) 2008, 2011 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLPlugInImageElement.h" 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h" 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h" 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoaderClient.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLImageLoader.h" 282bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "HTMLNames.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Image.h" 305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "Page.h" 315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "RenderEmbeddedObject.h" 325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "RenderImage.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 362bde8e466a4451c7319e3a072d118917957d6554Steve BlockHTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Document* document, bool createdByParser, PreferPlugInsForImagesOption preferPlugInsForImagesOption) 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : HTMLPlugInElement(tagName, document) 385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // m_needsWidgetUpdate(!createdByParser) allows HTMLObjectElement to delay 395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // widget updates until after all children are parsed. For HTMLEmbedElement 405ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // this delay is unnecessary, but it is simpler to make both classes share 415ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // the same codepath in this class. 425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen , m_needsWidgetUpdate(!createdByParser) 432bde8e466a4451c7319e3a072d118917957d6554Steve Block , m_shouldPreferPlugInsForImages(preferPlugInsForImagesOption == ShouldPreferPlugInsForImages) 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenRenderEmbeddedObject* HTMLPlugInImageElement::renderEmbeddedObject() const 485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // HTMLObjectElement and HTMLEmbedElement may return arbitrary renderers 505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // when using fallback content. 515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (!renderer() || !renderer()->isEmbeddedObject()) 525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return 0; 535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return toRenderEmbeddedObject(renderer()); 545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLPlugInImageElement::isImageType() 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_serviceType.isEmpty() && protocolIs(m_url, "data")) 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_serviceType = mimeTypeFromDataURL(m_url); 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (Frame* frame = document()->frame()) { 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project KURL completedURL = frame->loader()->completeURL(m_url); 632bde8e466a4451c7319e3a072d118917957d6554Steve Block return frame->loader()->client()->objectContentType(completedURL, m_serviceType, shouldPreferPlugInsForImages()) == ObjectContentImage; 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Image::supportsType(m_serviceType); 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 695abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// We don't use m_url, as it may not be the final URL that the object loads, 705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// depending on <param> values. 715abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickbool HTMLPlugInImageElement::allowedToLoadFrameURL(const String& url) 725abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 735abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ASSERT(document()); 745abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ASSERT(document()->frame()); 755abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (document()->frame()->page()->frameCount() >= Page::maxNumberOfFrames) 765abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return false; 775abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 785abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // We allow one level of self-reference because some sites depend on that. 795abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // But we don't allow more than one. 805abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick KURL completeURL = document()->completeURL(url); 815abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick bool foundSelfReference = false; 825abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick for (Frame* frame = document()->frame(); frame; frame = frame->tree()->parent()) { 832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (equalIgnoringFragmentIdentifier(frame->document()->url(), completeURL)) { 845abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (foundSelfReference) 855abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return false; 865abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick foundSelfReference = true; 875abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 885abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 895abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return true; 905abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 915abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 925abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// We don't use m_url, or m_serviceType as they may not be the final values 935abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// that <object> uses depending on <param> values. 945abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickbool HTMLPlugInImageElement::wouldLoadAsNetscapePlugin(const String& url, const String& serviceType) 955abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 965abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ASSERT(document()); 975abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ASSERT(document()->frame()); 985abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick FrameLoader* frameLoader = document()->frame()->loader(); 995abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ASSERT(frameLoader); 1005abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick KURL completedURL; 1015abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!url.isEmpty()) 1025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick completedURL = frameLoader->completeURL(url); 1035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1042bde8e466a4451c7319e3a072d118917957d6554Steve Block if (frameLoader->client()->objectContentType(completedURL, serviceType, shouldPreferPlugInsForImages()) == ObjectContentNetscapePlugin) 1055abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return true; 1065abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return false; 1075abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 1085abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1095ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenRenderObject* HTMLPlugInImageElement::createRenderer(RenderArena* arena, RenderStyle* style) 1105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // Fallback content breaks the DOM->Renderer class relationship of this 1125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // class and all superclasses because createObject won't necessarily 1135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // return a RenderEmbeddedObject, RenderPart or even RenderWidget. 1145ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (useFallbackContent()) 1155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return RenderObject::createObject(this, style); 1165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (isImageType()) { 1175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen RenderImage* image = new (arena) RenderImage(this); 1185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen image->setImageResource(RenderImageResource::create()); 1195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return image; 1205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 1215ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return new (arena) RenderEmbeddedObject(this); 1225ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid HTMLPlugInImageElement::recalcStyle(StyleChange ch) 1255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // FIXME: Why is this necessary? Manual re-attach is almost always wrong. 1275ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (!useFallbackContent() && needsWidgetUpdate() && renderer() && !isImageType()) { 1285ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen detach(); 1295ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen attach(); 1305ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 1315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen HTMLPlugInElement::recalcStyle(ch); 1325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid HTMLPlugInImageElement::attach() 1355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen bool isImage = isImageType(); 1375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (!isImage) 1395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen queuePostAttachCallback(&HTMLPlugInImageElement::updateWidgetCallback, this); 1405ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1415ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen HTMLPlugInElement::attach(); 1425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (isImage && renderer() && !useFallbackContent()) { 1445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (!m_imageLoader) 1455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_imageLoader = adoptPtr(new HTMLImageLoader(this)); 1465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_imageLoader->updateFromElement(); 1475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 1485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid HTMLPlugInImageElement::detach() 1515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1525abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // FIXME: Because of the insanity that is HTMLPlugInImageElement::recalcStyle, 1535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // we can end up detaching during an attach() call, before we even have a 1545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // renderer. In that case, don't mark the widget for update. 1555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (attached() && renderer() && !useFallbackContent()) 1565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // Update the widget the next time we attach (detaching destroys the plugin). 1575ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen setNeedsWidgetUpdate(true); 1585ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen HTMLPlugInElement::detach(); 1595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1605ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1615abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid HTMLPlugInImageElement::updateWidgetIfNecessary() 1625ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen document()->updateStyleIfNeeded(); 1645abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1655abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!needsWidgetUpdate() || useFallbackContent() || isImageType()) 1665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 1675abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1685abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!renderEmbeddedObject() || renderEmbeddedObject()->pluginCrashedOrWasMissing()) 1695abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 1705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block updateWidget(CreateOnlyNonNetscapePlugins); 1725ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1735ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1745ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid HTMLPlugInImageElement::finishParsingChildren() 1755ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1765ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen HTMLPlugInElement::finishParsingChildren(); 1775ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (useFallbackContent()) 1785ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return; 1795ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1805ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen setNeedsWidgetUpdate(true); 1815ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (inDocument()) 1825ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen setNeedsStyleRecalc(); 1835ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1845ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 185dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid HTMLPlugInImageElement::willMoveToNewOwnerDocument() 186dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 187dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_imageLoader) 188dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_imageLoader->elementWillMoveToNewOwnerDocument(); 189dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block HTMLPlugInElement::willMoveToNewOwnerDocument(); 190dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1925ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid HTMLPlugInImageElement::updateWidgetCallback(Node* n) 1935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1945abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick static_cast<HTMLPlugInImageElement*>(n)->updateWidgetIfNecessary(); 1955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1965ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 198