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 "HTMLNames.h"
29 #include "bindings/v8/ExceptionStatePlaceholder.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 PassRefPtr<PluginDocumentParser> create(PluginDocument* document)
51 return adoptRef(new PluginDocumentParser(document));
55 PluginDocumentParser(Document* document)
56 : RawDataDocumentParser(document)
57 , m_embedElement(nullptr)
61 virtual void appendBytes(const char*, size_t) OVERRIDE;
63 virtual void finish() OVERRIDE;
65 void createDocumentStructure();
67 PluginView* pluginView() const;
69 RefPtr<HTMLEmbedElement> m_embedElement;
72 void PluginDocumentParser::createDocumentStructure()
74 // FIXME: Assert we have a loader to figure out why the original null checks
75 // and assert were added for the security bug in http://trac.webkit.org/changeset/87566
77 RELEASE_ASSERT(document()->loader());
79 LocalFrame* frame = document()->frame();
83 // FIXME: Why does this check settings?
84 if (!frame->settings() || !frame->loader().allowPlugins(NotAboutToInstantiatePlugin))
87 RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
88 rootElement->insertedByParser();
89 document()->appendChild(rootElement);
90 frame->loader().dispatchDocumentElementAvailable();
92 RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
93 body->setAttribute(marginwidthAttr, "0");
94 body->setAttribute(marginheightAttr, "0");
95 body->setAttribute(styleAttr, "background-color: rgb(38,38,38)");
96 rootElement->appendChild(body);
98 m_embedElement = HTMLEmbedElement::create(*document());
99 m_embedElement->setAttribute(widthAttr, "100%");
100 m_embedElement->setAttribute(heightAttr, "100%");
101 m_embedElement->setAttribute(nameAttr, "plugin");
102 m_embedElement->setAttribute(srcAttr, AtomicString(document()->url().string()));
103 m_embedElement->setAttribute(typeAttr, document()->loader()->mimeType());
104 body->appendChild(m_embedElement);
106 toPluginDocument(document())->setPluginNode(m_embedElement.get());
108 document()->updateLayout();
110 // We need the plugin to load synchronously so we can get the PluginView
111 // below so flush the layout tasks now instead of waiting on the timer.
112 frame->view()->flushAnyPendingPostLayoutTasks();
114 if (PluginView* view = pluginView())
115 view->didReceiveResponse(document()->loader()->response());
118 void PluginDocumentParser::appendBytes(const char* data, size_t length)
121 createDocumentStructure();
125 if (PluginView* view = pluginView())
126 view->didReceiveData(data, length);
129 void PluginDocumentParser::finish()
131 if (PluginView* view = pluginView()) {
132 const ResourceError& error = document()->loader()->mainDocumentError();
134 view->didFinishLoading();
136 view->didFailLoading(error);
137 m_embedElement = nullptr;
139 RawDataDocumentParser::finish();
142 PluginView* PluginDocumentParser::pluginView() const
144 if (Widget* widget = toPluginDocument(document())->pluginWidget()) {
145 ASSERT_WITH_SECURITY_IMPLICATION(widget->isPluginContainer());
146 return toPluginView(widget);
151 PluginDocument::PluginDocument(const DocumentInit& initializer)
152 : HTMLDocument(initializer, PluginDocumentClass)
153 , m_shouldLoadPluginManually(true)
155 setCompatibilityMode(QuirksMode);
156 lockCompatibilityMode();
159 PassRefPtr<DocumentParser> PluginDocument::createParser()
161 return PluginDocumentParser::create(this);
164 Widget* PluginDocument::pluginWidget()
166 if (m_pluginNode && m_pluginNode->renderer()) {
167 ASSERT(m_pluginNode->renderer()->isEmbeddedObject());
168 return toRenderEmbeddedObject(m_pluginNode->renderer())->widget();
173 Node* PluginDocument::pluginNode()
175 return m_pluginNode.get();
178 void PluginDocument::detach(const AttachContext& context)
180 // Release the plugin node so that we don't have a circular reference.
181 m_pluginNode = nullptr;
182 HTMLDocument::detach(context);
185 void PluginDocument::trace(Visitor* visitor)
187 visitor->trace(m_pluginNode);
188 HTMLDocument::trace(visitor);