blob: 566351d30a906c1015606baf0ceb224a0d8a666d [file] [log] [blame]
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001/*
2 * Copyright (C) 2010. Adam Barth. 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 *
8 * 1. Redistributions of source code must retain the above copyright
Ben Murdoch02772c62013-07-26 10:21:05 +01009 * notice, this list of conditions and the following disclaimer.
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010010 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
Ben Murdoch02772c62013-07-26 10:21:05 +010012 * documentation and/or other materials provided with the distribution.
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010013 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
Ben Murdoch02772c62013-07-26 10:21:05 +010015 * from this software without specific prior written permission.
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010016 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "config.h"
30#include "core/loader/DocumentWriter.h"
31
Ben Murdoch591b9582013-07-10 11:41:44 +010032#include "core/dom/Document.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010033#include "core/dom/ScriptableDocumentParser.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010034#include "core/loader/FrameLoader.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010035#include "core/loader/FrameLoaderStateMachine.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010036#include "core/loader/TextResourceDecoder.h"
37#include "core/page/DOMWindow.h"
38#include "core/page/Frame.h"
39#include "core/page/FrameView.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010040#include "core/page/Settings.h"
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +010041#include "weborigin/KURL.h"
Torne (Richard Coles)e5249552013-05-15 11:35:13 +010042#include "weborigin/SecurityOrigin.h"
Ben Murdoch591b9582013-07-10 11:41:44 +010043#include "wtf/PassOwnPtr.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010044
45namespace WebCore {
46
Ben Murdoch591b9582013-07-10 11:41:44 +010047PassRefPtr<DocumentWriter> DocumentWriter::create(Document* document, const String& mimeType, const String& encoding, bool encodingUserChoosen)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010048{
Ben Murdoch591b9582013-07-10 11:41:44 +010049 return adoptRef(new DocumentWriter(document, mimeType, encoding, encodingUserChoosen));
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010050}
Ben Murdoch591b9582013-07-10 11:41:44 +010051
52DocumentWriter::DocumentWriter(Document* document, const String& mimeType, const String& encoding, bool encodingUserChoosen)
53 : m_document(document)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010054 , m_hasReceivedSomeData(false)
Ben Murdoch591b9582013-07-10 11:41:44 +010055 , m_decoderBuilder(mimeType, encoding, encodingUserChoosen)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010056 // We grab a reference to the parser so that we'll always send data to the
57 // original parser, even if the document acquires a new parser (e.g., via
58 // document.open).
Ben Murdoch591b9582013-07-10 11:41:44 +010059 , m_parser(m_document->implicitOpen())
60{
Ben Murdoche69819b2013-07-17 14:56:49 +010061 if (m_document->frame()) {
62 if (FrameView* view = m_document->frame()->view())
63 view->setContentsSize(IntSize());
64 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010065}
66
Ben Murdoch591b9582013-07-10 11:41:44 +010067DocumentWriter::~DocumentWriter()
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010068{
Ben Murdoch591b9582013-07-10 11:41:44 +010069}
70
71void DocumentWriter::appendReplacingData(const String& source)
72{
73 ASSERT(!m_hasReceivedSomeData);
74 m_hasReceivedSomeData = true;
75 m_document->setCompatibilityMode(Document::NoQuirksMode);
76
77 // FIXME: This should call DocumentParser::appendBytes instead of append
78 // to support RawDataDocumentParsers.
79 if (DocumentParser* parser = m_document->parser()) {
80 parser->pinToMainThread();
81 // Because we're pinned to the main thread we don't need to worry about
82 // passing ownership of the source string.
83 parser->append(source.impl());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010084 }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010085}
86
87void DocumentWriter::reportDataReceived()
88{
89 ASSERT(m_decoder);
90 if (m_hasReceivedSomeData)
91 return;
92 m_hasReceivedSomeData = true;
93 if (m_decoder->encoding().usesVisualOrdering())
Ben Murdoch591b9582013-07-10 11:41:44 +010094 m_document->setVisuallyOrdered();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010095}
96
97void DocumentWriter::addData(const char* bytes, size_t length)
98{
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010099 ASSERT(m_parser);
Ben Murdoch591b9582013-07-10 11:41:44 +0100100 if (!m_decoder && m_parser->needsDecoder() && 0 < length)
101 m_decoder = m_decoderBuilder.buildFor(m_document);
102 // appendBytes() can result replacing DocumentLoader::m_writer.
103 RefPtr<DocumentWriter> protectingThis(this);
104 size_t consumedChars = m_parser->appendBytes(bytes, length);
105 if (consumedChars)
106 reportDataReceived();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100107}
108
109void DocumentWriter::end()
110{
Ben Murdoch591b9582013-07-10 11:41:44 +0100111 ASSERT(m_document);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100112
113 // http://bugs.webkit.org/show_bug.cgi?id=10854
Ben Murdoch02772c62013-07-26 10:21:05 +0100114 // The frame's last ref may be removed and it can be deleted by checkCompleted(),
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100115 // so we'll add a protective refcount
Ben Murdoch591b9582013-07-10 11:41:44 +0100116 RefPtr<Frame> protector(m_document->frame());
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100117
118 if (!m_parser)
119 return;
Ben Murdoch591b9582013-07-10 11:41:44 +0100120
121 if (!m_decoder && m_parser->needsDecoder())
122 m_decoder = m_decoderBuilder.buildFor(m_document);
123 // flush() can result replacing DocumentLoader::m_writer.
124 RefPtr<DocumentWriter> protectingThis(this);
125 size_t consumedChars = m_parser->flush();
126 if (consumedChars)
127 reportDataReceived();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100128 if (!m_parser)
129 return;
Ben Murdoch591b9582013-07-10 11:41:44 +0100130
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100131 m_parser->finish();
132 m_parser = 0;
Ben Murdoch591b9582013-07-10 11:41:44 +0100133 m_document = 0;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100134}
135
136void DocumentWriter::setDocumentWasLoadedAsPartOfNavigation()
137{
138 ASSERT(m_parser && !m_parser->isStopped());
139 m_parser->setDocumentWasLoadedAsPartOfNavigation();
140}
141
142} // namespace WebCore