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/layout/LayoutEmbeddedObject.h"
37 #include "core/loader/DocumentLoader.h"
38 #include "core/loader/FrameLoader.h"
39 #include "core/loader/FrameLoaderClient.h"
40 #include "core/plugins/PluginView.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 DEFINE_INLINE_VIRTUAL_TRACE()
56 visitor
->trace(m_embedElement
);
57 RawDataDocumentParser::trace(visitor
);
61 PluginDocumentParser(Document
* document
)
62 : RawDataDocumentParser(document
)
63 , m_embedElement(nullptr)
67 void appendBytes(const char*, size_t) override
;
69 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(styleAttr
, "background-color: rgb(38,38,38); height: 100%; width: 100%; overflow: hidden; margin: 0");
100 rootElement
->appendChild(body
);
102 m_embedElement
= HTMLEmbedElement::create(*document());
103 m_embedElement
->setAttribute(widthAttr
, "100%");
104 m_embedElement
->setAttribute(heightAttr
, "100%");
105 m_embedElement
->setAttribute(nameAttr
, "plugin");
106 m_embedElement
->setAttribute(srcAttr
, AtomicString(document()->url().string()));
107 m_embedElement
->setAttribute(typeAttr
, document()->loader()->mimeType());
108 body
->appendChild(m_embedElement
);
110 toPluginDocument(document())->setPluginNode(m_embedElement
.get());
112 document()->updateLayout();
114 // We need the plugin to load synchronously so we can get the PluginView
115 // below so flush the layout tasks now instead of waiting on the timer.
116 frame
->view()->flushAnyPendingPostLayoutTasks();
118 if (PluginView
* view
= pluginView())
119 view
->didReceiveResponse(document()->loader()->response());
122 void PluginDocumentParser::appendBytes(const char* data
, size_t length
)
125 createDocumentStructure();
129 if (PluginView
* view
= pluginView())
130 view
->didReceiveData(data
, length
);
133 void PluginDocumentParser::finish()
135 if (PluginView
* view
= pluginView()) {
136 const ResourceError
& error
= document()->loader()->mainDocumentError();
138 view
->didFinishLoading();
140 view
->didFailLoading(error
);
141 m_embedElement
= nullptr;
143 RawDataDocumentParser::finish();
146 PluginView
* PluginDocumentParser::pluginView() const
148 if (Widget
* widget
= toPluginDocument(document())->pluginWidget()) {
149 ASSERT_WITH_SECURITY_IMPLICATION(widget
->isPluginContainer());
150 return toPluginView(widget
);
155 PluginDocument::PluginDocument(const DocumentInit
& initializer
)
156 : HTMLDocument(initializer
, PluginDocumentClass
)
158 setCompatibilityMode(QuirksMode
);
159 lockCompatibilityMode();
162 PassRefPtrWillBeRawPtr
<DocumentParser
> PluginDocument::createParser()
164 return PluginDocumentParser::create(this);
167 Widget
* PluginDocument::pluginWidget()
169 if (m_pluginNode
&& m_pluginNode
->layoutObject()) {
170 ASSERT(m_pluginNode
->layoutObject()->isEmbeddedObject());
171 return toLayoutEmbeddedObject(m_pluginNode
->layoutObject())->widget();
176 Node
* PluginDocument::pluginNode()
178 return m_pluginNode
.get();
181 void PluginDocument::detach(const AttachContext
& context
)
183 // Release the plugin node so that we don't have a circular reference.
184 m_pluginNode
= nullptr;
185 HTMLDocument::detach(context
);
188 DEFINE_TRACE(PluginDocument
)
190 visitor
->trace(m_pluginNode
);
191 HTMLDocument::trace(visitor
);