This is an automated email from the git hooks/post-receive script.
richard pushed a commit to branch tor-browser-91.13.0esr-11.5-1 in repository tor-browser.
commit f2a333920ca11c54a8e82816f3fa250404f80336 Author: Peter Van der Beken peterv@propagandism.org AuthorDate: Tue Aug 2 19:27:49 2022 +0000
Bug 1769155 - Deal with document replacement. r=smaug, a=RyanVM
Differential Revision: https://phabricator.services.mozilla.com/D153513 --- dom/xml/nsXMLContentSink.cpp | 90 +++++++++++++++++--------------- dom/xml/nsXMLContentSink.h | 7 +-- dom/xslt/nsIDocumentTransformer.h | 9 ++-- dom/xslt/xslt/txMozillaTextOutput.cpp | 18 ++++--- dom/xslt/xslt/txMozillaTextOutput.h | 7 +-- dom/xslt/xslt/txMozillaXMLOutput.cpp | 15 +++--- dom/xslt/xslt/txMozillaXMLOutput.h | 6 ++- dom/xslt/xslt/txMozillaXSLTProcessor.cpp | 17 +++--- 8 files changed, 93 insertions(+), 76 deletions(-)
diff --git a/dom/xml/nsXMLContentSink.cpp b/dom/xml/nsXMLContentSink.cpp index 2b8c297c6894f..10eb75683ba52 100644 --- a/dom/xml/nsXMLContentSink.cpp +++ b/dom/xml/nsXMLContentSink.cpp @@ -322,22 +322,23 @@ nsXMLContentSink::DidBuildModel(bool aTerminated) { return NS_OK; }
-NS_IMETHODIMP -nsXMLContentSink::OnDocumentCreated(Document* aResultDocument) { - NS_ENSURE_ARG(aResultDocument); - +nsresult nsXMLContentSink::OnDocumentCreated(Document* aSourceDocument, + Document* aResultDocument) { aResultDocument->SetDocWriteDisabled(true);
nsCOMPtr<nsIContentViewer> contentViewer; mDocShell->GetContentViewer(getter_AddRefs(contentViewer)); - if (contentViewer) { + // Make sure that we haven't loaded a new document into the contentviewer + // after starting the XSLT transform. + if (contentViewer && contentViewer->GetDocument() == aSourceDocument) { return contentViewer->SetDocumentInternal(aResultDocument, true); } return NS_OK; }
-NS_IMETHODIMP -nsXMLContentSink::OnTransformDone(nsresult aResult, Document* aResultDocument) { +nsresult nsXMLContentSink::OnTransformDone(Document* aSourceDocument, + nsresult aResult, + Document* aResultDocument) { MOZ_ASSERT(aResultDocument, "Don't notify about transform end without a document.");
@@ -346,42 +347,49 @@ nsXMLContentSink::OnTransformDone(nsresult aResult, Document* aResultDocument) { nsCOMPtr<nsIContentViewer> contentViewer; mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
- if (NS_FAILED(aResult) && contentViewer) { - // Transform failed. - aResultDocument->SetMayStartLayout(false); - // We have an error document. - contentViewer->SetDocument(aResultDocument); - } - RefPtr<Document> originalDocument = mDocument; bool blockingOnload = mIsBlockingOnload; - if (!mRunsToCompletion) { - // This BlockOnload call corresponds to the UnblockOnload call in - // nsContentSink::DropParserAndPerfHint. - aResultDocument->BlockOnload(); - mIsBlockingOnload = true; - } - // Transform succeeded, or it failed and we have an error document to display. - mDocument = aResultDocument; - aResultDocument->SetDocWriteDisabled(false); - - // Notify document observers that all the content has been stuck - // into the document. - // XXX do we need to notify for things like PIs? Or just the - // documentElement? - nsIContent* rootElement = mDocument->GetRootElement(); - if (rootElement) { - NS_ASSERTION(mDocument->ComputeIndexOf(rootElement) != -1, - "rootElement not in doc?"); - mDocument->BeginUpdate(); - MutationObservers::NotifyContentInserted(mDocument, rootElement); - mDocument->EndUpdate(); - } - - // Start the layout process - StartLayout(false); - - ScrollToRef(); + + // Make sure that we haven't loaded a new document into the contentviewer + // after starting the XSLT transform. + if (contentViewer && (contentViewer->GetDocument() == aSourceDocument || + contentViewer->GetDocument() == aResultDocument)) { + if (NS_FAILED(aResult)) { + // Transform failed. + aResultDocument->SetMayStartLayout(false); + // We have an error document. + contentViewer->SetDocument(aResultDocument); + } + + if (!mRunsToCompletion) { + // This BlockOnload call corresponds to the UnblockOnload call in + // nsContentSink::DropParserAndPerfHint. + aResultDocument->BlockOnload(); + mIsBlockingOnload = true; + } + // Transform succeeded, or it failed and we have an error document to + // display. + mDocument = aResultDocument; + aResultDocument->SetDocWriteDisabled(false); + + // Notify document observers that all the content has been stuck + // into the document. + // XXX do we need to notify for things like PIs? Or just the + // documentElement? + nsIContent* rootElement = mDocument->GetRootElement(); + if (rootElement) { + NS_ASSERTION(mDocument->ComputeIndexOf(rootElement) != -1, + "rootElement not in doc?"); + mDocument->BeginUpdate(); + MutationObservers::NotifyContentInserted(mDocument, rootElement); + mDocument->EndUpdate(); + } + + // Start the layout process + StartLayout(false); + + ScrollToRef(); + }
originalDocument->EndLoad(); if (blockingOnload) { diff --git a/dom/xml/nsXMLContentSink.h b/dom/xml/nsXMLContentSink.h index 7f162bf7dcdfa..fdb43a7947c5c 100644 --- a/dom/xml/nsXMLContentSink.h +++ b/dom/xml/nsXMLContentSink.h @@ -78,10 +78,11 @@ class nsXMLContentSink : public nsContentSink, }
// nsITransformObserver - NS_IMETHOD OnDocumentCreated( - mozilla::dom::Document* aResultDocument) override; - NS_IMETHOD OnTransformDone(nsresult aResult, + nsresult OnDocumentCreated(mozilla::dom::Document* aSourceDocument, mozilla::dom::Document* aResultDocument) override; + nsresult OnTransformDone(mozilla::dom::Document* aSourceDocument, + nsresult aResult, + mozilla::dom::Document* aResultDocument) override;
// nsICSSLoaderObserver NS_IMETHOD StyleSheetLoaded(mozilla::StyleSheet* aSheet, bool aWasDeferred, diff --git a/dom/xslt/nsIDocumentTransformer.h b/dom/xslt/nsIDocumentTransformer.h index 110f2285671d2..3df790dae010d 100644 --- a/dom/xslt/nsIDocumentTransformer.h +++ b/dom/xslt/nsIDocumentTransformer.h @@ -33,10 +33,13 @@ class nsITransformObserver : public nsISupports { public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITRANSFORMOBSERVER_IID)
- NS_IMETHOD OnDocumentCreated(mozilla::dom::Document* aResultDocument) = 0; + virtual nsresult OnDocumentCreated( + mozilla::dom::Document* aSourceDocument, + mozilla::dom::Document* aResultDocument) = 0;
- NS_IMETHOD OnTransformDone(nsresult aResult, - mozilla::dom::Document* aResultDocument) = 0; + virtual nsresult OnTransformDone(mozilla::dom::Document* aSourceDocument, + nsresult aResult, + mozilla::dom::Document* aResultDocument) = 0; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsITransformObserver, NS_ITRANSFORMOBSERVER_IID) diff --git a/dom/xslt/xslt/txMozillaTextOutput.cpp b/dom/xslt/xslt/txMozillaTextOutput.cpp index 8d514d45f2398..0ff022224bfe7 100644 --- a/dom/xslt/xslt/txMozillaTextOutput.cpp +++ b/dom/xslt/xslt/txMozillaTextOutput.cpp @@ -21,8 +21,11 @@ using namespace mozilla; using namespace mozilla::dom;
-txMozillaTextOutput::txMozillaTextOutput(nsITransformObserver* aObserver) - : mObserver(do_GetWeakReference(aObserver)), mCreatedDocument(false) { +txMozillaTextOutput::txMozillaTextOutput(Document* aSourceDocument, + nsITransformObserver* aObserver) + : mSourceDocument(aSourceDocument), + mObserver(do_GetWeakReference(aObserver)), + mCreatedDocument(false) { MOZ_COUNT_CTOR(txMozillaTextOutput); }
@@ -86,7 +89,7 @@ nsresult txMozillaTextOutput::endDocument(nsresult aResult) { if (NS_SUCCEEDED(aResult)) { nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver); if (observer) { - observer->OnTransformDone(aResult, mDocument); + observer->OnTransformDone(mSourceDocument, aResult, mDocument); } }
@@ -102,8 +105,7 @@ nsresult txMozillaTextOutput::processingInstruction(const nsString& aTarget,
nsresult txMozillaTextOutput::startDocument() { return NS_OK; }
-nsresult txMozillaTextOutput::createResultDocument(Document* aSourceDocument, - bool aLoadedAsData) { +nsresult txMozillaTextOutput::createResultDocument(bool aLoadedAsData) { /* * Create an XHTML document to hold the text. * @@ -131,13 +133,13 @@ nsresult txMozillaTextOutput::createResultDocument(Document* aSourceDocument, mDocument->SetReadyStateInternal(Document::READYSTATE_LOADING); bool hasHadScriptObject = false; nsIScriptGlobalObject* sgo = - aSourceDocument->GetScriptHandlingObject(hasHadScriptObject); + mSourceDocument->GetScriptHandlingObject(hasHadScriptObject); NS_ENSURE_STATE(sgo || !hasHadScriptObject);
NS_ASSERTION(mDocument, "Need document");
// Reset and set up document - URIUtils::ResetWithSource(mDocument, aSourceDocument); + URIUtils::ResetWithSource(mDocument, mSourceDocument); // Only do this after resetting the document to ensure we have the // correct principal. mDocument->SetScriptHandlingObject(sgo); @@ -154,7 +156,7 @@ nsresult txMozillaTextOutput::createResultDocument(Document* aSourceDocument, // Notify the contentsink that the document is created nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver); if (observer) { - rv = observer->OnDocumentCreated(mDocument); + rv = observer->OnDocumentCreated(mSourceDocument, mDocument); NS_ENSURE_SUCCESS(rv, rv); }
diff --git a/dom/xslt/xslt/txMozillaTextOutput.h b/dom/xslt/xslt/txMozillaTextOutput.h index acf02b896e50c..2cc4793f4ba01 100644 --- a/dom/xslt/xslt/txMozillaTextOutput.h +++ b/dom/xslt/xslt/txMozillaTextOutput.h @@ -24,19 +24,20 @@ class Element;
class txMozillaTextOutput : public txAOutputXMLEventHandler { public: - explicit txMozillaTextOutput(nsITransformObserver* aObserver); + explicit txMozillaTextOutput(mozilla::dom::Document* aSourceDocument, + nsITransformObserver* aObserver); explicit txMozillaTextOutput(mozilla::dom::DocumentFragment* aDest); virtual ~txMozillaTextOutput();
TX_DECL_TXAXMLEVENTHANDLER TX_DECL_TXAOUTPUTXMLEVENTHANDLER
- nsresult createResultDocument(mozilla::dom::Document* aSourceDocument, - bool aLoadedAsData); + nsresult createResultDocument(bool aLoadedAsData);
private: nsresult createXHTMLElement(nsAtom* aName, mozilla::dom::Element** aResult);
+ nsCOMPtrmozilla::dom::Document mSourceDocument; nsCOMPtr<nsIContent> mTextParent; nsWeakPtr mObserver; RefPtrmozilla::dom::Document mDocument; diff --git a/dom/xslt/xslt/txMozillaXMLOutput.cpp b/dom/xslt/xslt/txMozillaXMLOutput.cpp index 4c8d7ccd6a6f0..05ab76501ee5a 100644 --- a/dom/xslt/xslt/txMozillaXMLOutput.cpp +++ b/dom/xslt/xslt/txMozillaXMLOutput.cpp @@ -47,7 +47,8 @@ using namespace mozilla::dom; NS_ASSERTION(mCurrentNode, "mCurrentNode is nullptr"); \ if (!mCurrentNode) return NS_ERROR_UNEXPECTED
-txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat, +txMozillaXMLOutput::txMozillaXMLOutput(Document* aSourceDocument, + txOutputFormat* aFormat, nsITransformObserver* aObserver) : mTreeDepth(0), mBadChildLevel(0), @@ -58,7 +59,7 @@ txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat, mNoFixup(false) { MOZ_COUNT_CTOR(txMozillaXMLOutput); if (aObserver) { - mNotifier = new txTransformNotifier(); + mNotifier = new txTransformNotifier(aSourceDocument); if (mNotifier) { mNotifier->Init(aObserver); } @@ -846,8 +847,10 @@ nsresult txMozillaXMLOutput::createHTMLElement(nsAtom* aName, return rv; }
-txTransformNotifier::txTransformNotifier() - : mPendingStylesheetCount(0), mInTransform(false) {} +txTransformNotifier::txTransformNotifier(Document* aSourceDocument) + : mSourceDocument(aSourceDocument), + mPendingStylesheetCount(0), + mInTransform(false) {}
txTransformNotifier::~txTransformNotifier() = default;
@@ -918,7 +921,7 @@ nsresult txTransformNotifier::SetOutputDocument(Document* aDocument) { mDocument = aDocument;
// Notify the contentsink that the document is created - return mObserver->OnDocumentCreated(mDocument); + return mObserver->OnDocumentCreated(mSourceDocument, mDocument); }
void txTransformNotifier::SignalTransformEnd(nsresult aResult) { @@ -949,6 +952,6 @@ void txTransformNotifier::SignalTransformEnd(nsresult aResult) { }
if (NS_SUCCEEDED(aResult)) { - mObserver->OnTransformDone(aResult, mDocument); + mObserver->OnTransformDone(mSourceDocument, aResult, mDocument); } } diff --git a/dom/xslt/xslt/txMozillaXMLOutput.h b/dom/xslt/xslt/txMozillaXMLOutput.h index 2f95a1face093..b1ed946a7bd31 100644 --- a/dom/xslt/xslt/txMozillaXMLOutput.h +++ b/dom/xslt/xslt/txMozillaXMLOutput.h @@ -32,7 +32,7 @@ class Element; class txTransformNotifier final : public nsIScriptLoaderObserver, public nsICSSLoaderObserver { public: - txTransformNotifier(); + explicit txTransformNotifier(mozilla::dom::Document* aSourceDocument);
NS_DECL_ISUPPORTS NS_DECL_NSISCRIPTLOADEROBSERVER @@ -52,6 +52,7 @@ class txTransformNotifier final : public nsIScriptLoaderObserver, ~txTransformNotifier(); void SignalTransformEnd(nsresult aResult = NS_OK);
+ nsCOMPtrmozilla::dom::Document mSourceDocument; nsCOMPtrmozilla::dom::Document mDocument; nsCOMPtr<nsITransformObserver> mObserver; nsCOMArray<nsIScriptElement> mScriptElements; @@ -61,7 +62,8 @@ class txTransformNotifier final : public nsIScriptLoaderObserver,
class txMozillaXMLOutput : public txAOutputXMLEventHandler { public: - txMozillaXMLOutput(txOutputFormat* aFormat, nsITransformObserver* aObserver); + txMozillaXMLOutput(mozilla::dom::Document* aSourceDocument, + txOutputFormat* aFormat, nsITransformObserver* aObserver); txMozillaXMLOutput(txOutputFormat* aFormat, mozilla::dom::DocumentFragment* aFragment, bool aNoFixup); ~txMozillaXMLOutput(); diff --git a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp index eee52e9ff9e34..fbfaadc1a1f56 100644 --- a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp +++ b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp @@ -79,7 +79,7 @@ nsresult txToDocHandlerFactory::createHandlerWith(
case eHTMLOutput: { UniquePtr<txMozillaXMLOutput> handler( - new txMozillaXMLOutput(aFormat, mObserver)); + new txMozillaXMLOutput(mSourceDocument, aFormat, mObserver));
nsresult rv = handler->createResultDocument( u""_ns, kNameSpaceID_None, mSourceDocument, mDocumentIsData); @@ -92,10 +92,9 @@ nsresult txToDocHandlerFactory::createHandlerWith(
case eTextOutput: { UniquePtr<txMozillaTextOutput> handler( - new txMozillaTextOutput(mObserver)); + new txMozillaTextOutput(mSourceDocument, mObserver));
- nsresult rv = - handler->createResultDocument(mSourceDocument, mDocumentIsData); + nsresult rv = handler->createResultDocument(mDocumentIsData); if (NS_SUCCEEDED(rv)) { *aHandler = handler.release(); } @@ -122,7 +121,7 @@ nsresult txToDocHandlerFactory::createHandlerWith( case eXMLOutput: case eHTMLOutput: { UniquePtr<txMozillaXMLOutput> handler( - new txMozillaXMLOutput(aFormat, mObserver)); + new txMozillaXMLOutput(mSourceDocument, aFormat, mObserver));
nsresult rv = handler->createResultDocument(aName, aNsID, mSourceDocument, mDocumentIsData); @@ -135,10 +134,9 @@ nsresult txToDocHandlerFactory::createHandlerWith(
case eTextOutput: { UniquePtr<txMozillaTextOutput> handler( - new txMozillaTextOutput(mObserver)); + new txMozillaTextOutput(mSourceDocument, mObserver));
- nsresult rv = - handler->createResultDocument(mSourceDocument, mDocumentIsData); + nsresult rv = handler->createResultDocument(mDocumentIsData); if (NS_SUCCEEDED(rv)) { *aHandler = handler.release(); } @@ -1028,8 +1026,7 @@ void txMozillaXSLTProcessor::notifyError() { MOZ_ASSERT(document->GetReadyStateEnum() == Document::READYSTATE_LOADING, "Bad readyState."); document->SetReadyStateInternal(Document::READYSTATE_INTERACTIVE); - - mObserver->OnTransformDone(mTransformResult, document); + mObserver->OnTransformDone(mSource->OwnerDoc(), mTransformResult, document); }
nsresult txMozillaXSLTProcessor::ensureStylesheet() {