[tbb-commits] [tor-browser] 09/15: Bug 1769155 - Deal with document replacement. r=smaug, a=RyanVM

gitolite role git at cupani.torproject.org
Thu Aug 18 22:31:51 UTC 2022


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 at 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);
 
+  nsCOMPtr<mozilla::dom::Document> mSourceDocument;
   nsCOMPtr<nsIContent> mTextParent;
   nsWeakPtr mObserver;
   RefPtr<mozilla::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);
 
+  nsCOMPtr<mozilla::dom::Document> mSourceDocument;
   nsCOMPtr<mozilla::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() {

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tbb-commits mailing list