1 /* 2 * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 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. 12 * 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. 23 */ 24 25 #include "config.h" 26 #include "PluginDocument.h" 27 28 #include "DocumentLoader.h" 29 #include "Element.h" 30 #include "Frame.h" 31 #include "FrameLoader.h" 32 #include "FrameLoaderClient.h" 33 #include "HTMLEmbedElement.h" 34 #include "HTMLNames.h" 35 #include "MainResourceLoader.h" 36 #include "Page.h" 37 #include "RenderWidget.h" 38 #include "SegmentedString.h" 39 #include "Settings.h" 40 #include "Text.h" 41 #include "XMLTokenizer.h" 42 43 namespace WebCore { 44 45 using namespace HTMLNames; 46 47 class PluginTokenizer : public Tokenizer { 48 public: 49 PluginTokenizer(Document* doc) : m_doc(doc), m_embedElement(0) {} 50 51 private: 52 virtual void write(const SegmentedString&, bool appendData); 53 virtual void stopParsing(); 54 virtual void finish(); 55 virtual bool isWaitingForScripts() const; 56 57 virtual bool wantsRawData() const { return true; } 58 virtual bool writeRawData(const char* data, int len); 59 60 void createDocumentStructure(); 61 62 Document* m_doc; 63 HTMLEmbedElement* m_embedElement; 64 }; 65 66 void PluginTokenizer::write(const SegmentedString&, bool) 67 { 68 ASSERT_NOT_REACHED(); 69 } 70 71 void PluginTokenizer::createDocumentStructure() 72 { 73 ExceptionCode ec; 74 RefPtr<Element> rootElement = m_doc->createElement(htmlTag, false); 75 m_doc->appendChild(rootElement, ec); 76 77 RefPtr<Element> body = m_doc->createElement(bodyTag, false); 78 body->setAttribute(marginwidthAttr, "0"); 79 body->setAttribute(marginheightAttr, "0"); 80 body->setAttribute(bgcolorAttr, "rgb(38,38,38)"); 81 82 rootElement->appendChild(body, ec); 83 84 RefPtr<Element> embedElement = m_doc->createElement(embedTag, false); 85 86 m_embedElement = static_cast<HTMLEmbedElement*>(embedElement.get()); 87 m_embedElement->setAttribute(widthAttr, "100%"); 88 m_embedElement->setAttribute(heightAttr, "100%"); 89 90 m_embedElement->setAttribute(nameAttr, "plugin"); 91 m_embedElement->setAttribute(srcAttr, m_doc->url().string()); 92 m_embedElement->setAttribute(typeAttr, m_doc->frame()->loader()->responseMIMEType()); 93 94 body->appendChild(embedElement, ec); 95 } 96 97 bool PluginTokenizer::writeRawData(const char*, int) 98 { 99 ASSERT(!m_embedElement); 100 if (m_embedElement) 101 return false; 102 103 createDocumentStructure(); 104 105 if (Frame* frame = m_doc->frame()) { 106 Settings* settings = frame->settings(); 107 if (settings && settings->arePluginsEnabled()) { 108 m_doc->updateLayout(); 109 110 if (RenderWidget* renderer = toRenderWidget(m_embedElement->renderer())) { 111 frame->loader()->client()->redirectDataToPlugin(renderer->widget()); 112 frame->loader()->activeDocumentLoader()->mainResourceLoader()->setShouldBufferData(false); 113 } 114 115 finish(); 116 } 117 } 118 119 return false; 120 } 121 122 void PluginTokenizer::stopParsing() 123 { 124 Tokenizer::stopParsing(); 125 } 126 127 void PluginTokenizer::finish() 128 { 129 if (!m_parserStopped) 130 m_doc->finishedParsing(); 131 } 132 133 bool PluginTokenizer::isWaitingForScripts() const 134 { 135 // A plugin document is never waiting for scripts 136 return false; 137 } 138 139 PluginDocument::PluginDocument(Frame* frame) 140 : HTMLDocument(frame) 141 { 142 setParseMode(Compat); 143 } 144 145 Tokenizer* PluginDocument::createTokenizer() 146 { 147 return new PluginTokenizer(this); 148 } 149 150 } 151