Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(744)

Unified Diff: Source/core/html/HTMLPlugInElement.cpp

Issue 23618022: BrowserPlugin/WebView - Move plugin lifetime to DOM (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix mac compile issue. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/html/HTMLPlugInElement.cpp
diff --git a/Source/core/html/HTMLPlugInElement.cpp b/Source/core/html/HTMLPlugInElement.cpp
index f2aaf0418bfc21ba56688e9ef998e4426212792f..9dac6104794456ec36993b9a60803648a2349737 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"
@@ -67,6 +68,7 @@ HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document& doc
, m_needsWidgetUpdate(!createdByParser)
, m_shouldPreferPlugInsForImages(preferPlugInsForImagesOption == ShouldPreferPlugInsForImages)
, m_displayState(Playing)
+ , m_persistedPluginWidget(0)
eseidel 2013/12/18 18:38:18 nit: RefPtr's default construtor sets to 0, no nee
wjmaclean 2013/12/23 23:49:53 Done.
{
setHasCustomStyleCallbacks();
}
@@ -84,7 +86,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 +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,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 +254,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 +284,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 +353,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 +445,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 +456,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 +468,46 @@ 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 (!widget) {
- if (!renderer->showsUnavailablePluginIndicator())
+ 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 (!plugin) {
+ if (renderer && !renderer->showsUnavailablePluginIndicator())
renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginMissing);
return false;
}
- renderer->setWidget(widget);
- document().setContainsPlugins();
+ ASSERT(plugin->isPluginContainer());
+
+ if (renderer) {
+ // FIXME: We assume we don't layout without a renderer, but check this assumption.
eseidel 2013/12/18 18:38:18 I'm not sure I understand this comment.
wjmaclean 2013/12/23 23:49:53 This was just a reminder to myself ... removed.
+ setWidget(plugin);
+ m_persistedPluginWidget = 0;
+ } else {
+ if (plugin != m_persistedPluginWidget)
+ m_persistedPluginWidget = plugin;
+ }
+ // FIXME: it may be that nothing has change (we might be continuing to
eseidel 2013/12/18 18:38:18 No, the recalc style is only needed to trigger ren
wjmaclean 2013/12/23 23:49:53 recalc style removed.
+ // persist the same plugin? In that case, would we need to recalc style?
setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
+ document().setContainsPlugins();
return true;
}

Powered by Google App Engine
This is Rietveld 408576698