From 49233e234e5c787396cadb2cea33b31ae0cd65c1 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 20 Jun 2012 13:01:08 +0200 Subject: Imported WebKit commit 3a8c29f35d00659d2ce7a0ccdfa8304f14e82327 (http://svn.webkit.org/repository/webkit/trunk@120813) New snapshot with Windows build fixes --- Source/WebKit/chromium/src/WebHelperPluginImpl.cpp | 255 +++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 Source/WebKit/chromium/src/WebHelperPluginImpl.cpp (limited to 'Source/WebKit/chromium/src/WebHelperPluginImpl.cpp') diff --git a/Source/WebKit/chromium/src/WebHelperPluginImpl.cpp b/Source/WebKit/chromium/src/WebHelperPluginImpl.cpp new file mode 100644 index 000000000..afa3701aa --- /dev/null +++ b/Source/WebKit/chromium/src/WebHelperPluginImpl.cpp @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebHelperPluginImpl.h" + +#include "DocumentLoader.h" +#include "EmptyClients.h" +#include "FocusController.h" +#include "FrameView.h" +#include "HTMLPlugInElement.h" +#include "NodeList.h" +#include "Page.h" +#include "PageWidgetDelegate.h" +#include "Settings.h" +#include "WebFrameImpl.h" +#include "WebPlugin.h" +#include "WebPluginContainerImpl.h" +#include "WebViewClient.h" +#include "WebViewImpl.h" +#include "WebWidgetClient.h" + +using namespace WebCore; + +namespace WebKit { + +#define addLiteral(literal, writer) writer.addData(literal, sizeof(literal) - 1) + +static inline void addString(const String& str, DocumentWriter& writer) +{ + CString str8 = str.utf8(); + writer.addData(str8.data(), str8.length()); +} + +void writeDocument(WebCore::DocumentWriter& writer, const String& pluginType) +{ + writer.setMIMEType("text/html"); + writer.setEncoding("UTF-8", false); + writer.begin(); + + addLiteral("\n", writer); + String objectTag = ""; + addString(objectTag, writer); + addLiteral("\n", writer); + + writer.end(); +} + +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 + { + m_widget->closeHelperPlugin(); + } + + virtual void* webView() const OVERRIDE + { + return m_widget->m_webView; + } + + WebHelperPluginImpl* m_widget; +}; + +// WebHelperPluginImpl ---------------------------------------------------------------- + +WebHelperPluginImpl::WebHelperPluginImpl(WebWidgetClient* client) + : m_widgetClient(client) + , m_webView(0) +{ + ASSERT(client); +} + +WebHelperPluginImpl::~WebHelperPluginImpl() +{ + ASSERT(!m_page); +} + +bool WebHelperPluginImpl::init(WebViewImpl* webView, const String& pluginType) +{ + ASSERT(webView); + m_webView = webView; + + if (!initPage(webView, pluginType)) + return false; + m_widgetClient->show(WebNavigationPolicy()); + + setFocus(true); + + return true; +} + +void WebHelperPluginImpl::closeHelperPlugin() +{ + if (m_page) { + m_page->setGroupName(String()); + m_page->mainFrame()->loader()->stopAllLoaders(); + m_page->mainFrame()->loader()->stopLoading(UnloadEventPolicyNone); + } + // m_widgetClient might be 0 because this widget might be already closed. + if (m_widgetClient) { + // closeWidgetSoon() will call this->close() later. + m_widgetClient->closeWidgetSoon(); + } +} + +void WebHelperPluginImpl::initializeFrame(WebFrameClient* client) +{ + ASSERT(m_page); + RefPtr frame = WebFrameImpl::create(client); + frame->initializeAsMainFrame(m_page.get()); +} + +// Returns a pointer to the WebPlugin by finding the single tag in the page. +WebPlugin* WebHelperPluginImpl::getPlugin() +{ + ASSERT(m_page); + + RefPtr 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 = static_cast(node)->pluginWidget(); + if (!widget) + return 0; + WebPlugin* plugin = static_cast(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::initPage(WebKit::WebViewImpl* webView, const String& pluginType) +{ + Page::PageClients pageClients; + fillWithEmptyClients(pageClients); + m_chromeClient = adoptPtr(new HelperPluginChromeClient(this)); + pageClients.chromeClient = m_chromeClient.get(); + + m_page = adoptPtr(new Page(pageClients)); + // Scripting must be enabled in ScriptController::windowScriptNPObject(). + m_page->settings()->setScriptEnabled(true); + m_page->settings()->setPluginsEnabled(true); + + 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->setView(FrameView::create(frame)); + // No need to set a size or make it not transparent. + + DocumentWriter* writer = frame->loader()->activeDocumentLoader()->writer(); + writeDocument(*writer, pluginType); + + return true; +} + +void WebHelperPluginImpl::setCompositorSurfaceReady() +{ +} + +void WebHelperPluginImpl::composite(bool) +{ +} + +void WebHelperPluginImpl::layout() +{ + PageWidgetDelegate::layout(m_page.get()); +} + +void WebHelperPluginImpl::setFocus(bool enable) +{ + if (!m_page) + return; + m_page->focusController()->setFocused(enable); + if (enable) + m_page->focusController()->setActive(true); +} + +void WebHelperPluginImpl::close() +{ + RefPtr mainFrameImpl; + + if (m_page) { + // Initiate shutdown. This will cause a lot of notifications to be sent. + if (m_page->mainFrame()) { + mainFrameImpl = WebFrameImpl::fromFrame(m_page->mainFrame()); + m_page->mainFrame()->loader()->frameDetached(); + } + m_page.clear(); + } + + m_widgetClient = 0; + deref(); +} + +// WebHelperPlugin ---------------------------------------------------------------- + +WebHelperPlugin* WebHelperPlugin::create(WebWidgetClient* client) +{ + if (!client) + CRASH(); + // A WebHelperPluginImpl instance usually has two references. + // - One owned by the instance itself. It represents the visible widget. + // - One owned by a WebViewImpl. It's released when the WebViewImpl ask the + // WebHelperPluginImpl to close. + // We need them because the closing operation is asynchronous and the widget + // can be closed while the WebViewImpl is unaware of it. + return adoptRef(new WebHelperPluginImpl(client)).leakRef(); +} + +} // namespace WebKit -- cgit v1.2.1