2 * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
20 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include "core/html/PluginDocument.h"
28 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
29 #include "core/HTMLNames.h"
30 #include "core/dom/RawDataDocumentParser.h"
31 #include "core/frame/FrameView.h"
32 #include "core/frame/LocalFrame.h"
33 #include "core/html/HTMLBodyElement.h"
34 #include "core/html/HTMLEmbedElement.h"
35 #include "core/html/HTMLHtmlElement.h"
36 #include "core/loader/DocumentLoader.h"
37 #include "core/loader/FrameLoader.h"
38 #include "core/loader/FrameLoaderClient.h"
39 #include "core/plugins/PluginView.h"
40 #include "core/rendering/RenderEmbeddedObject.h"
44 using namespace HTMLNames;
46 // FIXME: Share more code with MediaDocumentParser.
47 class PluginDocumentParser : public RawDataDocumentParser {
49 static PassRefPtrWillBeRawPtr<PluginDocumentParser> create(PluginDocument* document)
51 return adoptRefWillBeNoop(new PluginDocumentParser(document));
54 virtual void trace(Visitor* visitor) OVERRIDE
56 visitor->trace(m_embedElement);
57 RawDataDocumentParser::trace(visitor);
61 PluginDocumentParser(Document* document)
62 : RawDataDocumentParser(document)
63 , m_embedElement(nullptr)
67 virtual void appendBytes(const char*, size_t) OVERRIDE;
69 virtual void finish() OVERRIDE;
71 void createDocumentStructure();
73 PluginView* pluginView() const;
75 RefPtrWillBeMember<HTMLEmbedElement> m_embedElement;
78 void PluginDocumentParser::createDocumentStructure()
80 // FIXME: Assert we have a loader to figure out why the original null checks
81 // and assert were added for the security bug in http://trac.webkit.org/changeset/87566
83 RELEASE_ASSERT(document()->loader());
85 LocalFrame* frame = document()->frame();
89 // FIXME: Why does this check settings?
90 if (!frame->settings() || !frame->loader().allowPlugins(NotAboutToInstantiatePlugin))
93 RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
94 rootElement->insertedByParser();
95 document()->appendChild(rootElement);
96 frame->loader().dispatchDocumentElementAvailable();
98 RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
99 body->setAttribute(marginwidthAttr, "0");
100 body->setAttribute(marginheightAttr, "0");
101 body->setAttribute(styleAttr, "background-color: rgb(38,38,38)");
102 rootElement->appendChild(body);
104 m_embedElement = HTMLEmbedElement::create(*document());
105 m_embedElement->setAttribute(widthAttr, "100%");
106 m_embedElement->setAttribute(heightAttr, "100%");
107 m_embedElement->setAttribute(nameAttr, "plugin");
108 m_embedElement->setAttribute(srcAttr, AtomicString(document()->url().string()));
109 m_embedElement->setAttribute(typeAttr, document()->loader()->mimeType());
110 body->appendChild(m_embedElement);
112 toPluginDocument(document())->setPluginNode(m_embedElement.get());
114 document()->updateLayout();
116 // We need the plugin to load synchronously so we can get the PluginView
117 // below so flush the layout tasks now instead of waiting on the timer.
118 frame->view()->flushAnyPendingPostLayoutTasks();
120 if (PluginView* view = pluginView())
121 view->didReceiveResponse(document()->loader()->response());
124 void PluginDocumentParser::appendBytes(const char* data, size_t length)
127 createDocumentStructure();
131 if (PluginView* view = pluginView())
132 view->didReceiveData(data, length);
135 void PluginDocumentParser::finish()
137 if (PluginView* view = pluginView()) {
138 const ResourceError& error = document()->loader()->mainDocumentError();
140 view->didFinishLoading();
142 view->didFailLoading(error);
143 m_embedElement = nullptr;
145 RawDataDocumentParser::finish();
148 PluginView* PluginDocumentParser::pluginView() const
150 if (Widget* widget = toPluginDocument(document())->pluginWidget()) {
151 ASSERT_WITH_SECURITY_IMPLICATION(widget->isPluginContainer());
152 return toPluginView(widget);
157 PluginDocument::PluginDocument(const DocumentInit& initializer)
158 : HTMLDocument(initializer, PluginDocumentClass)
159 , m_shouldLoadPluginManually(true)
161 setCompatibilityMode(QuirksMode);
162 lockCompatibilityMode();
165 PassRefPtrWillBeRawPtr<DocumentParser> PluginDocument::createParser()
167 return PluginDocumentParser::create(this);
170 Widget* PluginDocument::pluginWidget()
172 if (m_pluginNode && m_pluginNode->renderer()) {
173 ASSERT(m_pluginNode->renderer()->isEmbeddedObject());
174 return toRenderEmbeddedObject(m_pluginNode->renderer())->widget();
179 Node* PluginDocument::pluginNode()
181 return m_pluginNode.get();
184 void PluginDocument::detach(const AttachContext& context)
186 // Release the plugin node so that we don't have a circular reference.
187 m_pluginNode = nullptr;
188 HTMLDocument::detach(context);
191 void PluginDocument::trace(Visitor* visitor)
193 visitor->trace(m_pluginNode);
194 HTMLDocument::trace(visitor);