Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / HTMLEmbedElement.cpp
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, 2011 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 "core/html/HTMLEmbedElement.h"
26
27 #include "CSSPropertyNames.h"
28 #include "HTMLNames.h"
29 #include "core/dom/Attribute.h"
30 #include "core/dom/shadow/ShadowRoot.h"
31 #include "core/html/HTMLImageLoader.h"
32 #include "core/html/HTMLObjectElement.h"
33 #include "core/html/PluginDocument.h"
34 #include "core/html/parser/HTMLParserIdioms.h"
35 #include "core/rendering/RenderEmbeddedObject.h"
36 #include "core/rendering/RenderWidget.h"
37
38 namespace WebCore {
39
40 using namespace HTMLNames;
41
42 inline HTMLEmbedElement::HTMLEmbedElement(Document& document, bool createdByParser)
43     : HTMLPlugInElement(embedTag, document, createdByParser, ShouldPreferPlugInsForImages)
44 {
45     ScriptWrappable::init(this);
46 }
47
48 PassRefPtrWillBeRawPtr<HTMLEmbedElement> HTMLEmbedElement::create(Document& document, bool createdByParser)
49 {
50     RefPtrWillBeRawPtr<HTMLEmbedElement> element = adoptRefWillBeRefCountedGarbageCollected(new HTMLEmbedElement(document, createdByParser));
51     element->ensureUserAgentShadowRoot();
52     return element.release();
53 }
54
55 static inline RenderWidget* findWidgetRenderer(const Node* n)
56 {
57     if (!n->renderer())
58         n = Traversal<HTMLObjectElement>::firstAncestor(*n);
59
60     if (n && n->renderer() && n->renderer()->isWidget())
61         return toRenderWidget(n->renderer());
62
63     return 0;
64 }
65
66 RenderWidget* HTMLEmbedElement::existingRenderWidget() const
67 {
68     return findWidgetRenderer(this);
69 }
70
71 bool HTMLEmbedElement::isPresentationAttribute(const QualifiedName& name) const
72 {
73     if (name == hiddenAttr)
74         return true;
75     return HTMLPlugInElement::isPresentationAttribute(name);
76 }
77
78 void HTMLEmbedElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
79 {
80     if (name == hiddenAttr) {
81         if (equalIgnoringCase(value, "yes") || equalIgnoringCase(value, "true")) {
82             addPropertyToPresentationAttributeStyle(style, CSSPropertyWidth, 0, CSSPrimitiveValue::CSS_PX);
83             addPropertyToPresentationAttributeStyle(style, CSSPropertyHeight, 0, CSSPrimitiveValue::CSS_PX);
84         }
85     } else {
86         HTMLPlugInElement::collectStyleForPresentationAttribute(name, value, style);
87     }
88 }
89
90 void HTMLEmbedElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
91 {
92     if (name == typeAttr) {
93         m_serviceType = value.string().lower();
94         size_t pos = m_serviceType.find(";");
95         if (pos != kNotFound)
96             m_serviceType = m_serviceType.left(pos);
97         if (!renderer())
98             requestPluginCreationWithoutRendererIfPossible();
99     } else if (name == codeAttr) {
100         m_url = stripLeadingAndTrailingHTMLSpaces(value);
101     } else if (name == srcAttr) {
102         m_url = stripLeadingAndTrailingHTMLSpaces(value);
103         if (renderer() && isImageType()) {
104             if (!m_imageLoader)
105                 m_imageLoader = adoptPtr(new HTMLImageLoader(this));
106             m_imageLoader->updateFromElementIgnoringPreviousError();
107         }
108     } else {
109         HTMLPlugInElement::parseAttribute(name, value);
110     }
111 }
112
113 void HTMLEmbedElement::parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues)
114 {
115     if (!hasAttributes())
116         return;
117
118     unsigned attributeCount = this->attributeCount();
119     for (unsigned i = 0; i < attributeCount; ++i) {
120         const Attribute& attribute = attributeItem(i);
121         paramNames.append(attribute.localName().string());
122         paramValues.append(attribute.value().string());
123     }
124 }
125
126 // FIXME: This should be unified with HTMLObjectElement::updateWidget and
127 // moved down into HTMLPluginElement.cpp
128 void HTMLEmbedElement::updateWidgetInternal()
129 {
130     ASSERT(!renderEmbeddedObject()->showsUnavailablePluginIndicator());
131     ASSERT(needsWidgetUpdate());
132     setNeedsWidgetUpdate(false);
133
134     if (m_url.isEmpty() && m_serviceType.isEmpty())
135         return;
136
137     // Note these pass m_url and m_serviceType to allow better code sharing with
138     // <object> which modifies url and serviceType before calling these.
139     if (!allowedToLoadFrameURL(m_url))
140         return;
141
142     // FIXME: These should be joined into a PluginParameters class.
143     Vector<String> paramNames;
144     Vector<String> paramValues;
145     parametersForPlugin(paramNames, paramValues);
146
147     RefPtr<HTMLEmbedElement> protect(this); // Loading the plugin might remove us from the document.
148
149     // FIXME: Can we not have renderer here now that beforeload events are gone?
150     if (!renderer())
151         return;
152
153     requestObject(m_url, m_serviceType, paramNames, paramValues);
154 }
155
156 bool HTMLEmbedElement::rendererIsNeeded(const RenderStyle& style)
157 {
158     if (isImageType())
159         return HTMLPlugInElement::rendererIsNeeded(style);
160
161     LocalFrame* frame = document().frame();
162     if (!frame)
163         return false;
164
165     // If my parent is an <object> and is not set to use fallback content, I
166     // should be ignored and not get a renderer.
167     ContainerNode* p = parentNode();
168     if (isHTMLObjectElement(p)) {
169         ASSERT(p->renderer());
170         if (!toHTMLObjectElement(p)->useFallbackContent()) {
171             ASSERT(!p->renderer()->isEmbeddedObject());
172             return false;
173         }
174     }
175     return HTMLPlugInElement::rendererIsNeeded(style);
176 }
177
178 bool HTMLEmbedElement::isURLAttribute(const Attribute& attribute) const
179 {
180     return attribute.name() == srcAttr || HTMLPlugInElement::isURLAttribute(attribute);
181 }
182
183 const QualifiedName& HTMLEmbedElement::subResourceAttributeName() const
184 {
185     return srcAttr;
186 }
187
188 const AtomicString HTMLEmbedElement::imageSourceURL() const
189 {
190     return getAttribute(srcAttr);
191 }
192
193 bool HTMLEmbedElement::isInteractiveContent() const
194 {
195     return true;
196 }
197
198 bool HTMLEmbedElement::isExposed() const
199 {
200     // http://www.whatwg.org/specs/web-apps/current-work/#exposed
201     for (HTMLObjectElement* object = Traversal<HTMLObjectElement>::firstAncestor(*this); object; object = Traversal<HTMLObjectElement>::firstAncestor(*object)) {
202         if (object->isExposed())
203             return false;
204     }
205     return true;
206 }
207
208 }