WebCore/html/HTMLEmbedElement.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
       
     3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
       
     4  *           (C) 2000 Stefan Schimanski (1Stein@gmx.de)
       
     5  * Copyright (C) 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved.
       
     6  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
       
     7  *
       
     8  * This library is free software; you can redistribute it and/or
       
     9  * modify it under the terms of the GNU Library General Public
       
    10  * License as published by the Free Software Foundation; either
       
    11  * version 2 of the License, or (at your option) any later version.
       
    12  *
       
    13  * This library is distributed in the hope that it will be useful,
       
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    16  * Library General Public License for more details.
       
    17  *
       
    18  * You should have received a copy of the GNU Library General Public License
       
    19  * along with this library; see the file COPYING.LIB.  If not, write to
       
    20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    21  * Boston, MA 02110-1301, USA.
       
    22  */
       
    23 
       
    24 #include "config.h"
       
    25 #include "HTMLEmbedElement.h"
       
    26 
       
    27 #include "Attribute.h"
       
    28 #include "CSSHelper.h"
       
    29 #include "CSSPropertyNames.h"
       
    30 #include "Frame.h"
       
    31 #include "HTMLDocument.h"
       
    32 #include "HTMLImageLoader.h"
       
    33 #include "HTMLNames.h"
       
    34 #include "HTMLObjectElement.h"
       
    35 #include "RenderEmbeddedObject.h"
       
    36 #include "RenderImage.h"
       
    37 #include "RenderWidget.h"
       
    38 #include "ScriptController.h"
       
    39 #include "Settings.h"
       
    40 
       
    41 namespace WebCore {
       
    42 
       
    43 using namespace HTMLNames;
       
    44 
       
    45 inline HTMLEmbedElement::HTMLEmbedElement(const QualifiedName& tagName, Document* document)
       
    46     : HTMLPlugInImageElement(tagName, document)
       
    47     , m_needWidgetUpdate(false)
       
    48 {
       
    49     ASSERT(hasTagName(embedTag));
       
    50 }
       
    51 
       
    52 PassRefPtr<HTMLEmbedElement> HTMLEmbedElement::create(const QualifiedName& tagName, Document* document)
       
    53 {
       
    54     return adoptRef(new HTMLEmbedElement(tagName, document));
       
    55 }
       
    56 
       
    57 static inline RenderWidget* findWidgetRenderer(const Node* n) 
       
    58 {
       
    59     if (!n->renderer())
       
    60         do
       
    61             n = n->parentNode();
       
    62         while (n && !n->hasTagName(objectTag));
       
    63 
       
    64     if (n && n->renderer() && n->renderer()->isWidget())
       
    65         return toRenderWidget(n->renderer());
       
    66 
       
    67     return 0;
       
    68 }
       
    69 
       
    70 RenderWidget* HTMLEmbedElement::renderWidgetForJSBindings() const
       
    71 {
       
    72     document()->updateLayoutIgnorePendingStylesheets();
       
    73     return findWidgetRenderer(this);
       
    74 }
       
    75 
       
    76 bool HTMLEmbedElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
       
    77 {
       
    78     if (attrName == hiddenAttr) {
       
    79         result = eUniversal;
       
    80         return false;
       
    81     }
       
    82         
       
    83     return HTMLPlugInElement::mapToEntry(attrName, result);
       
    84 }
       
    85 
       
    86 void HTMLEmbedElement::parseMappedAttribute(Attribute* attr)
       
    87 {
       
    88     const AtomicString& value = attr->value();
       
    89   
       
    90     if (attr->name() == typeAttr) {
       
    91         m_serviceType = value.string().lower();
       
    92         int pos = m_serviceType.find(";");
       
    93         if (pos != -1)
       
    94             m_serviceType = m_serviceType.left(pos);
       
    95         if (!isImageType() && m_imageLoader)
       
    96             m_imageLoader.clear();
       
    97     } else if (attr->name() == codeAttr)
       
    98         m_url = deprecatedParseURL(value.string());
       
    99     else if (attr->name() == srcAttr) {
       
   100         m_url = deprecatedParseURL(value.string());
       
   101         if (renderer() && isImageType()) {
       
   102             if (!m_imageLoader)
       
   103                 m_imageLoader.set(new HTMLImageLoader(this));
       
   104             m_imageLoader->updateFromElementIgnoringPreviousError();
       
   105         }
       
   106     } else if (attr->name() == hiddenAttr) {
       
   107         if (equalIgnoringCase(value.string(), "yes") || equalIgnoringCase(value.string(), "true")) {
       
   108             // FIXME: Not dynamic, since we add this but don't remove it, but it may be OK for now
       
   109             // that this rarely-used attribute won't work properly if you remove it.
       
   110             addCSSLength(attr, CSSPropertyWidth, "0");
       
   111             addCSSLength(attr, CSSPropertyHeight, "0");
       
   112         }
       
   113     } else if (attr->name() == nameAttr) {
       
   114         if (inDocument() && document()->isHTMLDocument()) {
       
   115             HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
       
   116             document->removeNamedItem(m_name);
       
   117             document->addNamedItem(value);
       
   118         }
       
   119         m_name = value;
       
   120     } else
       
   121         HTMLPlugInElement::parseMappedAttribute(attr);
       
   122 }
       
   123 
       
   124 bool HTMLEmbedElement::rendererIsNeeded(RenderStyle* style)
       
   125 {
       
   126     if (isImageType())
       
   127         return HTMLPlugInElement::rendererIsNeeded(style);
       
   128 
       
   129     Frame* frame = document()->frame();
       
   130     if (!frame)
       
   131         return false;
       
   132 
       
   133     Node* p = parentNode();
       
   134     if (p && p->hasTagName(objectTag)) {
       
   135         ASSERT(p->renderer());
       
   136         return false;
       
   137     }
       
   138 
       
   139 #if ENABLE(DASHBOARD_SUPPORT)
       
   140     // Workaround for <rdar://problem/6642221>. 
       
   141     if (Settings* settings = frame->settings()) {
       
   142         if (settings->usesDashboardBackwardCompatibilityMode())
       
   143             return true;
       
   144     }
       
   145 #endif
       
   146 
       
   147     return HTMLPlugInElement::rendererIsNeeded(style);
       
   148 }
       
   149 
       
   150 RenderObject* HTMLEmbedElement::createRenderer(RenderArena* arena, RenderStyle*)
       
   151 {
       
   152     if (isImageType())
       
   153         return new (arena) RenderImage(this);
       
   154     return new (arena) RenderEmbeddedObject(this);
       
   155 }
       
   156 
       
   157 void HTMLEmbedElement::attach()
       
   158 {
       
   159     m_needWidgetUpdate = true;
       
   160 
       
   161     bool isImage = isImageType();
       
   162 
       
   163     if (!isImage)
       
   164         queuePostAttachCallback(&HTMLPlugInElement::updateWidgetCallback, this);
       
   165 
       
   166     HTMLPlugInElement::attach();
       
   167 
       
   168     if (isImage && renderer()) {
       
   169         if (!m_imageLoader)
       
   170             m_imageLoader.set(new HTMLImageLoader(this));
       
   171         m_imageLoader->updateFromElement();
       
   172 
       
   173         if (renderer())
       
   174             toRenderImage(renderer())->setCachedImage(m_imageLoader->image());
       
   175     }
       
   176 }
       
   177 
       
   178 void HTMLEmbedElement::updateWidget()
       
   179 {
       
   180     document()->updateStyleIfNeeded();
       
   181     if (m_needWidgetUpdate && renderer() && !isImageType())
       
   182         toRenderEmbeddedObject(renderer())->updateWidget(true);
       
   183 }
       
   184 
       
   185 void HTMLEmbedElement::insertedIntoDocument()
       
   186 {
       
   187     if (document()->isHTMLDocument())
       
   188         static_cast<HTMLDocument*>(document())->addNamedItem(m_name);
       
   189 
       
   190     String width = getAttribute(widthAttr);
       
   191     String height = getAttribute(heightAttr);
       
   192     if (!width.isEmpty() || !height.isEmpty()) {
       
   193         Node* n = parent();
       
   194         while (n && !n->hasTagName(objectTag))
       
   195             n = n->parent();
       
   196         if (n) {
       
   197             if (!width.isEmpty())
       
   198                 static_cast<HTMLObjectElement*>(n)->setAttribute(widthAttr, width);
       
   199             if (!height.isEmpty())
       
   200                 static_cast<HTMLObjectElement*>(n)->setAttribute(heightAttr, height);
       
   201         }
       
   202     }
       
   203 
       
   204     HTMLPlugInElement::insertedIntoDocument();
       
   205 }
       
   206 
       
   207 void HTMLEmbedElement::removedFromDocument()
       
   208 {
       
   209     if (document()->isHTMLDocument())
       
   210         static_cast<HTMLDocument*>(document())->removeNamedItem(m_name);
       
   211 
       
   212     HTMLPlugInElement::removedFromDocument();
       
   213 }
       
   214 
       
   215 void HTMLEmbedElement::attributeChanged(Attribute* attr, bool preserveDecls)
       
   216 {
       
   217     HTMLPlugInElement::attributeChanged(attr, preserveDecls);
       
   218 
       
   219     if ((attr->name() == widthAttr || attr->name() == heightAttr) && !attr->isEmpty()) {
       
   220         Node* n = parent();
       
   221         while (n && !n->hasTagName(objectTag))
       
   222             n = n->parent();
       
   223         if (n)
       
   224             static_cast<HTMLObjectElement*>(n)->setAttribute(attr->name(), attr->value());
       
   225     }
       
   226 }
       
   227 
       
   228 bool HTMLEmbedElement::isURLAttribute(Attribute* attr) const
       
   229 {
       
   230     return attr->name() == srcAttr;
       
   231 }
       
   232 
       
   233 const QualifiedName& HTMLEmbedElement::imageSourceAttributeName() const
       
   234 {
       
   235     return srcAttr;
       
   236 }
       
   237 
       
   238 void HTMLEmbedElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
       
   239 {
       
   240     HTMLPlugInImageElement::addSubresourceAttributeURLs(urls);
       
   241 
       
   242     addSubresourceURL(urls, document()->completeURL(getAttribute(srcAttr)));
       
   243 }
       
   244 
       
   245 }