/* * 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 "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" using namespace WebCore; namespace blink { #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()); } 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("
\n", writer); String objectTag = ""; addString(objectTag, writer); addLiteral("\n", writer); loader->endWriting(writer); } 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) { ASSERT(client); } WebHelperPluginImpl::~WebHelperPluginImpl() { ASSERT(!m_page); } bool WebHelperPluginImpl::initialize(const String& pluginType, const WebDocument& hostDocument, WebViewImpl* webView) { ASSERT(webView); m_webView = webView; return initializePage(pluginType, hostDocument); } void WebHelperPluginImpl::closeHelperPlugin() { 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(); } void WebHelperPluginImpl::initializeFrame(WebFrameClient* client) { 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()); } // Returns a pointer to the WebPlugin by finding the single