summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/web/WebHelperPluginImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/web/WebHelperPluginImpl.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/web/WebHelperPluginImpl.cpp265
1 files changed, 50 insertions, 215 deletions
diff --git a/chromium/third_party/WebKit/Source/web/WebHelperPluginImpl.cpp b/chromium/third_party/WebKit/Source/web/WebHelperPluginImpl.cpp
index d72d4b17128..bbe66c9ea36 100644
--- a/chromium/third_party/WebKit/Source/web/WebHelperPluginImpl.cpp
+++ b/chromium/third_party/WebKit/Source/web/WebHelperPluginImpl.cpp
@@ -29,249 +29,84 @@
*/
#include "config.h"
-#include "WebHelperPluginImpl.h"
+#include "web/WebHelperPluginImpl.h"
-#include "PageWidgetDelegate.h"
-#include "WebDocument.h"
-#include "WebFrameClient.h"
-#include "WebFrameImpl.h"
-#include "WebPlugin.h"
-#include "WebPluginContainerImpl.h"
-#include "WebViewClient.h"
-#include "WebViewImpl.h"
-#include "WebWidgetClient.h"
-#include "core/dom/NodeList.h"
-#include "core/html/HTMLPlugInElement.h"
-#include "core/loader/DocumentLoader.h"
-#include "core/loader/EmptyClients.h"
-#include "core/page/FocusController.h"
-#include "core/frame/FrameView.h"
-#include "core/page/Page.h"
-#include "core/frame/Settings.h"
+#include "core/html/HTMLObjectElement.h"
+#include "core/loader/FrameLoader.h"
+#include "core/loader/FrameLoaderClient.h"
+#include "public/web/WebPlugin.h"
+#include "web/WebLocalFrameImpl.h"
+#include "web/WebPluginContainerImpl.h"
using namespace WebCore;
namespace blink {
-#define addLiteral(literal, writer) writer->addData(literal, sizeof(literal) - 1)
+DEFINE_TYPE_CASTS(WebHelperPluginImpl, WebHelperPlugin, plugin, true, true);
-static inline void addString(const String& str, DocumentWriter* writer)
+WebHelperPlugin* WebHelperPlugin::create(const WebString& pluginType, WebLocalFrame* frame)
{
- CString str8 = str.utf8();
- writer->addData(str8.data(), str8.length());
-}
-
-static void writeDocument(const String& pluginType, const WebDocument& hostDocument, WebCore::DocumentLoader* loader)
-{
- // Give the new document the same URL as the hose document so that content
- // settings and other decisions can be made based on the correct origin.
- const WebURL& url = hostDocument.url();
-
- DocumentWriter* writer = loader->beginWriting("text/html", "UTF-8", url);
-
- addLiteral("<!DOCTYPE html><head><meta charset='UTF-8'></head><body>\n", writer);
- String objectTag = "<object type=\"" + pluginType + "\"></object>";
- addString(objectTag, writer);
- addLiteral("</body>\n", writer);
-
- loader->endWriting(writer);
+ OwnPtr<WebHelperPlugin> plugin = adoptPtr<WebHelperPlugin>(new WebHelperPluginImpl());
+ if (!toWebHelperPluginImpl(plugin.get())->initialize(pluginType, toWebLocalFrameImpl(frame)))
+ return 0;
+ return plugin.leakPtr();
}
-class HelperPluginChromeClient : public EmptyChromeClient {
- WTF_MAKE_NONCOPYABLE(HelperPluginChromeClient);
- WTF_MAKE_FAST_ALLOCATED;
-
-public:
- explicit HelperPluginChromeClient(WebHelperPluginImpl* widget)
- : m_widget(widget)
- {
- ASSERT(m_widget->m_widgetClient);
- }
-
-private:
- virtual void closeWindowSoon() OVERRIDE
- {
- // This should never be called since the only way to close the
- // invisible page is via closeHelperPlugin().
- ASSERT_NOT_REACHED();
- m_widget->closeHelperPlugin();
- }
-
- virtual void* webView() const OVERRIDE
- {
- return m_widget->m_webView;
- }
-
- WebHelperPluginImpl* m_widget;
-};
-
-// HelperPluginFrameClient acts as a filter to only forward messages onto the
-// main render frame that WebHelperPlugin actually needs. This prevents
-// having the WebHelperPlugin's frame accidentally signaling events on the
-// client that are meant only for WebFrames which are part of the main DOM.
-class HelperPluginFrameClient : public WebFrameClient {
-public:
- HelperPluginFrameClient(WebFrameClient* hostWebFrameClient)
- : m_hostWebFrameClient(hostWebFrameClient)
- {
- }
-
- virtual ~HelperPluginFrameClient()
- {
- }
-
- virtual WebPlugin* createPlugin(blink::WebFrame* frame, const WebPluginParams& params)
- {
- return m_hostWebFrameClient->createPlugin(frame, params);
- }
-
-private:
- WebFrameClient* m_hostWebFrameClient;
-};
-
-
-// WebHelperPluginImpl ----------------------------------------------------------------
-
-WebHelperPluginImpl::WebHelperPluginImpl(WebWidgetClient* client)
- : m_widgetClient(client)
- , m_webView(0)
- , m_mainFrame(0)
+WebHelperPluginImpl::WebHelperPluginImpl()
+ : m_destructionTimer(this, &WebHelperPluginImpl::reallyDestroy)
{
- ASSERT(client);
}
WebHelperPluginImpl::~WebHelperPluginImpl()
{
- ASSERT(!m_page);
}
-bool WebHelperPluginImpl::initialize(const String& pluginType, const WebDocument& hostDocument, WebViewImpl* webView)
+bool WebHelperPluginImpl::initialize(const String& pluginType, WebLocalFrameImpl* frame)
{
- ASSERT(webView);
- m_webView = webView;
-
- return initializePage(pluginType, hostDocument);
+ ASSERT(!m_objectElement && !m_pluginContainer);
+ if (!frame->frame()->loader().client())
+ return false;
+
+ m_objectElement = HTMLObjectElement::create(*frame->frame()->document(), 0, false);
+ Vector<String> attributeNames;
+ Vector<String> attributeValues;
+ ASSERT(frame->frame()->document()->url().isValid());
+ m_pluginContainer = adoptRef(toWebPluginContainerImpl(frame->frame()->loader().client()->createPlugin(
+ m_objectElement.get(),
+ frame->frame()->document()->url(),
+ attributeNames,
+ attributeValues,
+ pluginType,
+ false,
+ FrameLoaderClient::AllowDetachedPlugin).leakRef()));
+
+ if (!m_pluginContainer)
+ return false;
+
+ // Getting a placeholder plugin is also failure, since it's not the plugin the caller needed.
+ return !getPlugin()->isPlaceholder();
}
-void WebHelperPluginImpl::closeHelperPlugin()
+void WebHelperPluginImpl::reallyDestroy(Timer<WebHelperPluginImpl>*)
{
- if (m_page) {
- m_page->clearPageGroup();
- m_page->mainFrame()->loader().stopAllLoaders();
- }
-
- // We must destroy the page now in case the host page is being destroyed, in
- // which case some of the objects the page depends on may have been
- // destroyed by the time this->close() is called asynchronously.
- destroyPage();
-
- // m_widgetClient might be 0 because this widget might be already closed.
- if (m_widgetClient) {
- // closeWidgetSoon() will call this->close() later.
- m_widgetClient->closeWidgetSoon();
- }
- m_mainFrame->close();
+ delete this;
}
-void WebHelperPluginImpl::initializeFrame(WebFrameClient* client)
+void WebHelperPluginImpl::destroy()
{
- ASSERT(m_page);
- ASSERT(!m_frameClient);
- m_frameClient = adoptPtr(new HelperPluginFrameClient(client));
- m_mainFrame = WebFrameImpl::create(m_frameClient.get());
- m_mainFrame->initializeAsMainFrame(m_page.get());
+ // Defer deletion so we don't do too much work when called via stopActiveDOMObjects().
+ // FIXME: It's not clear why we still need this. The original code held a Page and a
+ // WebFrame, and destroying it would cause JavaScript triggered by frame detach to run,
+ // which isn't allowed inside stopActiveDOMObjects(). Removing this causes one Chrome test
+ // to fail with a timeout.
+ m_destructionTimer.startOneShot(0, FROM_HERE);
}
-// Returns a pointer to the WebPlugin by finding the single <object> tag in the page.
WebPlugin* WebHelperPluginImpl::getPlugin()
{
- ASSERT(m_page);
-
- RefPtr<NodeList> objectElements = m_page->mainFrame()->document()->getElementsByTagName(WebCore::HTMLNames::objectTag.localName());
- ASSERT(objectElements && objectElements->length() == 1);
- if (!objectElements || objectElements->length() < 1)
- return 0;
- Node* node = objectElements->item(0);
- ASSERT(node->hasTagName(WebCore::HTMLNames::objectTag));
- WebCore::Widget* widget = toHTMLPlugInElement(node)->pluginWidget();
- if (!widget)
- return 0;
- WebPlugin* plugin = toPluginContainerImpl(widget)->plugin();
- ASSERT(plugin);
- // If the plugin is a placeholder, it is not useful to the caller, and it
- // could be replaced at any time. Therefore, do not return it.
- if (plugin->isPlaceholder())
- return 0;
-
- // The plugin was instantiated and will outlive this object.
- return plugin;
-}
-
-bool WebHelperPluginImpl::initializePage(const String& pluginType, const WebDocument& hostDocument)
-{
- Page::PageClients pageClients;
- fillWithEmptyClients(pageClients);
- m_chromeClient = adoptPtr(new HelperPluginChromeClient(this));
- pageClients.chromeClient = m_chromeClient.get();
-
- m_page = adoptPtr(new Page(pageClients));
- ASSERT(!m_page->settings().isScriptEnabled());
- m_page->settings().setPluginsEnabled(true);
-
- m_webView->client()->initializeHelperPluginWebFrame(this);
-
- // The page's main frame was set in initializeFrame() as a result of the above call.
- Frame* frame = m_page->mainFrame();
- ASSERT(frame);
- frame->loader().forceSandboxFlags(SandboxAll & ~SandboxPlugins);
- frame->setView(FrameView::create(frame));
- // No need to set a size or make it not transparent.
-
- writeDocument(pluginType, hostDocument, frame->loader().activeDocumentLoader());
-
- return true;
-}
-
-void WebHelperPluginImpl::destroyPage()
-{
- if (!m_page)
- return;
-
- if (m_page->mainFrame())
- m_page->mainFrame()->loader().frameDetached();
-
- m_page.clear();
-}
-
-void WebHelperPluginImpl::layout()
-{
- PageWidgetDelegate::layout(m_page.get());
-}
-
-void WebHelperPluginImpl::setFocus(bool)
-{
- ASSERT_NOT_REACHED();
-}
-
-void WebHelperPluginImpl::close()
-{
- ASSERT(!m_page); // Should only be called via closePopup().
- m_widgetClient = 0;
- deref();
-}
-
-// WebHelperPlugin ----------------------------------------------------------------
-
-WebHelperPlugin* WebHelperPlugin::create(WebWidgetClient* client)
-{
- RELEASE_ASSERT(client);
- // A WebHelperPluginImpl instance usually has two references.
- // - One owned by the instance itself. It represents the visible widget.
- // - One owned by the hosting element. It's released when the hosting
- // element asks the WebHelperPluginImpl to close.
- // We need them because the closing operation is asynchronous and the widget
- // can be closed while the hosting element is unaware of it.
- return adoptRef(new WebHelperPluginImpl(client)).leakRef();
+ ASSERT(m_pluginContainer);
+ ASSERT(m_pluginContainer->plugin());
+ return m_pluginContainer->plugin();
}
} // namespace blink