| Index: Source/core/html/HTMLPlugInElement.cpp
|
| diff --git a/Source/core/html/HTMLPlugInElement.cpp b/Source/core/html/HTMLPlugInElement.cpp
|
| index 9b00bb2bf990ffdea1787a7501b9bddab47eb539..5a2e5f6cbcb4d615142eee2674e4ab7b82d458d3 100644
|
| --- a/Source/core/html/HTMLPlugInElement.cpp
|
| +++ b/Source/core/html/HTMLPlugInElement.cpp
|
| @@ -31,6 +31,7 @@
|
| #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"
|
| @@ -116,6 +117,7 @@ void HTMLPlugInElement::attach(const AttachContext& context)
|
|
|
| if (!renderer() || useFallbackContent())
|
| return;
|
| +
|
| if (isImageType()) {
|
| if (!m_imageLoader)
|
| m_imageLoader = adoptPtr(new HTMLImageLoader(this));
|
| @@ -141,6 +143,35 @@ void HTMLPlugInElement::updateWidget()
|
| }
|
| }
|
|
|
| +void HTMLPlugInElement::requestPluginCreationWithoutRendererIfPossible()
|
| +{
|
| + if (m_serviceType.isEmpty())
|
| + return;
|
| +
|
| + if (!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).
|
| @@ -152,7 +183,13 @@ void HTMLPlugInElement::detach(const AttachContext& context)
|
| 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())
|
| @@ -218,8 +255,15 @@ SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper()
|
| // 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();
|
| }
|
| @@ -399,8 +443,9 @@ bool HTMLPlugInElement::requestObject(const String& url, const String& mimeType,
|
| 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
|
| @@ -409,7 +454,7 @@ bool HTMLPlugInElement::requestObject(const String& url, const String& mimeType,
|
| 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();
|
|
|
| @@ -418,23 +463,32 @@ bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, cons
|
|
|
| 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;
|
|
|