nsresult txMozillaXMLOutput::endDocument(nsresult aResult) { TX_ENSURE_CURRENTNODE; if (NS_FAILED(aResult)) { if (mNotifier) { mNotifier->OnTransformEnd(aResult); } return NS_OK; } nsresult rv = closePrevious(true); if (NS_FAILED(rv)) { if (mNotifier) { mNotifier->OnTransformEnd(rv); } return rv; } if (mCreatingNewDocument) { // This should really be handled by nsIDocument::EndLoad MOZ_ASSERT(mDocument->GetReadyStateEnum() == nsIDocument::READYSTATE_LOADING, "Bad readyState"); mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE); ScriptLoader* loader = mDocument->ScriptLoader(); if (loader) { loader->ParsingComplete(false); } } if (!mRefreshString.IsEmpty()) { nsPIDOMWindowOuter* win = mDocument->GetWindow(); if (win) { nsCOMPtr<nsIRefreshURI> refURI = do_QueryInterface(win->GetDocShell()); if (refURI) { refURI->SetupRefreshURIFromHeader(mDocument->GetDocBaseURI(), mDocument->NodePrincipal(), mRefreshString); } } } if (mNotifier) { mNotifier->OnTransformEnd(); } return NS_OK; }
nsresult txMozillaXMLOutput::startDocument() { if (mNotifier) { mNotifier->OnTransformStart(); } if (mCreatingNewDocument) { ScriptLoader* loader = mDocument->ScriptLoader(); if (loader) { loader->BeginDeferringScripts(); } } return NS_OK; }
// Implements the initial steps for 'An end tag whose tag name is "script"' // http://whatwg.org/html#scriptEndTag void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStartPosition) { ASSERT(m_document); ASSERT(!hasParserBlockingScript()); { ScriptLoader* scriptLoader = toScriptLoaderIfPossible(script); // This contains both and ASSERTION and a null check since we should not // be getting into the case of a null script element, but seem to be from // time to time. The assertion is left in to help find those cases and // is being tracked by <https://bugs.webkit.org/show_bug.cgi?id=60559>. ASSERT(scriptLoader); if (!scriptLoader) return; ASSERT(scriptLoader->isParserInserted()); if (!isExecutingScript()) Microtask::performCheckpoint(); InsertionPointRecord insertionPointRecord(m_host->inputStream()); NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel); scriptLoader->prepareScript(scriptStartPosition); if (!scriptLoader->willBeParserExecuted()) return; if (scriptLoader->willExecuteWhenDocumentFinishedParsing()) { requestDeferredScript(script); } else if (scriptLoader->readyToBeParserExecuted()) { if (m_scriptNestingLevel == 1) { m_parserBlockingScript.setElement(script); m_parserBlockingScript.setStartingPosition(scriptStartPosition); } else { ScriptSourceCode sourceCode(script->textContent(), documentURLForScriptExecution(m_document), scriptStartPosition); scriptLoader->executeScript(sourceCode); } } else { requestParsingBlockingScript(script); } } }
nsresult txMozillaXMLOutput::createResultDocument(const nsAString& aName, int32_t aNsID, nsIDocument* aSourceDocument, bool aLoadedAsData) { nsresult rv; // Create the document if (mOutputFormat.mMethod == eHTMLOutput) { rv = NS_NewHTMLDocument(getter_AddRefs(mDocument), aLoadedAsData); NS_ENSURE_SUCCESS(rv, rv); } else { // We should check the root name/namespace here and create the // appropriate document rv = NS_NewXMLDocument(getter_AddRefs(mDocument), aLoadedAsData); NS_ENSURE_SUCCESS(rv, rv); } // This should really be handled by nsIDocument::BeginLoad MOZ_ASSERT(mDocument->GetReadyStateEnum() == nsIDocument::READYSTATE_UNINITIALIZED, "Bad readyState"); mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_LOADING); mDocument->SetMayStartLayout(false); bool hasHadScriptObject = false; nsIScriptGlobalObject* sgo = aSourceDocument->GetScriptHandlingObject(hasHadScriptObject); NS_ENSURE_STATE(sgo || !hasHadScriptObject); mCurrentNode = mDocument; mNodeInfoManager = mDocument->NodeInfoManager(); // Reset and set up the document URIUtils::ResetWithSource(mDocument, aSourceDocument); // Make sure we set the script handling object after resetting with the // source, so that we have the right principal. mDocument->SetScriptHandlingObject(sgo); // Set the charset if (!mOutputFormat.mEncoding.IsEmpty()) { const Encoding* encoding = Encoding::ForLabel(mOutputFormat.mEncoding); if (encoding) { mDocument->SetDocumentCharacterSetSource(kCharsetFromOtherComponent); mDocument->SetDocumentCharacterSet(WrapNotNull(encoding)); } } // Set the mime-type if (!mOutputFormat.mMediaType.IsEmpty()) { mDocument->SetContentType(mOutputFormat.mMediaType); } else if (mOutputFormat.mMethod == eHTMLOutput) { mDocument->SetContentType(NS_LITERAL_STRING("text/html")); } else { mDocument->SetContentType(NS_LITERAL_STRING("application/xml")); } if (mOutputFormat.mMethod == eXMLOutput && mOutputFormat.mOmitXMLDeclaration != eTrue) { int32_t standalone; if (mOutputFormat.mStandalone == eNotSet) { standalone = -1; } else if (mOutputFormat.mStandalone == eFalse) { standalone = 0; } else { standalone = 1; } // Could use mOutputFormat.mVersion.get() when we support // versions > 1.0. static const char16_t kOneDotZero[] = { '1', '.', '0', '\0' }; mDocument->SetXMLDeclaration(kOneDotZero, mOutputFormat.mEncoding.get(), standalone); } // Set up script loader of the result document. ScriptLoader *loader = mDocument->ScriptLoader(); if (mNotifier) { loader->AddObserver(mNotifier); } else { // Don't load scripts, we can't notify the caller when they're loaded. loader->SetEnabled(false); } if (mNotifier) { rv = mNotifier->SetOutputDocument(mDocument); NS_ENSURE_SUCCESS(rv, rv); } // Do this after calling OnDocumentCreated to ensure that the // PresShell/PresContext has been hooked up and get notified. nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument); if (htmlDoc) { htmlDoc->SetCompatibilityMode(eCompatibility_FullStandards); } // Add a doc-type if requested if (!mOutputFormat.mSystemId.IsEmpty()) { nsAutoString qName; if (mOutputFormat.mMethod == eHTMLOutput) { qName.AssignLiteral("html"); } else { qName.Assign(aName); } nsCOMPtr<nsIDOMDocumentType> documentType; nsresult rv = nsContentUtils::CheckQName(qName); if (NS_SUCCEEDED(rv)) { RefPtr<nsAtom> doctypeName = NS_Atomize(qName); if (!doctypeName) { return NS_ERROR_OUT_OF_MEMORY; } // Indicate that there is no internal subset (not just an empty one) rv = NS_NewDOMDocumentType(getter_AddRefs(documentType), mNodeInfoManager, doctypeName, mOutputFormat.mPublicId, mOutputFormat.mSystemId, VoidString()); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIContent> docType = do_QueryInterface(documentType); rv = mDocument->AppendChildTo(docType, true); NS_ENSURE_SUCCESS(rv, rv); } } return NS_OK; }