| Index: Source/core/loader/DocumentWriter.cpp
|
| diff --git a/Source/core/loader/DocumentWriter.cpp b/Source/core/loader/DocumentWriter.cpp
|
| index 3dc0282ab700ae5ba7eeefd6fcbfd5c8b2b8f0f2..9290db54effd2cdb9372b4e090123fe1e183a3d3 100644
|
| --- a/Source/core/loader/DocumentWriter.cpp
|
| +++ b/Source/core/loader/DocumentWriter.cpp
|
| @@ -29,11 +29,10 @@
|
| #include "config.h"
|
| #include "core/loader/DocumentWriter.h"
|
|
|
| -#include "core/dom/DOMImplementation.h"
|
| +#include "core/dom/Document.h"
|
| #include "core/dom/ScriptableDocumentParser.h"
|
| #include "core/loader/FrameLoader.h"
|
| #include "core/loader/FrameLoaderStateMachine.h"
|
| -#include "core/loader/SinkDocument.h"
|
| #include "core/loader/TextResourceDecoder.h"
|
| #include "core/page/DOMWindow.h"
|
| #include "core/page/Frame.h"
|
| @@ -41,118 +40,46 @@
|
| #include "core/page/Settings.h"
|
| #include "weborigin/KURL.h"
|
| #include "weborigin/SecurityOrigin.h"
|
| +#include "wtf/PassOwnPtr.h"
|
|
|
| namespace WebCore {
|
|
|
| -DocumentWriter::DocumentWriter(Frame* frame)
|
| - : m_frame(frame)
|
| - , m_hasReceivedSomeData(false)
|
| - , m_state(NotStartedWritingState)
|
| -{
|
| -}
|
| -
|
| -// This is only called by ScriptController::executeScriptIfJavaScriptURL
|
| -// and always contains the result of evaluating a javascript: url.
|
| -// This is the <iframe src="javascript:'html'"> case.
|
| -void DocumentWriter::replaceDocument(const String& source, Document* ownerDocument)
|
| +PassRefPtr<DocumentWriter> DocumentWriter::create(Document* document, const String& mimeType, const String& encoding, bool encodingUserChoosen)
|
| {
|
| - m_frame->loader()->stopAllLoaders();
|
| - begin(m_frame->document()->url(), true, ownerDocument);
|
| -
|
| - if (!source.isNull()) {
|
| - if (!m_hasReceivedSomeData) {
|
| - m_hasReceivedSomeData = true;
|
| - m_frame->document()->setCompatibilityMode(Document::NoQuirksMode);
|
| - }
|
| -
|
| - // FIXME: This should call DocumentParser::appendBytes instead of append
|
| - // to support RawDataDocumentParsers.
|
| - if (DocumentParser* parser = m_frame->document()->parser()) {
|
| - parser->pinToMainThread();
|
| - // Because we're pinned to the main thread we don't need to worry about
|
| - // passing ownership of the source string.
|
| - parser->append(source.impl());
|
| - }
|
| - }
|
| -
|
| - end();
|
| + return adoptRef(new DocumentWriter(document, mimeType, encoding, encodingUserChoosen));
|
| }
|
|
|
| -void DocumentWriter::clear()
|
| -{
|
| - m_decoder = 0;
|
| - m_decoderBuilder.clear();
|
| - m_hasReceivedSomeData = false;
|
| -}
|
| -
|
| -void DocumentWriter::begin()
|
| +DocumentWriter::DocumentWriter(Document* document, const String& mimeType, const String& encoding, bool encodingUserChoosen)
|
| + : m_document(document)
|
| + , m_hasReceivedSomeData(false)
|
| + , m_decoderBuilder(mimeType, encoding, encodingUserChoosen)
|
| + // We grab a reference to the parser so that we'll always send data to the
|
| + // original parser, even if the document acquires a new parser (e.g., via
|
| + // document.open).
|
| + , m_parser(m_document->implicitOpen())
|
| {
|
| - begin(KURL());
|
| + if (FrameView* view = m_document->frame()->view())
|
| + view->setContentsSize(IntSize());
|
| }
|
|
|
| -PassRefPtr<Document> DocumentWriter::createDocument(const KURL& url)
|
| +DocumentWriter::~DocumentWriter()
|
| {
|
| - return DOMImplementation::createDocument(mimeType(), m_frame, url, m_frame->inViewSourceMode());
|
| }
|
|
|
| -void DocumentWriter::begin(const KURL& urlReference, bool dispatch, Document* ownerDocument)
|
| +void DocumentWriter::appendReplacingData(const String& source)
|
| {
|
| - // We grab a local copy of the URL because it's easy for callers to supply
|
| - // a URL that will be deallocated during the execution of this function.
|
| - // For example, see <https://bugs.webkit.org/show_bug.cgi?id=66360>.
|
| - KURL url = urlReference;
|
| -
|
| - // Create a new document before clearing the frame, because it may need to
|
| - // inherit an aliased security context.
|
| - RefPtr<Document> document = createDocument(url);
|
| -
|
| - // If the new document is for a Plugin but we're supposed to be sandboxed from Plugins,
|
| - // then replace the document with one whose parser will ignore the incoming data (bug 39323)
|
| - if (document->isPluginDocument() && document->isSandboxed(SandboxPlugins))
|
| - document = SinkDocument::create(m_frame, url);
|
| -
|
| - // FIXME: Do we need to consult the content security policy here about blocked plug-ins?
|
| -
|
| - bool shouldReuseDefaultView = m_frame->loader()->stateMachine()->isDisplayingInitialEmptyDocument() && m_frame->document()->isSecureTransitionTo(url);
|
| -
|
| - RefPtr<DOMWindow> originalDOMWindow;
|
| - if (shouldReuseDefaultView)
|
| - originalDOMWindow = m_frame->domWindow();
|
| - m_frame->loader()->clear(!shouldReuseDefaultView, !shouldReuseDefaultView);
|
| - clear();
|
| -
|
| - if (!shouldReuseDefaultView)
|
| - m_frame->setDOMWindow(DOMWindow::create(m_frame));
|
| - else {
|
| - // Note that the old Document is still attached to the DOMWindow; the
|
| - // setDocument() call below will detach the old Document.
|
| - ASSERT(originalDOMWindow);
|
| - m_frame->setDOMWindow(originalDOMWindow);
|
| - }
|
| -
|
| - m_frame->loader()->setOutgoingReferrer(url);
|
| - m_frame->domWindow()->setDocument(document);
|
| -
|
| - if (m_decoder)
|
| - document->setDecoder(m_decoder.get());
|
| - if (ownerDocument) {
|
| - document->setCookieURL(ownerDocument->cookieURL());
|
| - document->setSecurityOrigin(ownerDocument->securityOrigin());
|
| + ASSERT(!m_hasReceivedSomeData);
|
| + m_hasReceivedSomeData = true;
|
| + m_document->setCompatibilityMode(Document::NoQuirksMode);
|
| +
|
| + // FIXME: This should call DocumentParser::appendBytes instead of append
|
| + // to support RawDataDocumentParsers.
|
| + if (DocumentParser* parser = m_document->parser()) {
|
| + parser->pinToMainThread();
|
| + // Because we're pinned to the main thread we don't need to worry about
|
| + // passing ownership of the source string.
|
| + parser->append(source.impl());
|
| }
|
| -
|
| - m_frame->loader()->didBeginDocument(dispatch);
|
| -
|
| - document->implicitOpen();
|
| -
|
| - // We grab a reference to the parser so that we'll always send data to the
|
| - // original parser, even if the document acquires a new parser (e.g., via
|
| - // document.open).
|
| - m_parser = document->parser();
|
| -
|
| - if (m_frame->view())
|
| - m_frame->view()->setContentsSize(IntSize());
|
| -
|
| - m_state = StartedWritingState;
|
| }
|
|
|
| void DocumentWriter::reportDataReceived()
|
| @@ -162,22 +89,16 @@ void DocumentWriter::reportDataReceived()
|
| return;
|
| m_hasReceivedSomeData = true;
|
| if (m_decoder->encoding().usesVisualOrdering())
|
| - m_frame->document()->setVisuallyOrdered();
|
| + m_document->setVisuallyOrdered();
|
| }
|
|
|
| void DocumentWriter::addData(const char* bytes, size_t length)
|
| {
|
| - // Check that we're inside begin()/end().
|
| - // FIXME: Change these to ASSERT once https://bugs.webkit.org/show_bug.cgi?id=80427 has
|
| - // been resolved.
|
| - if (m_state == NotStartedWritingState)
|
| - CRASH();
|
| - if (m_state == FinishedWritingState)
|
| - CRASH();
|
| -
|
| ASSERT(m_parser);
|
| if (!m_decoder && m_parser->needsDecoder() && 0 < length)
|
| - m_decoder = m_decoderBuilder.buildFor(m_frame->document());
|
| + m_decoder = m_decoderBuilder.buildFor(m_document);
|
| + // appendBytes() can result replacing DocumentLoader::m_writer.
|
| + RefPtr<DocumentWriter> protectingThis(this);
|
| size_t consumedChars = m_parser->appendBytes(bytes, length);
|
| if (consumedChars)
|
| reportDataReceived();
|
| @@ -185,29 +106,29 @@ void DocumentWriter::addData(const char* bytes, size_t length)
|
|
|
| void DocumentWriter::end()
|
| {
|
| - ASSERT(m_frame->page());
|
| - ASSERT(m_frame->document());
|
| -
|
| - // The parser is guaranteed to be released after this point. begin() would
|
| - // have to be called again before we can start writing more data.
|
| - m_state = FinishedWritingState;
|
| + ASSERT(m_document);
|
|
|
| // http://bugs.webkit.org/show_bug.cgi?id=10854
|
| // The frame's last ref may be removed and it can be deleted by checkCompleted(),
|
| // so we'll add a protective refcount
|
| - RefPtr<Frame> protector(m_frame);
|
| + RefPtr<Frame> protector(m_document->frame());
|
|
|
| if (!m_parser)
|
| return;
|
| +
|
| if (!m_decoder && m_parser->needsDecoder())
|
| - m_decoder = m_decoderBuilder.buildFor(m_frame->document());
|
| + m_decoder = m_decoderBuilder.buildFor(m_document);
|
| + // flush() can result replacing DocumentLoader::m_writer.
|
| + RefPtr<DocumentWriter> protectingThis(this);
|
| size_t consumedChars = m_parser->flush();
|
| if (consumedChars)
|
| reportDataReceived();
|
| if (!m_parser)
|
| return;
|
| +
|
| m_parser->finish();
|
| m_parser = 0;
|
| + m_document = 0;
|
| }
|
|
|
| void DocumentWriter::setDocumentWasLoadedAsPartOfNavigation()
|
|
|