| Index: Source/core/html/HTMLPlugInElement.cpp
|
| diff --git a/Source/core/html/HTMLPlugInElement.cpp b/Source/core/html/HTMLPlugInElement.cpp
|
| index f2aaf0418bfc21ba56688e9ef998e4426212792f..de7d83ed3f09a162072b9a575d67293b515270c9 100644
|
| --- a/Source/core/html/HTMLPlugInElement.cpp
|
| +++ b/Source/core/html/HTMLPlugInElement.cpp
|
| @@ -33,6 +33,7 @@
|
| #include "core/events/Event.h"
|
| #include "core/frame/ContentSecurityPolicy.h"
|
| #include "core/frame/Frame.h"
|
| +#include "core/frame/FrameView.h"
|
| #include "core/html/HTMLImageLoader.h"
|
| #include "core/html/PluginDocument.h"
|
| #include "core/html/shadow/HTMLContentElement.h"
|
| @@ -84,7 +85,7 @@ HTMLPlugInElement::~HTMLPlugInElement()
|
|
|
| bool HTMLPlugInElement::canProcessDrag() const
|
| {
|
| - return pluginWidget() && pluginWidget()->isPluginView() && toPluginView(pluginWidget())->canProcessDrag();
|
| + return widget() && widget()->isPluginView() && toPluginView(widget())->canProcessDrag();
|
| }
|
|
|
| bool HTMLPlugInElement::willRespondToMouseClickEvents()
|
| @@ -141,6 +142,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 +182,12 @@ void HTMLPlugInElement::detach(const AttachContext& context)
|
| document().decrementLoadEventDelayCount();
|
| }
|
|
|
| + Widget* plugin = widget();
|
| + if (plugin && plugin->pluginShouldPersist())
|
| + m_persistedPluginWidget = plugin;
|
| resetInstance();
|
| + setWidget(0);
|
| +
|
|
|
| if (m_isCapturingMouseEvents) {
|
| if (Frame* frame = document().frame())
|
| @@ -218,8 +253,19 @@ 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 = widget();
|
| + if (!plugin && m_persistedPluginWidget)
|
| + plugin = m_persistedPluginWidget.get();
|
| + if (!plugin && !m_inBeforeLoadEventHandler) {
|
| + // If the plugin wasn't created without a renderer, then we can
|
| + // trigger its creation here. Although widgets are no longer owned
|
| + // by the renderWidget, the creation of the latter will still lead
|
| + // to loadPlugin() being called.
|
| + renderWidgetForJSBindings();
|
| + plugin = widget();
|
| + }
|
| + if (plugin)
|
| + m_pluginWrapper = frame->script().createPluginWrapper(plugin);
|
| }
|
| return m_pluginWrapper.get();
|
| }
|
| @@ -237,20 +283,6 @@ bool HTMLPlugInElement::dispatchBeforeLoadEvent(const String& sourceURL)
|
| return beforeLoadAllowedLoad;
|
| }
|
|
|
| -Widget* HTMLPlugInElement::pluginWidget() const
|
| -{
|
| - if (m_inBeforeLoadEventHandler) {
|
| - // The plug-in hasn't loaded yet, and it makes no sense to try to load
|
| - // if beforeload handler happened to touch the plug-in element. That
|
| - // would recursively call beforeload for the same element.
|
| - return 0;
|
| - }
|
| -
|
| - if (RenderWidget* renderWidget = renderWidgetForJSBindings())
|
| - return renderWidget->widget();
|
| - return 0;
|
| -}
|
| -
|
| bool HTMLPlugInElement::isPresentationAttribute(const QualifiedName& name) const
|
| {
|
| if (name == widthAttr || name == heightAttr || name == vspaceAttr || name == hspaceAttr || name == alignAttr)
|
| @@ -320,7 +352,7 @@ bool HTMLPlugInElement::isKeyboardFocusable() const
|
| {
|
| if (!document().isActive())
|
| return false;
|
| - return pluginWidget() && pluginWidget()->isPluginView() && toPluginView(pluginWidget())->supportsKeyboardFocus();
|
| + return widget() && widget()->isPluginView() && toPluginView(widget())->supportsKeyboardFocus();
|
| }
|
|
|
| bool HTMLPlugInElement::isPluginElement() const
|
| @@ -412,8 +444,9 @@ bool HTMLPlugInElement::requestObject(const String& url, const String& mimeType,
|
| KURL completedURL = document().completeURL(url);
|
|
|
| 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
|
| @@ -422,7 +455,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)
|
| {
|
| Frame* frame = document().frame();
|
|
|
| @@ -434,26 +467,42 @@ 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;
|
|
|
| + FrameLoaderClient::PluginLoadType loadType = renderer ? FrameLoaderClient::PluginLoadRequiresRenderer : FrameLoaderClient::PluginLoadWithoutRenderer;
|
| +
|
| 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;
|
|
|
| - IntSize contentSize = roundedIntSize(LayoutSize(renderer->contentWidth(), renderer->contentHeight()));
|
| - bool loadManually = document().isPluginDocument() && !document().containsPlugins() && toPluginDocument(document()).shouldLoadPluginManually();
|
| - RefPtr<Widget> widget = frame->loader().client()->createPlugin(contentSize, this, url, paramNames, paramValues, mimeType, loadManually);
|
| + IntSize contentSize;
|
| + if (renderer)
|
| + contentSize = roundedIntSize(LayoutSize(renderer->contentWidth(), renderer->contentHeight()));
|
| + RefPtr<Widget> plugin = m_persistedPluginWidget;
|
| +
|
| + if (!plugin) {
|
| + bool loadManually = document().isPluginDocument() && !document().containsPlugins() && toPluginDocument(document()).shouldLoadPluginManually();
|
| + plugin = frame->loader().client()->createPlugin(contentSize, this, url, paramNames, paramValues, mimeType, loadManually, loadType);
|
| + }
|
|
|
| - if (!widget) {
|
| - if (!renderer->showsUnavailablePluginIndicator())
|
| + if (!plugin) {
|
| + if (renderer && !renderer->showsUnavailablePluginIndicator())
|
| renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginMissing);
|
| return false;
|
| }
|
|
|
| - renderer->setWidget(widget);
|
| + ASSERT(plugin->isPluginContainer());
|
| +
|
| + if (renderer) {
|
| + setWidget(plugin);
|
| + m_persistedPluginWidget = 0;
|
| + } else {
|
| + if (plugin != m_persistedPluginWidget)
|
| + m_persistedPluginWidget = plugin;
|
| + }
|
| document().setContainsPlugins();
|
| - setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
|
| return true;
|
| }
|
|
|
|
|