summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderEmbeddedObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/RenderEmbeddedObject.cpp')
-rw-r--r--WebCore/rendering/RenderEmbeddedObject.cpp278
1 files changed, 7 insertions, 271 deletions
diff --git a/WebCore/rendering/RenderEmbeddedObject.cpp b/WebCore/rendering/RenderEmbeddedObject.cpp
index b1b253a..d08174d 100644
--- a/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -102,275 +102,6 @@ bool RenderEmbeddedObject::allowsAcceleratedCompositing() const
}
#endif
-// FIXME: This belongs in HTMLPluginElement.cpp to be shared by HTMLObjectElement and HTMLEmbedElement.
-static bool isURLAllowed(Document* doc, const String& url)
-{
- if (doc->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 = doc->completeURL(url);
- bool foundSelfReference = false;
- for (Frame* frame = doc->frame(); frame; frame = frame->tree()->parent()) {
- if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) {
- if (foundSelfReference)
- return false;
- foundSelfReference = true;
- }
- }
- return true;
-}
-
-typedef HashMap<String, String, CaseFoldingHash> ClassIdToTypeMap;
-
-// FIXME: This belongs in HTMLObjectElement.cpp
-static ClassIdToTypeMap* createClassIdToTypeMap()
-{
- ClassIdToTypeMap* map = new ClassIdToTypeMap;
- map->add("clsid:D27CDB6E-AE6D-11CF-96B8-444553540000", "application/x-shockwave-flash");
- map->add("clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA", "audio/x-pn-realaudio-plugin");
- map->add("clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B", "video/quicktime");
- map->add("clsid:166B1BCA-3F9C-11CF-8075-444553540000", "application/x-director");
- map->add("clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6", "application/x-mplayer2");
- map->add("clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95", "application/x-mplayer2");
- return map;
-}
-
-// FIXME: This belongs in HTMLObjectElement.cpp
-static String serviceTypeForClassId(const String& classId)
-{
- // Return early if classId is empty (since we won't do anything below).
- // Furthermore, if classId is null, calling get() below will crash.
- if (classId.isEmpty())
- return String();
-
- static ClassIdToTypeMap* map = createClassIdToTypeMap();
- return map->get(classId);
-}
-
-// FIXME: This belongs in HTMLObjectElement.cpp
-static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramValues)
-{
- // Some plugins don't understand the "data" attribute of the OBJECT tag (i.e. Real and WMP
- // require "src" attribute).
- int srcIndex = -1, dataIndex = -1;
- for (unsigned int i = 0; i < paramNames->size(); ++i) {
- if (equalIgnoringCase((*paramNames)[i], "src"))
- srcIndex = i;
- else if (equalIgnoringCase((*paramNames)[i], "data"))
- dataIndex = i;
- }
-
- if (srcIndex == -1 && dataIndex != -1) {
- paramNames->append("src");
- paramValues->append((*paramValues)[dataIndex]);
- }
-}
-
-// FIXME: This belongs in some loader header?
-static bool isNetscapePlugin(Frame* frame, const String& url, const String& serviceType)
-{
- KURL completedURL;
- if (!url.isEmpty())
- completedURL = frame->loader()->completeURL(url);
-
- if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
- return true;
- return false;
-}
-
-// FIXME: This belongs on HTMLObjectElement.
-static bool hasFallbackContent(HTMLObjectElement* objectElement)
-{
- for (Node* child = objectElement->firstChild(); child; child = child->nextSibling()) {
- if ((!child->isTextNode() && !child->hasTagName(paramTag)) // Discount <param>
- || (child->isTextNode() && !static_cast<Text*>(child)->containsOnlyWhitespace()))
- return true;
- }
- return false;
-}
-
-// FIXME: This belongs on HTMLObjectElement.
-static void parametersFromObject(HTMLObjectElement* objectElement, Vector<String>& paramNames, Vector<String>& paramValues, String& url, String& serviceType)
-{
- HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
-
- // Scan the PARAM children and store their name/value pairs.
- // Get the URL and type from the params if we don't already have them.
- Node* child = objectElement->firstChild();
- while (child) {
- if (child->hasTagName(paramTag)) {
- HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
- String name = p->name();
- if (url.isEmpty() && (equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")))
- url = deprecatedParseURL(p->value());
- // FIXME: serviceType calculation does not belong in this function.
- if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
- serviceType = p->value();
- size_t pos = serviceType.find(";");
- if (pos != notFound)
- serviceType = serviceType.left(pos);
- }
- if (!name.isEmpty()) {
- uniqueParamNames.add(name.impl());
- paramNames.append(p->name());
- paramValues.append(p->value());
- }
- }
- child = child->nextSibling();
- }
-
- // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag
- // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is
- // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means
- // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM,
- // else our Java plugin will misinterpret it. [4004531]
- String codebase;
- if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
- codebase = "codebase";
- uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
- }
-
- // Turn the attributes of the <object> element into arrays, but don't override <param> values.
- NamedNodeMap* attributes = objectElement->attributes();
- if (attributes) {
- for (unsigned i = 0; i < attributes->length(); ++i) {
- Attribute* it = attributes->attributeItem(i);
- const AtomicString& name = it->name().localName();
- if (!uniqueParamNames.contains(name.impl())) {
- paramNames.append(name.string());
- paramValues.append(it->value().string());
- }
- }
- }
-
- mapDataParamToSrc(&paramNames, &paramValues);
-
- // If we still don't have a type, try to map from a specific CLASSID to a type.
- if (serviceType.isEmpty())
- serviceType = serviceTypeForClassId(objectElement->classId());
-}
-
-// FIXME: This belongs on HTMLObjectElement, HTMLPluginElement or HTMLFrameOwnerElement.
-static void updateWidgetForObjectElement(HTMLObjectElement* objectElement, bool onlyCreateNonNetscapePlugins)
-{
- objectElement->setNeedsWidgetUpdate(false);
- if (!objectElement->isFinishedParsingChildren())
- return;
-
- Frame* frame = objectElement->document()->frame();
- String url = objectElement->url();
- String serviceType = objectElement->serviceType();
-
- Vector<String> paramNames;
- Vector<String> paramValues;
- parametersFromObject(objectElement, paramNames, paramValues, url, serviceType);
-
- if (!isURLAllowed(objectElement->document(), url))
- return;
-
- bool fallbackContent = hasFallbackContent(objectElement);
- objectElement->renderEmbeddedObject()->setHasFallbackContent(fallbackContent);
-
- if (onlyCreateNonNetscapePlugins && isNetscapePlugin(frame, url, serviceType))
- return;
-
- bool beforeLoadAllowedLoad = objectElement->dispatchBeforeLoadEvent(url);
-
- // beforeload events can modify the DOM, potentially causing
- // RenderWidget::destroy() to be called. Ensure we haven't been
- // destroyed before continuing.
- // FIXME: Should this render fallback content?
- if (!objectElement->renderer())
- return;
-
- bool success = beforeLoadAllowedLoad && frame->loader()->subframeLoader()->requestObject(objectElement, url, objectElement->getAttribute(nameAttr), serviceType, paramNames, paramValues);
-
- if (!success && fallbackContent)
- objectElement->renderFallbackContent();
-}
-
-// FIXME: This belongs on HTMLEmbedElement.
-static void parametersFromEmbed(HTMLEmbedElement* embedElement, Vector<String>& paramNames, Vector<String>& paramValues)
-{
- NamedNodeMap* attributes = embedElement->attributes();
- if (attributes) {
- for (unsigned i = 0; i < attributes->length(); ++i) {
- Attribute* it = attributes->attributeItem(i);
- paramNames.append(it->name().localName().string());
- paramValues.append(it->value().string());
- }
- }
-}
-
-// FIXME: This belongs on HTMLEmbedElement, HTMLPluginElement or HTMLFrameOwnerElement.
-static void updateWidgetForEmbedElement(HTMLEmbedElement* embedElement, bool onlyCreateNonNetscapePlugins)
-{
- Frame* frame = embedElement->document()->frame();
- String url = embedElement->url();
- String serviceType = embedElement->serviceType();
-
- embedElement->setNeedsWidgetUpdate(false);
-
- if (url.isEmpty() && serviceType.isEmpty())
- return;
- if (!isURLAllowed(embedElement->document(), url))
- return;
-
- Vector<String> paramNames;
- Vector<String> paramValues;
- parametersFromEmbed(embedElement, paramNames, paramValues);
-
- if (onlyCreateNonNetscapePlugins && isNetscapePlugin(frame, url, serviceType))
- return;
-
- if (embedElement->dispatchBeforeLoadEvent(url)) {
- // FIXME: beforeLoad could have detached the renderer! Just like in the <object> case above.
- frame->loader()->subframeLoader()->requestObject(embedElement, url, embedElement->getAttribute(nameAttr), serviceType, paramNames, paramValues);
- }
-}
-
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-// FIXME: This belongs on HTMLMediaElement.
-static void updateWidgetForMediaElement(HTMLMediaElement* mediaElement, bool ignored)
-{
- Vector<String> paramNames;
- Vector<String> paramValues;
- KURL kurl;
-
- mediaElement->getPluginProxyParams(kurl, paramNames, paramValues);
- mediaElement->setNeedWidgetUpdate(false);
- frame->loader()->subframeLoader()->loadMediaPlayerProxyPlugin(mediaElement, kurl, paramNames, paramValues);
-}
-#endif
-
-void RenderEmbeddedObject::updateWidget(bool onlyCreateNonNetscapePlugins)
-{
- if (!m_replacementText.isNull() || !node()) // Check the node in case destroy() has been called.
- return;
-
- // The calls to SubframeLoader::requestObject within this function can result in a plug-in being initialized.
- // This can run cause arbitrary JavaScript to run and may result in this RenderObject being detached from
- // the render tree and destroyed, causing a crash like <rdar://problem/6954546>. By extending our lifetime
- // artifically to ensure that we remain alive for the duration of plug-in initialization.
- RenderWidgetProtector protector(this);
-
- if (node()->hasTagName(objectTag)) {
- HTMLObjectElement* objectElement = static_cast<HTMLObjectElement*>(node());
- updateWidgetForObjectElement(objectElement, onlyCreateNonNetscapePlugins);
- } else if (node()->hasTagName(embedTag)) {
- HTMLEmbedElement* embedElement = static_cast<HTMLEmbedElement*>(node());
- updateWidgetForEmbedElement(embedElement, onlyCreateNonNetscapePlugins);
- }
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
- else if (node()->hasTagName(videoTag) || node()->hasTagName(audioTag)) {
- HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node());
- updateWidgetForMediaElement(mediaElement, onlyCreateNonNetscapePlugins);
- }
-#endif
-}
-
void RenderEmbeddedObject::setShowsMissingPluginIndicator()
{
ASSERT(m_replacementText.isEmpty());
@@ -384,6 +115,11 @@ void RenderEmbeddedObject::setShowsCrashedPluginIndicator()
m_replacementText = crashedPluginText();
}
+bool RenderEmbeddedObject::pluginCrashedOrWasMissing() const
+{
+ return !m_replacementText.isNull();
+}
+
void RenderEmbeddedObject::setMissingPluginIndicatorIsPressed(bool pressed)
{
if (m_missingPluginIndicatorIsPressed == pressed)
@@ -395,7 +131,7 @@ void RenderEmbeddedObject::setMissingPluginIndicatorIsPressed(bool pressed)
void RenderEmbeddedObject::paint(PaintInfo& paintInfo, int tx, int ty)
{
- if (!m_replacementText.isNull()) {
+ if (pluginCrashedOrWasMissing()) {
RenderReplaced::paint(paintInfo, tx, ty);
return;
}
@@ -405,7 +141,7 @@ void RenderEmbeddedObject::paint(PaintInfo& paintInfo, int tx, int ty)
void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
{
- if (!m_replacementText)
+ if (pluginCrashedOrWasMissing())
return;
if (paintInfo.phase == PaintPhaseSelection)