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() |