#include "core/dom/Node.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/Event.h"
+#include "core/frame/FrameView.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLContentElement.h"
if (!renderer() || useFallbackContent())
return;
+
if (isImageType()) {
if (!m_imageLoader)
m_imageLoader = adoptPtr(new HTMLImageLoader(this));
}
}
+void HTMLPlugInElement::requestPluginCreationWithoutRendererIfPossible()
+{
+ if (m_serviceType.isEmpty())
+ return;
+
+ if (!document().frame()
+ || !document().frame()->loader().client()->canCreatePluginWithoutRenderer(m_serviceType))
+ return;
+
+ if (renderer() && renderer()->isWidget())
+ return;
+
+ createPluginWithoutRenderer();
+}
+
+void HTMLPlugInElement::createPluginWithoutRenderer()
+{
+ ASSERT(document().frame()->loader().client()->canCreatePluginWithoutRenderer(m_serviceType));
+
+ KURL url;
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+
+ paramNames.append("type");
+ paramValues.append(m_serviceType);
+
+ bool useFallback = false;
+ loadPlugin(url, m_serviceType, paramNames, paramValues, useFallback, false);
+}
+
void HTMLPlugInElement::detach(const AttachContext& context)
{
// Update the widget the next time we attach (detaching destroys the plugin).
document().decrementLoadEventDelayCount();
}
+ // Only try to persist a plugin widget we actually own.
+ Widget* plugin = ownedWidget();
+ if (plugin && plugin->pluginShouldPersist())
+ m_persistedPluginWidget = plugin;
resetInstance();
+ // FIXME - is this next line necessary?
+ setWidget(nullptr);
if (m_isCapturingMouseEvents) {
if (LocalFrame* frame = document().frame())
// return the cached allocated Bindings::Instance. Not supporting this
// edge-case is OK.
if (!m_pluginWrapper) {
- if (Widget* widget = pluginWidget())
- m_pluginWrapper = frame->script().createPluginWrapper(widget);
+ Widget* plugin;
+
+ if (m_persistedPluginWidget)
+ plugin = m_persistedPluginWidget.get();
+ else
+ plugin = pluginWidget();
+
+ if (plugin)
+ m_pluginWrapper = frame->script().createPluginWrapper(plugin);
}
return m_pluginWrapper.get();
}
return Image::supportsType(m_serviceType);
}
-const String HTMLPlugInElement::loadedMimeType() const
-{
- String mimeType = m_serviceType;
- if (mimeType.isEmpty())
- mimeType = mimeTypeFromURL(m_loadedUrl);
- return mimeType;
-}
-
RenderEmbeddedObject* HTMLPlugInElement::renderEmbeddedObject() const
{
// HTMLObjectElement and HTMLEmbedElement may return arbitrary renderers
return false;
bool useFallback;
+ bool requireRenderer = true;
if (shouldUsePlugin(completedURL, mimeType, renderer->hasFallbackContent(), useFallback))
- return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFallback);
+ return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFallback, requireRenderer);
// If the plug-in element already contains a subframe,
// loadOrRedirectSubframe will re-use it. Otherwise, it will create a new
return loadOrRedirectSubframe(completedURL, getNameAttribute(), true);
}
-bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback)
+bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback, bool requireRenderer)
{
LocalFrame* frame = document().frame();
RenderEmbeddedObject* renderer = renderEmbeddedObject();
// FIXME: This code should not depend on renderer!
- if (!renderer || useFallback)
+ if ((!renderer && requireRenderer) || useFallback)
return false;
WTF_LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data());
WTF_LOG(Plugins, " Loaded URL: %s", url.string().utf8().data());
m_loadedUrl = url;
- bool loadManually = document().isPluginDocument() && !document().containsPlugins() && toPluginDocument(document()).shouldLoadPluginManually();
- RefPtr<Widget> widget = frame->loader().client()->createPlugin(this, url, paramNames, paramValues, mimeType, loadManually, FrameLoaderClient::FailOnDetachedPlugin);
+ RefPtr<Widget> widget = m_persistedPluginWidget;
+ if (!widget) {
+ bool loadManually = document().isPluginDocument() && !document().containsPlugins() && toPluginDocument(document()).shouldLoadPluginManually();
+ FrameLoaderClient::DetachedPluginPolicy policy = requireRenderer ? FrameLoaderClient::FailOnDetachedPlugin : FrameLoaderClient::AllowDetachedPlugin;
+ widget = frame->loader().client()->createPlugin(this, url, paramNames, paramValues, mimeType, loadManually, policy);
+ }
if (!widget) {
- if (!renderer->showsUnavailablePluginIndicator())
+ if (renderer && !renderer->showsUnavailablePluginIndicator())
renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginMissing);
return false;
}
- renderer->setWidget(widget);
+ if (renderer) {
+ setWidget(widget);
+ m_persistedPluginWidget = nullptr;
+ } else if (widget != m_persistedPluginWidget) {
+ m_persistedPluginWidget = widget;
+ }
document().setContainsPlugins();
scheduleLayerUpdate();
return true;
userAgentShadowRoot()->appendChild(HTMLContentElement::create(document()));
}
-void HTMLPlugInElement::didAddShadowRoot(ShadowRoot& root)
+void HTMLPlugInElement::willAddFirstAuthorShadowRoot()
{
- if (root.isOldestAuthorShadowRoot())
- lazyReattachIfAttached();
+ lazyReattachIfAttached();
}
bool HTMLPlugInElement::useFallbackContent() const