author | Ciure Andrei <aciure@mozilla.com> |
Fri, 04 Jan 2019 01:03:06 +0200 | |
changeset 452493 | 95d275f757c3501fcdc8e00e84f8ae1a3be0cf48 |
parent 452492 | ec8667678f3a7fa4d6259b070a35a4c4a5c14209 (current diff) |
parent 452469 | b762378e8c7e1127f555f54d2ab770a5a4c9e430 (diff) |
child 452494 | 0097778657282369dc3e4201818aff8c7ebfa9c3 |
push id | 110902 |
push user | aciure@mozilla.com |
push date | Fri, 04 Jan 2019 03:48:17 +0000 |
treeherder | mozilla-inbound@81804f8f55d0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 66.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/accessible/android/DocAccessibleWrap.cpp +++ b/accessible/android/DocAccessibleWrap.cpp @@ -17,17 +17,17 @@ using namespace mozilla::a11y; const uint32_t kCacheRefreshInterval = 500; //////////////////////////////////////////////////////////////////////////////// // DocAccessibleWrap //////////////////////////////////////////////////////////////////////////////// -DocAccessibleWrap::DocAccessibleWrap(nsIDocument* aDocument, +DocAccessibleWrap::DocAccessibleWrap(Document* aDocument, nsIPresShell* aPresShell) : DocAccessible(aDocument, aPresShell) { nsCOMPtr<nsIDocShellTreeItem> treeItem(aDocument->GetDocShell()); nsCOMPtr<nsIDocShellTreeItem> parentTreeItem; treeItem->GetParent(getter_AddRefs(parentTreeItem)); if (treeItem->ItemType() == nsIDocShellTreeItem::typeContent &&
--- a/accessible/android/DocAccessibleWrap.h +++ b/accessible/android/DocAccessibleWrap.h @@ -9,17 +9,17 @@ #include "DocAccessible.h" #include "nsITimer.h" namespace mozilla { namespace a11y { class DocAccessibleWrap : public DocAccessible { public: - DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell); + DocAccessibleWrap(Document* aDocument, nsIPresShell* aPresShell); virtual ~DocAccessibleWrap(); virtual nsresult HandleAccEvent(AccEvent* aEvent) override; /** * Manage the mapping from id to Accessible. */ void AddID(uint32_t aID, AccessibleWrap* aAcc) {
--- a/accessible/android/RootAccessibleWrap.cpp +++ b/accessible/android/RootAccessibleWrap.cpp @@ -8,17 +8,17 @@ #include "Accessible-inl.h" #include "AccessibleOrProxy.h" #include "DocAccessibleParent.h" #include "ProxyAccessibleWrap.h" #include "SessionAccessibility.h" using namespace mozilla::a11y; -RootAccessibleWrap::RootAccessibleWrap(nsIDocument* aDoc, +RootAccessibleWrap::RootAccessibleWrap(mozilla::dom::Document* aDoc, nsIPresShell* aPresShell) : RootAccessible(aDoc, aPresShell) {} RootAccessibleWrap::~RootAccessibleWrap() {} AccessibleWrap* RootAccessibleWrap::GetContentAccessible() { if (ProxyAccessible* proxy = GetPrimaryRemoteTopLevelContentDoc()) { return WrapperFor(proxy);
--- a/accessible/android/RootAccessibleWrap.h +++ b/accessible/android/RootAccessibleWrap.h @@ -10,17 +10,17 @@ namespace mozilla { namespace a11y { class DocProxyAccessibleWrap; class RootAccessibleWrap : public RootAccessible { public: - RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell); + RootAccessibleWrap(dom::Document* aDocument, nsIPresShell* aPresShell); virtual ~RootAccessibleWrap(); AccessibleWrap* GetContentAccessible(); AccessibleWrap* FindAccessibleById(int32_t aID); // Recursively searches for the accessible ID within the document tree. AccessibleWrap* FindAccessibleById(DocAccessibleWrap* aDocument, int32_t aID);
--- a/accessible/atk/DocAccessibleWrap.cpp +++ b/accessible/atk/DocAccessibleWrap.cpp @@ -8,13 +8,13 @@ #include "DocAccessibleWrap.h" using namespace mozilla::a11y; //////////////////////////////////////////////////////////////////////////////// // DocAccessibleWrap //////////////////////////////////////////////////////////////////////////////// -DocAccessibleWrap::DocAccessibleWrap(nsIDocument* aDocument, +DocAccessibleWrap::DocAccessibleWrap(dom::Document* aDocument, nsIPresShell* aPresShell) : DocAccessible(aDocument, aPresShell), mActivated(false) {} DocAccessibleWrap::~DocAccessibleWrap() {}
--- a/accessible/atk/DocAccessibleWrap.h +++ b/accessible/atk/DocAccessibleWrap.h @@ -13,17 +13,17 @@ #include "DocAccessible.h" namespace mozilla { namespace a11y { class DocAccessibleWrap : public DocAccessible { public: - DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell); + DocAccessibleWrap(dom::Document* aDocument, nsIPresShell* aPresShell); virtual ~DocAccessibleWrap(); bool mActivated; }; } // namespace a11y } // namespace mozilla
--- a/accessible/base/DocManager.cpp +++ b/accessible/base/DocManager.cpp @@ -47,17 +47,17 @@ nsRefPtrHashtable<nsPtrHashKey<const Doc // DocManager //////////////////////////////////////////////////////////////////////////////// DocManager::DocManager() : mDocAccessibleCache(2), mXPCDocumentCache(0) {} //////////////////////////////////////////////////////////////////////////////// // DocManager public -DocAccessible* DocManager::GetDocAccessible(nsIDocument* aDocument) { +DocAccessible* DocManager::GetDocAccessible(Document* aDocument) { if (!aDocument) return nullptr; DocAccessible* docAcc = GetExistingDocAccessible(aDocument); if (docAcc) return docAcc; return CreateDocOrRootAccessible(aDocument); } @@ -85,17 +85,17 @@ void DocManager::RemoveFromXPCDocumentCa if (!HasXPCDocuments()) { MaybeShutdownAccService(nsAccessibilityService::eXPCOM); } } } void DocManager::NotifyOfDocumentShutdown(DocAccessible* aDocument, - nsIDocument* aDOMDocument) { + Document* aDOMDocument) { // We need to remove listeners in both cases, when document is being shutdown // or when accessibility service is being shut down as well. RemoveListeners(aDOMDocument); // Document will already be removed when accessibility service is shutting // down so we do not need to remove it twice. if (nsAccessibilityService::IsShutdown()) { return; @@ -213,17 +213,17 @@ DocManager::OnStateChange(nsIWebProgress nsCOMPtr<mozIDOMWindowProxy> DOMWindow; aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow)); NS_ENSURE_STATE(DOMWindow); nsPIDOMWindowOuter* piWindow = nsPIDOMWindowOuter::From(DOMWindow); MOZ_ASSERT(piWindow); - nsCOMPtr<nsIDocument> document = piWindow->GetDoc(); + nsCOMPtr<Document> document = piWindow->GetDoc(); NS_ENSURE_STATE(document); // Document was loaded. if (aStateFlags & STATE_STOP) { #ifdef A11Y_LOG if (logging::IsEnabled(logging::eDocLoad)) logging::DocLoad("document loaded", aWebProgress, aRequest, aStateFlags); #endif @@ -311,17 +311,17 @@ DocManager::OnSecurityChange(nsIWebProgr //////////////////////////////////////////////////////////////////////////////// // nsIDOMEventListener NS_IMETHODIMP DocManager::HandleEvent(Event* aEvent) { nsAutoString type; aEvent->GetType(type); - nsCOMPtr<nsIDocument> document = do_QueryInterface(aEvent->GetTarget()); + nsCOMPtr<Document> document = do_QueryInterface(aEvent->GetTarget()); NS_ASSERTION(document, "pagehide or DOMContentLoaded for non document!"); if (!document) return NS_OK; if (type.EqualsLiteral("pagehide")) { // 'pagehide' event is registered on every DOM document we create an // accessible for, process the event for the target. This document // accessible and all its sub document accessible are shutdown as result of // processing. @@ -356,30 +356,30 @@ DocManager::HandleEvent(Event* aEvent) { } return NS_OK; } //////////////////////////////////////////////////////////////////////////////// // DocManager private -void DocManager::HandleDOMDocumentLoad(nsIDocument* aDocument, +void DocManager::HandleDOMDocumentLoad(Document* aDocument, uint32_t aLoadEventType) { // Document accessible can be created before we were notified the DOM document // was loaded completely. However if it's not created yet then create it. DocAccessible* docAcc = GetExistingDocAccessible(aDocument); if (!docAcc) { docAcc = CreateDocOrRootAccessible(aDocument); if (!docAcc) return; } docAcc->NotifyOfLoad(aLoadEventType); } -void DocManager::AddListeners(nsIDocument* aDocument, +void DocManager::AddListeners(Document* aDocument, bool aAddDOMContentLoadedListener) { nsPIDOMWindowOuter* window = aDocument->GetWindow(); EventTarget* target = window->GetChromeEventHandler(); EventListenerManager* elm = target->GetOrCreateListenerManager(); elm->AddEventListenerByType(this, NS_LITERAL_STRING("pagehide"), TrustedEventsAtCapture()); #ifdef A11Y_LOG @@ -392,32 +392,32 @@ void DocManager::AddListeners(nsIDocumen TrustedEventsAtCapture()); #ifdef A11Y_LOG if (logging::IsEnabled(logging::eDocCreate)) logging::Text("added 'DOMContentLoaded' listener"); #endif } } -void DocManager::RemoveListeners(nsIDocument* aDocument) { +void DocManager::RemoveListeners(Document* aDocument) { nsPIDOMWindowOuter* window = aDocument->GetWindow(); if (!window) return; EventTarget* target = window->GetChromeEventHandler(); if (!target) return; EventListenerManager* elm = target->GetOrCreateListenerManager(); elm->RemoveEventListenerByType(this, NS_LITERAL_STRING("pagehide"), TrustedEventsAtCapture()); elm->RemoveEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"), TrustedEventsAtCapture()); } -DocAccessible* DocManager::CreateDocOrRootAccessible(nsIDocument* aDocument) { +DocAccessible* DocManager::CreateDocOrRootAccessible(Document* aDocument) { // Ignore hidden documents, resource documents, static clone // (printing) documents and documents without a docshell. if (!aDocument->IsVisibleConsideringAncestors() || aDocument->IsResourceDoc() || aDocument->IsStaticDocument() || !aDocument->IsActive()) { return nullptr; }
--- a/accessible/base/DocManager.h +++ b/accessible/base/DocManager.h @@ -1,17 +1,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_a11_DocManager_h_ #define mozilla_a11_DocManager_h_ #include "mozilla/ClearOnShutdown.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIDOMEventListener.h" #include "nsRefPtrHashtable.h" #include "nsIWebProgressListener.h" #include "nsWeakReference.h" #include "nsIPresShell.h" #include "mozilla/StaticPtr.h" namespace mozilla { @@ -31,17 +31,17 @@ class DocManager : public nsIWebProgress public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIWEBPROGRESSLISTENER NS_DECL_NSIDOMEVENTLISTENER /** * Return document accessible for the given DOM node. */ - DocAccessible* GetDocAccessible(nsIDocument* aDocument); + DocAccessible* GetDocAccessible(dom::Document* aDocument); /** * Return document accessible for the given presshell. */ DocAccessible* GetDocAccessible(const nsIPresShell* aPresShell) { if (!aPresShell) return nullptr; DocAccessible* doc = aPresShell->GetDocAccessible(); @@ -55,17 +55,17 @@ class DocManager : public nsIWebProgress * unique id. */ Accessible* FindAccessibleInCache(nsINode* aNode) const; /** * Called by document accessible when it gets shutdown. */ void NotifyOfDocumentShutdown(DocAccessible* aDocument, - nsIDocument* aDOMDocument); + dom::Document* aDOMDocument); void RemoveFromXPCDocumentCache(DocAccessible* aDocument); /** * Return XPCOM accessible document. */ xpcAccessibleDocument* GetXPCDocument(DocAccessible* aDocument); xpcAccessibleDocument* GetCachedXPCDocument(DocAccessible* aDocument) const { @@ -137,35 +137,35 @@ class DocManager : public nsIWebProgress /** * Create an accessible document if it was't created and fire accessibility * events if needed. * * @param aDocument [in] loaded DOM document * @param aLoadEventType [in] specifies the event type to fire load event, * if 0 then no event is fired */ - void HandleDOMDocumentLoad(nsIDocument* aDocument, uint32_t aLoadEventType); + void HandleDOMDocumentLoad(dom::Document* aDocument, uint32_t aLoadEventType); /** * Add/remove 'pagehide' and 'DOMContentLoaded' event listeners. */ - void AddListeners(nsIDocument* aDocument, bool aAddPageShowListener); - void RemoveListeners(nsIDocument* aDocument); + void AddListeners(dom::Document* aDocument, bool aAddPageShowListener); + void RemoveListeners(dom::Document* aDocument); /** * Create document or root accessible. */ - DocAccessible* CreateDocOrRootAccessible(nsIDocument* aDocument); + DocAccessible* CreateDocOrRootAccessible(dom::Document* aDocument); /** * Clear the cache and shutdown the document accessibles. */ void ClearDocCache(); - typedef nsRefPtrHashtable<nsPtrHashKey<const nsIDocument>, DocAccessible> + typedef nsRefPtrHashtable<nsPtrHashKey<const dom::Document>, DocAccessible> DocAccessibleHashtable; DocAccessibleHashtable mDocAccessibleCache; typedef nsRefPtrHashtable<nsPtrHashKey<const DocAccessible>, xpcAccessibleDocument> XPCDocumentHashtable; XPCDocumentHashtable mXPCDocumentCache; static nsRefPtrHashtable<nsPtrHashKey<const DocAccessibleParent>, @@ -177,17 +177,17 @@ class DocManager : public nsIWebProgress static StaticAutoPtr<nsTArray<DocAccessibleParent*>> sRemoteDocuments; }; /** * Return the existing document accessible for the document if any. * Note this returns the doc accessible for the primary pres shell if there is * more than one. */ -inline DocAccessible* GetExistingDocAccessible(const nsIDocument* aDocument) { +inline DocAccessible* GetExistingDocAccessible(const dom::Document* aDocument) { nsIPresShell* ps = aDocument->GetShell(); return ps ? ps->GetDocAccessible() : nullptr; } } // namespace a11y } // namespace mozilla #endif // mozilla_a11_DocManager_h_
--- a/accessible/base/FocusManager.cpp +++ b/accessible/base/FocusManager.cpp @@ -129,17 +129,17 @@ void FocusManager::NotifyOfDOMBlur(nsISu #endif mActiveItem = nullptr; // If DOM document stays focused then fire accessible focus event to process // the case when no element within this DOM document will be focused. nsCOMPtr<nsINode> targetNode(do_QueryInterface(aTarget)); if (targetNode && targetNode->OwnerDoc() == FocusedDOMDocument()) { - nsIDocument* DOMDoc = targetNode->OwnerDoc(); + dom::Document* DOMDoc = targetNode->OwnerDoc(); DocAccessible* document = GetAccService()->GetDocAccessible(DOMDoc); if (document) { // Clear selection listener for previously focused element. if (targetNode->IsElement()) SelectionMgr()->ClearControlSelectionListener(); document->HandleNotification<FocusManager, nsINode>( this, &FocusManager::ProcessDOMFocus, DOMDoc); @@ -371,15 +371,15 @@ nsINode* FocusManager::FocusedDOMNode() return focusedElm; } // Otherwise the focus can be on DOM document. nsPIDOMWindowOuter* focusedWnd = DOMFocusManager->GetFocusedWindow(); return focusedWnd ? focusedWnd->GetExtantDoc() : nullptr; } -nsIDocument* FocusManager::FocusedDOMDocument() const { +dom::Document* FocusManager::FocusedDOMDocument() const { nsINode* focusedNode = FocusedDOMNode(); return focusedNode ? focusedNode->OwnerDoc() : nullptr; } } // namespace a11y } // namespace mozilla
--- a/accessible/base/FocusManager.h +++ b/accessible/base/FocusManager.h @@ -3,20 +3,23 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_a11y_FocusManager_h_ #define mozilla_a11y_FocusManager_h_ #include "mozilla/RefPtr.h" class nsINode; -class nsIDocument; class nsISupports; namespace mozilla { +namespace dom { +class Document; +} + namespace a11y { class AccEvent; class Accessible; class DocAccessible; /** * Manage the accessible focus. Used to fire and process accessible events. @@ -112,17 +115,17 @@ class FocusManager { private: FocusManager(const FocusManager&); FocusManager& operator=(const FocusManager&); /** * Return DOM document having DOM focus. */ - nsIDocument* FocusedDOMDocument() const; + dom::Document* FocusedDOMDocument() const; private: RefPtr<Accessible> mActiveItem; RefPtr<Accessible> mActiveARIAMenubar; }; } // namespace a11y } // namespace mozilla
--- a/accessible/base/Logging.cpp +++ b/accessible/base/Logging.cpp @@ -77,21 +77,21 @@ static void EnableLogging(const char* aM } } token += tokenLen; if (*token == ',') token++; // skip ',' char } } -static void LogDocURI(nsIDocument* aDocumentNode) { +static void LogDocURI(dom::Document* aDocumentNode) { printf("uri: %s", aDocumentNode->GetDocumentURI()->GetSpecOrDefault().get()); } -static void LogDocShellState(nsIDocument* aDocumentNode) { +static void LogDocShellState(dom::Document* aDocumentNode) { printf("docshell busy: "); nsAutoCString docShellBusy; nsCOMPtr<nsIDocShell> docShell = aDocumentNode->GetDocShell(); nsIDocShell::BusyFlags busyFlags = nsIDocShell::BUSY_FLAGS_NONE; docShell->GetBusyFlags(&busyFlags); if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE) { printf("'none'"); @@ -102,52 +102,52 @@ static void LogDocShellState(nsIDocument if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD) { printf(", 'before page load'"); } if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING) { printf(", 'page loading'"); } } -static void LogDocType(nsIDocument* aDocumentNode) { +static void LogDocType(dom::Document* aDocumentNode) { if (aDocumentNode->IsActive()) { bool isContent = nsCoreUtils::IsContentDocument(aDocumentNode); printf("%s document", (isContent ? "content" : "chrome")); } else { printf("document type: [failed]"); } } -static void LogDocShellTree(nsIDocument* aDocumentNode) { +static void LogDocShellTree(dom::Document* aDocumentNode) { if (aDocumentNode->IsActive()) { nsCOMPtr<nsIDocShellTreeItem> treeItem(aDocumentNode->GetDocShell()); nsCOMPtr<nsIDocShellTreeItem> parentTreeItem; treeItem->GetParent(getter_AddRefs(parentTreeItem)); nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;", static_cast<void*>(parentTreeItem), static_cast<void*>(rootTreeItem), (nsCoreUtils::IsTabDocument(aDocumentNode) ? "yes" : "no")); } } -static void LogDocState(nsIDocument* aDocumentNode) { +static void LogDocState(dom::Document* aDocumentNode) { const char* docState = nullptr; - nsIDocument::ReadyState docStateFlag = aDocumentNode->GetReadyStateEnum(); + dom::Document::ReadyState docStateFlag = aDocumentNode->GetReadyStateEnum(); switch (docStateFlag) { - case nsIDocument::READYSTATE_UNINITIALIZED: + case dom::Document::READYSTATE_UNINITIALIZED: docState = "uninitialized"; break; - case nsIDocument::READYSTATE_LOADING: + case dom::Document::READYSTATE_LOADING: docState = "loading"; break; - case nsIDocument::READYSTATE_INTERACTIVE: + case dom::Document::READYSTATE_INTERACTIVE: docState = "interactive"; break; - case nsIDocument::READYSTATE_COMPLETE: + case dom::Document::READYSTATE_COMPLETE: docState = "complete"; break; } printf("doc state: %s", docState); printf(", %sinitial", aDocumentNode->IsInitialDocument() ? "" : "not "); printf(", %sshowing", aDocumentNode->IsShowing() ? "" : "not "); printf(", %svisible", aDocumentNode->IsVisible() ? "" : "not "); @@ -158,46 +158,46 @@ static void LogDocState(nsIDocument* aDo dom::Element* rootEl = aDocumentNode->GetBodyElement(); if (!rootEl) { rootEl = aDocumentNode->GetRootElement(); } printf(", has %srole content", rootEl ? "" : "no "); } -static void LogPresShell(nsIDocument* aDocumentNode) { +static void LogPresShell(dom::Document* aDocumentNode) { nsIPresShell* ps = aDocumentNode->GetShell(); printf("presshell: %p", static_cast<void*>(ps)); nsIScrollableFrame* sf = nullptr; if (ps) { printf(", is %s destroying", (ps->IsDestroying() ? "" : "not")); sf = ps->GetRootScrollFrameAsScrollable(); } printf(", root scroll frame: %p", static_cast<void*>(sf)); } -static void LogDocLoadGroup(nsIDocument* aDocumentNode) { +static void LogDocLoadGroup(dom::Document* aDocumentNode) { nsCOMPtr<nsILoadGroup> loadGroup = aDocumentNode->GetDocumentLoadGroup(); printf("load group: %p", static_cast<void*>(loadGroup)); } -static void LogDocParent(nsIDocument* aDocumentNode) { - nsIDocument* parentDoc = aDocumentNode->GetParentDocument(); +static void LogDocParent(dom::Document* aDocumentNode) { + dom::Document* parentDoc = aDocumentNode->GetParentDocument(); printf("parent DOM document: %p", static_cast<void*>(parentDoc)); if (parentDoc) { printf(", parent acc document: %p", static_cast<void*>(GetExistingDocAccessible(parentDoc))); printf("\n parent "); LogDocURI(parentDoc); printf("\n"); } } -static void LogDocInfo(nsIDocument* aDocumentNode, DocAccessible* aDocument) { +static void LogDocInfo(dom::Document* aDocumentNode, DocAccessible* aDocument) { printf(" DOM document: %p, acc document: %p\n ", static_cast<void*>(aDocumentNode), static_cast<void*>(aDocument)); // log document info if (aDocumentNode) { LogDocURI(aDocumentNode); printf("\n "); LogDocShellState(aDocumentNode); @@ -365,17 +365,17 @@ void logging::DocLoad(const char* aMsg, nsCOMPtr<mozIDOMWindowProxy> DOMWindow; aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow)); nsPIDOMWindowOuter* window = nsPIDOMWindowOuter::From(DOMWindow); if (!window) { MsgEnd(); return; } - nsCOMPtr<nsIDocument> documentNode = window->GetDoc(); + nsCOMPtr<dom::Document> documentNode = window->GetDoc(); if (!documentNode) { MsgEnd(); return; } DocAccessible* document = GetExistingDocAccessible(documentNode); LogDocInfo(documentNode, document); @@ -389,17 +389,17 @@ void logging::DocLoad(const char* aMsg, printf(" state flags: %x", aStateFlags); bool isDocLoading; aWebProgress->GetIsLoadingDocument(&isDocLoading); printf(", document is %sloading\n", (isDocLoading ? "" : "not ")); MsgEnd(); } -void logging::DocLoad(const char* aMsg, nsIDocument* aDocumentNode) { +void logging::DocLoad(const char* aMsg, dom::Document* aDocumentNode) { MsgBegin(sDocLoadTitle, "%s", aMsg); DocAccessible* document = GetExistingDocAccessible(aDocumentNode); LogDocInfo(aDocumentNode, document); MsgEnd(); } @@ -439,27 +439,27 @@ void logging::DocLoadEventHandled(AccEve MsgBegin(sDocEventTitle, "handled '%s' event", strEventType.get()); DocAccessible* document = aEvent->GetAccessible()->AsDoc(); if (document) LogDocInfo(document->DocumentNode(), document); MsgEnd(); } -void logging::DocCreate(const char* aMsg, nsIDocument* aDocumentNode, +void logging::DocCreate(const char* aMsg, dom::Document* aDocumentNode, DocAccessible* aDocument) { DocAccessible* document = aDocument ? aDocument : GetExistingDocAccessible(aDocumentNode); MsgBegin(sDocCreateTitle, "%s", aMsg); LogDocInfo(aDocumentNode, document); MsgEnd(); } -void logging::DocDestroy(const char* aMsg, nsIDocument* aDocumentNode, +void logging::DocDestroy(const char* aMsg, dom::Document* aDocumentNode, DocAccessible* aDocument) { DocAccessible* document = aDocument ? aDocument : GetExistingDocAccessible(aDocumentNode); MsgBegin(sDocDestroyTitle, "%s", aMsg); LogDocInfo(aDocumentNode, document); MsgEnd(); } @@ -708,17 +708,17 @@ void logging::Text(const char* aText) { void logging::Address(const char* aDescr, Accessible* aAcc) { if (!aAcc->IsDoc()) { printf(" %s accessible: %p, node: %p\n", aDescr, static_cast<void*>(aAcc), static_cast<void*>(aAcc->GetNode())); } DocAccessible* doc = aAcc->Document(); - nsIDocument* docNode = doc->DocumentNode(); + dom::Document* docNode = doc->DocumentNode(); printf(" document: %p, node: %p\n", static_cast<void*>(doc), static_cast<void*>(docNode)); printf(" "); LogDocURI(docNode); printf("\n"); }
--- a/accessible/base/Logging.h +++ b/accessible/base/Logging.h @@ -6,25 +6,25 @@ #ifndef mozilla_a11y_logs_h__ #define mozilla_a11y_logs_h__ #include "nscore.h" #include "nsStringFwd.h" #include "mozilla/Attributes.h" -class nsIDocument; class nsINode; class nsIRequest; class nsISupports; class nsIWebProgress; namespace mozilla { namespace dom { +class Document; class Selection; } // namespace dom namespace a11y { class AccEvent; class Accessible; class DocAccessible; @@ -69,39 +69,39 @@ bool IsEnabledAll(uint32_t aModules); */ bool IsEnabled(const nsAString& aModules); /** * Log the document loading progress. */ void DocLoad(const char* aMsg, nsIWebProgress* aWebProgress, nsIRequest* aRequest, uint32_t aStateFlags); -void DocLoad(const char* aMsg, nsIDocument* aDocumentNode); +void DocLoad(const char* aMsg, dom::Document* aDocumentNode); void DocCompleteLoad(DocAccessible* aDocument, bool aIsLoadEventTarget); /** * Log that document load event was fired. */ void DocLoadEventFired(AccEvent* aEvent); /** * Log that document laod event was handled. */ void DocLoadEventHandled(AccEvent* aEvent); /** * Log the document was created. */ -void DocCreate(const char* aMsg, nsIDocument* aDocumentNode, +void DocCreate(const char* aMsg, dom::Document* aDocumentNode, DocAccessible* aDocument = nullptr); /** * Log the document was destroyed. */ -void DocDestroy(const char* aMsg, nsIDocument* aDocumentNode, +void DocDestroy(const char* aMsg, dom::Document* aDocumentNode, DocAccessible* aDocument = nullptr); /** * Log the outer document was destroyed. */ void OuterDocDestroy(OuterDocAccessible* OuterDoc); /**
--- a/accessible/base/SelectionManager.cpp +++ b/accessible/base/SelectionManager.cpp @@ -10,17 +10,17 @@ #include "HyperTextAccessible-inl.h" #include "nsAccessibilityService.h" #include "nsAccUtils.h" #include "nsCoreUtils.h" #include "nsEventShell.h" #include "nsFrameSelection.h" #include "nsIAccessibleTypes.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIPresShell.h" #include "mozilla/dom/Selection.h" #include "mozilla/dom/Element.h" using namespace mozilla; using namespace mozilla::a11y; using mozilla::dom::Selection; @@ -133,17 +133,17 @@ void SelectionManager::ProcessTextSelCha if (mCaretOffset != -1) { RefPtr<AccCaretMoveEvent> caretMoveEvent = new AccCaretMoveEvent(caretCntr, mCaretOffset, aEvent->FromUserInput()); nsEventShell::FireEvent(caretMoveEvent); } } NS_IMETHODIMP -SelectionManager::NotifySelectionChanged(nsIDocument* aDocument, +SelectionManager::NotifySelectionChanged(dom::Document* aDocument, Selection* aSelection, int16_t aReason) { if (NS_WARN_IF(!aDocument) || NS_WARN_IF(!aSelection)) { return NS_ERROR_INVALID_ARG; } DocAccessible* document = GetAccService()->GetDocAccessible(aDocument);
--- a/accessible/base/nsAccUtils.cpp +++ b/accessible/base/nsAccUtils.cpp @@ -444,17 +444,17 @@ bool nsAccUtils::IsARIALive(const Access // Get computed aria-live property based on the closest container with the // attribute. Inner nodes override outer nodes within the same // document, but nodes in outer documents override nodes in inner documents. // This should be the same as the container-live attribute, but we don't need // the other container-* attributes, so we can't use the same function. nsAutoString live; nsIContent* startContent = aAccessible->GetContent(); while (startContent) { - nsIDocument* doc = startContent->GetComposedDoc(); + dom::Document* doc = startContent->GetComposedDoc(); if (!doc) { break; } dom::Element* aTopEl = doc->GetRootElement(); nsIContent* ancestor = startContent; while (ancestor) { nsAutoString docLive; @@ -490,17 +490,17 @@ bool nsAccUtils::IsARIALive(const Access } nsCOMPtr<nsIDocShellTreeItem> sameTypeParent; docShellTreeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent)); if (!sameTypeParent || sameTypeParent == docShellTreeItem) { break; } - nsIDocument* parentDoc = doc->GetParentDocument(); + dom::Document* parentDoc = doc->GetParentDocument(); if (!parentDoc) { break; } startContent = parentDoc->FindContentForSubDocument(doc); } return !live.IsEmpty() && !live.EqualsLiteral("off");
--- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -277,17 +277,17 @@ nsAccessibilityService::ListenersChanged continue; } uint32_t changeCount; change->GetCountOfEventListenerChangesAffectingAccessibility(&changeCount); NS_ENSURE_SUCCESS(rv, rv); for (uint32_t i = 0; i < changeCount; i++) { - nsIDocument* ownerDoc = node->OwnerDoc(); + Document* ownerDoc = node->OwnerDoc(); DocAccessible* document = GetExistingDocAccessible(ownerDoc); // Create an accessible for a inaccessible element having click event // handler. if (document && !document->HasAccessible(node) && nsCoreUtils::HasClickListener(node)) { document->ContentInserted(node, node->GetNextSibling()); break; @@ -313,32 +313,32 @@ nsAccessibilityService::Observe(nsISuppo if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) { Shutdown(); } return NS_OK; } void nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent* aTargetNode) { - nsIDocument* documentNode = aTargetNode->GetUncomposedDoc(); + Document* documentNode = aTargetNode->GetUncomposedDoc(); if (documentNode) { DocAccessible* document = GetDocAccessible(documentNode); if (document) document->SetAnchorJump(aTargetNode); } } void nsAccessibilityService::FireAccessibleEvent(uint32_t aEvent, Accessible* aTarget) { nsEventShell::FireEvent(aEvent, aTarget); } Accessible* nsAccessibilityService::GetRootDocumentAccessible( nsIPresShell* aPresShell, bool aCanCreate) { nsIPresShell* ps = aPresShell; - nsIDocument* documentNode = aPresShell->GetDocument(); + Document* documentNode = aPresShell->GetDocument(); if (documentNode) { nsCOMPtr<nsIDocShellTreeItem> treeItem(documentNode->GetDocShell()); if (treeItem) { nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); if (treeItem != rootTreeItem) { nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(rootTreeItem)); ps = docShell->GetPresShell();
--- a/accessible/base/nsCoreUtils.cpp +++ b/accessible/base/nsCoreUtils.cpp @@ -4,17 +4,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsCoreUtils.h" #include "nsIAccessibleTypes.h" #include "nsIBaseWindow.h" #include "nsIDocShellTreeOwner.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsRange.h" #include "nsIBoxObject.h" #include "nsXULElement.h" #include "mozilla/dom/BoxObject.h" #include "nsIDocShell.h" #include "nsIObserverService.h" #include "nsIPresShell.h" #include "nsPresContext.h" @@ -65,17 +65,17 @@ bool nsCoreUtils::HasClickListener(nsICo void nsCoreUtils::DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj, int32_t aRowIndex, nsTreeColumn *aColumn, const nsAString &aPseudoElt) { RefPtr<dom::Element> tcElm; aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm)); if (!tcElm) return; - nsIDocument *document = tcElm->GetUncomposedDoc(); + Document *document = tcElm->GetUncomposedDoc(); if (!document) return; nsCOMPtr<nsIPresShell> presShell = document->GetShell(); if (!presShell) return; // Ensure row is visible. aTreeBoxObj->EnsureRowIsVisible(aRowIndex); @@ -335,50 +335,50 @@ nsIntPoint nsCoreUtils::GetScreenCoordsF already_AddRefed<nsIDocShell> nsCoreUtils::GetDocShellFor(nsINode *aNode) { if (!aNode) return nullptr; nsCOMPtr<nsIDocShell> docShell = aNode->OwnerDoc()->GetDocShell(); return docShell.forget(); } -bool nsCoreUtils::IsRootDocument(nsIDocument *aDocument) { +bool nsCoreUtils::IsRootDocument(Document *aDocument) { nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = aDocument->GetDocShell(); NS_ASSERTION(docShellTreeItem, "No document shell for document!"); nsCOMPtr<nsIDocShellTreeItem> parentTreeItem; docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem)); return !parentTreeItem; } -bool nsCoreUtils::IsContentDocument(nsIDocument *aDocument) { +bool nsCoreUtils::IsContentDocument(Document *aDocument) { nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = aDocument->GetDocShell(); NS_ASSERTION(docShellTreeItem, "No document shell tree item for document!"); return (docShellTreeItem->ItemType() == nsIDocShellTreeItem::typeContent); } -bool nsCoreUtils::IsTabDocument(nsIDocument *aDocumentNode) { +bool nsCoreUtils::IsTabDocument(Document *aDocumentNode) { nsCOMPtr<nsIDocShellTreeItem> treeItem(aDocumentNode->GetDocShell()); nsCOMPtr<nsIDocShellTreeItem> parentTreeItem; treeItem->GetParent(getter_AddRefs(parentTreeItem)); // Tab document running in own process doesn't have parent. if (XRE_IsContentProcess()) return !parentTreeItem; // Parent of docshell for tab document running in chrome process is root. nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); return parentTreeItem == rootTreeItem; } -bool nsCoreUtils::IsErrorPage(nsIDocument *aDocument) { +bool nsCoreUtils::IsErrorPage(Document *aDocument) { nsIURI *uri = aDocument->GetDocumentURI(); bool isAboutScheme = false; uri->SchemeIs("about", &isAboutScheme); if (!isAboutScheme) return false; nsAutoCString path; uri->GetPathQueryRef(path);
--- a/accessible/base/nsCoreUtils.h +++ b/accessible/base/nsCoreUtils.h @@ -5,17 +5,17 @@ #ifndef nsCoreUtils_h_ #define nsCoreUtils_h_ #include "mozilla/EventForwards.h" #include "mozilla/dom/Element.h" #include "nsIAccessibleEvent.h" #include "nsIContent.h" -#include "nsIDocument.h" // for GetShell() +#include "mozilla/dom/Document.h" // for GetShell() #include "nsIPresShell.h" #include "nsPoint.h" #include "nsTArray.h" class nsRange; class nsTreeColumn; class nsIBoxObject; @@ -24,16 +24,18 @@ class nsIDocShell; class nsITreeBoxObject; class nsIWidget; /** * Core utils. */ class nsCoreUtils { public: + typedef mozilla::dom::Document Document; + /** * Return true if the given node is a label of a control. */ static bool IsLabelWithControl(nsIContent *aContent); /** * Return true if the given node has registered click, mousedown or mouseup * event listeners. @@ -180,32 +182,32 @@ class nsCoreUtils { /** * Return document shell for the given DOM node. */ static already_AddRefed<nsIDocShell> GetDocShellFor(nsINode *aNode); /** * Return true if the given document is root document. */ - static bool IsRootDocument(nsIDocument *aDocument); + static bool IsRootDocument(Document *aDocument); /** * Return true if the given document is content document (not chrome). */ - static bool IsContentDocument(nsIDocument *aDocument); + static bool IsContentDocument(Document *aDocument); /** * Return true if the given document node is for tab document accessible. */ - static bool IsTabDocument(nsIDocument *aDocumentNode); + static bool IsTabDocument(Document *aDocumentNode); /** * Return true if the given document is an error page. */ - static bool IsErrorPage(nsIDocument *aDocument); + static bool IsErrorPage(Document *aDocument); /** * Return presShell for the document containing the given DOM node. */ static nsIPresShell *GetPresShellFor(nsINode *aNode) { return aNode->OwnerDoc()->GetShell(); }
--- a/accessible/generic/Accessible.cpp +++ b/accessible/generic/Accessible.cpp @@ -32,17 +32,17 @@ #include "XULDocument.h" #include "nsIDOMXULButtonElement.h" #include "nsIDOMXULSelectCntrlEl.h" #include "nsIDOMXULSelectCntrlItemEl.h" #include "nsINodeList.h" #include "nsPIDOMWindow.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIContent.h" #include "nsIForm.h" #include "nsIFormControl.h" #include "nsDeckFrame.h" #include "nsLayoutUtils.h" #include "nsIPresShell.h" #include "nsIStringBundle.h" @@ -260,17 +260,17 @@ KeyBinding Accessible::AccessKey() const return KeyBinding(key, KeyBinding::kAlt); case dom::KeyboardEvent_Binding::DOM_VK_META: return KeyBinding(key, KeyBinding::kMeta); default: return KeyBinding(); } // Determine the access modifier used in this context. - nsIDocument* document = mContent->GetUncomposedDoc(); + dom::Document* document = mContent->GetUncomposedDoc(); if (!document) return KeyBinding(); nsCOMPtr<nsIDocShellTreeItem> treeItem(document->GetDocShell()); if (!treeItem) return KeyBinding(); nsresult rv = NS_ERROR_FAILURE; int32_t modifierMask = 0; switch (treeItem->ItemType()) { @@ -1020,31 +1020,31 @@ already_AddRefed<nsIPersistentProperties // Get container-foo computed live region properties based on the closest // container with the live region attribute. Inner nodes override outer nodes // within the same document. The inner nodes can be used to override live // region behavior on more general outer nodes. However, nodes in outer // documents override nodes in inner documents: outer doc author may want to // override properties on a widget they used in an iframe. nsIContent* startContent = mContent; while (startContent) { - nsIDocument* doc = startContent->GetComposedDoc(); + dom::Document* doc = startContent->GetComposedDoc(); if (!doc) break; nsAccUtils::SetLiveContainerAttributes(attributes, startContent, doc->GetRootElement()); // Allow ARIA live region markup from outer documents to override nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = doc->GetDocShell(); if (!docShellTreeItem) break; nsCOMPtr<nsIDocShellTreeItem> sameTypeParent; docShellTreeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent)); if (!sameTypeParent || sameTypeParent == docShellTreeItem) break; - nsIDocument* parentDoc = doc->GetParentDocument(); + dom::Document* parentDoc = doc->GetParentDocument(); if (!parentDoc) break; startContent = parentDoc->FindContentForSubDocument(doc); } if (!mContent->IsElement()) return attributes.forget(); nsAutoString id; @@ -1682,17 +1682,17 @@ Relation Accessible::RelationByType(Rela if (form) { nsCOMPtr<nsIContent> formContent = do_QueryInterface(form->GetDefaultSubmitElement()); return Relation(mDoc, formContent); } } } else { // In XUL, use first <button default="true" .../> in the document - nsIDocument* doc = mContent->OwnerDoc(); + dom::Document* doc = mContent->OwnerDoc(); nsIContent* buttonEl = nullptr; if (doc->IsXULDocument()) { dom::XULDocument* xulDoc = doc->AsXULDocument(); nsCOMPtr<nsIHTMLCollection> possibleDefaultButtons = xulDoc->GetElementsByAttribute(NS_LITERAL_STRING("default"), NS_LITERAL_STRING("true")); if (possibleDefaultButtons) { uint32_t length = possibleDefaultButtons->Length(); @@ -2388,17 +2388,17 @@ Accessible* Accessible::CurrentItem() co // Check for aria-activedescendant, which changes which element has focus. // For activedescendant, the ARIA spec does not require that the user agent // checks whether pointed node is actually a DOM descendant of the element // with the aria-activedescendant attribute. nsAutoString id; if (HasOwnContent() && mContent->IsElement() && mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant, id)) { - nsIDocument* DOMDoc = mContent->OwnerDoc(); + dom::Document* DOMDoc = mContent->OwnerDoc(); dom::Element* activeDescendantElm = DOMDoc->GetElementById(id); if (activeDescendantElm) { DocAccessible* document = Document(); if (document) return document->GetAccessible(activeDescendantElm); } } return nullptr; }
--- a/accessible/generic/ApplicationAccessible.cpp +++ b/accessible/generic/ApplicationAccessible.cpp @@ -120,19 +120,17 @@ void ApplicationAccessible::Init() { if (!windowsById) { return; } for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) { nsGlobalWindowOuter* window = iter.Data(); if (window->GetDocShell() && window->IsRootOuterWindow()) { - nsCOMPtr<nsIDocument> docNode = window->GetExtantDoc(); - - if (docNode) { + if (RefPtr<dom::Document> docNode = window->GetExtantDoc()) { GetAccService()->GetDocAccessible(docNode); // ensure creation } } } } Accessible* ApplicationAccessible::GetSiblingAtOffset(int32_t aOffset, nsresult* aError) const {
--- a/accessible/generic/DocAccessible-inl.h +++ b/accessible/generic/DocAccessible-inl.h @@ -8,17 +8,17 @@ #define mozilla_a11y_DocAccessible_inl_h_ #include "DocAccessible.h" #include "nsAccessibilityService.h" #include "nsAccessiblePivot.h" #include "NotificationController.h" #include "States.h" #include "nsIScrollableFrame.h" -#include "nsIDocumentInlines.h" +#include "mozilla/dom/DocumentInlines.h" #ifdef A11Y_LOG #include "Logging.h" #endif namespace mozilla { namespace a11y {
--- a/accessible/generic/DocAccessible.cpp +++ b/accessible/generic/DocAccessible.cpp @@ -18,17 +18,17 @@ #include "RootAccessible.h" #include "TreeWalker.h" #include "xpcAccessibleDocument.h" #include "nsContentUtils.h" #include "nsIMutableArray.h" #include "nsICommandManager.h" #include "nsIDocShell.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsPIDOMWindow.h" #include "nsIEditingSession.h" #include "nsIFrame.h" #include "nsIInterfaceRequestorUtils.h" #include "nsImageFrame.h" #include "nsIPersistentProperties2.h" #include "nsIPresShell.h" #include "nsIServiceManager.h" @@ -65,17 +65,17 @@ static nsStaticAtom* const kRelationAttr nsGkAtoms::_for, nsGkAtoms::control}; static const uint32_t kRelationAttrsLen = ArrayLength(kRelationAttrs); //////////////////////////////////////////////////////////////////////////////// // Constructor/desctructor -DocAccessible::DocAccessible(nsIDocument* aDocument, nsIPresShell* aPresShell) +DocAccessible::DocAccessible(dom::Document* aDocument, nsIPresShell* aPresShell) : // XXX don't pass a document to the Accessible constructor so that we // don't set mDoc until our vtable is fully setup. If we set mDoc before // setting up the vtable we will call Accessible::AddRef() but not the // overrides of it for subclasses. It is important to call those // overrides to avoid confusing leak checking machinary. HyperTextAccessibleWrap(nullptr, nullptr), // XXX aaronl should we use an algorithm for the initial cache size? mAccessibleCache(kDefaultCacheLength), @@ -367,17 +367,17 @@ void DocAccessible::Init() { #endif // Initialize notification controller. mNotificationController = new NotificationController(this, mPresShell); // Mark the document accessible as loaded if its DOM document was loaded at // this point (this can happen because a11y is started late or DOM document // having no container was loaded. - if (mDocumentNode->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE) + if (mDocumentNode->GetReadyStateEnum() == dom::Document::READYSTATE_COMPLETE) mLoadState |= eDOMLoaded; AddEventListeners(); } void DocAccessible::Shutdown() { if (!mPresShell) // already shutdown return; @@ -456,18 +456,18 @@ nsIFrame* DocAccessible::GetFrame() cons return root; } // DocAccessible protected member nsRect DocAccessible::RelativeBounds(nsIFrame** aRelativeFrame) const { *aRelativeFrame = GetFrame(); - nsIDocument* document = mDocumentNode; - nsIDocument* parentDoc = nullptr; + dom::Document* document = mDocumentNode; + dom::Document* parentDoc = nullptr; nsRect bounds; while (document) { nsIPresShell* presShell = document->GetShell(); if (!presShell) return nsRect(); nsRect scrollPort; nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable(); @@ -1015,17 +1015,17 @@ void DocAccessible::ARIAActiveDescendant aAccessible); } #endif } } void DocAccessible::ContentAppended(nsIContent* aFirstNewContent) {} -void DocAccessible::ContentStateChanged(nsIDocument* aDocument, +void DocAccessible::ContentStateChanged(dom::Document* aDocument, nsIContent* aContent, EventStates aStateMask) { Accessible* accessible = GetAccessible(aContent); if (!accessible) return; if (aStateMask.HasState(NS_EVENT_STATE_CHECKED)) { Accessible* widget = accessible->ContainerWidget(); if (widget && widget->IsSelect()) { @@ -1053,17 +1053,17 @@ void DocAccessible::ContentStateChanged( if (aStateMask.HasState(NS_EVENT_STATE_VISITED)) { RefPtr<AccEvent> event = new AccStateChangeEvent(accessible, states::TRAVERSED, true); FireDelayedEvent(event); } } -void DocAccessible::DocumentStatesChanged(nsIDocument* aDocument, +void DocAccessible::DocumentStatesChanged(dom::Document* aDocument, EventStates aStateMask) {} void DocAccessible::CharacterDataWillChange(nsIContent* aContent, const CharacterDataChangeInfo&) {} void DocAccessible::CharacterDataChanged(nsIContent* aContent, const CharacterDataChangeInfo&) {}
--- a/accessible/generic/DocAccessible.h +++ b/accessible/generic/DocAccessible.h @@ -9,31 +9,35 @@ #include "nsIAccessiblePivot.h" #include "HyperTextAccessibleWrap.h" #include "AccEvent.h" #include "nsAutoPtr.h" #include "nsClassHashtable.h" #include "nsDataHashtable.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIDocumentObserver.h" #include "nsIObserver.h" #include "nsIScrollPositionListener.h" #include "nsITimer.h" #include "nsIWeakReference.h" class nsAccessiblePivot; const uint32_t kDefaultCacheLength = 128; namespace mozilla { class TextEditor; +namespace dom { +class Document; +} + namespace a11y { class DocManager; class NotificationController; class DocAccessibleChild; class RelatedAccIterator; template <class Class, class... Args> class TNotification; @@ -45,32 +49,35 @@ class DocAccessible : public HyperTextAc public nsSupportsWeakReference, public nsIAccessiblePivotObserver { NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DocAccessible, Accessible) NS_DECL_NSIOBSERVER NS_DECL_NSIACCESSIBLEPIVOTOBSERVER + protected: + typedef mozilla::dom::Document Document; + public: - DocAccessible(nsIDocument* aDocument, nsIPresShell* aPresShell); + DocAccessible(Document* aDocument, nsIPresShell* aPresShell); // nsIScrollPositionListener virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) override {} virtual void ScrollPositionDidChange(nscoord aX, nscoord aY) override; // nsIDocumentObserver NS_DECL_NSIDOCUMENTOBSERVER // Accessible virtual void Init(); virtual void Shutdown() override; virtual nsIFrame* GetFrame() const override; virtual nsINode* GetNode() const override { return mDocumentNode; } - nsIDocument* DocumentNode() const { return mDocumentNode; } + Document* DocumentNode() const { return mDocumentNode; } virtual mozilla::a11y::ENameValueFlag Name(nsString& aName) const override; virtual void Description(nsString& aDescription) override; virtual Accessible* FocusedChild() override; virtual mozilla::a11y::role NativeRole() const override; virtual uint64_t NativeState() const override; virtual uint64_t NativeInteractiveState() const override; virtual bool NativelyUnavailable() const override; @@ -128,17 +135,17 @@ class DocAccessible : public HyperTextAc nsPresContext* PresContext() const { return mPresShell->GetPresContext(); } /** * Return true if associated DOM document was loaded and isn't unloading. */ bool IsContentLoaded() const { // eDOMLoaded flag check is used for error pages as workaround to make this // method return correct result since error pages do not receive 'pageshow' - // event and as consequence nsIDocument::IsShowing() returns false. + // event and as consequence Document::IsShowing() returns false. return mDocumentNode && mDocumentNode->IsVisible() && (mDocumentNode->IsShowing() || HasLoadState(eDOMLoaded)); } bool IsHidden() const { return mDocumentNode->Hidden(); } /** * Document load states. @@ -591,17 +598,17 @@ class DocAccessible : public HyperTextAc /** * Cache of accessibles within this document accessible. */ AccessibleHashtable mAccessibleCache; nsDataHashtable<nsPtrHashKey<const nsINode>, Accessible*> mNodeToAccessibleMap; - nsIDocument* mDocumentNode; + Document* mDocumentNode; nsCOMPtr<nsITimer> mScrollWatchTimer; uint16_t mScrollPositionChangedTicks; // Used for tracking scroll events TimeStamp mLastScrollingDispatch; /** * Bit mask of document load states (@see LoadState). */ uint32_t mLoadState : 3;
--- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -1233,17 +1233,17 @@ already_AddRefed<TextEditor> HyperTextAc return nullptr; } nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mContent); nsCOMPtr<nsIEditingSession> editingSession; docShell->GetEditingSession(getter_AddRefs(editingSession)); if (!editingSession) return nullptr; // No editing session interface - nsIDocument* docNode = mDoc->DocumentNode(); + dom::Document* docNode = mDoc->DocumentNode(); RefPtr<HTMLEditor> htmlEditor = editingSession->GetHTMLEditorForWindow(docNode->GetWindow()); return htmlEditor.forget(); } /** * =================== Caret & Selection ====================== */ @@ -1283,17 +1283,17 @@ nsresult HyperTextAccessible::SetSelecti // When selection is done, move the focus to the selection if accessible is // not focusable. That happens when selection is set within hypertext // accessible. if (isFocusable) return NS_OK; nsFocusManager* DOMFocusManager = nsFocusManager::GetFocusManager(); if (DOMFocusManager) { NS_ENSURE_TRUE(mDoc, NS_ERROR_FAILURE); - nsIDocument* docNode = mDoc->DocumentNode(); + dom::Document* docNode = mDoc->DocumentNode(); NS_ENSURE_TRUE(docNode, NS_ERROR_FAILURE); nsCOMPtr<nsPIDOMWindowOuter> window = docNode->GetWindow(); RefPtr<dom::Element> result; DOMFocusManager->MoveFocus( window, nullptr, nsIFocusManager::MOVEFOCUS_CARET, nsIFocusManager::FLAG_BYMOVEFOCUS, getter_AddRefs(result)); }
--- a/accessible/generic/ImageAccessible.cpp +++ b/accessible/generic/ImageAccessible.cpp @@ -8,17 +8,17 @@ #include "nsAccUtils.h" #include "Role.h" #include "AccIterator.h" #include "States.h" #include "imgIContainer.h" #include "imgIRequest.h" #include "nsGenericHTMLElement.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIImageLoadingContent.h" #include "nsIPresShell.h" #include "nsIServiceManager.h" #include "nsIPersistentProperties2.h" #include "nsPIDOMWindow.h" #include "nsIURI.h" using namespace mozilla::a11y; @@ -101,17 +101,17 @@ bool ImageAccessible::DoAction(uint8_t a nsCOMPtr<nsIURI> uri = GetLongDescURI(); if (!uri) return false; nsAutoCString utf8spec; uri->GetSpec(utf8spec); NS_ConvertUTF8toUTF16 spec(utf8spec); - nsIDocument* document = mContent->OwnerDoc(); + dom::Document* document = mContent->OwnerDoc(); nsCOMPtr<nsPIDOMWindowOuter> piWindow = document->GetWindow(); if (!piWindow) return false; nsCOMPtr<nsPIDOMWindowOuter> tmp; return NS_SUCCEEDED(piWindow->Open(spec, EmptyString(), EmptyString(), /* aLoadInfo = */ nullptr, /* aForceNoOpener = */ false, getter_AddRefs(tmp)));
--- a/accessible/generic/OuterDocAccessible.cpp +++ b/accessible/generic/OuterDocAccessible.cpp @@ -32,19 +32,19 @@ OuterDocAccessible::OuterDocAccessible(n #ifdef XP_WIN if (DocAccessibleParent* remoteDoc = RemoteChildDoc()) { remoteDoc->SendParentCOMProxy(); } #endif // Request document accessible for the content document to make sure it's // created. It will appended to outerdoc accessible children asynchronously. - nsIDocument* outerDoc = mContent->GetUncomposedDoc(); + dom::Document* outerDoc = mContent->GetUncomposedDoc(); if (outerDoc) { - nsIDocument* innerDoc = outerDoc->GetSubDocumentFor(mContent); + dom::Document* innerDoc = outerDoc->GetSubDocumentFor(mContent); if (innerDoc) GetAccService()->GetDocAccessible(innerDoc); } } OuterDocAccessible::~OuterDocAccessible() {} //////////////////////////////////////////////////////////////////////////////// // Accessible public (DON'T add methods here)
--- a/accessible/generic/RootAccessible.cpp +++ b/accessible/generic/RootAccessible.cpp @@ -27,17 +27,17 @@ #include "mozilla/dom/Element.h" #include "mozilla/dom/ScriptSettings.h" #include "nsIDocShellTreeItem.h" #include "nsIDocShellTreeOwner.h" #include "mozilla/dom/Event.h" #include "mozilla/dom/EventTarget.h" #include "nsIDOMXULMultSelectCntrlEl.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIPropertyBag2.h" #include "nsIServiceManager.h" #include "nsPIDOMWindow.h" #include "nsIWebBrowserChrome.h" #include "nsReadableUtils.h" #include "nsFocusManager.h" #include "nsGlobalWindow.h" @@ -53,17 +53,17 @@ using namespace mozilla::dom; //////////////////////////////////////////////////////////////////////////////// // nsISupports NS_IMPL_ISUPPORTS_INHERITED(RootAccessible, DocAccessible, nsIDOMEventListener) //////////////////////////////////////////////////////////////////////////////// // Constructor/destructor -RootAccessible::RootAccessible(nsIDocument* aDocument, nsIPresShell* aPresShell) +RootAccessible::RootAccessible(Document* aDocument, nsIPresShell* aPresShell) : DocAccessibleWrap(aDocument, aPresShell) { mType = eRootType; } RootAccessible::~RootAccessible() {} //////////////////////////////////////////////////////////////////////////////// // Accessible @@ -443,17 +443,17 @@ void RootAccessible::Shutdown() { Relation RootAccessible::RelationByType(RelationType aType) const { if (!mDocumentNode || aType != RelationType::EMBEDS) return DocAccessibleWrap::RelationByType(aType); if (nsPIDOMWindowOuter* rootWindow = mDocumentNode->GetWindow()) { nsCOMPtr<nsPIDOMWindowOuter> contentWindow = nsGlobalWindowOuter::Cast(rootWindow)->GetContent(); if (contentWindow) { - nsCOMPtr<nsIDocument> contentDocumentNode = contentWindow->GetDoc(); + RefPtr<Document> contentDocumentNode = contentWindow->GetDoc(); if (contentDocumentNode) { DocAccessible* contentDocument = GetAccService()->GetDocAccessible(contentDocumentNode); if (contentDocument) return Relation(contentDocument); } } }
--- a/accessible/generic/RootAccessible.h +++ b/accessible/generic/RootAccessible.h @@ -6,26 +6,24 @@ #ifndef mozilla_a11y_RootAccessible_h__ #define mozilla_a11y_RootAccessible_h__ #include "HyperTextAccessible.h" #include "DocAccessibleWrap.h" #include "nsIDOMEventListener.h" -class nsIDocument; - namespace mozilla { namespace a11y { class RootAccessible : public DocAccessibleWrap, public nsIDOMEventListener { NS_DECL_ISUPPORTS_INHERITED public: - RootAccessible(nsIDocument* aDocument, nsIPresShell* aPresShell); + RootAccessible(dom::Document* aDocument, nsIPresShell* aPresShell); // nsIDOMEventListener NS_DECL_NSIDOMEVENTLISTENER // Accessible virtual void Shutdown() override; virtual mozilla::a11y::ENameValueFlag Name(nsString& aName) const override; virtual Relation RelationByType(RelationType aType) const override;
--- a/accessible/html/HTMLTableAccessible.cpp +++ b/accessible/html/HTMLTableAccessible.cpp @@ -14,17 +14,17 @@ #include "nsTextEquivUtils.h" #include "Relation.h" #include "Role.h" #include "States.h" #include "TreeWalker.h" #include "mozilla/dom/HTMLTableElement.h" #include "nsIHTMLCollection.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIMutableArray.h" #include "nsIPersistentProperties2.h" #include "nsIPresShell.h" #include "nsITableCellLayout.h" #include "nsFrameSelection.h" #include "nsError.h" #include "nsArrayUtils.h" #include "nsComponentManagerUtils.h"
--- a/accessible/mac/DocAccessibleWrap.h +++ b/accessible/mac/DocAccessibleWrap.h @@ -8,16 +8,16 @@ #include "DocAccessible.h" namespace mozilla { namespace a11y { class DocAccessibleWrap : public DocAccessible { public: - DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell); + DocAccessibleWrap(dom::Document* aDocument, nsIPresShell* aPresShell); virtual ~DocAccessibleWrap(); }; } // namespace a11y } // namespace mozilla #endif
--- a/accessible/mac/DocAccessibleWrap.mm +++ b/accessible/mac/DocAccessibleWrap.mm @@ -5,17 +5,17 @@ #include "DocAccessibleWrap.h" #import "mozAccessible.h" using namespace mozilla::a11y; DocAccessibleWrap:: - DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) : + DocAccessibleWrap(mozilla::dom::Document* aDocument, nsIPresShell* aPresShell) : DocAccessible(aDocument, aPresShell) { } DocAccessibleWrap::~DocAccessibleWrap() { }
--- a/accessible/mac/RootAccessibleWrap.h +++ b/accessible/mac/RootAccessibleWrap.h @@ -12,17 +12,17 @@ #include "RootAccessible.h" namespace mozilla { namespace a11y { class RootAccessibleWrap : public RootAccessible { public: - RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell); + RootAccessibleWrap(dom::Document* aDocument, nsIPresShell* aPresShell); virtual ~RootAccessibleWrap(); Class GetNativeType(); // let's our native accessible get in touch with the // native cocoa view that is our accessible parent. void GetNativeWidget(void** aOutView); };
--- a/accessible/mac/RootAccessibleWrap.mm +++ b/accessible/mac/RootAccessibleWrap.mm @@ -11,17 +11,17 @@ #include "nsObjCExceptions.h" #include "nsIFrame.h" #include "nsView.h" #include "nsIWidget.h" using namespace mozilla::a11y; RootAccessibleWrap:: - RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) : + RootAccessibleWrap(mozilla::dom::Document* aDocument, nsIPresShell* aPresShell) : RootAccessible(aDocument, aPresShell) { } RootAccessibleWrap::~RootAccessibleWrap() { }
--- a/accessible/windows/msaa/AccessibleWrap.cpp +++ b/accessible/windows/msaa/AccessibleWrap.cpp @@ -476,17 +476,17 @@ AccessibleWrap::get_accRole( nsAutoString roleString; // Try the role attribute. content->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::role, roleString); if (roleString.IsEmpty()) { // No role attribute (or it is an empty string). // Use the tag name. - nsIDocument* document = content->GetUncomposedDoc(); + dom::Document* document = content->GetUncomposedDoc(); if (!document) return E_FAIL; dom::NodeInfo* nodeInfo = content->NodeInfo(); nodeInfo->GetName(roleString); // Only append name space if different from that of current document. if (!nodeInfo->NamespaceEquals(document->GetDefaultNamespaceID())) { nsAutoString nameSpaceURI;
--- a/accessible/windows/msaa/DocAccessibleWrap.cpp +++ b/accessible/windows/msaa/DocAccessibleWrap.cpp @@ -20,17 +20,17 @@ using namespace mozilla; using namespace mozilla::a11y; //////////////////////////////////////////////////////////////////////////////// // DocAccessibleWrap //////////////////////////////////////////////////////////////////////////////// -DocAccessibleWrap::DocAccessibleWrap(nsIDocument* aDocument, +DocAccessibleWrap::DocAccessibleWrap(dom::Document* aDocument, nsIPresShell* aPresShell) : DocAccessible(aDocument, aPresShell), mHWND(nullptr) {} DocAccessibleWrap::~DocAccessibleWrap() {} IMPL_IUNKNOWN_QUERY_HEAD(DocAccessibleWrap) if (aIID == IID_ISimpleDOMDocument) { statistics::ISimpleDOMUsed();
--- a/accessible/windows/msaa/DocAccessibleWrap.h +++ b/accessible/windows/msaa/DocAccessibleWrap.h @@ -9,17 +9,17 @@ #include "DocAccessible.h" namespace mozilla { namespace a11y { class DocAccessibleWrap : public DocAccessible { public: - DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell); + DocAccessibleWrap(dom::Document* aDocument, nsIPresShell* aPresShell); virtual ~DocAccessibleWrap(); DECL_IUNKNOWN_INHERITED // IAccessible // Override get_accParent for e10s virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent(
--- a/accessible/windows/msaa/RootAccessibleWrap.cpp +++ b/accessible/windows/msaa/RootAccessibleWrap.cpp @@ -10,17 +10,17 @@ #include "nsCoreUtils.h" #include "nsWinUtils.h" using namespace mozilla::a11y; //////////////////////////////////////////////////////////////////////////////// // Constructor/destructor -RootAccessibleWrap::RootAccessibleWrap(nsIDocument* aDocument, +RootAccessibleWrap::RootAccessibleWrap(dom::Document* aDocument, nsIPresShell* aPresShell) : RootAccessible(aDocument, aPresShell), mOuter(&mInternalUnknown) {} RootAccessibleWrap::~RootAccessibleWrap() {} //////////////////////////////////////////////////////////////////////////////// // Aggregated IUnknown HRESULT
--- a/accessible/windows/msaa/RootAccessibleWrap.h +++ b/accessible/windows/msaa/RootAccessibleWrap.h @@ -9,17 +9,17 @@ #include "mozilla/mscom/Aggregation.h" #include "RootAccessible.h" namespace mozilla { namespace a11y { class RootAccessibleWrap : public RootAccessible { public: - RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell); + RootAccessibleWrap(dom::Document* aDocument, nsIPresShell* aPresShell); virtual ~RootAccessibleWrap(); // RootAccessible virtual void DocumentActivated(DocAccessible* aDocument); /** * This method enables a RootAccessibleWrap to be wrapped by a * LazyInstantiator.
--- a/accessible/windows/msaa/nsWinUtils.cpp +++ b/accessible/windows/msaa/nsWinUtils.cpp @@ -12,17 +12,17 @@ #include "nsAccessibilityService.h" #include "nsCoreUtils.h" #include "mozilla/a11y/DocAccessibleParent.h" #include "mozilla/Preferences.h" #include "nsArrayUtils.h" #include "nsIArray.h" #include "nsICSSDeclaration.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIDocShellTreeItem.h" #include "mozilla/dom/Element.h" #include "nsXULAppAPI.h" #include "ProxyWrappers.h" using namespace mozilla; using namespace mozilla::a11y; using mozilla::dom::Element;
--- a/accessible/xpcom/xpcAccessibilityService.cpp +++ b/accessible/xpcom/xpcAccessibilityService.cpp @@ -187,21 +187,18 @@ xpcAccessibilityService::GetAccessibleFr // Search for an accessible in each of our per document accessible object // caches. If we don't find it, and the given node is itself a document, check // our cache of document accessibles (document cache). Note usually shutdown // document accessibles are not stored in the document cache, however an // "unofficially" shutdown document (i.e. not from DocManager) can still // exist in the document cache. Accessible* accessible = accService->FindAccessibleInCache(aNode); - if (!accessible) { - nsCOMPtr<nsIDocument> document(do_QueryInterface(aNode)); - if (document) { - accessible = mozilla::a11y::GetExistingDocAccessible(document); - } + if (!accessible && aNode->IsDocument()) { + accessible = mozilla::a11y::GetExistingDocAccessible(aNode->AsDocument()); } NS_IF_ADDREF(*aAccessible = ToXPC(accessible)); return NS_OK; } NS_IMETHODIMP xpcAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
--- a/accessible/xpcom/xpcAccessibleDocument.cpp +++ b/accessible/xpcom/xpcAccessibleDocument.cpp @@ -71,17 +71,17 @@ NS_IMETHODIMP xpcAccessibleDocument::GetDocType(nsAString& aType) { if (!Intl()) return NS_ERROR_FAILURE; Intl()->DocType(aType); return NS_OK; } NS_IMETHODIMP -xpcAccessibleDocument::GetDOMDocument(nsIDocument** aDOMDocument) { +xpcAccessibleDocument::GetDOMDocument(dom::Document** aDOMDocument) { NS_ENSURE_ARG_POINTER(aDOMDocument); *aDOMDocument = nullptr; if (!Intl()) return NS_ERROR_FAILURE; if (Intl()->DocumentNode()) NS_ADDREF(*aDOMDocument = Intl()->DocumentNode()); return NS_OK;
--- a/accessible/xpcom/xpcAccessibleDocument.h +++ b/accessible/xpcom/xpcAccessibleDocument.h @@ -35,17 +35,17 @@ class xpcAccessibleDocument : public xpc NS_DECL_ISUPPORTS_INHERITED // nsIAccessibleDocument NS_IMETHOD GetURL(nsAString& aURL) final; NS_IMETHOD GetTitle(nsAString& aTitle) final; NS_IMETHOD GetMimeType(nsAString& aType) final; NS_IMETHOD GetDocType(nsAString& aType) final; - NS_IMETHOD GetDOMDocument(nsIDocument** aDOMDocument) final; + NS_IMETHOD GetDOMDocument(dom::Document** aDOMDocument) final; NS_IMETHOD GetWindow(mozIDOMWindowProxy** aDOMWindow) final; NS_IMETHOD GetParentDocument(nsIAccessibleDocument** aDocument) final; NS_IMETHOD GetChildDocumentCount(uint32_t* aCount) final; NS_IMETHOD GetChildDocumentAt(uint32_t aIndex, nsIAccessibleDocument** aDocument) final; NS_IMETHOD GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor) final; /**
--- a/accessible/xul/XULElementAccessibles.cpp +++ b/accessible/xul/XULElementAccessibles.cpp @@ -201,16 +201,16 @@ uint32_t XULLinkAccessible::EndOffset() already_AddRefed<nsIURI> XULLinkAccessible::AnchorURIAt( uint32_t aAnchorIndex) const { if (aAnchorIndex != 0) return nullptr; nsAutoString href; mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href); nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI(); - nsIDocument* document = mContent->OwnerDoc(); + dom::Document* document = mContent->OwnerDoc(); nsCOMPtr<nsIURI> anchorURI; NS_NewURI(getter_AddRefs(anchorURI), href, document->GetDocumentCharacterSet(), baseURI); return anchorURI.forget(); }
--- a/accessible/xul/XULTabAccessible.cpp +++ b/accessible/xul/XULTabAccessible.cpp @@ -7,17 +7,17 @@ #include "ARIAMap.h" #include "nsAccUtils.h" #include "Relation.h" #include "Role.h" #include "States.h" // NOTE: alphabetically ordered -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIDOMXULSelectCntrlEl.h" #include "nsIDOMXULSelectCntrlItemEl.h" #include "nsIDOMXULRelatedElement.h" #include "nsXULElement.h" #include "mozilla/dom/BindingDeclarations.h" using namespace mozilla::a11y;
--- a/browser/components/aboutconfig/content/aboutconfig.js +++ b/browser/components/aboutconfig/content/aboutconfig.js @@ -5,16 +5,45 @@ ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/Preferences.jsm"); let gDefaultBranch = Services.prefs.getDefaultBranch(""); let gPrefArray; let gPrefRowInEdit; let gPrefInEdit; +class PrefRow { + constructor(name) { + this.name = name; + this.refreshValue(); + } + + refreshValue() { + this.hasUserValue = Services.prefs.prefHasUserValue(this.name); + this.hasDefaultValue = this.hasUserValue ? prefHasDefaultValue(this.name) + : true; + this.isLocked = Services.prefs.prefIsLocked(this.name); + + try { + // This can throw for locked preferences without a default value. + this.value = Preferences.get(this.name); + // We don't know which preferences should be read using getComplexValue, + // so we use a heuristic to determine if this is a localized preference. + if (!this.hasUserValue && + /^chrome:\/\/.+\/locale\/.+\.properties/.test(this.value)) { + // This can throw if there is no value in the localized files. + this.value = Services.prefs.getComplexValue(this.name, + Ci.nsIPrefLocalizedString).data; + } + } catch (ex) { + this.value = ""; + } + } +} + function getPrefName(prefRow) { return prefRow.getAttribute("aria-label"); } document.addEventListener("DOMContentLoaded", () => { if (!Preferences.get("browser.aboutConfig.showWarning")) { loadPrefs(); } @@ -33,38 +62,17 @@ function loadPrefs() { search.type = "text"; search.id = "search"; document.l10n.setAttributes(search, "about-config-search"); document.body.appendChild(search); let prefs = document.createElement("table"); prefs.id = "prefs"; document.body.appendChild(prefs); - gPrefArray = Services.prefs.getChildList("").map(function(name) { - let hasUserValue = Services.prefs.prefHasUserValue(name); - let pref = { - name, - hasUserValue, - hasDefaultValue: hasUserValue ? prefHasDefaultValue(name) : true, - isLocked: Services.prefs.prefIsLocked(name), - }; - // Try in case it's a localized string or locked user added pref - // If an execption is thrown the pref value is set to the empty string. - try { - // Throws an exception in case locked user added pref without default value - pref.value = Preferences.get(name); - // Throws an exception if there is no equivalent value in the localized files for the pref. - if (!pref.hasUserValue && /^chrome:\/\/.+\/locale\/.+\.properties/.test(pref.value)) { - pref.value = Services.prefs.getComplexValue(name, Ci.nsIPrefLocalizedString).data; - } - } catch (ex) { - pref.value = ""; - } - return pref; - }); + gPrefArray = Services.prefs.getChildList("").map(name => new PrefRow(name)); gPrefArray.sort((a, b) => a.name > b.name); search.addEventListener("keypress", e => { if (e.key == "Enter") { filterPrefs(); } }); @@ -75,18 +83,17 @@ function loadPrefs() { } let prefRow = event.target.closest("tr"); let prefName = getPrefName(prefRow); let pref = gPrefArray.find(p => p.name == prefName); let button = event.target.closest("button"); if (button.classList.contains("button-reset")) { // Reset pref and update gPrefArray. Services.prefs.clearUserPref(prefName); - pref.value = Preferences.get(prefName); - pref.hasUserValue = false; + pref.refreshValue(); // Update UI. prefRow.textContent = ""; prefRow.classList.remove("has-user-value"); prefRow.appendChild(getPrefRow(pref)); prefRow.querySelector("td.cell-edit").firstChild.focus(); } else if (button.classList.contains("add-true")) { addNewPref(prefRow.firstChild.innerHTML, true); } else if (button.classList.contains("add-false")) { @@ -97,18 +104,17 @@ function loadPrefs() { button.classList.contains("add-Number") ? 0 : ""); prefRow = [...prefs.getElementsByTagName("tr")] .find(row => row.querySelector("td").textContent == prefName); startEditingPref(prefRow, gPrefArray.find(p => p.name == prefName)); prefRow.querySelector("td.cell-value").firstChild.firstChild.focus(); } else if (button.classList.contains("button-toggle")) { // Toggle the pref and update gPrefArray. Services.prefs.setBoolPref(prefName, !pref.value); - pref.value = !pref.value; - pref.hasUserValue = Services.prefs.prefHasUserValue(pref.name); + pref.refreshValue(); // Update UI. prefRow.textContent = ""; if (pref.hasUserValue) { prefRow.classList.add("has-user-value"); } else { prefRow.classList.remove("has-user-value"); } prefRow.appendChild(getPrefRow(pref)); @@ -291,18 +297,17 @@ function endEditingPref(row) { } newValue = numberValue; Services.prefs.setIntPref(name, newValue); } else { Services.prefs.setStringPref(name, newValue); } // Update gPrefArray. - gPrefInEdit.value = newValue; - gPrefInEdit.hasUserValue = Services.prefs.prefHasUserValue(name); + gPrefInEdit.refreshValue(); // Update UI. row.textContent = ""; if (gPrefInEdit.hasUserValue) { row.classList.add("has-user-value"); } else { row.classList.remove("has-user-value"); } row.appendChild(getPrefRow(gPrefInEdit)); @@ -322,17 +327,12 @@ function prefHasDefaultValue(name) { return true; } } catch (ex) {} return false; } function addNewPref(name, value) { Preferences.set(name, value); - gPrefArray.push({ - name, - value, - hasUserValue: true, - hasDefaultValue: false, - }); + gPrefArray.push(new PrefRow(name)); gPrefArray.sort((a, b) => a.name > b.name); filterPrefs(); }
--- a/browser/components/aboutconfig/test/browser/browser_basic.js +++ b/browser/components/aboutconfig/test/browser/browser_basic.js @@ -1,51 +1,49 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ add_task(async function setup() { await SpecialPowers.pushPrefEnv({ set: [ - ["random.user.pref", "chrome://test/locale/testing.properties"], + ["test.aboutconfig.userValueLikeLocalized", + "chrome://test/locale/testing.properties"], ], }); }); add_task(async function test_load_title() { await AboutConfigTest.withNewTab(async function() { Assert.equal(this.document.title, "about:config"); }); }); add_task(async function test_load_settings() { await AboutConfigTest.withNewTab(async function() { // Test if page contains elements. - Assert.ok(this.getRow("plugins.testmode")); - Assert.ok(this.getRow("dom.vr.enabled")); - Assert.ok(this.getRow("accessibility.AOM.enabled")); + Assert.equal(this.getRow(PREF_NUMBER_DEFAULT_ZERO).value, 0); + Assert.equal(this.getRow(PREF_STRING_DEFAULT_EMPTY).value, ""); // Test if the modified state is displayed for the right prefs. - let prefArray = Services.prefs.getChildList(""); - let nameOfEdited = prefArray.find( - name => Services.prefs.prefHasUserValue(name)); - let nameOfDefault = prefArray.find( - name => !Services.prefs.prefHasUserValue(name)); - Assert.ok(!this.getRow(nameOfDefault).hasClass("has-user-value")); - Assert.ok(this.getRow(nameOfEdited).hasClass("has-user-value")); + Assert.ok(!this.getRow(PREF_BOOLEAN_DEFAULT_TRUE) + .hasClass("has-user-value")); + Assert.ok(this.getRow(PREF_BOOLEAN_USERVALUE_TRUE) + .hasClass("has-user-value")); - // Test to see if values are localized. + // Test to see if values are localized, sampling from different files. If + // any of these are removed or their value changes, just update the value + // here or point to a different preference in the same file. Assert.equal(this.getRow("font.language.group").value, "x-western"); Assert.equal(this.getRow("intl.ellipsis").value, "\u2026"); Assert.equal( this.getRow("gecko.handlerService.schemes.mailto.1.uriTemplate").value, "https://mail.google.com/mail/?extsrc=mailto&url=%s"); // Test to see if user created value is not empty string when it matches // /^chrome:\/\/.+\/locale\/.+\.properties/. - Assert.equal(this.getRow("random.user.pref").value, + Assert.equal(this.getRow("test.aboutconfig.userValueLikeLocalized").value, "chrome://test/locale/testing.properties"); // Test to see if empty string when value matches // /^chrome:\/\/.+\/locale\/.+\.properties/ and an exception is thrown. - Assert.equal(this.getRow("gecko.handlerService.schemes.irc.1.name").value, - ""); + Assert.equal(this.getRow(PREF_STRING_LOCALIZED_MISSING).value, ""); }); });
--- a/browser/components/aboutconfig/test/browser/browser_edit.js +++ b/browser/components/aboutconfig/test/browser/browser_edit.js @@ -6,19 +6,19 @@ add_task(async function setup() { set: [ ["test.aboutconfig.modify.boolean", true], ["test.aboutconfig.modify.number", 1337], ["test.aboutconfig.modify.string", "the answer to the life the universe and everything"], ], }); registerCleanupFunction(() => { - Services.prefs.clearUserPref("accessibility.typeaheadfind.autostart"); - Services.prefs.clearUserPref("accessibility.typeaheadfind.soundURL"); - Services.prefs.clearUserPref("accessibility.typeaheadfind.casesensitive"); + Services.prefs.clearUserPref(PREF_BOOLEAN_DEFAULT_TRUE); + Services.prefs.clearUserPref(PREF_NUMBER_DEFAULT_ZERO); + Services.prefs.clearUserPref(PREF_STRING_DEFAULT_EMPTY); }); }); add_task(async function test_add_user_pref() { await AboutConfigTest.withNewTab(async function() { Assert.ok(!Services.prefs.getChildList("").find(pref => pref == "testPref")); for (let [buttonSelector, expectedValue] of [ @@ -35,101 +35,112 @@ add_task(async function test_add_user_pr } }); }); add_task(async function test_delete_user_pref() { Services.prefs.setBoolPref("userAddedPref", true); await AboutConfigTest.withNewTab(async function() { let row = this.getRow("userAddedPref"); - row.element.lastChild.lastChild.click(); + row.resetColumnButton.click(); Assert.ok(!this.getRow("userAddedPref")); Assert.ok(!Services.prefs.getChildList("").includes("userAddedPref")); // Search for nothing to test gPrefArray this.search(); Assert.ok(!this.getRow("userAddedPref")); }); }); add_task(async function test_reset_user_pref() { - await SpecialPowers.pushPrefEnv({"set": [["browser.autofocus", false]]}); + await SpecialPowers.pushPrefEnv({ + "set": [ + [PREF_BOOLEAN_DEFAULT_TRUE, false], + [PREF_STRING_LOCALIZED_MISSING, "user-value"], + ], + }); await AboutConfigTest.withNewTab(async function() { - let testPref = "browser.autofocus"; // Click reset. - let row = this.getRow(testPref); - row.element.lastChild.lastChild.click(); + let row = this.getRow(PREF_BOOLEAN_DEFAULT_TRUE); + row.resetColumnButton.click(); // Check new layout and reset. Assert.ok(!row.hasClass("has-user-value")); - Assert.equal(row.element.lastChild.childNodes.length, 0); - Assert.ok(!Services.prefs.prefHasUserValue(testPref)); - Assert.equal(this.getRow(testPref).value, "" + Preferences.get(testPref)); + Assert.ok(!row.resetColumnButton); + Assert.ok(!Services.prefs.prefHasUserValue(PREF_BOOLEAN_DEFAULT_TRUE)); + Assert.equal(this.getRow(PREF_BOOLEAN_DEFAULT_TRUE).value, "true"); // Search for nothing to test gPrefArray this.search(); - row = this.getRow(testPref); + row = this.getRow(PREF_BOOLEAN_DEFAULT_TRUE); Assert.ok(!row.hasClass("has-user-value")); - Assert.equal(row.element.lastChild.childNodes.length, 0); - Assert.equal(this.getRow(testPref).value, "" + Preferences.get(testPref)); + Assert.ok(!row.resetColumnButton); + Assert.equal(this.getRow(PREF_BOOLEAN_DEFAULT_TRUE).value, "true"); + + // Clicking reset on a localized preference without a corresponding value. + row = this.getRow(PREF_STRING_LOCALIZED_MISSING); + Assert.equal(row.value, "user-value"); + row.resetColumnButton.click(); + // Check new layout and reset. + Assert.ok(!row.hasClass("has-user-value")); + Assert.ok(!row.resetColumnButton); + Assert.ok(!Services.prefs.prefHasUserValue(PREF_STRING_LOCALIZED_MISSING)); + Assert.equal(this.getRow(PREF_STRING_LOCALIZED_MISSING).value, ""); }); }); add_task(async function test_modify() { await AboutConfigTest.withNewTab(async function() { // Test toggle for boolean prefs. for (let nameOfBoolPref of [ "test.aboutconfig.modify.boolean", - "accessibility.typeaheadfind.autostart", + PREF_BOOLEAN_DEFAULT_TRUE, ]) { let row = this.getRow(nameOfBoolPref); // Do this a two times to reset the pref. for (let i = 0; i < 2; i++) { - row.querySelector("td.cell-edit").firstChild.click(); + row.editColumnButton.click(); // Check new layout and saving in backend. Assert.equal(this.getRow(nameOfBoolPref).value, "" + Preferences.get(nameOfBoolPref)); let prefHasUserValue = Services.prefs.prefHasUserValue(nameOfBoolPref); Assert.equal(row.hasClass("has-user-value"), prefHasUserValue); - Assert.equal(row.element.lastChild.childNodes.length > 0, prefHasUserValue); + Assert.equal(!!row.resetColumnButton, prefHasUserValue); } } // Test abort of edit by starting with string and continuing with editing Int pref. let row = this.getRow("test.aboutconfig.modify.string"); - row.querySelector("td.cell-edit").firstChild.click(); - row.querySelector("td.cell-value").firstChild.firstChild.value = "test"; + row.editColumnButton.click(); + row.valueInput.value = "test"; let intRow = this.getRow("test.aboutconfig.modify.number"); - intRow.querySelector("td.cell-edit").firstChild.click(); - Assert.equal(intRow.querySelector("td.cell-value").firstChild.firstChild.value, + intRow.editColumnButton.click(); + Assert.equal(intRow.valueInput.value, Preferences.get("test.aboutconfig.modify.number")); - Assert.equal(this.getRow("test.aboutconfig.modify.string").value, - "" + Preferences.get("test.aboutconfig.modify.string")); - Assert.equal(row.querySelector("td.cell-value").textContent, - Preferences.get("test.aboutconfig.modify.string")); + Assert.ok(!row.valueInput); + Assert.equal(row.value, Preferences.get("test.aboutconfig.modify.string")); // Test regex check for Int pref. - intRow.querySelector("td.cell-value").firstChild.firstChild.value += "a"; - intRow.querySelector("td.cell-edit").firstChild.click(); - Assert.ok(!intRow.querySelector("td.cell-value").firstChild.firstChild.checkValidity()); + intRow.valueInput.value += "a"; + intRow.editColumnButton.click(); + Assert.ok(!intRow.valueInput.checkValidity()); // Test correct saving and DOM-update. for (let prefName of [ "test.aboutconfig.modify.string", "test.aboutconfig.modify.number", - "accessibility.typeaheadfind.soundURL", - "accessibility.typeaheadfind.casesensitive", + PREF_NUMBER_DEFAULT_ZERO, + PREF_STRING_DEFAULT_EMPTY, ]) { row = this.getRow(prefName); // Activate edit and check displaying. - row.querySelector("td.cell-edit").firstChild.click(); - Assert.equal(row.querySelector("td.cell-value").firstChild.firstChild.value, - Preferences.get(prefName)); - row.querySelector("td.cell-value").firstChild.firstChild.value = "42"; + row.editColumnButton.click(); + Assert.equal(row.valueInput.value, Preferences.get(prefName)); + row.valueInput.value = "42"; // Save and check saving. - row.querySelector("td.cell-edit").firstChild.click(); + row.editColumnButton.click(); Assert.equal(row.value, "" + Preferences.get(prefName)); let prefHasUserValue = Services.prefs.prefHasUserValue(prefName); - Assert.equal(row.element.lastChild.childNodes.length > 0, prefHasUserValue); + Assert.equal(!!row.resetColumnButton, prefHasUserValue); Assert.equal(row.hasClass("has-user-value"), prefHasUserValue); } }); });
--- a/browser/components/aboutconfig/test/browser/browser_locked.js +++ b/browser/components/aboutconfig/test/browser/browser_locked.js @@ -1,51 +1,54 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +const PREF_STRING_NO_DEFAULT = "test.aboutconfig.a"; + add_task(async function setup() { await SpecialPowers.pushPrefEnv({ set: [ - ["test.aboutconfig.a", "some value"], + [PREF_STRING_NO_DEFAULT, "some value"], ], }); }); add_task(async function test_locked() { registerCleanupFunction(() => { - Services.prefs.unlockPref("browser.search.searchEnginesURL"); - Services.prefs.unlockPref("test.aboutconfig.a"); - Services.prefs.unlockPref("accessibility.AOM.enabled"); + Services.prefs.unlockPref(PREF_STRING_DEFAULT_NOTEMPTY); + Services.prefs.unlockPref(PREF_BOOLEAN_DEFAULT_TRUE); + Services.prefs.unlockPref(PREF_STRING_NO_DEFAULT); }); - Services.prefs.lockPref("browser.search.searchEnginesURL"); - Services.prefs.lockPref("test.aboutconfig.a"); - Services.prefs.lockPref("accessibility.AOM.enabled"); + Services.prefs.lockPref(PREF_STRING_DEFAULT_NOTEMPTY); + Services.prefs.lockPref(PREF_BOOLEAN_DEFAULT_TRUE); + Services.prefs.lockPref(PREF_STRING_NO_DEFAULT); + await AboutConfigTest.withNewTab(async function() { // Test locked default string pref. - let lockedPref = this.getRow("browser.search.searchEnginesURL"); + let lockedPref = this.getRow(PREF_STRING_DEFAULT_NOTEMPTY); Assert.ok(lockedPref.hasClass("locked")); - Assert.equal(lockedPref.value, "https://addons.mozilla.org/%LOCALE%/firefox/search-engines/"); - Assert.ok(lockedPref.firstButton.classList.contains("button-edit")); - Assert.ok(lockedPref.firstButton.disabled); + Assert.equal(lockedPref.value, PREF_STRING_DEFAULT_NOTEMPTY_VALUE); + Assert.ok(lockedPref.editColumnButton.classList.contains("button-edit")); + Assert.ok(lockedPref.editColumnButton.disabled); // Test locked default boolean pref. - lockedPref = this.getRow("accessibility.AOM.enabled"); + lockedPref = this.getRow(PREF_BOOLEAN_DEFAULT_TRUE); Assert.ok(lockedPref.hasClass("locked")); - Assert.equal(lockedPref.value, "false"); - Assert.ok(lockedPref.firstButton.classList.contains("button-toggle")); - Assert.ok(lockedPref.firstButton.disabled); + Assert.equal(lockedPref.value, "true"); + Assert.ok(lockedPref.editColumnButton.classList.contains("button-toggle")); + Assert.ok(lockedPref.editColumnButton.disabled); // Test locked user added pref. - lockedPref = this.getRow("test.aboutconfig.a"); + lockedPref = this.getRow(PREF_STRING_NO_DEFAULT); Assert.ok(lockedPref.hasClass("locked")); Assert.equal(lockedPref.value, ""); - Assert.ok(lockedPref.firstButton.classList.contains("button-edit")); - Assert.ok(lockedPref.firstButton.disabled); + Assert.ok(lockedPref.editColumnButton.classList.contains("button-edit")); + Assert.ok(lockedPref.editColumnButton.disabled); - // Test pref not locked - let unlockedPref = this.getRow("accessibility.indicator.enabled"); + // Test pref not locked. + let unlockedPref = this.getRow(PREF_BOOLEAN_USERVALUE_TRUE); Assert.ok(!unlockedPref.hasClass("locked")); - Assert.equal(unlockedPref.value, "false"); - Assert.ok(unlockedPref.firstButton.classList.contains("button-toggle")); - Assert.ok(!unlockedPref.firstButton.disabled); + Assert.equal(unlockedPref.value, "true"); + Assert.ok(unlockedPref.editColumnButton.classList.contains("button-toggle")); + Assert.ok(!unlockedPref.editColumnButton.disabled); }); });
--- a/browser/components/aboutconfig/test/browser/browser_search.js +++ b/browser/components/aboutconfig/test/browser/browser_search.js @@ -9,17 +9,16 @@ add_task(async function setup() { ["test.aboutconfig.b", "test value 3"], ], }); }); add_task(async function test_search() { await AboutConfigTest.withNewTab(async function() { let prefArray = Services.prefs.getChildList(""); - await this.document.querySelector("button").click(); // The total number of preferences may change at any time because of // operations running in the background, so we only test approximately. // The change in count would be because of one or two added preferences, // but we tolerate a difference of up to 50 preferences just to be safe. // We want thousands of prefs instead of a few dozen that are filtered. Assert.greater(this.rows.length, prefArray.length - 50);
--- a/browser/components/aboutconfig/test/browser/head.js +++ b/browser/components/aboutconfig/test/browser/head.js @@ -1,15 +1,27 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; ChromeUtils.import("resource://gre/modules/Preferences.jsm", this); +// List of default preferences that can be used for tests, chosen because they +// have little or no side-effects when they are modified for a brief time. If +// any of these preferences are removed or their default state changes, just +// update the constant to point to a different preference with the same default. +const PREF_BOOLEAN_DEFAULT_TRUE = "accessibility.typeaheadfind.manual"; +const PREF_BOOLEAN_USERVALUE_TRUE = "browser.dom.window.dump.enabled"; +const PREF_NUMBER_DEFAULT_ZERO = "accessibility.typeaheadfind.casesensitive"; +const PREF_STRING_DEFAULT_EMPTY = "browser.helperApps.neverAsk.openFile"; +const PREF_STRING_DEFAULT_NOTEMPTY = "accessibility.typeaheadfind.soundURL"; +const PREF_STRING_DEFAULT_NOTEMPTY_VALUE = "beep"; +const PREF_STRING_LOCALIZED_MISSING = "gecko.handlerService.schemes.irc.1.name"; + class AboutConfigRowTest { constructor(element) { this.element = element; } querySelector(selector) { return this.element.querySelector(selector); } @@ -17,18 +29,36 @@ class AboutConfigRowTest { get name() { return this.querySelector("td").textContent; } get value() { return this.querySelector("td.cell-value").textContent; } - get firstButton() { - return this.querySelector("button"); + /** + * Text input field when the row is in edit mode. + */ + get valueInput() { + return this.querySelector("td.cell-value input"); + } + + /** + * This is normally "edit" or "toggle" based on the preference type, or "save" + * when the row is in edit mode. + */ + get editColumnButton() { + return this.querySelector("td.cell-edit > button"); + } + + /** + * This can be "reset" or "delete" based on whether a default exists. + */ + get resetColumnButton() { + return this.querySelector("td:last-child > button"); } hasClass(className) { return this.element.classList.contains(className); } } class AboutConfigTest {
--- a/browser/components/shell/nsMacShellService.cpp +++ b/browser/components/shell/nsMacShellService.cpp @@ -1,16 +1,16 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsDirectoryServiceDefs.h" #include "nsIImageLoadingContent.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIContent.h" #include "nsILocalFileMac.h" #include "nsIObserverService.h" #include "nsIPrefService.h" #include "nsIServiceManager.h" #include "nsIStringBundle.h" #include "nsIURL.h" #include "nsIWebBrowserPersist.h"
--- a/browser/components/tests/browser/browser.ini +++ b/browser/components/tests/browser/browser.ini @@ -1,10 +1,9 @@ [DEFAULT] [browser_bug538331.js] skip-if = !updater reason = test depends on update channel [browser_contentpermissionprompt.js] [browser_default_bookmark_toolbar_visibility.js] [browser_initial_tab_remoteType.js] -skip-if = verify && !debug && os == 'mac' # Bug 1514778 [browser_urlbar_matchBuckets_migration60.js]
--- a/caps/BasePrincipal.cpp +++ b/caps/BasePrincipal.cpp @@ -180,17 +180,17 @@ BasePrincipal::SetCsp(nsIContentSecurity return NS_ERROR_ALREADY_INITIALIZED; } mCSP = aCsp; return NS_OK; } NS_IMETHODIMP -BasePrincipal::EnsureCSP(nsIDocument* aDocument, +BasePrincipal::EnsureCSP(dom::Document* aDocument, nsIContentSecurityPolicy** aCSP) { if (mCSP) { // if there is a CSP already associated with this principal // then just return that - do not overwrite it!!! NS_IF_ADDREF(*aCSP = mCSP); return NS_OK; } @@ -208,17 +208,17 @@ BasePrincipal::EnsureCSP(nsIDocument* aD NS_IMETHODIMP BasePrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) { NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP); return NS_OK; } NS_IMETHODIMP -BasePrincipal::EnsurePreloadCSP(nsIDocument* aDocument, +BasePrincipal::EnsurePreloadCSP(dom::Document* aDocument, nsIContentSecurityPolicy** aPreloadCSP) { if (mPreloadCSP) { // if there is a speculative CSP already associated with this principal // then just return that - do not overwrite it!!! NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP); return NS_OK; }
--- a/caps/BasePrincipal.h +++ b/caps/BasePrincipal.h @@ -16,16 +16,19 @@ class nsAtom; class nsIContentSecurityPolicy; class nsIObjectOutputStream; class nsIObjectInputStream; class nsIURI; class ExpandedPrincipal; namespace mozilla { +namespace dom { +class Document; +} namespace extensions { class WebExtensionPolicy; } class BasePrincipal; // Codebase principals (and codebase principals embedded within expanded // principals) stored in SiteIdentifier are guaranteed to contain only the @@ -100,20 +103,20 @@ class BasePrincipal : public nsJSPrincip bool* _retval) final; NS_IMETHOD SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* other, bool* _retval) final; NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) final; NS_IMETHOD GetAddonPolicy(nsISupports** aResult) final; NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override; NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override; - NS_IMETHOD EnsureCSP(nsIDocument* aDocument, + NS_IMETHOD EnsureCSP(dom::Document* aDocument, nsIContentSecurityPolicy** aCSP) override; NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override; - NS_IMETHOD EnsurePreloadCSP(nsIDocument* aDocument, + NS_IMETHOD EnsurePreloadCSP(dom::Document* aDocument, nsIContentSecurityPolicy** aCSP) override; NS_IMETHOD GetCspJSON(nsAString& outCSPinJSON) override; NS_IMETHOD GetIsNullPrincipal(bool* aResult) override; NS_IMETHOD GetIsCodebasePrincipal(bool* aResult) override; NS_IMETHOD GetIsExpandedPrincipal(bool* aResult) override; NS_IMETHOD GetIsSystemPrincipal(bool* aResult) override; NS_IMETHOD GetIsAddonOrExpandedAddonPrincipal(bool* aResult) override; NS_IMETHOD GetOriginAttributes(JSContext* aCx,
--- a/caps/SystemPrincipal.cpp +++ b/caps/SystemPrincipal.cpp @@ -61,30 +61,30 @@ NS_IMETHODIMP SystemPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) { // Never destroy an existing CSP on the principal. // This method should only be called in rare cases. return NS_ERROR_FAILURE; } NS_IMETHODIMP -SystemPrincipal::EnsureCSP(nsIDocument* aDocument, +SystemPrincipal::EnsureCSP(dom::Document* aDocument, nsIContentSecurityPolicy** aCSP) { // CSP on a system principal makes no sense return NS_ERROR_FAILURE; } NS_IMETHODIMP SystemPrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) { *aPreloadCSP = nullptr; return NS_OK; } NS_IMETHODIMP -SystemPrincipal::EnsurePreloadCSP(nsIDocument* aDocument, +SystemPrincipal::EnsurePreloadCSP(dom::Document* aDocument, nsIContentSecurityPolicy** aPreloadCSP) { // CSP on a system principal makes no sense return NS_ERROR_FAILURE; } NS_IMETHODIMP SystemPrincipal::GetDomain(nsIURI** aDomain) { *aDomain = nullptr;
--- a/caps/SystemPrincipal.h +++ b/caps/SystemPrincipal.h @@ -35,20 +35,20 @@ class SystemPrincipal final : public Bas NS_DECL_NSISERIALIZABLE NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override; uint32_t GetHashValue() override; NS_IMETHOD GetURI(nsIURI** aURI) override; NS_IMETHOD GetDomain(nsIURI** aDomain) override; NS_IMETHOD SetDomain(nsIURI* aDomain) override; NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override; NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override; - NS_IMETHOD EnsureCSP(nsIDocument* aDocument, + NS_IMETHOD EnsureCSP(dom::Document* aDocument, nsIContentSecurityPolicy** aCSP) override; NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override; - NS_IMETHOD EnsurePreloadCSP(nsIDocument* aDocument, + NS_IMETHOD EnsurePreloadCSP(dom::Document* aDocument, nsIContentSecurityPolicy** aCSP) override; NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override; NS_IMETHOD GetAddonId(nsAString& aAddonId) override; virtual nsresult GetScriptLocation(nsACString& aStr) override; nsresult GetSiteIdentifier(SiteIdentifier& aSite) override { aSite.Init(this);
--- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -385,17 +385,17 @@ nsresult nsScriptSecurityManager::GetCha * that may or may not inherit)." */ NS_IMETHODIMP nsScriptSecurityManager::GetChannelURIPrincipal(nsIChannel* aChannel, nsIPrincipal** aPrincipal) { MOZ_ASSERT(aChannel, "Must have channel!"); // Get the principal from the URI. Make sure this does the same thing - // as nsIDocument::Reset and XULDocument::StartDocumentLoad. + // as Document::Reset and XULDocument::StartDocumentLoad. nsCOMPtr<nsIURI> uri; nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsILoadInfo> loadInfo; aChannel->GetLoadInfo(getter_AddRefs(loadInfo)); // Inherit the origin attributes from loadInfo.
--- a/chrome/nsChromeRegistry.cpp +++ b/chrome/nsChromeRegistry.cpp @@ -13,17 +13,17 @@ #include "nsEscape.h" #include "nsNetUtil.h" #include "nsString.h" #include "nsQueryObject.h" #include "mozilla/dom/URL.h" #include "nsDOMWindowList.h" #include "nsIConsoleService.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIDOMWindow.h" #include "nsIObserverService.h" #include "nsIPresShell.h" #include "nsIScriptError.h" #include "nsIWindowMediator.h" #include "nsIPrefService.h" #include "mozilla/Preferences.h" #include "mozilla/Printf.h" @@ -34,16 +34,17 @@ #include "unicode/uloc.h" nsChromeRegistry* nsChromeRegistry::gChromeRegistry; // DO NOT use namespace mozilla; it'll break due to a naming conflict between // mozilla::TextRange and a TextRange in OSX headers. using mozilla::StyleSheet; +using mozilla::dom::Document; using mozilla::dom::IsChromeURI; using mozilla::dom::Location; //////////////////////////////////////////////////////////////////////////////// void nsChromeRegistry::LogMessage(const char* aMsg, ...) { nsCOMPtr<nsIConsoleService> console( do_GetService(NS_CONSOLESERVICE_CONTRACTID)); @@ -270,17 +271,17 @@ nsChromeRegistry::ConvertChromeURL(nsIUR } //////////////////////////////////////////////////////////////////////// // theme stuff static void FlushSkinBindingsForWindow(nsPIDOMWindowOuter* aWindow) { // Get the document. - nsCOMPtr<nsIDocument> document = aWindow->GetDoc(); + RefPtr<Document> document = aWindow->GetDoc(); if (!document) return; // Annihilate all XBL bindings. document->FlushSkinBindings(); } // XXXbsmedberg: move this to nsIWindowMediator NS_IMETHODIMP nsChromeRegistry::RefreshSkins() { @@ -334,17 +335,17 @@ nsresult nsChromeRegistry::RefreshWindow uint32_t length = frames->GetLength(); for (uint32_t j = 0; j < length; j++) { nsCOMPtr<nsPIDOMWindowOuter> piWindow = frames->IndexedGetter(j); RefreshWindow(piWindow); } nsresult rv; // Get the document. - nsCOMPtr<nsIDocument> document = aWindow->GetDoc(); + RefPtr<Document> document = aWindow->GetDoc(); if (!document) return NS_OK; // Deal with the agent sheets first. Have to do all the style sets by hand. nsCOMPtr<nsIPresShell> shell = document->GetShell(); if (shell) { // Reload only the chrome URL agent style sheets. nsTArray<RefPtr<StyleSheet>> agentSheets; rv = shell->GetAgentStyleSheets(agentSheets);
--- a/devtools/client/shared/widgets/Chart.js +++ b/devtools/client/shared/widgets/Chart.js @@ -69,17 +69,17 @@ function PieTableChart(node, pie, table) this.pie = pie; this.table = table; EventEmitter.decorate(this); } /** * Creates the DOM for a pie+table chart. * - * @param nsIDocument document + * @param Document document * The document responsible with creating the DOM. * @param object * An object containing all or some of the following properties: * - title: a string displayed as the table chart's (description)/local * - diameter: the diameter of the pie chart, in pixels * - data: an array of items used to display each slice in the pie * and each row in the table; * @see `createPieChart` and `createTableChart` for details. @@ -156,17 +156,17 @@ function createPieTableChart(document, }); return proxy; } /** * Creates the DOM for a pie chart based on the specified properties. * - * @param nsIDocument document + * @param Document document * The document responsible with creating the DOM. * @param object * An object containing all or some of the following properties: * - data: an array of items used to display each slice; all the items * should be objects containing a `size` and a `label` property. * e.g: [{ * size: 1, * label: "foo" @@ -288,17 +288,17 @@ function createPieChart(document, { data } return proxy; } /** * Creates the DOM for a table chart based on the specified properties. * - * @param nsIDocument document + * @param Document document * The document responsible with creating the DOM. * @param object * An object containing all or some of the following properties: * - title: a string displayed as the chart's (description)/local * - data: an array of items used to display each row; all the items * should be objects representing columns, for which the * properties' values will be displayed in each cell of a row. * e.g: [{
--- a/devtools/docs/getting-started/README.md +++ b/devtools/docs/getting-started/README.md @@ -2,11 +2,11 @@ 1. Learn [where the code is](./where-is-the-code.md) and about the [architecture](./architecture-overview.md) of the tools. 2. [Set up your machine](./build.md) to build the tools, then [configure a development profile](development-profiles.md). 3. You can now experiment by changing things and rebuilding, look at the [files and directories overview](../files/README.md) or you could also [find something to work on](../bugs-issues.md). ## Additional documentation * [MDN Web Docs](http://developer.mozilla.org/) (also known as *MDN*) has a lot of information about XUL elements, HTML, JS, DOM, Web APIs, Gecko-specific APIs, and more. -* [DXR](http://dxr.mozilla.org/mozilla-central/source/) is a source code search engine - search for symbols you want to learn about, eg. `nsIDocument`. [Searchfox](http://searchfox.org/mozilla-central/source) is an alternative. +* [DXR](http://dxr.mozilla.org/mozilla-central/source/) is a source code search engine - search for symbols you want to learn about, eg. `Document`. [Searchfox](http://searchfox.org/mozilla-central/source) is an alternative. It is a good idea to [add smart keyword searches](https://support.mozilla.org/en-US/kb/how-search-from-address-bar) for DXR and MDN, so you can search faster.
--- a/docshell/base/nsDSURIContentListener.cpp +++ b/docshell/base/nsDSURIContentListener.cpp @@ -5,17 +5,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsDocShell.h" #include "nsDSURIContentListener.h" #include "nsIChannel.h" #include "nsServiceManagerUtils.h" #include "nsDocShellCID.h" #include "nsIWebNavigationInfo.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIDOMWindow.h" #include "nsIHttpChannel.h" #include "nsError.h" #include "nsContentSecurityManager.h" #include "nsDocShellLoadTypes.h" #include "nsIInterfaceRequestor.h" #include "nsIMultiPartChannel.h"
--- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -77,17 +77,17 @@ #include "nsIContent.h" #include "nsIContentInlines.h" #include "nsIContentSecurityPolicy.h" #include "nsIContentViewer.h" #include "nsIController.h" #include "nsICookieService.h" #include "nsIDocShellTreeItem.h" #include "nsIDocShellTreeOwner.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIDocumentLoaderFactory.h" #include "nsIDOMWindow.h" #include "nsIEditingSession.h" #include "nsIExternalProtocolService.h" #include "nsIFormPOSTActionChannel.h" #include "nsIFrame.h" #include "nsIGlobalObject.h" #include "nsIHttpChannel.h" @@ -563,33 +563,33 @@ nsDocShell::GetInterface(const nsIID& aI *aSink = mContentListener; } else if ((aIID.Equals(NS_GET_IID(nsIScriptGlobalObject)) || aIID.Equals(NS_GET_IID(nsIGlobalObject)) || aIID.Equals(NS_GET_IID(nsPIDOMWindowOuter)) || aIID.Equals(NS_GET_IID(mozIDOMWindowProxy)) || aIID.Equals(NS_GET_IID(nsIDOMWindow))) && NS_SUCCEEDED(EnsureScriptEnvironment())) { return mScriptGlobal->QueryInterface(aIID, aSink); - } else if (aIID.Equals(NS_GET_IID(nsIDocument)) && + } else if (aIID.Equals(NS_GET_IID(Document)) && NS_SUCCEEDED(EnsureContentViewer())) { - nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument(); + RefPtr<Document> doc = mContentViewer->GetDocument(); doc.forget(aSink); return *aSink ? NS_OK : NS_NOINTERFACE; } else if (aIID.Equals(NS_GET_IID(nsIApplicationCacheContainer))) { *aSink = nullptr; // Return application cache associated with this docshell, if any nsCOMPtr<nsIContentViewer> contentViewer; GetContentViewer(getter_AddRefs(contentViewer)); if (!contentViewer) { return NS_ERROR_NO_INTERFACE; } - nsCOMPtr<nsIDocument> doc = contentViewer->GetDocument(); + RefPtr<Document> doc = contentViewer->GetDocument(); NS_ASSERTION(doc, "Should have a document."); if (!doc) { return NS_ERROR_NO_INTERFACE; } #if defined(DEBUG) MOZ_LOG( gDocShellLog, LogLevel::Debug, @@ -1025,21 +1025,21 @@ nsDOMNavigationTiming* nsDocShell::GetNa if (nsContentUtils::GetCurrentJSContext() && nsContentUtils::IsCallerChrome()) { return true; } MOZ_ASSERT(aOriginTreeItem && aTargetTreeItem, "need two docshells"); // Get origin document principal - nsCOMPtr<nsIDocument> originDocument = aOriginTreeItem->GetDocument(); + RefPtr<Document> originDocument = aOriginTreeItem->GetDocument(); NS_ENSURE_TRUE(originDocument, false); // Get target principal - nsCOMPtr<nsIDocument> targetDocument = aTargetTreeItem->GetDocument(); + RefPtr<Document> targetDocument = aTargetTreeItem->GetDocument(); NS_ENSURE_TRUE(targetDocument, false); bool equal; nsresult rv = originDocument->NodePrincipal()->Equals( targetDocument->NodePrincipal(), &equal); if (NS_SUCCEEDED(rv) && equal) { return true; } @@ -1204,31 +1204,31 @@ bool nsDocShell::SetCurrentURI(nsIURI* a } NS_IMETHODIMP nsDocShell::GetCharset(nsACString& aCharset) { aCharset.Truncate(); nsIPresShell* presShell = GetPresShell(); NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); - nsIDocument* doc = presShell->GetDocument(); + Document* doc = presShell->GetDocument(); NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); doc->GetDocumentCharacterSet()->Name(aCharset); return NS_OK; } NS_IMETHODIMP nsDocShell::GatherCharsetMenuTelemetry() { nsCOMPtr<nsIContentViewer> viewer; GetContentViewer(getter_AddRefs(viewer)); if (!viewer) { return NS_OK; } - nsIDocument* doc = viewer->GetDocument(); + Document* doc = viewer->GetDocument(); if (!doc || doc->WillIgnoreCharsetOverride()) { return NS_OK; } Telemetry::ScalarSet(Telemetry::ScalarID::ENCODING_OVERRIDE_USED, true); bool isFileURL = false; nsIURI* url = doc->GetOriginalURI(); @@ -1341,97 +1341,97 @@ void nsDocShell::GetParentCharset(const nsIPrincipal** aPrincipal) { aCharset = mParentCharset; *aCharsetSource = mParentCharsetSource; NS_IF_ADDREF(*aPrincipal = mParentCharsetPrincipal); } NS_IMETHODIMP nsDocShell::GetHasMixedActiveContentLoaded(bool* aHasMixedActiveContentLoaded) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); *aHasMixedActiveContentLoaded = doc && doc->GetHasMixedActiveContentLoaded(); return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasMixedActiveContentBlocked( bool* aHasMixedActiveContentBlocked) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); *aHasMixedActiveContentBlocked = doc && doc->GetHasMixedActiveContentBlocked(); return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasMixedDisplayContentLoaded( bool* aHasMixedDisplayContentLoaded) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); *aHasMixedDisplayContentLoaded = doc && doc->GetHasMixedDisplayContentLoaded(); return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasMixedDisplayContentBlocked( bool* aHasMixedDisplayContentBlocked) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); *aHasMixedDisplayContentBlocked = doc && doc->GetHasMixedDisplayContentBlocked(); return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasTrackingContentBlocked(bool* aHasTrackingContentBlocked) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); *aHasTrackingContentBlocked = doc && doc->GetHasTrackingContentBlocked(); return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasTrackingContentLoaded(bool* aHasTrackingContentLoaded) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); *aHasTrackingContentLoaded = doc && doc->GetHasTrackingContentLoaded(); return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasCookiesBlockedByPermission( bool* aHasCookiesBlockedByPermission) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); *aHasCookiesBlockedByPermission = doc && doc->GetHasCookiesBlockedByPermission(); return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasCookiesBlockedDueToTrackers( bool* aHasCookiesBlockedDueToTrackers) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); *aHasCookiesBlockedDueToTrackers = doc && doc->GetHasTrackingCookiesBlocked(); return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasAllCookiesBeenBlocked(bool* aHasAllCookiesBeenBlocked) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); *aHasAllCookiesBeenBlocked = doc && doc->GetHasAllCookiesBlocked(); return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasForeignCookiesBeenBlocked( bool* aHasForeignCookiesBeenBlocked) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); *aHasForeignCookiesBeenBlocked = doc && doc->GetHasForeignCookiesBlocked(); return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasCookiesLoaded(bool* aHasCookiesLoaded) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); *aHasCookiesLoaded = doc && doc->GetHasCookiesLoaded(); return NS_OK; } NS_IMETHODIMP nsDocShell::GetAllowPlugins(bool* aAllowPlugins) { NS_ENSURE_ARG_POINTER(aAllowPlugins); @@ -1874,17 +1874,17 @@ void nsDocShell::SetOrientationLock(hal: NS_IMETHODIMP nsDocShell::GetMayEnableCharacterEncodingMenu( bool* aMayEnableCharacterEncodingMenu) { *aMayEnableCharacterEncodingMenu = false; if (!mContentViewer) { return NS_OK; } - nsIDocument* doc = mContentViewer->GetDocument(); + Document* doc = mContentViewer->GetDocument(); if (!doc) { return NS_OK; } if (doc->WillIgnoreCharsetOverride()) { return NS_OK; } *aMayEnableCharacterEncodingMenu = true; @@ -2233,17 +2233,17 @@ nsIDOMStorageManager* nsDocShell::TopSes NS_IMETHODIMP nsDocShell::GetCurrentDocumentChannel(nsIChannel** aResult) { NS_IF_ADDREF(*aResult = GetCurrentDocChannel()); return NS_OK; } nsIChannel* nsDocShell::GetCurrentDocChannel() { if (mContentViewer) { - nsIDocument* doc = mContentViewer->GetDocument(); + Document* doc = mContentViewer->GetDocument(); if (doc) { return doc->GetChannel(); } } return nullptr; } NS_IMETHODIMP @@ -2471,17 +2471,17 @@ void nsDocShell::MaybeCreateInitialClien } nsIPrincipal* principal = aPrincipal ? aPrincipal : GetInheritedPrincipal(false); // Sometimes there is no principal available when we are called from // CreateAboutBlankContentViewer. For example, sometimes the principal // is only extracted from the load context after the document is created - // in nsIDocument::ResetToURI(). Ideally we would do something similar + // in Document::ResetToURI(). Ideally we would do something similar // here, but for now lets just avoid the issue by not preallocating the // client. if (!principal) { return; } nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow(); if (!win) { @@ -2526,17 +2526,17 @@ Maybe<ClientInfo> nsDocShell::GetInitial if (mInitialClientSource) { Maybe<ClientInfo> result; result.emplace(mInitialClientSource->Info()); return result; } nsGlobalWindowInner* innerWindow = mScriptGlobal ? mScriptGlobal->GetCurrentInnerWindowInternal() : nullptr; - nsIDocument* doc = innerWindow ? innerWindow->GetExtantDoc() : nullptr; + Document* doc = innerWindow ? innerWindow->GetExtantDoc() : nullptr; if (!doc || !doc->IsInitialDocument()) { return Maybe<ClientInfo>(); } return innerWindow->GetClientInfo(); } @@ -2850,30 +2850,30 @@ bool nsDocShell::CanAccessItem(nsIDocShe // When the first party isolation is on, the top-level docShell may not have // the firstPartyDomain in its originAttributes, but its document will have // it. So we get the firstPartyDomain from the nodePrincipal of the document // before we compare the originAttributes. if (OriginAttributes::IsFirstPartyEnabled()) { if (aAccessingItem->ItemType() == nsIDocShellTreeItem::typeContent && (accessingDS == accessingRootDS || accessingDS->GetIsMozBrowser())) { - nsCOMPtr<nsIDocument> accessingDoc = aAccessingItem->GetDocument(); + RefPtr<Document> accessingDoc = aAccessingItem->GetDocument(); if (accessingDoc) { nsCOMPtr<nsIPrincipal> accessingPrincipal = accessingDoc->NodePrincipal(); accessingOA.mFirstPartyDomain = accessingPrincipal->OriginAttributesRef().mFirstPartyDomain; } } if (aTargetItem->ItemType() == nsIDocShellTreeItem::typeContent && (targetDS == targetRootDS || targetDS->GetIsMozBrowser())) { - nsCOMPtr<nsIDocument> targetDoc = aAccessingItem->GetDocument(); + RefPtr<Document> targetDoc = aAccessingItem->GetDocument(); if (targetDoc) { nsCOMPtr<nsIPrincipal> targetPrincipal = targetDoc->NodePrincipal(); targetOA.mFirstPartyDomain = targetPrincipal->OriginAttributesRef().mFirstPartyDomain; } } @@ -3085,17 +3085,17 @@ bool nsDocShell::IsSandboxedFrom(nsIDocS if (aTargetDocShell == this) { return false; } // Default the sandbox flags to our flags, so that if we can't retrieve the // active document, we will still enforce our own. uint32_t sandboxFlags = mSandboxFlags; if (mContentViewer) { - nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument(); + RefPtr<Document> doc = mContentViewer->GetDocument(); if (doc) { sandboxFlags = doc->GetSandboxFlags(); } } // If no flags, we are not sandboxed at all. if (!sandboxFlags) { return false; @@ -3322,17 +3322,17 @@ nsDocShell::AddChild(nsIDocShellTreeItem if (mItemType == nsIDocShellTreeItem::typeChrome) { return NS_OK; } // get the parent's current charset if (!mContentViewer) { return NS_OK; } - nsIDocument* doc = mContentViewer->GetDocument(); + Document* doc = mContentViewer->GetDocument(); if (!doc) { return NS_OK; } bool isWyciwyg = false; if (mCurrentURI) { // Check if the url is wyciwyg @@ -3662,17 +3662,17 @@ nsDocShell::GetCurrentSHEntry(nsISHEntry return NS_OK; } nsIScriptGlobalObject* nsDocShell::GetScriptGlobalObject() { NS_ENSURE_SUCCESS(EnsureScriptEnvironment(), nullptr); return mScriptGlobal; } -nsIDocument* nsDocShell::GetDocument() { +Document* nsDocShell::GetDocument() { NS_ENSURE_SUCCESS(EnsureContentViewer(), nullptr); return mContentViewer->GetDocument(); } nsPIDOMWindowOuter* nsDocShell::GetWindow() { if (NS_FAILED(EnsureScriptEnvironment())) { return nullptr; } @@ -3707,17 +3707,17 @@ NS_IMETHODIMP nsDocShell::GetContentBlockingLog(Promise** aPromise) { NS_ENSURE_ARG_POINTER(aPromise); if (!mContentViewer) { *aPromise = nullptr; return NS_ERROR_FAILURE; } - nsIDocument* doc = mContentViewer->GetDocument(); + Document* doc = mContentViewer->GetDocument(); ErrorResult rv; RefPtr<Promise> promise = Promise::Create(doc->GetOwnerGlobal(), rv); if (NS_WARN_IF(rv.Failed())) { return rv.StealNSResult(); } promise->MaybeResolve(doc->GetContentBlockingLog()->Stringify()); promise.forget(aPromise); return NS_OK; @@ -4609,17 +4609,17 @@ nsDocShell::Reload(uint32_t aReloadFlags /* If you change this part of code, make sure bug 45297 does not re-occur */ if (mOSHE) { rv = LoadHistoryEntry(mOSHE, loadType); } else if (mLSHE) { // In case a reload happened before the current load is // done rv = LoadHistoryEntry(mLSHE, loadType); } else { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); if (!doc) { return NS_OK; } // Do not inherit owner from document uint32_t flags = INTERNAL_LOAD_FLAGS_NONE; nsAutoString srcdoc; @@ -4735,21 +4735,21 @@ nsDocShell::Stop(uint32_t aStopFlags) { shellAsNav->Stop(aStopFlags); } } return NS_OK; } NS_IMETHODIMP -nsDocShell::GetDocument(nsIDocument** aDocument) { +nsDocShell::GetDocument(Document** aDocument) { NS_ENSURE_ARG_POINTER(aDocument); NS_ENSURE_SUCCESS(EnsureContentViewer(), NS_ERROR_FAILURE); - nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument(); + RefPtr<Document> doc = mContentViewer->GetDocument(); if (!doc) { return NS_ERROR_NOT_AVAILABLE; } doc.forget(aDocument); return NS_OK; } @@ -5173,17 +5173,17 @@ nsDocShell::GetPositionAndSize(int32_t* SetPositionAndSize(mBounds.X(), mBounds.Y(), r.Width(), r.Height(), 0); } // We should really consider just getting this information from // our window instead of duplicating the storage and code... if (aWidth || aHeight) { // Caller wants to know our size; make sure to give them up to // date information. - nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(mParent))); + RefPtr<Document> doc(do_GetInterface(GetAsSupports(mParent))); if (doc) { doc->FlushPendingNotifications(FlushType::Layout); } } DoGetPositionAndSize(aX, aY, aWidth, aHeight); return NS_OK; } @@ -5366,17 +5366,17 @@ nsDocShell::SetIsActive(bool aIsActive) nsCOMPtr<nsIPresShell> pshell = GetPresShell(); if (pshell) { pshell->SetIsActive(aIsActive); } // Tell the window about it if (mScriptGlobal) { mScriptGlobal->SetIsBackground(!aIsActive); - if (nsCOMPtr<nsIDocument> doc = mScriptGlobal->GetExtantDoc()) { + if (RefPtr<Document> doc = mScriptGlobal->GetExtantDoc()) { // Update orientation when the top-level browsing context becomes active. if (aIsActive) { nsCOMPtr<nsIDocShellTreeItem> parent; GetSameTypeParent(getter_AddRefs(parent)); if (!parent) { // We only care about the top-level browsing context. uint16_t orientation = OrientationLock(); ScreenOrientation::UpdateActiveOrientationLock(orientation); @@ -5385,17 +5385,17 @@ nsDocShell::SetIsActive(bool aIsActive) doc->PostVisibilityUpdateEvent(); } } // Tell the nsDOMNavigationTiming about it RefPtr<nsDOMNavigationTiming> timing = mTiming; if (!timing && mContentViewer) { - nsIDocument* doc = mContentViewer->GetDocument(); + Document* doc = mContentViewer->GetDocument(); if (doc) { timing = doc->GetNavigationTiming(); } } if (timing) { timing->NotifyDocShellStateChanged( aIsActive ? nsDOMNavigationTiming::DocShellState::eActive : nsDOMNavigationTiming::DocShellState::eInactive); @@ -5533,17 +5533,17 @@ nsDocShell::SetMixedContentChannel(nsICh #endif mMixedContentChannel = aMixedContentChannel; return NS_OK; } NS_IMETHODIMP nsDocShell::GetFailedChannel(nsIChannel** aFailedChannel) { NS_ENSURE_ARG_POINTER(aFailedChannel); - nsIDocument* doc = GetDocument(); + Document* doc = GetDocument(); if (!doc) { *aFailedChannel = nullptr; return NS_OK; } NS_IF_ADDREF(*aFailedChannel = doc->GetFailedChannel()); return NS_OK; } @@ -5566,17 +5566,17 @@ nsDocShell::GetAllowMixedContentAndConne GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot)); NS_ASSERTION( sameTypeRoot, "No document shell root tree item from document shell tree item!"); *aIsRootDocShell = sameTypeRoot.get() == static_cast<nsIDocShellTreeItem*>(this); // now get the document from sameTypeRoot - nsCOMPtr<nsIDocument> rootDoc = sameTypeRoot->GetDocument(); + RefPtr<Document> rootDoc = sameTypeRoot->GetDocument(); if (rootDoc) { nsCOMPtr<nsIPrincipal> rootPrincipal = rootDoc->NodePrincipal(); // For things with system principal (e.g. scratchpad) there is no uri // aRootHasSecureConnection should be false. nsCOMPtr<nsIURI> rootUri; if (nsContentUtils::IsSystemPrincipal(rootPrincipal) || NS_FAILED(rootPrincipal->GetURI(getter_AddRefs(rootUri))) || !rootUri || @@ -5886,17 +5886,17 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI loadState->SetResultPrincipalURI(aURI); loadState->SetResultPrincipalURIIsSome(true); loadState->SetKeepResultPrincipalURIIfSet(true); // Set the triggering pricipal to aPrincipal if available, or current // document's principal otherwise. nsCOMPtr<nsIPrincipal> principal = aPrincipal; if (!principal) { - nsCOMPtr<nsIDocument> doc = GetDocument(); + RefPtr<Document> doc = GetDocument(); if (!doc) { return NS_ERROR_FAILURE; } principal = doc->NodePrincipal(); } loadState->SetTriggeringPrincipal(principal); loadState->SetPrincipalIsExplicit(true); @@ -6799,17 +6799,17 @@ nsresult nsDocShell::EndPageLoad(nsIWebP // Parent window nsCOMPtr<nsIDocShellTreeItem> parentItem; GetSameTypeParent(getter_AddRefs(parentItem)); if (!parentItem) { return NS_OK; } - nsCOMPtr<nsIDocument> parentDoc; + RefPtr<Document> parentDoc; parentDoc = parentItem->GetDocument(); if (!parentDoc) { return NS_OK; } parentDoc->AddBlockedTrackingNode(frameElement); return NS_OK; @@ -7046,17 +7046,17 @@ nsresult nsDocShell::EnsureContentViewer } } nsresult rv = CreateAboutBlankContentViewer(principal, baseURI); NS_ENSURE_STATE(mContentViewer); if (NS_SUCCEEDED(rv)) { - nsCOMPtr<nsIDocument> doc(GetDocument()); + RefPtr<Document> doc(GetDocument()); NS_ASSERTION(doc, "Should have doc if CreateAboutBlankContentViewer " "succeeded!"); doc->SetIsInitialDocument(true); // Documents created using EnsureContentViewer may be transient // placeholders created by framescripts before content has a chance to @@ -7069,17 +7069,17 @@ nsresult nsDocShell::EnsureContentViewer } return rv; } nsresult nsDocShell::CreateAboutBlankContentViewer( nsIPrincipal* aPrincipal, nsIURI* aBaseURI, bool aTryToSaveOldPresentation, bool aCheckPermitUnload) { - nsCOMPtr<nsIDocument> blankDoc; + RefPtr<Document> blankDoc; nsCOMPtr<nsIContentViewer> viewer; nsresult rv = NS_ERROR_FAILURE; /* mCreatingDocument should never be true at this point. However, it's a theoretical possibility. We want to know about it and make it stop, and this sounds like a job for an assertion. */ NS_ASSERTION(!mCreatingDocument, "infinite(?) loop creating document averted"); @@ -7217,17 +7217,17 @@ nsresult nsDocShell::CreateAboutBlankCon NS_IMETHODIMP nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal) { return CreateAboutBlankContentViewer(aPrincipal, nullptr); } bool nsDocShell::CanSavePresentation(uint32_t aLoadType, nsIRequest* aNewRequest, - nsIDocument* aNewDocument) { + Document* aNewDocument) { if (!mOSHE) { return false; // no entry to save into } nsCOMPtr<nsIContentViewer> viewer = mOSHE->GetContentViewer(); if (viewer) { NS_WARNING("mOSHE already has a content viewer!"); return false; @@ -7267,17 +7267,17 @@ bool nsDocShell::CanSavePresentation(uin // Don't cache the content viewer if we're in a subframe. nsCOMPtr<nsIDocShellTreeItem> root; GetSameTypeParent(getter_AddRefs(root)); if (root && root != this) { return false; // this is a subframe load } // If the document does not want its presentation cached, then don't. - nsCOMPtr<nsIDocument> doc = mScriptGlobal->GetExtantDoc(); + RefPtr<Document> doc = mScriptGlobal->GetExtantDoc(); return doc && doc->CanSavePresentation(aNewRequest); } void nsDocShell::ReattachEditorToWindow(nsISHEntry* aSHEntry) { MOZ_ASSERT(!mIsBeingDestroyed); NS_ASSERTION(!mEditorData, "Why reattach an editor when we already have one?"); @@ -7402,17 +7402,17 @@ nsDocShell::BeginRestore(nsIContentViewe aContentViewer = mContentViewer; } // Dispatch events for restoring the presentation. We try to simulate // the progress notifications loading the document would cause, so we add // the document's channel to the loadgroup to initiate stateChange // notifications. - nsCOMPtr<nsIDocument> doc = aContentViewer->GetDocument(); + RefPtr<Document> doc = aContentViewer->GetDocument(); if (doc) { nsIChannel* channel = doc->GetChannel(); if (channel) { mEODForCurrentDocument = false; mIsRestoringDocument = true; mLoadGroup->AddRequest(channel, nullptr); mIsRestoringDocument = false; } @@ -7460,17 +7460,17 @@ nsDocShell::FinishRestore() { child->FinishRestore(); } } if (mOSHE && mOSHE->HasDetachedEditor()) { ReattachEditorToWindow(mOSHE); } - nsCOMPtr<nsIDocument> doc = GetDocument(); + RefPtr<Document> doc = GetDocument(); if (doc) { // Finally, we remove the request from the loadgroup. This will // cause onStateChange(STATE_STOP) to fire, which will fire the // pageshow event to the chrome. nsIChannel* channel = doc->GetChannel(); if (channel) { mIsRestoringDocument = true; @@ -7605,17 +7605,17 @@ nsresult nsDocShell::RestoreFromHistory( return NS_ERROR_FAILURE; } if (mSavingOldViewer) { // We determined that it was safe to cache the document presentation // at the time we initiated the new load. We need to check whether // it's still safe to do so, since there may have been DOM mutations // or new requests initiated. - nsCOMPtr<nsIDocument> doc = viewer->GetDocument(); + RefPtr<Document> doc = viewer->GetDocument(); nsIRequest* request = nullptr; if (doc) { request = doc->GetChannel(); } mSavingOldViewer = CanSavePresentation(mLoadType, request, doc); } nsCOMPtr<nsIContentViewer> oldCv(mContentViewer); @@ -7741,17 +7741,17 @@ nsresult nsDocShell::RestoreFromHistory( rootViewParent = oldRootView->GetParent(); mContentViewer->GetBounds(newBounds); } } } nsCOMPtr<nsIContent> container; - nsCOMPtr<nsIDocument> sibling; + RefPtr<Document> sibling; if (rootViewParent && rootViewParent->GetParent()) { nsIFrame* frame = rootViewParent->GetParent()->GetFrame(); container = frame ? frame->GetContent() : nullptr; } if (rootViewSibling) { nsIFrame* frame = rootViewSibling->GetFrame(); sibling = frame ? frame->PresShell()->GetDocument() : nullptr; } @@ -7782,17 +7782,17 @@ nsresult nsDocShell::RestoreFromHistory( // Grab all of the related presentation from the SHEntry now. // Clearing the viewer from the SHEntry will clear all of this state. nsCOMPtr<nsISupports> windowState = mLSHE->GetWindowState(); mLSHE->SetWindowState(nullptr); bool sticky = mLSHE->GetSticky(); - nsCOMPtr<nsIDocument> document = mContentViewer->GetDocument(); + RefPtr<Document> document = mContentViewer->GetDocument(); nsCOMArray<nsIDocShellTreeItem> childShells; int32_t i = 0; nsCOMPtr<nsIDocShellTreeItem> child; while (NS_SUCCEEDED(mLSHE->ChildShellAt(i++, getter_AddRefs(child))) && child) { childShells.AppendObject(child); } @@ -7863,17 +7863,17 @@ nsresult nsDocShell::RestoreFromHistory( newCv->SetFullZoom(pageZoom); newCv->SetOverrideDPPX(overrideDPPX); newCv->SetAuthorStyleDisabled(styleDisabled); } if (document) { RefPtr<nsDocShell> parent = GetParentDocshell(); if (parent) { - nsCOMPtr<nsIDocument> d = parent->GetDocument(); + RefPtr<Document> d = parent->GetDocument(); if (d) { if (d->EventHandlingSuppressed()) { document->SuppressEventHandling(d->EventHandlingSuppressed()); } } } // Use the uri from the mLSHE we had when we entered this function @@ -8118,17 +8118,17 @@ nsresult nsDocShell::CreateContentViewer // wrong information :-( // if (mSavingOldViewer) { // We determined that it was safe to cache the document presentation // at the time we initiated the new load. We need to check whether // it's still safe to do so, since there may have been DOM mutations // or new requests initiated. - nsCOMPtr<nsIDocument> doc = viewer->GetDocument(); + RefPtr<Document> doc = viewer->GetDocument(); mSavingOldViewer = CanSavePresentation(mLoadType, aRequest, doc); } NS_ASSERTION(!mLoadingURI, "Re-entering unload?"); nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(aRequest); if (aOpenedChannel) { aOpenedChannel->GetURI(getter_AddRefs(mLoadingURI)); @@ -8157,17 +8157,17 @@ nsresult nsDocShell::CreateContentViewer // We need to set the SH entry and our current URI here and not // at the moment we load the page. We want the same behavior // of Stop() as for a normal page load. See bug 514232 for details. // Revert mLoadType to load type to state the page load failed, // following function calls need it. mLoadType = mFailedLoadType; - nsIDocument* doc = viewer->GetDocument(); + Document* doc = viewer->GetDocument(); if (doc) { doc->SetFailedChannel(failedChannel); } nsCOMPtr<nsIPrincipal> triggeringPrincipal; if (failedChannel) { // Make sure we have a URI to set currentURI. NS_GetFinalChannelURI(failedChannel, getter_AddRefs(failedURI)); @@ -8263,17 +8263,17 @@ nsresult nsDocShell::CreateContentViewer mEODForCurrentDocument = false; // if this document is part of a multipart document, // the ID can be used to distinguish it from the other parts. nsCOMPtr<nsIMultiPartChannel> multiPartChannel(do_QueryInterface(aRequest)); if (multiPartChannel) { nsCOMPtr<nsIPresShell> shell = GetPresShell(); if (NS_SUCCEEDED(rv) && shell) { - nsIDocument* doc = shell->GetDocument(); + Document* doc = shell->GetDocument(); if (doc) { uint32_t partID; multiPartChannel->GetPartID(&partID); doc->SetPartID(partID); } } } @@ -8487,17 +8487,17 @@ nsresult nsDocShell::SetupNewViewer(nsIC // until we have enough of the new page to show. Just return with the new // viewer still set to hidden. return NS_OK; } nsresult nsDocShell::SetDocCurrentStateObj(nsISHEntry* aShEntry) { NS_ENSURE_STATE(mContentViewer); - nsCOMPtr<nsIDocument> document = GetDocument(); + RefPtr<Document> document = GetDocument(); NS_ENSURE_TRUE(document, NS_ERROR_FAILURE); nsCOMPtr<nsIStructuredCloneContainer> scContainer; if (aShEntry) { scContainer = aShEntry->GetStateData(); // If aShEntry is null, just set the document's state object to null. } @@ -8799,17 +8799,17 @@ nsresult nsDocShell::InternalLoad(nsDocS if (NS_SUCCEEDED(rv) && shouldLoad == nsIContentPolicy::REJECT_TYPE) { return NS_ERROR_CONTENT_BLOCKED_SHOW_ALT; } return NS_ERROR_CONTENT_BLOCKED; } } - nsIDocument* doc = mContentViewer ? mContentViewer->GetDocument() : nullptr; + Document* doc = mContentViewer ? mContentViewer->GetDocument() : nullptr; const bool isDocumentAuxSandboxed = doc && (doc->GetSandboxFlags() & SANDBOXED_AUXILIARY_NAVIGATION); if (mLoadURIDelegate && aLoadState->LoadType() != LOAD_ERROR_PAGE && (!targetDocShell || targetDocShell == static_cast<nsIDocShell*>(this))) { // Dispatch only load requests for the current or a new window to the // delegate, e.g., to allow for GeckoView apps to handle the load event @@ -8932,17 +8932,17 @@ nsresult nsDocShell::InternalLoad(nsDocS EmptyString(), // Features getter_AddRefs(newWin)); // In some cases the Open call doesn't actually result in a new // window being opened. We can detect these cases by examining the // document in |newWin|, if any. nsCOMPtr<nsPIDOMWindowOuter> piNewWin = newWin; if (piNewWin) { - nsCOMPtr<nsIDocument> newDoc = piNewWin->GetExtantDoc(); + RefPtr<Document> newDoc = piNewWin->GetExtantDoc(); if (!newDoc || newDoc->IsInitialDocument()) { isNewWindow = true; aLoadState->SetLoadFlag(INTERNAL_LOAD_FLAGS_FIRST_LOAD); } } nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(newWin); targetDocShell = do_QueryInterface(webNav); @@ -9085,17 +9085,17 @@ nsresult nsDocShell::InternalLoad(nsDocS aLoadState->SourceDocShell()->IsSandboxedFrom(this)) { return NS_ERROR_DOM_INVALID_ACCESS_ERR; } // If this docshell is owned by a frameloader, make sure to cancel // possible frameloader initialization before loading a new page. nsCOMPtr<nsIDocShellTreeItem> parent = GetParentDocshell(); if (parent) { - nsCOMPtr<nsIDocument> doc = parent->GetDocument(); + RefPtr<Document> doc = parent->GetDocument(); if (doc) { doc->TryCancelFrameLoaderInitialization(this); } } bool loadFromExternal = false; // Before going any further vet loads initiated by external programs. @@ -9235,17 +9235,17 @@ nsresult nsDocShell::InternalLoad(nsDocS // we need to assign aLoadState->SHEntry() to mLSHE right here, so that on // History loads, SetCurrentURI() called from OnNewURI() will send proper // onLocationChange() notifications to the browser to update back/forward // buttons. SetHistoryEntry(&mLSHE, aLoadState->SHEntry()); // Set the doc's URI according to the new history entry's URI. - nsCOMPtr<nsIDocument> doc = GetDocument(); + RefPtr<Document> doc = GetDocument(); NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); doc->SetDocumentURI(aLoadState->URI()); /* This is a anchor traversal with in the same page. * call OnNewURI() so that, this traversal will be * recorded in session and global history. */ nsCOMPtr<nsIPrincipal> newURITriggeringPrincipal, @@ -9616,17 +9616,17 @@ nsresult nsDocShell::InternalLoad(nsDocS return NS_OK; } } return rv; } nsIPrincipal* nsDocShell::GetInheritedPrincipal(bool aConsiderCurrentDocument) { - nsCOMPtr<nsIDocument> document; + RefPtr<Document> document; bool inheritedFromCurrent = false; if (aConsiderCurrentDocument && mContentViewer) { document = mContentViewer->GetDocument(); inheritedFromCurrent = true; } if (!document) { @@ -9815,17 +9815,17 @@ nsresult nsDocShell::DoURILoad(nsDocShel } else { loadingWindow = nullptr; loadingNode = mScriptGlobal->AsOuter()->GetFrameElementInternal(); if (loadingNode) { // If we have a loading node, then use that as our loadingPrincipal. loadingPrincipal = loadingNode->NodePrincipal(); #ifdef DEBUG // Get the docshell type for requestingElement. - nsCOMPtr<nsIDocument> requestingDoc = loadingNode->OwnerDoc(); + RefPtr<Document> requestingDoc = loadingNode->OwnerDoc(); nsCOMPtr<nsIDocShell> elementDocShell = requestingDoc->GetDocShell(); // requestingElement docshell type = current docshell type. MOZ_ASSERT( mItemType == elementDocShell->ItemType(), "subframes should have the same docshell type as their parent"); #endif } else { // If this isn't a top-level load and mScriptGlobal's frame element is @@ -10553,17 +10553,17 @@ nsresult nsDocShell::ScrollToAnchor(bool free(str); } // Above will fail if the anchor name is not UTF-8. Need to // convert from document charset to unicode. if (NS_FAILED(rv)) { // Get a document charset NS_ENSURE_TRUE(mContentViewer, NS_ERROR_FAILURE); - nsIDocument* doc = mContentViewer->GetDocument(); + Document* doc = mContentViewer->GetDocument(); NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); nsAutoCString charset; doc->GetDocumentCharacterSet()->Name(charset); nsCOMPtr<nsITextToSubURI> textToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); @@ -10880,17 +10880,17 @@ bool nsDocShell::OnNewURI(nsIURI* aURI, } bool nsDocShell::OnLoadingSite(nsIChannel* aChannel, bool aFireOnLocationChange, bool aAddToGlobalHistory) { nsCOMPtr<nsIURI> uri; // If this a redirect, use the final url (uri) // else use the original url // - // Note that this should match what documents do (see nsIDocument::Reset). + // Note that this should match what documents do (see Document::Reset). NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); NS_ENSURE_TRUE(uri, false); // Pass false for aCloneSHChildren, since we're loading a new page here. return OnNewURI(uri, aChannel, nullptr, nullptr, mLoadType, aFireOnLocationChange, aAddToGlobalHistory, false); } @@ -10951,38 +10951,38 @@ nsDocShell::AddState(JS::Handle<JS::Valu // pushState effectively becomes replaceState when we've started a network // load but haven't adopted its document yet. This mirrors what we do with // changes to the hash at this stage of the game. if (JustStartedNetworkLoad()) { aReplace = true; } - nsCOMPtr<nsIDocument> document = GetDocument(); + RefPtr<Document> document = GetDocument(); NS_ENSURE_TRUE(document, NS_ERROR_FAILURE); // Step 1: Serialize aData using structured clone. nsCOMPtr<nsIStructuredCloneContainer> scContainer; // scContainer->Init might cause arbitrary JS to run, and this code might // navigate the page we're on, potentially to a different origin! (bug // 634834) To protect against this, we abort if our principal changes due // to the InitFromJSVal() call. { - nsCOMPtr<nsIDocument> origDocument = GetDocument(); + RefPtr<Document> origDocument = GetDocument(); if (!origDocument) { return NS_ERROR_DOM_SECURITY_ERR; } nsCOMPtr<nsIPrincipal> origPrincipal = origDocument->NodePrincipal(); scContainer = new nsStructuredCloneContainer(); rv = scContainer->InitFromJSVal(aData, aCx); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr<nsIDocument> newDocument = GetDocument(); + RefPtr<Document> newDocument = GetDocument(); if (!newDocument) { return NS_ERROR_DOM_SECURITY_ERR; } nsCOMPtr<nsIPrincipal> newPrincipal = newDocument->NodePrincipal(); bool principalsEqual = false; origPrincipal->Equals(newPrincipal, &principalsEqual); NS_ENSURE_TRUE(principalsEqual, NS_ERROR_DOM_SECURITY_ERR); @@ -12207,17 +12207,17 @@ nsresult nsDocShell::SetBaseUrlForWyciwy nsresult rv = NS_ERROR_NOT_AVAILABLE; if (sURIFixup) { rv = sURIFixup->CreateExposableURI(mCurrentURI, getter_AddRefs(baseURI)); } // Get the current document and set the base uri if (baseURI) { - nsIDocument* document = aContentViewer->GetDocument(); + Document* document = aContentViewer->GetDocument(); if (document) { document->SetBaseURI(baseURI); } } return rv; } //***************************************************************************** @@ -12344,17 +12344,17 @@ bool nsDocShell::IsOKToLoadURI(nsIURI* a return true; } if (!mLoadingURI) { return false; } bool isPrivateWin = false; - nsIDocument* doc = GetDocument(); + Document* doc = GetDocument(); if (doc) { isPrivateWin = doc->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId > 0; } nsCOMPtr<nsIScriptSecurityManager> secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID); return secMan && NS_SUCCEEDED(secMan->CheckSameOriginURI( @@ -12673,17 +12673,17 @@ nsDocShell::OnLinkClickSync(nsIContent* } } // Get the owner document of the link that was clicked, this will be // the document that the link is in, or the last document that the // link was in. From that document, we'll get the URI to use as the // referer, since the current URI in this docshell may be a // new document that we're in the process of loading. - nsCOMPtr<nsIDocument> refererDoc = aContent->OwnerDoc(); + RefPtr<Document> refererDoc = aContent->OwnerDoc(); NS_ENSURE_TRUE(refererDoc, NS_ERROR_UNEXPECTED); // Now check that the refererDoc's inner window is the current inner // window for mScriptGlobal. If it's not, then we don't want to // follow this link. nsPIDOMWindowInner* refererInner = refererDoc->GetInnerWindow(); NS_ENSURE_TRUE(refererInner, NS_ERROR_UNEXPECTED); if (!mScriptGlobal || @@ -12812,17 +12812,17 @@ bool nsDocShell::ShouldBlockLoadingForBa return canGoForward; } bool nsDocShell::PluginsAllowedInCurrentDoc() { if (!mContentViewer) { return false; } - nsIDocument* doc = mContentViewer->GetDocument(); + Document* doc = mContentViewer->GetDocument(); if (!doc) { return false; } return doc->GetAllowPlugins(); } //---------------------------------------------------------------------- @@ -13010,17 +13010,17 @@ bool nsDocShell::CanSetOriginAttributes( MOZ_ASSERT(mChildList.IsEmpty()); if (!mChildList.IsEmpty()) { return false; } // TODO: Bug 1273058 - mContentViewer should be null when setting origin // attributes. if (mContentViewer) { - nsIDocument* doc = mContentViewer->GetDocument(); + Document* doc = mContentViewer->GetDocument(); if (doc) { nsIURI* uri = doc->GetDocumentURI(); if (!uri) { return false; } nsCString uriSpec = uri->GetSpecOrDefault(); MOZ_ASSERT(uriSpec.EqualsLiteral("about:blank")); if (!uriSpec.EqualsLiteral("about:blank")) { @@ -13250,19 +13250,19 @@ bool nsDocShell::InFrameSwap() { UniquePtr<ClientSource> nsDocShell::TakeInitialClientSource() { return std::move(mInitialClientSource); } NS_IMETHODIMP nsDocShell::IssueWarning(uint32_t aWarning, bool aAsError) { if (mContentViewer) { - nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument(); + RefPtr<Document> doc = mContentViewer->GetDocument(); if (doc) { - doc->WarnOnceAbout(nsIDocument::DeprecatedOperations(aWarning), aAsError); + doc->WarnOnceAbout(Document::DeprecatedOperations(aWarning), aAsError); } } return NS_OK; } NS_IMETHODIMP nsDocShell::GetEditingSession(nsIEditingSession** aEditSession) { if (!NS_SUCCEEDED(EnsureEditorData())) {
--- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -72,17 +72,16 @@ class ClientSource; class EventTarget; } // namespace dom } // namespace mozilla class nsICommandManager; class nsIContentViewer; class nsIController; class nsIDocShellTreeOwner; -class nsIDocument; class nsIHttpChannel; class nsIMutableArray; class nsIPrompt; class nsIScrollableFrame; class nsISecureBrowserUI; class nsISHistory; class nsIStringBundle; class nsIURIFixup; @@ -724,17 +723,17 @@ class nsDocShell final : public nsDocLoa // session history. This checks a number of factors such as cache policy, // pending requests, and unload handlers. // |aLoadType| should be the load type that will replace the current // presentation. |aNewRequest| should be the request for the document to // be loaded in place of the current document, or null if such a request // has not been created yet. |aNewDocument| should be the document that will // replace the current document. bool CanSavePresentation(uint32_t aLoadType, nsIRequest* aNewRequest, - nsIDocument* aNewDocument); + mozilla::dom::Document* aNewDocument); // Captures the state of the supporting elements of the presentation // (the "window" object, docshell tree, meta-refresh loads, and security // state) and stores them on |mOSHE|. nsresult CaptureState(); // Begin the toplevel restore process for |aSHEntry|. // This simulates a channel open, and defers the real work until
--- a/docshell/base/nsDocShellEditorData.cpp +++ b/docshell/base/nsDocShellEditorData.cpp @@ -124,17 +124,17 @@ nsresult nsDocShellEditorData::DetachFro mDocShell ? mDocShell->GetWindow() : nullptr; nsresult rv = mEditingSession->DetachFromWindow(domWindow); NS_ENSURE_SUCCESS(rv, rv); mIsDetached = true; mDetachedMakeEditable = mMakeEditable; mMakeEditable = false; - nsCOMPtr<nsIDocument> doc = domWindow->GetDoc(); + nsCOMPtr<dom::Document> doc = domWindow->GetDoc(); nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc); if (htmlDoc) { mDetachedEditingState = htmlDoc->GetEditingState(); } mDocShell = nullptr; return NS_OK; @@ -146,16 +146,16 @@ nsresult nsDocShellEditorData::ReattachT nsCOMPtr<nsPIDOMWindowOuter> domWindow = mDocShell ? mDocShell->GetWindow() : nullptr; nsresult rv = mEditingSession->ReattachToWindow(domWindow); NS_ENSURE_SUCCESS(rv, rv); mIsDetached = false; mMakeEditable = mDetachedMakeEditable; - nsCOMPtr<nsIDocument> doc = domWindow->GetDoc(); + RefPtr<dom::Document> doc = domWindow->GetDoc(); nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc); if (htmlDoc) { htmlDoc->SetEditingState(mDetachedEditingState); } return NS_OK; }
--- a/docshell/base/nsDocShellTreeOwner.cpp +++ b/docshell/base/nsDocShellTreeOwner.cpp @@ -373,17 +373,17 @@ nsDocShellTreeOwner::SizeShellTo(nsIDocS // XXX: this is weird, but we used to call a method here // (webBrowserChrome->SizeBrowserTo()) whose implementations all failed // like this, so... return NS_ERROR_NOT_IMPLEMENTED; } NS_ENSURE_TRUE(aShellItem, NS_ERROR_FAILURE); - nsCOMPtr<nsIDocument> document = aShellItem->GetDocument(); + RefPtr<Document> document = aShellItem->GetDocument(); NS_ENSURE_TRUE(document, NS_ERROR_FAILURE); NS_ENSURE_TRUE(document->GetDocumentElement(), NS_ERROR_FAILURE); // Set the preferred Size // XXX NS_ERROR("Implement this"); /*
--- a/docshell/base/nsIDocShellTreeItem.idl +++ b/docshell/base/nsIDocShellTreeItem.idl @@ -3,19 +3,20 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" interface mozIDOMWindowProxy; interface nsIDocShellTreeOwner; -interface nsIDocument; interface nsPIDOMWindowOuter; +webidl Document; + /** * The nsIDocShellTreeItem supplies the methods that are required of any item * that wishes to be able to live within the docshell tree either as a middle * node or a leaf. */ [scriptable, uuid(9b7c586f-9214-480c-a2c4-49b526fff1a6)] interface nsIDocShellTreeItem : nsISupports @@ -179,12 +180,12 @@ interface nsIDocShellTreeItem : nsISuppo in nsIDocShellTreeItem aRequestor, in nsIDocShellTreeItem aOriginalRequestor); /** * Returns the DOM outer window for the content viewer. */ readonly attribute mozIDOMWindowProxy domWindow; - [noscript,nostdcall,notxpcom] nsIDocument getDocument(); + [noscript,nostdcall,notxpcom] Document getDocument(); [noscript,nostdcall,notxpcom] nsPIDOMWindowOuter getWindow(); };
--- a/docshell/base/nsIDocumentLoaderFactory.idl +++ b/docshell/base/nsIDocumentLoaderFactory.idl @@ -5,20 +5,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" interface nsIChannel; interface nsIContentViewer; interface nsIStreamListener; interface nsIDocShell; -interface nsIDocument; interface nsILoadGroup; interface nsIPrincipal; +webidl Document; + /** * To get a component that implements nsIDocumentLoaderFactory * for a given mimetype, use nsICategoryManager to find an entry * with the mimetype as its name in the category "Gecko-Content-Viewers". * The value of the entry is the contractid of the component. * The component is a service, so use GetService, not CreateInstance to get it. */ @@ -28,11 +29,11 @@ interface nsIDocumentLoaderFactory : nsI in nsIChannel aChannel, in nsILoadGroup aLoadGroup, in ACString aContentType, in nsIDocShell aContainer, in nsISupports aExtraInfo, out nsIStreamListener aDocListenerResult); nsIContentViewer createInstanceForDocument(in nsISupports aContainer, - in nsIDocument aDocument, + in Document aDocument, in string aCommand); };
--- a/docshell/base/nsPingListener.cpp +++ b/docshell/base/nsPingListener.cpp @@ -4,24 +4,23 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsPingListener.h" #include "mozilla/Preferences.h" #include "mozilla/dom/DocGroup.h" +#include "mozilla/dom/Document.h" -#include "nsIDocument.h" #include "nsIHttpChannelInternal.h" #include "nsIInputStream.h" #include "nsIProtocolHandler.h" #include "nsIUploadChannel2.h" -#include "nsIDocument.h" #include "nsNetUtil.h" #include "nsStreamUtils.h" #include "nsStringStream.h" #include "nsWhitespaceTokenizer.h" using namespace mozilla; using namespace mozilla::dom; @@ -87,17 +86,17 @@ struct MOZ_STACK_CLASS SendPingInfo { static void SendPing(void* aClosure, nsIContent* aContent, nsIURI* aURI, nsIIOService* aIOService) { SendPingInfo* info = static_cast<SendPingInfo*>(aClosure); if (info->maxPings > -1 && info->numPings >= info->maxPings) { return; } - nsIDocument* doc = aContent->OwnerDoc(); + Document* doc = aContent->OwnerDoc(); nsCOMPtr<nsIChannel> chan; NS_NewChannel(getter_AddRefs(chan), aURI, doc, info->requireSameHost ? nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED : nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, nsIContentPolicy::TYPE_PING, nullptr, // PerformanceStorage @@ -262,17 +261,17 @@ static void ForEachPing(nsIContent* aCon return; } nsCOMPtr<nsIIOService> ios = do_GetIOService(); if (!ios) { return; } - nsIDocument* doc = aContent->OwnerDoc(); + Document* doc = aContent->OwnerDoc(); nsAutoCString charset; doc->GetDocumentCharacterSet()->Name(charset); nsWhitespaceTokenizer tokenizer(value); while (tokenizer.hasMoreTokens()) { nsCOMPtr<nsIURI> uri, baseURI = aContent->GetBaseURI(); ios->NewURI(NS_ConvertUTF16toUTF8(tokenizer.nextToken()), charset.get(),
--- a/docshell/shistory/nsSHEntryShared.cpp +++ b/docshell/shistory/nsSHEntryShared.cpp @@ -6,17 +6,17 @@ #include "nsSHEntryShared.h" #include "nsArray.h" #include "nsDocShellEditorData.h" #include "nsIContentViewer.h" #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsILayoutHistoryState.h" #include "nsISHistory.h" #include "nsIWebNavigation.h" #include "nsThreadUtils.h" #include "mozilla/Attributes.h" #include "mozilla/Preferences.h" @@ -185,17 +185,17 @@ nsresult nsSHEntryShared::RemoveFromBFCa if (!mDocument) { return NS_ERROR_UNEXPECTED; } // DropPresentationState would clear mContentViewer & mDocument. Capture and // release the references asynchronously so that the document doesn't get // nuked mid-mutation. nsCOMPtr<nsIContentViewer> viewer = mContentViewer; - nsCOMPtr<nsIDocument> document = mDocument; + RefPtr<dom::Document> document = mDocument; RefPtr<nsSHEntryShared> self = this; nsresult rv = mDocument->Dispatch( mozilla::TaskCategory::Other, NS_NewRunnableFunction( "nsSHEntryShared::RemoveFromBFCacheAsync", [self, viewer, document]() { if (viewer) { viewer->Destroy();
--- a/docshell/shistory/nsSHEntryShared.h +++ b/docshell/shistory/nsSHEntryShared.h @@ -16,23 +16,28 @@ #include "nsRect.h" #include "nsString.h" #include "nsStubMutationObserver.h" #include "mozilla/Attributes.h" class nsSHEntry; class nsISHEntry; -class nsIDocument; class nsIContentViewer; class nsIDocShellTreeItem; class nsILayoutHistoryState; class nsDocShellEditorData; class nsIMutableArray; +namespace mozilla { +namespace dom { +class Document; +} +} // namespace mozilla + // A document may have multiple SHEntries, either due to hash navigations or // calls to history.pushState. SHEntries corresponding to the same document // share many members; in particular, they share state related to the // back/forward cache. // // nsSHEntryShared is the vehicle for this sharing. class nsSHEntryShared final : public nsIBFCacheEntry, public nsStubMutationObserver { @@ -79,17 +84,17 @@ class nsSHEntryShared final : public nsI uint32_t mCacheKey; uint32_t mLastTouched; // These members aren't copied by nsSHEntryShared::Duplicate() because // they're specific to a particular content viewer. uint64_t mID; nsCOMPtr<nsIContentViewer> mContentViewer; - nsCOMPtr<nsIDocument> mDocument; + RefPtr<mozilla::dom::Document> mDocument; nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState; nsCOMPtr<nsISupports> mWindowState; nsIntRect mViewerBounds; nsCOMPtr<nsIMutableArray> mRefreshURIList; nsExpirationState mExpirationState; nsAutoPtr<nsDocShellEditorData> mEditorData; nsWeakPtr mSHistory;
--- a/dom/animation/Animation.cpp +++ b/dom/animation/Animation.cpp @@ -11,17 +11,17 @@ #include "mozilla/dom/DocumentTimeline.h" #include "mozilla/AnimationEventDispatcher.h" #include "mozilla/AnimationTarget.h" #include "mozilla/AutoRestore.h" #include "mozilla/Maybe.h" // For Maybe #include "mozilla/TypeTraits.h" // For std::forward<> #include "nsAnimationManager.h" // For CSSAnimation #include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch -#include "nsIDocument.h" // For nsIDocument +#include "mozilla/dom/Document.h" #include "nsIPresShell.h" // For nsIPresShell #include "nsThreadUtils.h" // For nsRunnableMethod and nsRevocableEventPtr #include "nsTransitionManager.h" // For CSSTransition #include "PendingAnimationTracker.h" // For PendingAnimationTracker namespace mozilla { namespace dom { @@ -58,22 +58,17 @@ class MOZ_RAII AutoMutationBatchForAnima MOZ_GUARD_OBJECT_NOTIFIER_INIT; Maybe<NonOwningAnimationTarget> target = nsNodeUtils::GetTargetForAnimation(&aAnimation); if (!target) { return; } // For mutation observers, we use the OwnerDoc. - nsIDocument* doc = target->mElement->OwnerDoc(); - if (!doc) { - return; - } - - mAutoBatch.emplace(doc); + mAutoBatch.emplace(target->mElement->OwnerDoc()); } private: MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER Maybe<nsAutoAnimationMutationBatch> mAutoBatch; }; } // namespace @@ -87,17 +82,17 @@ class MOZ_RAII AutoMutationBatchForAnima const Optional<AnimationTimeline*>& aTimeline, ErrorResult& aRv) { nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports()); RefPtr<Animation> animation = new Animation(global); AnimationTimeline* timeline; if (aTimeline.WasPassed()) { timeline = aTimeline.Value(); } else { - nsIDocument* document = + Document* document = AnimationUtils::GetCurrentRealmDocument(aGlobal.Context()); if (!document) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } timeline = document->Timeline(); } @@ -1072,18 +1067,17 @@ void Animation::PlayNoUpdate(ErrorResult mPendingState = PendingState::PlayPending; // Clear flag that causes us to sync transform animations with the main // thread for now. We'll set this when we go to set up compositor // animations if it applies. mSyncWithGeometricAnimations = false; - nsIDocument* doc = GetRenderedDocument(); - if (doc) { + if (Document* doc = GetRenderedDocument()) { PendingAnimationTracker* tracker = doc->GetOrCreatePendingAnimationTracker(); tracker->AddPlayPending(*this); } else { TriggerOnNextTick(Nullable<TimeDuration>()); } UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async); @@ -1121,18 +1115,17 @@ void Animation::Pause(ErrorResult& aRv) if (!reuseReadyPromise) { // Clear ready promise. We'll create a new one lazily. mReady = nullptr; } mPendingState = PendingState::PausePending; - nsIDocument* doc = GetRenderedDocument(); - if (doc) { + if (Document* doc = GetRenderedDocument()) { PendingAnimationTracker* tracker = doc->GetOrCreatePendingAnimationTracker(); tracker->AddPausePending(*this); } else { TriggerOnNextTick(Nullable<TimeDuration>()); } UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async); @@ -1279,18 +1272,17 @@ void Animation::UpdateEffect() { KeyframeEffect* keyframeEffect = mEffect->AsKeyframeEffect(); if (keyframeEffect) { keyframeEffect->NotifyAnimationTimingUpdated(); } } } void Animation::FlushUnanimatedStyle() const { - nsIDocument* doc = GetRenderedDocument(); - if (doc) { + if (Document* doc = GetRenderedDocument()) { doc->FlushPendingNotifications( ChangesToFlush(FlushType::Style, false /* flush animations */)); } } void Animation::PostUpdate() { if (!mEffect) { return; @@ -1303,18 +1295,17 @@ void Animation::PostUpdate() { keyframeEffect->RequestRestyle(EffectCompositor::RestyleType::Layer); } void Animation::CancelPendingTasks() { if (mPendingState == PendingState::NotPending) { return; } - nsIDocument* doc = GetRenderedDocument(); - if (doc) { + if (Document* doc = GetRenderedDocument()) { PendingAnimationTracker* tracker = doc->GetPendingAnimationTracker(); if (tracker) { if (mPendingState == PendingState::PlayPending) { tracker->RemovePlayPending(*this); } else { tracker->RemovePausePending(*this); } } @@ -1341,18 +1332,17 @@ void Animation::ResetPendingTasks() { void Animation::ReschedulePendingTasks() { if (mPendingState == PendingState::NotPending) { return; } mPendingReadyTime.SetNull(); - nsIDocument* doc = GetRenderedDocument(); - if (doc) { + if (Document* doc = GetRenderedDocument()) { PendingAnimationTracker* tracker = doc->GetOrCreatePendingAnimationTracker(); if (mPendingState == PendingState::PlayPending && !tracker->IsWaitingToPlay(*this)) { tracker->AddPlayPending(*this); } else if (mPendingState == PendingState::PausePending && !tracker->IsWaitingToPause(*this)) { tracker->AddPausePending(*this); @@ -1396,17 +1386,17 @@ bool Animation::IsPossiblyOrphanedPendin } // If we have no rendered document, or we're not in our rendered document's // PendingAnimationTracker then there's a good chance no one is tracking us. // // If we're wrong and another document is tracking us then, at worst, we'll // simply start/pause the animation one tick too soon. That's better than // never starting/pausing the animation and is unlikely. - nsIDocument* doc = GetRenderedDocument(); + Document* doc = GetRenderedDocument(); if (!doc) { return true; } PendingAnimationTracker* tracker = doc->GetPendingAnimationTracker(); return !tracker || (!tracker->IsWaitingToPlay(*this) && !tracker->IsWaitingToPause(*this)); } @@ -1414,25 +1404,25 @@ bool Animation::IsPossiblyOrphanedPendin StickyTimeDuration Animation::EffectEnd() const { if (!mEffect) { return StickyTimeDuration(0); } return mEffect->SpecifiedTiming().EndTime(); } -nsIDocument* Animation::GetRenderedDocument() const { +Document* Animation::GetRenderedDocument() const { if (!mEffect || !mEffect->AsKeyframeEffect()) { return nullptr; } return mEffect->AsKeyframeEffect()->GetRenderedDocument(); } -nsIDocument* Animation::GetTimelineDocument() const { +Document* Animation::GetTimelineDocument() const { return mTimeline ? mTimeline->GetDocument() : nullptr; } class AsyncFinishNotification : public MicroTaskRunnable { public: explicit AsyncFinishNotification(Animation* aAnimation) : MicroTaskRunnable(), mAnimation(aAnimation) {} @@ -1490,17 +1480,17 @@ void Animation::DoFinishNotificationImme QueuePlaybackEvent(NS_LITERAL_STRING("finish"), AnimationTimeToTimeStamp(EffectEnd())); } void Animation::QueuePlaybackEvent(const nsAString& aName, TimeStamp&& aScheduledEventTime) { // Use document for timing. // https://drafts.csswg.org/web-animations-1/#document-for-timing - nsIDocument* doc = GetTimelineDocument(); + Document* doc = GetTimelineDocument(); if (!doc) { return; } nsPresContext* presContext = doc->GetPresContext(); if (!presContext) { return; }
--- a/dom/animation/Animation.h +++ b/dom/animation/Animation.h @@ -25,28 +25,28 @@ // X11 has a #define for CurrentTime. #ifdef CurrentTime #undef CurrentTime #endif struct JSContext; class nsCSSPropertyIDSet; -class nsIDocument; class nsIFrame; namespace mozilla { struct AnimationRule; namespace dom { class AsyncFinishNotification; class CSSAnimation; class CSSTransition; +class Document; class Animation : public DOMEventTargetHelper, public LinkedListElement<Animation> { protected: virtual ~Animation() {} public: explicit Animation(nsIGlobalObject* aGlobal) @@ -496,18 +496,18 @@ class Animation : public DOMEventTargetH aActiveDuration), zeroDuration); } TimeStamp GetTimelineCurrentTimeAsTimeStamp() const { return mTimeline ? mTimeline->GetCurrentTimeAsTimeStamp() : TimeStamp(); } - nsIDocument* GetRenderedDocument() const; - nsIDocument* GetTimelineDocument() const; + Document* GetRenderedDocument() const; + Document* GetTimelineDocument() const; RefPtr<AnimationTimeline> mTimeline; RefPtr<AnimationEffect> mEffect; // The beginning of the delay period. Nullable<TimeDuration> mStartTime; // Timeline timescale Nullable<TimeDuration> mHoldTime; // Animation timescale Nullable<TimeDuration> mPendingReadyTime; // Timeline timescale Nullable<TimeDuration> mPreviousCurrentTime; // Animation timescale
--- a/dom/animation/AnimationEffect.cpp +++ b/dom/animation/AnimationEffect.cpp @@ -30,17 +30,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCA NS_IMPL_CYCLE_COLLECTING_ADDREF(AnimationEffect) NS_IMPL_CYCLE_COLLECTING_RELEASE(AnimationEffect) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AnimationEffect) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END -AnimationEffect::AnimationEffect(nsIDocument* aDocument, TimingParams&& aTiming) +AnimationEffect::AnimationEffect(Document* aDocument, TimingParams&& aTiming) : mDocument(aDocument), mTiming(std::move(aTiming)) {} AnimationEffect::~AnimationEffect() = default; // https://drafts.csswg.org/web-animations/#current bool AnimationEffect::IsCurrent() const { if (!mAnimation || mAnimation->PlayState() == AnimationPlayState::Finished) { return false;
--- a/dom/animation/AnimationEffect.h +++ b/dom/animation/AnimationEffect.h @@ -21,23 +21,24 @@ namespace mozilla { struct ElementPropertyTransition; namespace dom { class Animation; class KeyframeEffect; struct ComputedEffectTiming; +class Document; class AnimationEffect : public nsISupports, public nsWrapperCache { public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AnimationEffect) - AnimationEffect(nsIDocument* aDocument, TimingParams&& aTiming); + AnimationEffect(Document* aDocument, TimingParams&& aTiming); virtual KeyframeEffect* AsKeyframeEffect() { return nullptr; } virtual ElementPropertyTransition* AsTransition() { return nullptr; } virtual const ElementPropertyTransition* AsTransition() const { return nullptr; } @@ -86,17 +87,17 @@ class AnimationEffect : public nsISuppor virtual bool AffectsGeometry() const = 0; protected: virtual ~AnimationEffect(); Nullable<TimeDuration> GetLocalTime() const; protected: - RefPtr<nsIDocument> mDocument; + RefPtr<Document> mDocument; RefPtr<Animation> mAnimation; TimingParams mTiming; }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_AnimationEffect_h
--- a/dom/animation/AnimationTimeline.h +++ b/dom/animation/AnimationTimeline.h @@ -12,22 +12,21 @@ #include "nsCycleCollectionParticipant.h" #include "js/TypeDecls.h" #include "mozilla/AnimationUtils.h" #include "mozilla/Attributes.h" #include "nsHashKeys.h" #include "nsIGlobalObject.h" #include "nsTHashtable.h" -class nsIDocument; - namespace mozilla { namespace dom { class Animation; +class Document; class AnimationTimeline : public nsISupports, public nsWrapperCache { public: explicit AnimationTimeline(nsIGlobalObject* aWindow) : mWindow(aWindow) { MOZ_ASSERT(mWindow); } protected: @@ -91,17 +90,17 @@ class AnimationTimeline : public nsISupp * applied to an element it is associated with the timeline even if it has a * delayed start, so this includes animations that may not be active for some * time. */ bool HasAnimations() const { return !mAnimations.IsEmpty(); } virtual void RemoveAnimation(Animation* aAnimation); - virtual nsIDocument* GetDocument() const = 0; + virtual Document* GetDocument() const = 0; protected: nsCOMPtr<nsIGlobalObject> mWindow; // Animations observing this timeline // // We store them in (a) a hashset for quick lookup, and (b) an array // to maintain a fixed sampling order.
--- a/dom/animation/AnimationUtils.cpp +++ b/dom/animation/AnimationUtils.cpp @@ -4,24 +4,26 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "AnimationUtils.h" #include "nsDebug.h" #include "nsAtom.h" #include "nsIContent.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsGlobalWindow.h" #include "nsString.h" #include "xpcpublic.h" // For xpc::NativeGlobal #include "mozilla/EffectSet.h" #include "mozilla/dom/KeyframeEffect.h" #include "mozilla/Preferences.h" +using namespace mozilla::dom; + namespace mozilla { /* static */ void AnimationUtils::LogAsyncAnimationFailure( nsCString& aMessage, const nsIContent* aContent) { if (aContent) { aMessage.AppendLiteral(" ["); aMessage.Append(nsAtomCString(aContent->NodeInfo()->NameAtom())); @@ -32,26 +34,25 @@ namespace mozilla { aMessage.Append('\''); } aMessage.Append(']'); } aMessage.Append('\n'); printf_stderr("%s", aMessage.get()); } -/* static */ nsIDocument* AnimationUtils::GetCurrentRealmDocument( - JSContext* aCx) { +/* static */ Document* AnimationUtils::GetCurrentRealmDocument(JSContext* aCx) { nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(aCx); if (!win) { return nullptr; } return win->GetDoc(); } -/* static */ nsIDocument* AnimationUtils::GetDocumentFromGlobal( +/* static */ Document* AnimationUtils::GetDocumentFromGlobal( JSObject* aGlobalObject) { nsGlobalWindowInner* win = xpc::WindowOrNull(aGlobalObject); if (!win) { return nullptr; } return win->GetDoc(); }
--- a/dom/animation/AnimationUtils.h +++ b/dom/animation/AnimationUtils.h @@ -9,27 +9,32 @@ #include "mozilla/TimeStamp.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/Nullable.h" #include "nsRFPService.h" #include "nsStringFwd.h" class nsIContent; -class nsIDocument; class nsIFrame; struct JSContext; namespace mozilla { class ComputedTimingFunction; class EffectSet; +namespace dom { +class Document; +} + class AnimationUtils { public: + typedef dom::Document Document; + static dom::Nullable<double> TimeDurationToDouble( const dom::Nullable<TimeDuration>& aTime) { dom::Nullable<double> result; if (!aTime.IsNull()) { // 0 is an inappropriate mixin for this this area; however CSS Animations // needs to have it's Time Reduction Logic refactored, so it's currently // only clamping for RFP mode. RFP mode gives a much lower time precision, @@ -53,24 +58,24 @@ class AnimationUtils { } static void LogAsyncAnimationFailure(nsCString& aMessage, const nsIContent* aContent = nullptr); /** * Get the document from the JS context to use when parsing CSS properties. */ - static nsIDocument* GetCurrentRealmDocument(JSContext* aCx); + static Document* GetCurrentRealmDocument(JSContext* aCx); /** * Get the document from the global object, or nullptr if the document has * no window, to use when constructing DOM object without entering the * target window's compartment (see KeyframeEffect constructor). */ - static nsIDocument* GetDocumentFromGlobal(JSObject* aGlobalObject); + static Document* GetDocumentFromGlobal(JSObject* aGlobalObject); /** * Checks if offscreen animation throttling is enabled. */ static bool IsOffscreenThrottlingEnabled(); /** * Returns true if the given EffectSet contains a current effect that animates
--- a/dom/animation/CSSPseudoElement.cpp +++ b/dom/animation/CSSPseudoElement.cpp @@ -41,17 +41,17 @@ ParentObject CSSPseudoElement::GetParent JSObject* CSSPseudoElement::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { return CSSPseudoElement_Binding::Wrap(aCx, this, aGivenProto); } void CSSPseudoElement::GetAnimations(const AnimationFilter& filter, nsTArray<RefPtr<Animation>>& aRetVal) { - nsIDocument* doc = mParentElement->GetComposedDoc(); + Document* doc = mParentElement->GetComposedDoc(); if (doc) { // We don't need to explicitly flush throttled animations here, since // updating the animation style of (pseudo-)elements will never affect the // set of running animations and it's only the set of running animations // that is important here. doc->FlushPendingNotifications( ChangesToFlush(FlushType::Style, false /* flush animations */)); }
--- a/dom/animation/DocumentTimeline.cpp +++ b/dom/animation/DocumentTimeline.cpp @@ -45,17 +45,17 @@ NS_IMPL_RELEASE_INHERITED(DocumentTimeli JSObject* DocumentTimeline::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { return DocumentTimeline_Binding::Wrap(aCx, this, aGivenProto); } /* static */ already_AddRefed<DocumentTimeline> DocumentTimeline::Constructor( const GlobalObject& aGlobal, const DocumentTimelineOptions& aOptions, ErrorResult& aRv) { - nsIDocument* doc = AnimationUtils::GetCurrentRealmDocument(aGlobal.Context()); + Document* doc = AnimationUtils::GetCurrentRealmDocument(aGlobal.Context()); if (!doc) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } TimeDuration originTime = TimeDuration::FromMilliseconds(aOptions.mOriginTime); if (originTime == TimeDuration::Forever() ||
--- a/dom/animation/DocumentTimeline.h +++ b/dom/animation/DocumentTimeline.h @@ -6,31 +6,31 @@ #ifndef mozilla_dom_DocumentTimeline_h #define mozilla_dom_DocumentTimeline_h #include "mozilla/dom/DocumentTimelineBinding.h" #include "mozilla/LinkedList.h" #include "mozilla/TimeStamp.h" #include "AnimationTimeline.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsDOMNavigationTiming.h" // for DOMHighResTimeStamp #include "nsRefreshDriver.h" struct JSContext; namespace mozilla { namespace dom { class DocumentTimeline final : public AnimationTimeline, public nsARefreshObserver, public nsATimerAdjustmentObserver, public LinkedListElement<DocumentTimeline> { public: - DocumentTimeline(nsIDocument* aDocument, const TimeDuration& aOriginTime) + DocumentTimeline(Document* aDocument, const TimeDuration& aOriginTime) : AnimationTimeline(aDocument->GetParentObject()), mDocument(aDocument), mIsObservingRefreshDriver(false), mOriginTime(aOriginTime) { if (mDocument) { mDocument->Timelines().insertBack(this); } } @@ -79,27 +79,27 @@ class DocumentTimeline final : public An // nsARefreshObserver methods void WillRefresh(TimeStamp aTime) override; // nsATimerAdjustmentObserver methods void NotifyTimerAdjusted(TimeStamp aTime) override; void NotifyRefreshDriverCreated(nsRefreshDriver* aDriver); void NotifyRefreshDriverDestroying(nsRefreshDriver* aDriver); - nsIDocument* GetDocument() const override { return mDocument; } + Document* GetDocument() const override { return mDocument; } protected: TimeStamp GetCurrentTimeStamp() const; nsRefreshDriver* GetRefreshDriver() const; void UnregisterFromRefreshDriver(); void MostRecentRefreshTimeUpdated(); void ObserveRefreshDriver(nsRefreshDriver* aDriver); void DisconnectRefreshDriver(nsRefreshDriver* aDriver); - nsCOMPtr<nsIDocument> mDocument; + RefPtr<Document> mDocument; // The most recently used refresh driver time. This is used in cases where // we don't have a refresh driver (e.g. because we are in a display:none // iframe). mutable TimeStamp mLastRefreshDriverTime; bool mIsObservingRefreshDriver; TimeDuration mOriginTime;
--- a/dom/animation/KeyframeEffect.cpp +++ b/dom/animation/KeyframeEffect.cpp @@ -58,17 +58,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INH NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(KeyframeEffect) NS_INTERFACE_MAP_END_INHERITING(AnimationEffect) NS_IMPL_ADDREF_INHERITED(KeyframeEffect, AnimationEffect) NS_IMPL_RELEASE_INHERITED(KeyframeEffect, AnimationEffect) -KeyframeEffect::KeyframeEffect(nsIDocument* aDocument, +KeyframeEffect::KeyframeEffect(Document* aDocument, const Maybe<OwningAnimationTarget>& aTarget, TimingParams&& aTiming, const KeyframeEffectParams& aOptions) : AnimationEffect(aDocument, std::move(aTiming)), mTarget(aTarget), mEffectOptions(aOptions), mInEffectOnLastAnimationTimingUpdate(false), mCumulativeChangeHint(nsChangeHint(0)) {} @@ -626,17 +626,17 @@ KeyframeEffect::ConstructKeyframeEffect( // to make this works in Xray case. // // In all non-Xray cases, `aGlobal` matches the current Realm, so this // matches the spec behavior. // // In Xray case, the new objects should be created using the document of // the target global, but the KeyframeEffect constructors are called in the // caller's compartment to access `aKeyframes` object. - nsIDocument* doc = AnimationUtils::GetDocumentFromGlobal(aGlobal.Get()); + Document* doc = AnimationUtils::GetDocumentFromGlobal(aGlobal.Get()); if (!doc) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } TimingParams timingParams = TimingParams::FromOptionsUnion(aOptions, doc, aRv); if (aRv.Failed()) { @@ -814,17 +814,17 @@ void DumpAnimationProperties( JS::Handle<JSObject*> aKeyframes, const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions, ErrorResult& aRv) { return ConstructKeyframeEffect(aGlobal, aTarget, aKeyframes, aOptions, aRv); } /* static */ already_AddRefed<KeyframeEffect> KeyframeEffect::Constructor( const GlobalObject& aGlobal, KeyframeEffect& aSource, ErrorResult& aRv) { - nsIDocument* doc = AnimationUtils::GetCurrentRealmDocument(aGlobal.Context()); + Document* doc = AnimationUtils::GetCurrentRealmDocument(aGlobal.Context()); if (!doc) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } // Create a new KeyframeEffect object with aSource's target, // iteration composite operation, composite operation, and spacing mode. // The constructor creates a new AnimationEffect object by @@ -1236,17 +1236,17 @@ bool KeyframeEffect::CanThrottleOverflow return (!lastSyncTime.IsNull() && (now - lastSyncTime) < OverflowRegionRefreshInterval()); } bool KeyframeEffect::CanThrottleOverflowChangesInScrollable( nsIFrame& aFrame) const { // If the target element is not associated with any documents, we don't care // it. - nsIDocument* doc = GetRenderedDocument(); + Document* doc = GetRenderedDocument(); if (!doc) { return true; } bool hasIntersectionObservers = doc->HasIntersectionObservers(); // If we know that the animation cannot cause overflow, // we can just disable flushes for this animation. @@ -1309,25 +1309,25 @@ nsIFrame* KeyframeEffect::GetPrimaryFram frame = mTarget->mElement->GetPrimaryFrame(); MOZ_ASSERT(mTarget->mPseudoType == CSSPseudoElementType::NotPseudo, "unknown mTarget->mPseudoType"); } return frame; } -nsIDocument* KeyframeEffect::GetRenderedDocument() const { +Document* KeyframeEffect::GetRenderedDocument() const { if (!mTarget) { return nullptr; } return mTarget->mElement->GetComposedDoc(); } nsIPresShell* KeyframeEffect::GetPresShell() const { - nsIDocument* doc = GetRenderedDocument(); + Document* doc = GetRenderedDocument(); if (!doc) { return nullptr; } return doc->GetShell(); } /* static */ bool KeyframeEffect::IsGeometricProperty( const nsCSSPropertyID aProperty) {
--- a/dom/animation/KeyframeEffect.h +++ b/dom/animation/KeyframeEffect.h @@ -28,17 +28,16 @@ #include "mozilla/StyleAnimationValue.h" #include "mozilla/dom/AnimationEffect.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/Element.h" struct JSContext; class JSObject; class nsIContent; -class nsIDocument; class nsIFrame; class nsIPresShell; namespace mozilla { class AnimValuesStyleRule; enum class CSSPseudoElementType : uint8_t; class ErrorResult; @@ -101,20 +100,21 @@ struct AnimationProperty { } }; struct ElementPropertyTransition; namespace dom { class Animation; +class Document; class KeyframeEffect : public AnimationEffect { public: - KeyframeEffect(nsIDocument* aDocument, + KeyframeEffect(Document* aDocument, const Maybe<OwningAnimationTarget>& aTarget, TimingParams&& aTiming, const KeyframeEffectParams& aOptions); NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(KeyframeEffect, AnimationEffect) virtual JSObject* WrapObject(JSContext* aCx, @@ -252,17 +252,17 @@ class KeyframeEffect : public AnimationE bool ShouldBlockAsyncTransformAnimations( const nsIFrame* aFrame, AnimationPerformanceWarning::Type& aPerformanceWarning /* out */) const; bool HasGeometricProperties() const; bool AffectsGeometry() const override { return GetTarget() && HasGeometricProperties(); } - nsIDocument* GetRenderedDocument() const; + Document* GetRenderedDocument() const; nsIPresShell* GetPresShell() const; // Associates a warning with the animated property on the specified frame // indicating why, for example, the property could not be animated on the // compositor. |aParams| and |aParamsLength| are optional parameters which // will be used to generate a localized message for devtools. void SetPerformanceWarning(nsCSSPropertyID aProperty, const AnimationPerformanceWarning& aWarning);
--- a/dom/animation/KeyframeUtils.cpp +++ b/dom/animation/KeyframeUtils.cpp @@ -22,17 +22,17 @@ #include "mozilla/dom/KeyframeEffect.h" // For PropertyValuesPair etc. #include "mozilla/dom/Nullable.h" #include "jsapi.h" // For ForOfIterator etc. #include "nsClassHashtable.h" #include "nsContentUtils.h" // For GetContextForContent #include "nsCSSPropertyIDSet.h" #include "nsCSSProps.h" #include "nsCSSPseudoElements.h" // For CSSPseudoElementType -#include "nsIDocument.h" // For nsIDocument::AreWebAnimationsImplicitKeyframesEnabled +#include "mozilla/dom/Document.h" // For Document::AreWebAnimationsImplicitKeyframesEnabled #include "nsIScriptError.h" #include "nsTArray.h" #include <algorithm> // For std::stable_sort, std::min using mozilla::dom::Nullable; namespace mozilla { @@ -128,22 +128,22 @@ class ComputedOffsetComparator { // ------------------------------------------------------------------ // // Internal helper method declarations // // ------------------------------------------------------------------ static void GetKeyframeListFromKeyframeSequence(JSContext* aCx, - nsIDocument* aDocument, + Document* aDocument, JS::ForOfIterator& aIterator, nsTArray<Keyframe>& aResult, ErrorResult& aRv); -static bool ConvertKeyframeSequence(JSContext* aCx, nsIDocument* aDocument, +static bool ConvertKeyframeSequence(JSContext* aCx, Document* aDocument, JS::ForOfIterator& aIterator, nsTArray<Keyframe>& aResult); static bool GetPropertyValuesPairs(JSContext* aCx, JS::Handle<JSObject*> aObject, ListAllowance aAllowLists, nsTArray<PropertyValuesPair>& aResult); @@ -152,17 +152,17 @@ static bool AppendStringOrStringSequence ListAllowance aAllowLists, nsTArray<nsString>& aValues); static bool AppendValueAsString(JSContext* aCx, nsTArray<nsString>& aValues, JS::Handle<JS::Value> aValue); static Maybe<PropertyValuePair> MakePropertyValuePair( nsCSSPropertyID aProperty, const nsAString& aStringValue, - nsIDocument* aDocument); + Document* aDocument); static bool HasValidOffsets(const nsTArray<Keyframe>& aKeyframes); #ifdef DEBUG static void MarkAsComputeValuesFailureKey(PropertyValuePair& aPair); #endif @@ -170,32 +170,32 @@ static nsTArray<ComputedKeyframeValues> const nsTArray<Keyframe>& aKeyframes, dom::Element* aElement, const ComputedStyle* aComputedValues); static void BuildSegmentsFromValueEntries( nsTArray<KeyframeValueEntry>& aEntries, nsTArray<AnimationProperty>& aResult); static void GetKeyframeListFromPropertyIndexedKeyframe( - JSContext* aCx, nsIDocument* aDocument, JS::Handle<JS::Value> aValue, + JSContext* aCx, Document* aDocument, JS::Handle<JS::Value> aValue, nsTArray<Keyframe>& aResult, ErrorResult& aRv); static bool HasImplicitKeyframeValues(const nsTArray<Keyframe>& aKeyframes, - nsIDocument* aDocument); + Document* aDocument); static void DistributeRange(const Range<Keyframe>& aRange); // ------------------------------------------------------------------ // // Public API // // ------------------------------------------------------------------ /* static */ nsTArray<Keyframe> KeyframeUtils::GetKeyframesFromObject( - JSContext* aCx, nsIDocument* aDocument, JS::Handle<JSObject*> aFrames, + JSContext* aCx, Document* aDocument, JS::Handle<JSObject*> aFrames, ErrorResult& aRv) { MOZ_ASSERT(!aRv.Failed()); nsTArray<Keyframe> keyframes; if (!aFrames) { // The argument was explicitly null meaning no keyframes. return keyframes; @@ -219,17 +219,17 @@ static void DistributeRange(const Range< } if (aRv.Failed()) { MOZ_ASSERT(keyframes.IsEmpty(), "Should not set any keyframes when there is an error"); return keyframes; } - if (!nsIDocument::AreWebAnimationsImplicitKeyframesEnabled(aCx, nullptr) && + if (!Document::AreWebAnimationsImplicitKeyframesEnabled(aCx, nullptr) && HasImplicitKeyframeValues(keyframes, aDocument)) { keyframes.Clear(); aRv.Throw(NS_ERROR_DOM_ANIM_MISSING_PROPS_ERR); } return keyframes; } @@ -335,17 +335,17 @@ KeyframeUtils::GetAnimationPropertiesFro * @param aDocument The document to use when parsing CSS properties. * @param aIterator An already-initialized ForOfIterator for the JS * object to iterate over as a sequence. * @param aResult The array into which the resulting Keyframe objects will be * appended. * @param aRv Out param to store any errors thrown by this function. */ static void GetKeyframeListFromKeyframeSequence(JSContext* aCx, - nsIDocument* aDocument, + Document* aDocument, JS::ForOfIterator& aIterator, nsTArray<Keyframe>& aResult, ErrorResult& aRv) { MOZ_ASSERT(!aRv.Failed()); MOZ_ASSERT(aResult.IsEmpty()); // Convert the object in aIterator to a sequence of keyframes producing // an array of Keyframe objects. @@ -370,17 +370,17 @@ static void GetKeyframeListFromKeyframeS } } /** * Converts a JS object wrapped by the given JS::ForIfIterator to an * IDL sequence<Keyframe> and stores the resulting Keyframe objects in * aResult. */ -static bool ConvertKeyframeSequence(JSContext* aCx, nsIDocument* aDocument, +static bool ConvertKeyframeSequence(JSContext* aCx, Document* aDocument, JS::ForOfIterator& aIterator, nsTArray<Keyframe>& aResult) { JS::Rooted<JS::Value> value(aCx); ErrorResult parseEasingResult; for (;;) { bool done; if (!aIterator.next(&value, &done)) { @@ -584,17 +584,17 @@ static bool AppendStringOrStringSequence static bool AppendValueAsString(JSContext* aCx, nsTArray<nsString>& aValues, JS::Handle<JS::Value> aValue) { return ConvertJSValueToString(aCx, aValue, dom::eStringify, dom::eStringify, *aValues.AppendElement()); } static void ReportInvalidPropertyValueToConsole( nsCSSPropertyID aProperty, const nsAString& aInvalidPropertyValue, - nsIDocument* aDoc) { + Document* aDoc) { const nsString& invalidValue = PromiseFlatString(aInvalidPropertyValue); const NS_ConvertASCIItoUTF16 propertyName( nsCSSProps::GetStringValue(aProperty)); const char16_t* params[] = {invalidValue.get(), propertyName.get()}; nsContentUtils::ReportToConsole( nsIScriptError::warningFlag, NS_LITERAL_CSTRING("Animation"), aDoc, nsContentUtils::eDOM_PROPERTIES, "InvalidKeyframePropertyValue", params, ArrayLength(params)); @@ -607,17 +607,17 @@ static void ReportInvalidPropertyValueTo * @param aProperty The CSS property. * @param aStringValue The property value to parse. * @param aDocument The document to use when parsing. * @return The constructed PropertyValuePair, or Nothing() if |aStringValue| is * an invalid property value. */ static Maybe<PropertyValuePair> MakePropertyValuePair( nsCSSPropertyID aProperty, const nsAString& aStringValue, - nsIDocument* aDocument) { + Document* aDocument) { MOZ_ASSERT(aDocument); Maybe<PropertyValuePair> result; ServoCSSParser::ParsingEnvironment env = ServoCSSParser::GetParsingEnvironment(aDocument); RefPtr<RawServoDeclarationBlock> servoDeclarationBlock = ServoCSSParser::ParseProperty(aProperty, aStringValue, env); @@ -937,17 +937,17 @@ static void BuildSegmentsFromValueEntrie * @param aCx The JSContext for |aValue|. * @param aDocument The document to use when parsing CSS properties. * @param aValue The JS object. * @param aResult The array into which the resulting AnimationProperty * objects will be appended. * @param aRv Out param to store any errors thrown by this function. */ static void GetKeyframeListFromPropertyIndexedKeyframe( - JSContext* aCx, nsIDocument* aDocument, JS::Handle<JS::Value> aValue, + JSContext* aCx, Document* aDocument, JS::Handle<JS::Value> aValue, nsTArray<Keyframe>& aResult, ErrorResult& aRv) { MOZ_ASSERT(aValue.isObject()); MOZ_ASSERT(aResult.IsEmpty()); MOZ_ASSERT(!aRv.Failed()); // Convert the object to a property-indexed keyframe dictionary to // get its explicit dictionary members. dom::binding_detail::FastBasePropertyIndexedKeyframe keyframeDict; @@ -1139,17 +1139,17 @@ static void GetKeyframeListFromPropertyI * offsets. The check is not entirely accurate but should detect most common * cases. * * @param aKeyframes The set of keyframes to analyze. * @param aDocument The document to use when parsing keyframes so we can * try to detect where we have an invalid value at 0%/100%. */ static bool HasImplicitKeyframeValues(const nsTArray<Keyframe>& aKeyframes, - nsIDocument* aDocument) { + Document* aDocument) { // We are looking to see if that every property referenced in |aKeyframes| // has a valid property at offset 0.0 and 1.0. The check as to whether a // property is valid or not, however, is not precise. We only check if the // property can be parsed, NOT whether it can also be converted to a // StyleAnimationValue since doing that requires a target element bound to // a document which we might not always have at the point where we want to // perform this check. //
--- a/dom/animation/KeyframeUtils.h +++ b/dom/animation/KeyframeUtils.h @@ -9,28 +9,28 @@ #include "mozilla/KeyframeEffectParams.h" // For CompositeOperation #include "nsCSSPropertyID.h" #include "nsTArrayForwardDeclare.h" // For nsTArray #include "js/RootingAPI.h" // For JS::Handle struct JSContext; class JSObject; -class nsIDocument; class ComputedStyle; struct RawServoDeclarationBlock; namespace mozilla { struct AnimationProperty; enum class CSSPseudoElementType : uint8_t; class ErrorResult; struct Keyframe; struct PropertyStyleAnimationValuePair; namespace dom { +class Document; class Element; } // namespace dom } // namespace mozilla namespace mozilla { // Represents the set of property-value pairs on a Keyframe converted to // computed values. @@ -51,17 +51,17 @@ class KeyframeUtils { * that is the keyframe list specification. * @param aRv (out) Out-param to hold any error returned by this function. * Must be initially empty. * @return The set of processed keyframes. If an error occurs, aRv will be * filled-in with the appropriate error code and an empty array will be * returned. */ static nsTArray<Keyframe> GetKeyframesFromObject( - JSContext* aCx, nsIDocument* aDocument, JS::Handle<JSObject*> aFrames, + JSContext* aCx, dom::Document* aDocument, JS::Handle<JSObject*> aFrames, ErrorResult& aRv); /** * Calculate the computed offset of keyframes by evenly distributing keyframes * with a missing offset. * * @see * https://drafts.csswg.org/web-animations/#calculating-computed-keyframes
--- a/dom/animation/PendingAnimationTracker.h +++ b/dom/animation/PendingAnimationTracker.h @@ -5,26 +5,30 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_PendingAnimationTracker_h #define mozilla_dom_PendingAnimationTracker_h #include "mozilla/dom/Animation.h" #include "mozilla/TypedEnumBits.h" #include "nsCycleCollectionParticipant.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsTHashtable.h" class nsIFrame; namespace mozilla { +namespace dom { +class Document; +} + class PendingAnimationTracker final { public: - explicit PendingAnimationTracker(nsIDocument* aDocument) + explicit PendingAnimationTracker(dom::Document* aDocument) : mDocument(aDocument) {} NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PendingAnimationTracker) NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(PendingAnimationTracker) void AddPlayPending(dom::Animation& aAnimation) { // We'd like to assert here that IsWaitingToPause(aAnimation) is false but // if |aAnimation| was tracked here as a pause-pending animation when it was @@ -81,17 +85,17 @@ class PendingAnimationTracker final { void AddPending(dom::Animation& aAnimation, AnimationSet& aSet); void RemovePending(dom::Animation& aAnimation, AnimationSet& aSet); bool IsWaiting(const dom::Animation& aAnimation, const AnimationSet& aSet) const; AnimationSet mPlayPendingSet; AnimationSet mPausePendingSet; - nsCOMPtr<nsIDocument> mDocument; + RefPtr<dom::Document> mDocument; public: enum class CheckState { Indeterminate = 0, Absent = 1 << 0, AnimationsPresent = 1 << 1, TransitionsPresent = 1 << 2, };
--- a/dom/animation/TimingParams.cpp +++ b/dom/animation/TimingParams.cpp @@ -6,17 +6,17 @@ #include "mozilla/TimingParams.h" #include "mozilla/AnimationUtils.h" #include "mozilla/dom/AnimatableBinding.h" #include "mozilla/dom/KeyframeAnimationOptionsBinding.h" #include "mozilla/dom/KeyframeEffectBinding.h" #include "mozilla/ServoCSSParser.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" namespace mozilla { template <class OptionsType> static const dom::EffectTiming& GetTimingProperties( const OptionsType& aOptions); template <> @@ -30,17 +30,17 @@ template <> /* static */ const dom::EffectTiming& GetTimingProperties( const dom::UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions) { MOZ_ASSERT(aOptions.IsKeyframeAnimationOptions()); return aOptions.GetAsKeyframeAnimationOptions(); } template <class OptionsType> /* static */ TimingParams TimingParams::FromOptionsType( - const OptionsType& aOptions, nsIDocument* aDocument, ErrorResult& aRv) { + const OptionsType& aOptions, Document* aDocument, ErrorResult& aRv) { TimingParams result; if (aOptions.IsUnrestrictedDouble()) { double durationInMs = aOptions.GetAsUnrestrictedDouble(); if (durationInMs >= 0) { result.mDuration.emplace( StickyTimeDuration::FromMilliseconds(durationInMs)); } else { @@ -53,28 +53,28 @@ template <class OptionsType> result = FromEffectTiming(timing, aDocument, aRv); } return result; } /* static */ TimingParams TimingParams::FromOptionsUnion( const dom::UnrestrictedDoubleOrKeyframeEffectOptions& aOptions, - nsIDocument* aDocument, ErrorResult& aRv) { + Document* aDocument, ErrorResult& aRv) { return FromOptionsType(aOptions, aDocument, aRv); } /* static */ TimingParams TimingParams::FromOptionsUnion( const dom::UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions, - nsIDocument* aDocument, ErrorResult& aRv) { + Document* aDocument, ErrorResult& aRv) { return FromOptionsType(aOptions, aDocument, aRv); } /* static */ TimingParams TimingParams::FromEffectTiming( - const dom::EffectTiming& aEffectTiming, nsIDocument* aDocument, + const dom::EffectTiming& aEffectTiming, Document* aDocument, ErrorResult& aRv) { TimingParams result; Maybe<StickyTimeDuration> duration = TimingParams::ParseDuration(aEffectTiming.mDuration, aRv); if (aRv.Failed()) { return result; } @@ -103,17 +103,17 @@ template <class OptionsType> result.Update(); return result; } /* static */ TimingParams TimingParams::MergeOptionalEffectTiming( const TimingParams& aSource, const dom::OptionalEffectTiming& aEffectTiming, - nsIDocument* aDocument, ErrorResult& aRv) { + Document* aDocument, ErrorResult& aRv) { MOZ_ASSERT(!aRv.Failed(), "Initially return value should be ok"); TimingParams result = aSource; // Check for errors first Maybe<StickyTimeDuration> duration; if (aEffectTiming.mDuration.WasPassed()) { @@ -178,17 +178,17 @@ template <class OptionsType> } result.Update(); return result; } /* static */ Maybe<ComputedTimingFunction> TimingParams::ParseEasing( - const nsAString& aEasing, nsIDocument* aDocument, ErrorResult& aRv) { + const nsAString& aEasing, Document* aDocument, ErrorResult& aRv) { MOZ_ASSERT(aDocument); nsTimingFunction timingFunction; RefPtr<URLExtraData> url = ServoCSSParser::GetURLExtraData(aDocument); if (!ServoCSSParser::ParseEasing(aEasing, url, timingFunction)) { aRv.ThrowTypeError<dom::MSG_INVALID_EASING_ERROR>(aEasing); return Nothing(); }
--- a/dom/animation/TimingParams.h +++ b/dom/animation/TimingParams.h @@ -13,21 +13,20 @@ #include "mozilla/ComputedTimingFunction.h" #include "mozilla/Maybe.h" #include "mozilla/StickyTimeDuration.h" #include "mozilla/TimeStamp.h" // for TimeDuration #include "mozilla/dom/AnimationEffectBinding.h" // for FillMode // and PlaybackDirection -class nsIDocument; - namespace mozilla { namespace dom { +class Document; class UnrestrictedDoubleOrKeyframeEffectOptions; class UnrestrictedDoubleOrKeyframeAnimationOptions; } // namespace dom struct TimingParams { TimingParams() = default; TimingParams(float aDuration, float aDelay, float aIterationCount, @@ -51,35 +50,36 @@ struct TimingParams { mFill(aFillMode), mFunction(aFunction) { mDuration.emplace(aDuration); Update(); } template <class OptionsType> static TimingParams FromOptionsType(const OptionsType& aOptions, - nsIDocument* aDocument, ErrorResult& aRv); + dom::Document* aDocument, + ErrorResult& aRv); static TimingParams FromOptionsUnion( const dom::UnrestrictedDoubleOrKeyframeEffectOptions& aOptions, - nsIDocument* aDocument, ErrorResult& aRv); + dom::Document* aDocument, ErrorResult& aRv); static TimingParams FromOptionsUnion( const dom::UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions, - nsIDocument* aDocument, ErrorResult& aRv); + dom::Document* aDocument, ErrorResult& aRv); static TimingParams FromEffectTiming(const dom::EffectTiming& aEffectTiming, - nsIDocument* aDocument, + dom::Document* aDocument, ErrorResult& aRv); // Returns a copy of |aSource| where each timing property in |aSource| that // is also specified in |aEffectTiming| is replaced with the value from // |aEffectTiming|. // // If any of the values in |aEffectTiming| are invalid, |aRv.Failed()| will be // true and an unmodified copy of |aSource| will be returned. static TimingParams MergeOptionalEffectTiming( const TimingParams& aSource, - const dom::OptionalEffectTiming& aEffectTiming, nsIDocument* aDocument, + const dom::OptionalEffectTiming& aEffectTiming, dom::Document* aDocument, ErrorResult& aRv); // Range-checks and validates an UnrestrictedDoubleOrString or // OwningUnrestrictedDoubleOrString object and converts to a // StickyTimeDuration value or Nothing() if aDuration is "auto". // Caller must check aRv.Failed(). template <class DoubleOrString> static Maybe<StickyTimeDuration> ParseDuration(DoubleOrString& aDuration, @@ -110,17 +110,17 @@ struct TimingParams { static void ValidateIterations(double aIterations, ErrorResult& aRv) { if (IsNaN(aIterations) || aIterations < 0) { aRv.ThrowTypeError<dom::MSG_ENFORCE_RANGE_OUT_OF_RANGE>( NS_LITERAL_STRING("iterations")); } } static Maybe<ComputedTimingFunction> ParseEasing(const nsAString& aEasing, - nsIDocument* aDocument, + dom::Document* aDocument, ErrorResult& aRv); static StickyTimeDuration CalcActiveDuration( const Maybe<StickyTimeDuration>& aDuration, double aIterations) { // If either the iteration duration or iteration count is zero, // Web Animations says that the active duration is zero. This is to // ensure that the result is defined when the other argument is Infinity. static const StickyTimeDuration zeroDuration;
--- a/dom/audiochannel/AudioChannelAgent.cpp +++ b/dom/audiochannel/AudioChannelAgent.cpp @@ -1,17 +1,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "AudioChannelAgent.h" #include "AudioChannelService.h" #include "mozilla/Preferences.h" #include "nsContentUtils.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIDOMWindow.h" #include "nsPIDOMWindow.h" #include "nsIURI.h" using namespace mozilla::dom; NS_IMPL_CYCLE_COLLECTION_CLASS(AudioChannelAgent) @@ -81,17 +81,17 @@ nsresult AudioChannelAgent::FindCorrectW return NS_OK; } nsCOMPtr<nsPIDOMWindowInner> parent = outerParent->GetCurrentInnerWindow(); if (!parent) { return NS_OK; } - nsCOMPtr<nsIDocument> doc = parent->GetExtantDoc(); + nsCOMPtr<Document> doc = parent->GetExtantDoc(); if (!doc) { return NS_OK; } if (nsContentUtils::IsChromeDoc(doc)) { return NS_OK; }
--- a/dom/audiochannel/AudioChannelService.cpp +++ b/dom/audiochannel/AudioChannelService.cpp @@ -872,17 +872,17 @@ void AudioChannelService::AudioChannelWi return; } nsCOMPtr<nsPIDOMWindowInner> inner = window->GetCurrentInnerWindow(); if (!inner) { return; } - nsCOMPtr<nsIDocument> doc = inner->GetExtantDoc(); + nsCOMPtr<Document> doc = inner->GetExtantDoc(); if (!doc) { return; } if (window->GetMediaSuspend() != nsISuspendedTypes::SUSPENDED_BLOCK || !doc->Hidden()) { return; }
--- a/dom/base/AnonymousContent.cpp +++ b/dom/base/AnonymousContent.cpp @@ -4,17 +4,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "AnonymousContent.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/AnonymousContentBinding.h" #include "nsComputedDOMStyle.h" #include "nsCycleCollectionParticipant.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIFrame.h" #include "nsStyledElement.h" #include "HTMLCanvasElement.h" namespace mozilla { namespace dom { // Ref counting and cycle collection
--- a/dom/base/AnonymousContent.h +++ b/dom/base/AnonymousContent.h @@ -5,17 +5,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_AnonymousContent_h #define mozilla_dom_AnonymousContent_h #include "mozilla/dom/Element.h" #include "nsCycleCollectionParticipant.h" #include "nsICSSDeclaration.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" namespace mozilla { namespace dom { class Element; class UnrestrictedDoubleOrAnonymousKeyframeAnimationOptions; class AnonymousContent final {
--- a/dom/base/Attr.cpp +++ b/dom/base/Attr.cpp @@ -13,17 +13,17 @@ #include "mozilla/dom/Element.h" #include "mozilla/EventDispatcher.h" #include "mozilla/InternalMutationEvent.h" #include "nsContentCreatorFunctions.h" #include "nsError.h" #include "nsUnicharUtils.h" #include "nsDOMString.h" #include "nsIContentInlines.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsGkAtoms.h" #include "nsCOMArray.h" #include "nsNameSpaceManager.h" #include "nsNodeUtils.h" #include "nsTextNode.h" #include "mozAutoDocUpdate.h" #include "nsWrapperCacheInlines.h" #include "NodeUbiReporting.h" @@ -110,20 +110,20 @@ void Attr::SetMap(nsDOMAttributeMap* aMa Element* Attr::GetElement() const { if (!mAttrMap) { return nullptr; } nsIContent* content = mAttrMap->GetContent(); return content ? content->AsElement() : nullptr; } -nsresult Attr::SetOwnerDocument(nsIDocument* aDocument) { +nsresult Attr::SetOwnerDocument(Document* aDocument) { NS_ASSERTION(aDocument, "Missing document"); - nsIDocument* doc = OwnerDoc(); + Document* doc = OwnerDoc(); NS_ASSERTION(doc != aDocument, "bad call to Attr::SetOwnerDocument"); doc->DeleteAllPropertiesFor(this); RefPtr<dom::NodeInfo> newNodeInfo = aDocument->NodeInfoManager()->GetNodeInfo( mNodeInfo->NameAtom(), mNodeInfo->GetPrefixAtom(), mNodeInfo->NamespaceID(), ATTRIBUTE_NODE); NS_ASSERTION(newNodeInfo, "GetNodeInfo lies"); mNodeInfo.swap(newNodeInfo);
--- a/dom/base/Attr.h +++ b/dom/base/Attr.h @@ -13,22 +13,22 @@ #include "mozilla/Attributes.h" #include "nsINode.h" #include "nsString.h" #include "nsCOMPtr.h" #include "nsCycleCollectionParticipant.h" #include "nsStubMutationObserver.h" -class nsIDocument; - namespace mozilla { class EventChainPreVisitor; namespace dom { +class Document; + // Attribute helper class used to wrap up an attribute with a dom // object that implements the DOM Attr interface. class Attr final : public nsINode { virtual ~Attr() {} public: Attr(nsDOMAttributeMap* aAttrMap, already_AddRefed<dom::NodeInfo>&& aNodeInfo, const nsAString& aValue); @@ -56,17 +56,17 @@ class Attr final : public nsINode { void SetMap(nsDOMAttributeMap* aMap); Element* GetElement() const; /** * Called when our ownerElement is moved into a new document. * Updates the nodeinfo of this node. */ - nsresult SetOwnerDocument(nsIDocument* aDocument); + nsresult SetOwnerDocument(Document* aDocument); // nsINode interface virtual bool IsNodeOfType(uint32_t aFlags) const override; virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override; virtual already_AddRefed<nsIURI> GetBaseURI( bool aTryUseXHRDocBaseURI = false) const override; static void Initialize();
--- a/dom/base/AttrArray.cpp +++ b/dom/base/AttrArray.cpp @@ -18,16 +18,17 @@ #include "nsMappedAttributeElement.h" #include "nsString.h" #include "nsHTMLStyleSheet.h" #include "nsMappedAttributes.h" #include "nsUnicharUtils.h" #include "nsContentUtils.h" // nsAutoScriptBlocker using mozilla::CheckedUint32; +using mozilla::dom::Document; AttrArray::Impl::~Impl() { for (InternalAttr& attr : NonMappedAttrs()) { attr.~InternalAttr(); } NS_IF_RELEASE(mMappedAttrs); } @@ -353,17 +354,17 @@ void AttrArray::Compact() { } uint32_t AttrArray::DoGetMappedAttrCount() const { MOZ_ASSERT(mImpl && mImpl->mMappedAttrs); return static_cast<uint32_t>(mImpl->mMappedAttrs->Count()); } nsresult AttrArray::ForceMapped(nsMappedAttributeElement* aContent, - nsIDocument* aDocument) { + Document* aDocument) { nsHTMLStyleSheet* sheet = aDocument->GetAttributeStyleSheet(); RefPtr<nsMappedAttributes> mapped = GetModifiableMapped(aContent, sheet, false, 0); return MakeMappedUnique(mapped); } void AttrArray::ClearMappedServoStyle() { if (mImpl && mImpl->mMappedAttrs) {
--- a/dom/base/AttrArray.h +++ b/dom/base/AttrArray.h @@ -105,17 +105,17 @@ class AttrArray { void Compact(); size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; bool HasMappedAttrs() const { return MappedAttrCount(); } const nsMappedAttributes* GetMapped() const; // Force this to have mapped attributes, even if those attributes are empty. nsresult ForceMapped(nsMappedAttributeElement* aContent, - nsIDocument* aDocument); + mozilla::dom::Document* aDocument); // Clear the servo declaration block on the mapped attributes, if any // Will assert off main thread void ClearMappedServoStyle(); // Increases capacity (if necessary) to have enough space to accomodate the // unmapped attributes of |aOther|. nsresult EnsureCapacityToClone(const AttrArray& aOther);
--- a/dom/base/CharacterData.cpp +++ b/dom/base/CharacterData.cpp @@ -13,17 +13,17 @@ #include "mozilla/DebugOnly.h" #include "mozilla/AsyncEventDispatcher.h" #include "mozilla/MemoryReporting.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/HTMLSlotElement.h" #include "mozilla/dom/ShadowRoot.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsReadableUtils.h" #include "mozilla/InternalMutationEvent.h" #include "nsIURI.h" #include "nsCOMPtr.h" #include "nsDOMString.h" #include "nsChangeHint.h" #include "nsCOMArray.h" #include "nsNodeUtils.h" @@ -225,17 +225,17 @@ nsresult CharacterData::SetTextInternal( uint32_t endOffset = aOffset + aCount; // Make sure the text fragment can hold the new data. if (aLength > aCount && !mText.CanGrowBy(aLength - aCount)) { return NS_ERROR_OUT_OF_MEMORY; } - nsIDocument* document = GetComposedDoc(); + Document* document = GetComposedDoc(); mozAutoDocUpdate updateBatch(document, aNotify); bool haveMutationListeners = aNotify && nsContentUtils::HasMutationListeners( this, NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED, this); RefPtr<nsAtom> oldValue; if (haveMutationListeners) { @@ -385,17 +385,17 @@ void CharacterData::ToCString(nsAString& } else { aBuf.Append(ch); } } } } #endif -nsresult CharacterData::BindToTree(nsIDocument* aDocument, nsIContent* aParent, +nsresult CharacterData::BindToTree(Document* aDocument, nsIContent* aParent, nsIContent* aBindingParent) { MOZ_ASSERT(aParent || aDocument, "Must have document if no parent!"); MOZ_ASSERT(NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc(), "Must have the same owner document"); MOZ_ASSERT(!aParent || aDocument == aParent->GetUncomposedDoc(), "aDocument must be current doc of aParent"); MOZ_ASSERT(!GetUncomposedDoc() && !IsInUncomposedDoc(), "Already have a document. Unbind first!"); @@ -495,17 +495,17 @@ nsresult CharacterData::BindToTree(nsIDo return NS_OK; } void CharacterData::UnbindFromTree(bool aDeep, bool aNullParent) { // Unset frame flags; if we need them again later, they'll get set again. UnsetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE | NS_REFRAME_IF_WHITESPACE); - nsIDocument* document = GetComposedDoc(); + Document* document = GetComposedDoc(); if (aNullParent) { if (this->IsRootOfNativeAnonymousSubtree()) { nsNodeUtils::NativeAnonymousChildListChange(this, true); } if (GetParent()) { NS_RELEASE(mParent); } else {
--- a/dom/base/CharacterData.h +++ b/dom/base/CharacterData.h @@ -18,18 +18,16 @@ #include "nsTextFragment.h" #include "nsError.h" #include "mozilla/dom/Element.h" #include "nsCycleCollectionParticipant.h" #include "nsISMILAttr.h" #include "mozilla/dom/ShadowRoot.h" -class nsIDocument; - namespace mozilla { namespace dom { class HTMLSlotElement; } // namespace dom } // namespace mozilla #define CHARACTER_DATA_FLAG_BIT(n_) \ NODE_FLAG_BIT(NODE_TYPE_SPECIFIC_BITS_OFFSET + (n_)) @@ -105,17 +103,17 @@ class CharacterData : public nsIContent nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) final { // Batch possible DOMSubtreeModified events. mozAutoSubtreeModified subtree(OwnerDoc(), nullptr); return SetNodeValue(aTextContent, aError); } // Implementation for nsIContent - nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsresult BindToTree(Document* aDocument, nsIContent* aParent, nsIContent* aBindingParent) override; void UnbindFromTree(bool aDeep = true, bool aNullParent = true) override; already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) final { return nullptr; }
--- a/dom/base/ChildIterator.cpp +++ b/dom/base/ChildIterator.cpp @@ -1,23 +1,23 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ChildIterator.h" #include "nsContentUtils.h" +#include "mozilla/dom/Document.h" #include "mozilla/dom/HTMLSlotElement.h" #include "mozilla/dom/XBLChildrenElement.h" #include "mozilla/dom/ShadowRoot.h" #include "nsIAnonymousContentCreator.h" #include "nsIFrame.h" #include "nsCSSAnonBoxes.h" -#include "nsIDocument.h" namespace mozilla { namespace dom { ExplicitChildIterator::ExplicitChildIterator(const nsIContent* aParent, bool aStartAtBeginning) : mParent(aParent), mChild(nullptr),
--- a/dom/base/ChromeNodeList.cpp +++ b/dom/base/ChromeNodeList.cpp @@ -8,17 +8,17 @@ #include "mozilla/dom/ChromeNodeListBinding.h" using namespace mozilla; using namespace mozilla::dom; already_AddRefed<ChromeNodeList> ChromeNodeList::Constructor( const GlobalObject& aGlobal, ErrorResult& aRv) { nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(aGlobal.GetAsSupports()); - nsIDocument* root = win ? win->GetExtantDoc() : nullptr; + Document* root = win ? win->GetExtantDoc() : nullptr; RefPtr<ChromeNodeList> list = new ChromeNodeList(root); return list.forget(); } JSObject* ChromeNodeList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { return ChromeNodeList_Binding::Wrap(aCx, this, aGivenProto); }
--- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -93,35 +93,35 @@ size_t LifecycleCallbackArgs::SizeOfExcl n += oldValue.SizeOfExcludingThisIfUnshared(aMallocSizeOf); n += newValue.SizeOfExcludingThisIfUnshared(aMallocSizeOf); n += namespaceURI.SizeOfExcludingThisIfUnshared(aMallocSizeOf); return n; } void CustomElementCallback::Call() { switch (mType) { - case nsIDocument::eConnected: + case Document::eConnected: static_cast<LifecycleConnectedCallback*>(mCallback.get()) ->Call(mThisObject); break; - case nsIDocument::eDisconnected: + case Document::eDisconnected: static_cast<LifecycleDisconnectedCallback*>(mCallback.get()) ->Call(mThisObject); break; - case nsIDocument::eAdopted: + case Document::eAdopted: static_cast<LifecycleAdoptedCallback*>(mCallback.get()) ->Call(mThisObject, mAdoptedCallbackArgs.mOldDocument, mAdoptedCallbackArgs.mNewDocument); break; - case nsIDocument::eAttributeChanged: + case Document::eAttributeChanged: static_cast<LifecycleAttributeChangedCallback*>(mCallback.get()) ->Call(mThisObject, mArgs.name, mArgs.oldValue, mArgs.newValue, mArgs.namespaceURI); break; - case nsIDocument::eGetCustomInterface: + case Document::eGetCustomInterface: MOZ_ASSERT_UNREACHABLE("Don't call GetCustomInterface through callback"); break; } } void CustomElementCallback::Traverse( nsCycleCollectionTraversalCallback& aCb) const { NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mThisObject"); @@ -144,17 +144,17 @@ size_t CustomElementCallback::SizeOfIncl n += mArgs.SizeOfExcludingThis(aMallocSizeOf); // mAdoptedCallbackArgs doesn't really uniquely own its members. return n; } CustomElementCallback::CustomElementCallback( - Element* aThisObject, nsIDocument::ElementCallbackType aCallbackType, + Element* aThisObject, Document::ElementCallbackType aCallbackType, mozilla::dom::CallbackFunction* aCallback) : mThisObject(aThisObject), mCallback(aCallback), mType(aCallbackType) {} //----------------------------------------------------- // CustomElementConstructor already_AddRefed<Element> CustomElementConstructor::Construct( const char* aExecutionReason, ErrorResult& aRv) { CallSetup s(this, aRv, aExecutionReason, @@ -441,52 +441,52 @@ void CustomElementRegistry::UnregisterUn if (mCandidatesMap.Get(aTypeName, &candidates)) { MOZ_ASSERT(candidates); candidates->RemoveEntry(weak); } } /* static */ UniquePtr<CustomElementCallback> CustomElementRegistry::CreateCustomElementCallback( - nsIDocument::ElementCallbackType aType, Element* aCustomElement, + Document::ElementCallbackType aType, Element* aCustomElement, LifecycleCallbackArgs* aArgs, LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs, CustomElementDefinition* aDefinition) { MOZ_ASSERT(aDefinition, "CustomElementDefinition should not be null"); MOZ_ASSERT(aCustomElement->GetCustomElementData(), "CustomElementData should exist"); // Let CALLBACK be the callback associated with the key NAME in CALLBACKS. CallbackFunction* func = nullptr; switch (aType) { - case nsIDocument::eConnected: + case Document::eConnected: if (aDefinition->mCallbacks->mConnectedCallback.WasPassed()) { func = aDefinition->mCallbacks->mConnectedCallback.Value(); } break; - case nsIDocument::eDisconnected: + case Document::eDisconnected: if (aDefinition->mCallbacks->mDisconnectedCallback.WasPassed()) { func = aDefinition->mCallbacks->mDisconnectedCallback.Value(); } break; - case nsIDocument::eAdopted: + case Document::eAdopted: if (aDefinition->mCallbacks->mAdoptedCallback.WasPassed()) { func = aDefinition->mCallbacks->mAdoptedCallback.Value(); } break; - case nsIDocument::eAttributeChanged: + case Document::eAttributeChanged: if (aDefinition->mCallbacks->mAttributeChangedCallback.WasPassed()) { func = aDefinition->mCallbacks->mAttributeChangedCallback.Value(); } break; - case nsIDocument::eGetCustomInterface: + case Document::eGetCustomInterface: MOZ_ASSERT_UNREACHABLE("Don't call GetCustomInterface through callback"); break; } // If there is no such callback, stop. if (!func) { return nullptr; } @@ -501,17 +501,17 @@ CustomElementRegistry::CreateCustomEleme if (aAdoptedCallbackArgs) { callback->SetAdoptedCallbackArgs(*aAdoptedCallbackArgs); } return callback; } /* static */ void CustomElementRegistry::EnqueueLifecycleCallback( - nsIDocument::ElementCallbackType aType, Element* aCustomElement, + Document::ElementCallbackType aType, Element* aCustomElement, LifecycleCallbackArgs* aArgs, LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs, CustomElementDefinition* aDefinition) { CustomElementDefinition* definition = aDefinition; if (!definition) { definition = aCustomElement->GetCustomElementDefinition(); if (!definition || definition->mLocalName != aCustomElement->NodeInfo()->NameAtom()) { @@ -530,17 +530,17 @@ CustomElementRegistry::CreateCustomEleme return; } DocGroup* docGroup = aCustomElement->OwnerDoc()->GetDocGroup(); if (!docGroup) { return; } - if (aType == nsIDocument::eAttributeChanged) { + if (aType == Document::eAttributeChanged) { RefPtr<nsAtom> attrName = NS_Atomize(aArgs->name); if (definition->mObservedAttributes.IsEmpty() || !definition->mObservedAttributes.Contains(attrName)) { return; } } CustomElementReactionsStack* reactionsStack = @@ -548,29 +548,29 @@ CustomElementRegistry::CreateCustomEleme reactionsStack->EnqueueCallbackReaction(aCustomElement, std::move(callback)); } namespace { class CandidateFinder { public: CandidateFinder(nsTHashtable<nsRefPtrHashKey<nsIWeakReference>>& aCandidates, - nsIDocument* aDoc); + Document* aDoc); nsTArray<nsCOMPtr<Element>> OrderedCandidates(); private: bool Traverse(Element* aRoot, nsTArray<nsCOMPtr<Element>>& aOrderedElements); - nsCOMPtr<nsIDocument> mDoc; + nsCOMPtr<Document> mDoc; nsInterfaceHashtable<nsPtrHashKey<Element>, Element> mCandidates; }; CandidateFinder::CandidateFinder( nsTHashtable<nsRefPtrHashKey<nsIWeakReference>>& aCandidates, - nsIDocument* aDoc) + Document* aDoc) : mDoc(aDoc), mCandidates(aCandidates.Count()) { MOZ_ASSERT(mDoc); for (auto iter = aCandidates.Iter(); !iter.Done(); iter.Next()) { nsCOMPtr<Element> elem = do_QueryReferent(iter.Get()->GetKey()); if (!elem) { continue; } @@ -709,17 +709,17 @@ void CustomElementRegistry::Define(JSCon } int32_t nameSpaceID = InferNamespace(aCx, constructor); /** * 2. If name is not a valid custom element name, then throw a "SyntaxError" * DOMException and abort these steps. */ - nsIDocument* doc = mWindow->GetExtantDoc(); + Document* doc = mWindow->GetExtantDoc(); RefPtr<nsAtom> nameAtom(NS_Atomize(aName)); if (!nsContentUtils::IsCustomElementName(nameAtom, nameSpaceID)) { aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); return; } /** * 3. If this CustomElementRegistry contains an entry with name name, then @@ -1055,17 +1055,17 @@ already_AddRefed<Promise> CustomElementR nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow); RefPtr<Promise> promise = Promise::Create(global, aRv); if (aRv.Failed()) { return nullptr; } RefPtr<nsAtom> nameAtom(NS_Atomize(aName)); - nsIDocument* doc = mWindow->GetExtantDoc(); + Document* doc = mWindow->GetExtantDoc(); uint32_t nameSpaceID = doc ? doc->GetDefaultNamespaceID() : kNameSpaceID_XHTML; if (!nsContentUtils::IsCustomElementName(nameAtom, nameSpaceID)) { promise->MaybeReject(NS_ERROR_DOM_SYNTAX_ERR); return promise.forget(); } if (mCustomDefinitions.GetWeak(nameAtom)) { @@ -1129,26 +1129,25 @@ static void DoUpgrade(Element* aElement, nsAutoString attrValue, namespaceURI; info.mValue->ToString(attrValue); nsContentUtils::NameSpaceManager()->GetNameSpaceURI(namespaceID, namespaceURI); LifecycleCallbackArgs args = { nsDependentAtomString(attrName), VoidString(), attrValue, (namespaceURI.IsEmpty() ? VoidString() : namespaceURI)}; - nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eAttributeChanged, - aElement, &args, nullptr, - aDefinition); + nsContentUtils::EnqueueLifecycleCallback( + Document::eAttributeChanged, aElement, &args, nullptr, aDefinition); } } } // Step 4. if (aElement->IsInComposedDoc()) { - nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eConnected, aElement, + nsContentUtils::EnqueueLifecycleCallback(Document::eConnected, aElement, nullptr, nullptr, aDefinition); } // Step 5. AutoConstructionStackEntry acs(aDefinition->mConstructionStack, aElement); // Step 6 and step 7. DoUpgrade(aElement, aDefinition->mConstructor, aRv);
--- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -38,47 +38,47 @@ struct LifecycleCallbackArgs { nsString oldValue; nsString newValue; nsString namespaceURI; size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const; }; struct LifecycleAdoptedCallbackArgs { - nsCOMPtr<nsIDocument> mOldDocument; - nsCOMPtr<nsIDocument> mNewDocument; + RefPtr<Document> mOldDocument; + RefPtr<Document> mNewDocument; }; class CustomElementCallback { public: CustomElementCallback(Element* aThisObject, - nsIDocument::ElementCallbackType aCallbackType, + Document::ElementCallbackType aCallbackType, CallbackFunction* aCallback); void Traverse(nsCycleCollectionTraversalCallback& aCb) const; size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const; void Call(); void SetArgs(LifecycleCallbackArgs& aArgs) { - MOZ_ASSERT(mType == nsIDocument::eAttributeChanged, + MOZ_ASSERT(mType == Document::eAttributeChanged, "Arguments are only used by attribute changed callback."); mArgs = aArgs; } void SetAdoptedCallbackArgs( LifecycleAdoptedCallbackArgs& aAdoptedCallbackArgs) { - MOZ_ASSERT(mType == nsIDocument::eAdopted, + MOZ_ASSERT(mType == Document::eAdopted, "Arguments are only used by adopted callback."); mAdoptedCallbackArgs = aAdoptedCallbackArgs; } private: // The this value to use for invocation of the callback. RefPtr<Element> mThisObject; RefPtr<CallbackFunction> mCallback; // The type of callback (eCreated, eAttached, etc.) - nsIDocument::ElementCallbackType mType; + Document::ElementCallbackType mType; // Arguments to be passed to the callback, // used by the attribute changed callback. LifecycleCallbackArgs mArgs; LifecycleAdoptedCallbackArgs mAdoptedCallbackArgs; }; class CustomElementConstructor final : public CallbackFunction { public: @@ -344,17 +344,16 @@ class CustomElementReactionsStack { } private: RefPtr<CustomElementReactionsStack> mReactionStack; }; }; class CustomElementRegistry final : public nsISupports, public nsWrapperCache { - public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CustomElementRegistry) public: explicit CustomElementRegistry(nsPIDOMWindowInner* aWindow); private: @@ -394,17 +393,17 @@ class CustomElementRegistry final : publ CustomElementDefinition* LookupCustomElementDefinition(nsAtom* aNameAtom, int32_t aNameSpaceID, nsAtom* aTypeAtom); CustomElementDefinition* LookupCustomElementDefinition( JSContext* aCx, JSObject* aConstructor) const; static void EnqueueLifecycleCallback( - nsIDocument::ElementCallbackType aType, Element* aCustomElement, + Document::ElementCallbackType aType, Element* aCustomElement, LifecycleCallbackArgs* aArgs, LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs, CustomElementDefinition* aDefinition); /** * Upgrade an element. * https://html.spec.whatwg.org/multipage/scripting.html#upgrades */ @@ -469,17 +468,17 @@ class CustomElementRegistry final : publ nsWeakPtr elem = do_GetWeakReference(aElement); elements->PutEntry(elem); } private: ~CustomElementRegistry(); static UniquePtr<CustomElementCallback> CreateCustomElementCallback( - nsIDocument::ElementCallbackType aType, Element* aCustomElement, + Document::ElementCallbackType aType, Element* aCustomElement, LifecycleCallbackArgs* aArgs, LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs, CustomElementDefinition* aDefinition); void UpgradeCandidates(nsAtom* aKey, CustomElementDefinition* aDefinition, ErrorResult& aRv); typedef nsRefPtrHashtable<nsRefPtrHashKey<nsAtom>, CustomElementDefinition>
--- a/dom/base/DOMError.cpp +++ b/dom/base/DOMError.cpp @@ -3,17 +3,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/DOMError.h" #include "mozilla/dom/DOMErrorBinding.h" #include "mozilla/dom/DOMException.h" #include "mozilla/UseCounter.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsPIDOMWindow.h" namespace mozilla { namespace dom { NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMError, mWindow) NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMError) NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMError) @@ -50,17 +50,17 @@ JSObject* DOMError::WrapObject(JSContext /* static */ already_AddRefed<DOMError> DOMError::Constructor( const GlobalObject& aGlobal, const nsAString& aName, const nsAString& aMessage, ErrorResult& aRv) { nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports()); if (window) { - nsCOMPtr<nsIDocument> doc = window->GetExtantDoc(); + nsCOMPtr<Document> doc = window->GetExtantDoc(); if (doc) { doc->SetDocumentAndPageUseCounter(eUseCounter_custom_DOMErrorConstructor); } } // Window is null for chrome code. RefPtr<DOMError> ret = new DOMError(window, aName, aMessage);
--- a/dom/base/DOMException.cpp +++ b/dom/base/DOMException.cpp @@ -6,17 +6,17 @@ #include "mozilla/dom/DOMException.h" #include "mozilla/ArrayUtils.h" #include "mozilla/HoldDropJSObjects.h" #include "mozilla/dom/Exceptions.h" #include "nsContentUtils.h" #include "nsCOMPtr.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIException.h" #include "nsMemory.h" #include "xpcprivate.h" #include "mozilla/dom/DOMExceptionBinding.h" #include "mozilla/ErrorResult.h" using namespace mozilla;
--- a/dom/base/DOMImplementation.cpp +++ b/dom/base/DOMImplementation.cpp @@ -55,17 +55,17 @@ already_AddRefed<DocumentType> DOMImplem RefPtr<DocumentType> docType = NS_NewDOMDocumentType( mOwner->NodeInfoManager(), name, aPublicId, aSystemId, VoidString()); return docType.forget(); } nsresult DOMImplementation::CreateDocument(const nsAString& aNamespaceURI, const nsAString& aQualifiedName, DocumentType* aDoctype, - nsIDocument** aDocument) { + Document** aDocument) { *aDocument = nullptr; nsresult rv; if (!aQualifiedName.IsEmpty()) { const nsString& qName = PromiseFlatString(aQualifiedName); const char16_t* colon; rv = nsContentUtils::CheckQName(qName, true, &colon); NS_ENSURE_SUCCESS(rv, rv); @@ -78,17 +78,17 @@ nsresult DOMImplementation::CreateDocume } } nsCOMPtr<nsIGlobalObject> scriptHandlingObject = do_QueryReferent(mScriptObject); NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject); - nsCOMPtr<nsIDocument> doc; + nsCOMPtr<Document> doc; rv = NS_NewDOMDocument(getter_AddRefs(doc), aNamespaceURI, aQualifiedName, aDoctype, mDocumentURI, mBaseURI, mOwner->NodePrincipal(), true, scriptHandlingObject, DocumentFlavorLegacyGuess); NS_ENSURE_SUCCESS(rv, rv); // When DOMImplementation's createDocument method is invoked with @@ -98,33 +98,33 @@ nsresult DOMImplementation::CreateDocume if (aNamespaceURI.EqualsLiteral("http://www.w3.org/1999/xhtml")) { doc->SetContentType(NS_LITERAL_STRING("application/xhtml+xml")); } else if (aNamespaceURI.EqualsLiteral("http://www.w3.org/2000/svg")) { doc->SetContentType(NS_LITERAL_STRING("image/svg+xml")); } else { doc->SetContentType(NS_LITERAL_STRING("application/xml")); } - doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE); + doc->SetReadyStateInternal(Document::READYSTATE_COMPLETE); doc.forget(aDocument); return NS_OK; } -already_AddRefed<nsIDocument> DOMImplementation::CreateDocument( +already_AddRefed<Document> DOMImplementation::CreateDocument( const nsAString& aNamespaceURI, const nsAString& aQualifiedName, DocumentType* aDoctype, ErrorResult& aRv) { - nsCOMPtr<nsIDocument> document; + nsCOMPtr<Document> document; aRv = CreateDocument(aNamespaceURI, aQualifiedName, aDoctype, getter_AddRefs(document)); return document.forget(); } nsresult DOMImplementation::CreateHTMLDocument(const nsAString& aTitle, - nsIDocument** aDocument) { + Document** aDocument) { *aDocument = nullptr; NS_ENSURE_STATE(mOwner); // Indicate that there is no internal subset (not just an empty one) RefPtr<DocumentType> doctype = NS_NewDOMDocumentType(mOwner->NodeInfoManager(), nsGkAtoms::html, // aName @@ -132,17 +132,17 @@ nsresult DOMImplementation::CreateHTMLDo EmptyString(), // aSystemId VoidString()); // aInternalSubset nsCOMPtr<nsIGlobalObject> scriptHandlingObject = do_QueryReferent(mScriptObject); NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject); - nsCOMPtr<nsIDocument> doc; + nsCOMPtr<Document> doc; nsresult rv = NS_NewDOMDocument( getter_AddRefs(doc), EmptyString(), EmptyString(), doctype, mDocumentURI, mBaseURI, mOwner->NodePrincipal(), true, scriptHandlingObject, DocumentFlavorLegacyGuess); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<Element> root = doc->CreateElem(NS_LITERAL_STRING("html"), nullptr, kNameSpaceID_XHTML); @@ -167,24 +167,24 @@ nsresult DOMImplementation::CreateHTMLDo NS_ENSURE_SUCCESS(rv, rv); } nsCOMPtr<Element> body = doc->CreateElem(NS_LITERAL_STRING("body"), nullptr, kNameSpaceID_XHTML); rv = root->AppendChildTo(body, false); NS_ENSURE_SUCCESS(rv, rv); - doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE); + doc->SetReadyStateInternal(Document::READYSTATE_COMPLETE); doc.forget(aDocument); return NS_OK; } -already_AddRefed<nsIDocument> DOMImplementation::CreateHTMLDocument( +already_AddRefed<Document> DOMImplementation::CreateHTMLDocument( const Optional<nsAString>& aTitle, ErrorResult& aRv) { - nsCOMPtr<nsIDocument> document; + nsCOMPtr<Document> document; aRv = CreateHTMLDocument(aTitle.WasPassed() ? aTitle.Value() : VoidString(), getter_AddRefs(document)); return document.forget(); } } // namespace dom } // namespace mozilla
--- a/dom/base/DOMImplementation.h +++ b/dom/base/DOMImplementation.h @@ -8,68 +8,69 @@ #define mozilla_dom_DOMImplementation_h #include "nsWrapperCache.h" #include "mozilla/Attributes.h" #include "mozilla/ErrorResult.h" #include "nsCOMPtr.h" #include "nsCycleCollectionParticipant.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsIScriptGlobalObject.h" #include "nsIURI.h" #include "nsIWeakReferenceUtils.h" #include "nsString.h" namespace mozilla { namespace dom { +class Document; class DocumentType; class DOMImplementation final : public nsISupports, public nsWrapperCache { ~DOMImplementation() {} public: - DOMImplementation(nsIDocument* aOwner, nsIGlobalObject* aScriptObject, + DOMImplementation(Document* aOwner, nsIGlobalObject* aScriptObject, nsIURI* aDocumentURI, nsIURI* aBaseURI) : mOwner(aOwner), mScriptObject(do_GetWeakReference(aScriptObject)), mDocumentURI(aDocumentURI), mBaseURI(aBaseURI) { MOZ_ASSERT(aOwner); } NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMImplementation) - nsIDocument* GetParentObject() const { return mOwner; } + Document* GetParentObject() const { return mOwner; } virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; bool HasFeature() { return true; } already_AddRefed<DocumentType> CreateDocumentType( const nsAString& aQualifiedName, const nsAString& aPublicId, const nsAString& aSystemId, ErrorResult& aRv); - already_AddRefed<nsIDocument> CreateDocument(const nsAString& aNamespaceURI, - const nsAString& aQualifiedName, - DocumentType* aDoctype, - ErrorResult& aRv); + already_AddRefed<Document> CreateDocument(const nsAString& aNamespaceURI, + const nsAString& aQualifiedName, + DocumentType* aDoctype, + ErrorResult& aRv); - already_AddRefed<nsIDocument> CreateHTMLDocument( + already_AddRefed<Document> CreateHTMLDocument( const Optional<nsAString>& aTitle, ErrorResult& aRv); private: nsresult CreateDocument(const nsAString& aNamespaceURI, const nsAString& aQualifiedName, - DocumentType* aDoctype, nsIDocument** aDocument); - nsresult CreateHTMLDocument(const nsAString& aTitle, nsIDocument** aDocument); + DocumentType* aDoctype, Document** aDocument); + nsresult CreateHTMLDocument(const nsAString& aTitle, Document** aDocument); - nsCOMPtr<nsIDocument> mOwner; + nsCOMPtr<Document> mOwner; nsWeakPtr mScriptObject; nsCOMPtr<nsIURI> mDocumentURI; nsCOMPtr<nsIURI> mBaseURI; }; } // namespace dom } // namespace mozilla
--- a/dom/base/DOMIntersectionObserver.cpp +++ b/dom/base/DOMIntersectionObserver.cpp @@ -221,17 +221,17 @@ static Maybe<nsRect> EdgeInclusiveInters } enum class BrowsingContextInfo { SimilarOriginBrowsingContext, DifferentOriginBrowsingContext, UnknownBrowsingContext }; -void DOMIntersectionObserver::Update(nsIDocument* aDocument, +void DOMIntersectionObserver::Update(Document* aDocument, DOMHighResTimeStamp time) { Element* root = nullptr; nsIFrame* rootFrame = nullptr; nsRect rootRect; if (mRoot) { root = mRoot; rootFrame = root->GetPrimaryFrame();
--- a/dom/base/DOMIntersectionObserver.h +++ b/dom/base/DOMIntersectionObserver.h @@ -126,30 +126,30 @@ class DOMIntersectionObserver final : pu void TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal); mozilla::dom::IntersectionCallback* IntersectionCallback() { return mCallback; } bool SetRootMargin(const nsAString& aString); - void Update(nsIDocument* aDocument, DOMHighResTimeStamp time); + void Update(Document* aDocument, DOMHighResTimeStamp time); void Notify(); protected: void Connect(); void QueueIntersectionObserverEntry(Element* aTarget, DOMHighResTimeStamp time, const Maybe<nsRect>& aRootRect, const nsRect& aTargetRect, const Maybe<nsRect>& aIntersectionRect, double aIntersectionRatio); nsCOMPtr<nsPIDOMWindowInner> mOwner; - RefPtr<nsIDocument> mDocument; + RefPtr<Document> mDocument; RefPtr<mozilla::dom::IntersectionCallback> mCallback; RefPtr<Element> mRoot; nsStyleSides mRootMargin; nsTArray<double> mThresholds; // Holds raw pointers which are explicitly cleared by UnlinkTarget(). nsTArray<Element*> mObservationTargets;
--- a/dom/base/DOMParser.cpp +++ b/dom/base/DOMParser.cpp @@ -50,21 +50,21 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DO NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMParser) NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMParser) static const char* StringFromSupportedType(SupportedType aType) { return SupportedTypeValues::strings[static_cast<int>(aType)].value; } -already_AddRefed<nsIDocument> DOMParser::ParseFromString(const nsAString& aStr, - SupportedType aType, - ErrorResult& aRv) { +already_AddRefed<Document> DOMParser::ParseFromString(const nsAString& aStr, + SupportedType aType, + ErrorResult& aRv) { if (aType == SupportedType::Text_html) { - nsCOMPtr<nsIDocument> document = SetUpDocument(DocumentFlavorHTML, aRv); + nsCOMPtr<Document> document = SetUpDocument(DocumentFlavorHTML, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } // Keep the XULXBL state in sync with the XML case. if (mForceEnableXULXBL) { document->ForceEnableXULXBL(); } @@ -93,41 +93,44 @@ already_AddRefed<nsIDocument> DOMParser: aRv.Throw(rv); return nullptr; } return ParseFromStream(stream, NS_LITERAL_STRING("UTF-8"), utf8str.Length(), aType, aRv); } -already_AddRefed<nsIDocument> DOMParser::ParseFromBuffer(const Uint8Array& aBuf, - SupportedType aType, - ErrorResult& aRv) { +already_AddRefed<Document> DOMParser::ParseFromBuffer(const Uint8Array& aBuf, + SupportedType aType, + ErrorResult& aRv) { aBuf.ComputeLengthAndData(); return ParseFromBuffer(MakeSpan(aBuf.Data(), aBuf.Length()), aType, aRv); } -already_AddRefed<nsIDocument> DOMParser::ParseFromBuffer( - Span<const uint8_t> aBuf, SupportedType aType, ErrorResult& aRv) { +already_AddRefed<Document> DOMParser::ParseFromBuffer(Span<const uint8_t> aBuf, + SupportedType aType, + ErrorResult& aRv) { // The new stream holds a reference to the buffer nsCOMPtr<nsIInputStream> stream; nsresult rv = NS_NewByteInputStream( getter_AddRefs(stream), reinterpret_cast<const char*>(aBuf.Elements()), aBuf.Length(), NS_ASSIGNMENT_DEPEND); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } return ParseFromStream(stream, VoidString(), aBuf.Length(), aType, aRv); } -already_AddRefed<nsIDocument> DOMParser::ParseFromStream( - nsIInputStream* aStream, const nsAString& aCharset, int32_t aContentLength, - SupportedType aType, ErrorResult& aRv) { +already_AddRefed<Document> DOMParser::ParseFromStream(nsIInputStream* aStream, + const nsAString& aCharset, + int32_t aContentLength, + SupportedType aType, + ErrorResult& aRv) { bool svg = (aType == SupportedType::Image_svg_xml); // For now, we can only create XML documents. // XXXsmaug Should we create an HTMLDocument (in XHTML mode) // for "application/xhtml+xml"? if (aType != SupportedType::Text_xml && aType != SupportedType::Application_xml && aType != SupportedType::Application_xhtml_xml && !svg) { @@ -144,17 +147,17 @@ already_AddRefed<nsIDocument> DOMParser: if (NS_WARN_IF(NS_FAILED(rv))) { aRv.Throw(rv); return nullptr; } stream = bufferedStream; } - nsCOMPtr<nsIDocument> document = + nsCOMPtr<Document> document = SetUpDocument(svg ? DocumentFlavorSVG : DocumentFlavorLegacyGuess, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } // Create a fake channel nsCOMPtr<nsIChannel> parserChannel; NS_NewInputStreamChannel(getter_AddRefs(parserChannel), mDocumentURI, @@ -264,31 +267,31 @@ already_AddRefed<DOMParser> DOMParser::C return nullptr; } RefPtr<DOMParser> domParser = new DOMParser(nullptr, docPrincipal, documentURI, nullptr); return domParser.forget(); } -already_AddRefed<nsIDocument> DOMParser::SetUpDocument(DocumentFlavor aFlavor, - ErrorResult& aRv) { - // We should really just use mOwner here, but nsIDocument gets confused +already_AddRefed<Document> DOMParser::SetUpDocument(DocumentFlavor aFlavor, + ErrorResult& aRv) { + // We should really just use mOwner here, but Document gets confused // if we pass it a scriptHandlingObject that doesn't QI to // nsIScriptGlobalObject, and test_isequalnode.js (an xpcshell test without - // a window global) breaks. The correct solution is just to wean nsIDocument - // off of nsIScriptGlobalObject, but that's a yak to shave another day. + // a window global) breaks. The correct solution is just to wean Document off + // of nsIScriptGlobalObject, but that's a yak to shave another day. nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject = do_QueryInterface(mOwner); // Try to inherit a style backend. NS_ASSERTION(mPrincipal, "Must have principal by now"); NS_ASSERTION(mDocumentURI, "Must have document URI by now"); - nsCOMPtr<nsIDocument> doc; + nsCOMPtr<Document> doc; nsresult rv = NS_NewDOMDocument( getter_AddRefs(doc), EmptyString(), EmptyString(), nullptr, mDocumentURI, mBaseURI, mPrincipal, true, scriptHandlingObject, aFlavor); if (NS_WARN_IF(NS_FAILED(rv))) { aRv.Throw(rv); return nullptr; }
--- a/dom/base/DOMParser.h +++ b/dom/base/DOMParser.h @@ -3,24 +3,23 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_DOMParser_h_ #define mozilla_dom_DOMParser_h_ #include "nsCOMPtr.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "nsWrapperCache.h" #include "mozilla/ErrorResult.h" #include "mozilla/Span.h" #include "mozilla/dom/DOMParserBinding.h" #include "mozilla/dom/TypedArray.h" -class nsIDocument; class nsIGlobalObject; namespace mozilla { namespace dom { class DOMParser final : public nsISupports, public nsWrapperCache { typedef mozilla::dom::GlobalObject GlobalObject; @@ -29,35 +28,35 @@ class DOMParser final : public nsISuppor public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMParser) // WebIDL API static already_AddRefed<DOMParser> Constructor(const GlobalObject& aOwner, mozilla::ErrorResult& rv); - already_AddRefed<nsIDocument> ParseFromString(const nsAString& aStr, - SupportedType aType, - ErrorResult& aRv); + already_AddRefed<Document> ParseFromString(const nsAString& aStr, + SupportedType aType, + ErrorResult& aRv); // Sequence converts to Span, so we can use this overload for both // the Sequence case and our internal uses. - already_AddRefed<nsIDocument> ParseFromBuffer(Span<const uint8_t> aBuf, - SupportedType aType, - ErrorResult& aRv); + already_AddRefed<Document> ParseFromBuffer(Span<const uint8_t> aBuf, + SupportedType aType, + ErrorResult& aRv); - already_AddRefed<nsIDocument> ParseFromBuffer(const Uint8Array& aBuf, - SupportedType aType, - ErrorResult& aRv); + already_AddRefed<Document> ParseFromBuffer(const Uint8Array& aBuf, + SupportedType aType, + ErrorResult& aRv); - already_AddRefed<nsIDocument> ParseFromStream(nsIInputStream* aStream, - const nsAString& aCharset, - int32_t aContentLength, - SupportedType aType, - ErrorResult& aRv); + already_AddRefed<Document> ParseFromStream(nsIInputStream* aStream, + const nsAString& aCharset, + int32_t aContentLength, + SupportedType aType, + ErrorResult& aRv); void ForceEnableXULXBL() { mForceEnableXULXBL = true; } nsIGlobalObject* GetParentObject() const { return mOwner; } virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override { return mozilla::dom::DOMParser_Binding::Wrap(aCx, this, aGivenProto); @@ -65,18 +64,18 @@ class DOMParser final : public nsISuppor // A way to create a non-global-associated DOMParser from C++. static already_AddRefed<DOMParser> CreateWithoutGlobal(ErrorResult& aRv); private: DOMParser(nsIGlobalObject* aOwner, nsIPrincipal* aDocPrincipal, nsIURI* aDocumentURI, nsIURI* aBaseURI); - already_AddRefed<nsIDocument> SetUpDocument(DocumentFlavor aFlavor, - ErrorResult& aRv); + already_AddRefed<Document> SetUpDocument(DocumentFlavor aFlavor, + ErrorResult& aRv); nsCOMPtr<nsIGlobalObject> mOwner; nsCOMPtr<nsIPrincipal> mPrincipal; nsCOMPtr<nsIURI> mDocumentURI; nsCOMPtr<nsIURI> mBaseURI; bool mForceEnableXULXBL; };
--- a/dom/base/DirectionalityUtils.cpp +++ b/dom/base/DirectionalityUtils.cpp @@ -204,17 +204,17 @@ gets called. */ #include "mozilla/dom/DirectionalityUtils.h" #include "nsINode.h" #include "nsIContent.h" #include "nsIContentInlines.h" -#include "nsIDocument.h" +#include "mozilla/dom/Document.h" #include "mozilla/AutoRestore.h" #include "mozilla/DebugOnly.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/HTMLSlotElement.h" #include "mozilla/dom/ShadowRoot.h" #include "nsUnicodeProperties.h" #include "nsTextFragment.h" #include "nsAttrValue.h"
--- a/dom/base/DispatcherTrait.h +++ b/dom/base/DispatcherTrait.h @@ -13,30 +13,30 @@ class nsIRunnable; class nsISerialEventTarget; namespace mozilla { class AbstractThread; namespace dom { class TabGroup; -// This trait should be attached to classes like nsIGlobalObject and nsIDocument +// This trait should be attached to classes like nsIGlobalObject and Document // that have a DocGroup or TabGroup attached to them. The methods here should // delegate to the DocGroup or TabGroup. We can't use the Dispatcher class // directly because it inherits from nsISupports. class DispatcherTrait { public: - // This method may or may not be safe off of the main thread. For nsIDocument - // it is safe. For nsIGlobalWindow it is not safe. + // This method may or may not be safe off of the main thread. For Document it + // is safe. For nsIGlobalWindow it is not safe. virtual nsresult Dispatch(TaskCategory aCategory, already_AddRefed<nsIRunnable>&& aRunnable); - // This method may or may not be safe off of the main thread. For nsIDocument - // it is safe. For nsIGlobalWindow it is not safe. The nsISerialEventTarget - // can always be used off the main thread. + // This method may or may not be safe off of the main thread. For Document it + // is safe. For nsIGlobalWindow it is not safe. The nsISerialEventTarget can + // always be used off the main thread. virtual nsISerialEventTarget* EventTargetFor(TaskCategory aCategory) const; // Must be called on the main thread. The AbstractThread can always be used // off the main thread. virtual AbstractThread* AbstractMainThreadFor(TaskCategory aCategory); }; } // namespace dom
--- a/dom/base/DocGroup.cpp +++ b/dom/base/DocGroup.cpp @@ -35,17 +35,17 @@ AutoTArray<RefPtr<DocGroup>, 2>* DocGrou // empty string to classify all such documents as belonging to the same // DocGroup. aKey.Truncate(); } return rv; } -void DocGroup::RemoveDocument(nsIDocument* aDocument) { +void DocGroup::RemoveDocument(Document* aDocument) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(mDocuments.Contains(aDocument)); mDocuments.RemoveElement(aDocument); } DocGroup::DocGroup(TabGroup* aTabGroup, const nsACString& aKey) : mKey(aKey), mTabGroup(aTabGroup) { // This method does not add itself to mTabGroup->mDocGroups as the caller does @@ -80,17 +80,17 @@ RefPtr<PerformanceInfoPromise> DocGroup: uint64_t duration = 0; bool isTopLevel = false; nsCString host; nsCOMPtr<nsPIDOMWindowOuter> top; RefPtr<AbstractThread> mainThread; // iterating on documents until we find the top window for (const auto& document : *this) { - nsCOMPtr<nsIDocument> doc = document; + nsCOMPtr<Document> doc = document; MOZ_ASSERT(doc); nsCOMPtr<nsIURI> docURI = doc->GetDocumentURI(); if (!docURI) { continue; } docURI->GetHost(host); // If the host is empty, using the url if (host.IsEmpty()) { @@ -196,17 +196,17 @@ void DocGroup::MoveSignalSlotListTo(nsTA for (RefPtr<HTMLSlotElement>& slot : mSignalSlotList) { slot->RemovedFromSignalSlotList(); aDest.AppendElement(std::move(slot)); } mSignalSlotList.Clear(); } bool DocGroup::IsActive() const { - for (nsIDocument* doc : mDocuments) { + for (Document* doc : mDocuments) { if (doc->IsCurrentActiveDocument()) { return true; } } return false; }
--- a/dom/base/DocGroup.h +++ b/dom/base/DocGroup.h @@ -35,17 +35,17 @@ namespace dom { // TabGroup, browsing contexts are broken into "similar-origin" DocGroups. In // more detail, a DocGroup is actually a collection of documents, and a // TabGroup is a collection of DocGroups. A TabGroup typically will contain // (through its DocGroups) the documents from one or more tabs related by // window.opener. A DocGroup is a member of exactly one TabGroup. class DocGroup final { public: - typedef nsTArray<nsIDocument*>::iterator Iterator; + typedef nsTArray<Document*>::iterator Iterator; friend class TabGroup; NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DocGroup) // Returns NS_ERROR_FAILURE and sets |aString| to an empty string if the TLD // service isn't available. Returns NS_OK on success, but may still set // |aString| may still be set to an empty string. static MOZ_MUST_USE nsresult GetKey(nsIPrincipal* aPrincipal, @@ -61,17 +61,17 @@ class DocGroup final { mozilla::dom::CustomElementReactionsStack* CustomElementReactionsStack() { MOZ_ASSERT(NS_IsMainThread()); if (!mReactionsStack) { mReactionsStack = new mozilla::dom::CustomElementReactionsStack(); } return mReactionsStack; } - void RemoveDocument(nsIDocument* aWindow); + void RemoveDocument(Document* aWindow); // Iterators for iterating over every document within the DocGroup Iterator begin() { MOZ_ASSERT(NS_IsMainThread()); return mDocuments.begin(); } Iterator end() { MOZ_ASSERT(NS_IsMainThread()); @@ -106,17 +106,17 @@ class DocGroup final { bool IsActive() const; private: DocGroup(TabGroup* aTabGroup, const nsACString& aKey); ~DocGroup(); nsCString mKey; RefPtr<TabGroup> mTabGroup; - nsTArray<nsIDocument*> mDocuments; + nsTArray<Document*> mDocuments; RefPtr<mozilla::dom::CustomElementReactionsStack> mReactionsStack; nsTArray<RefPtr<HTMLSlotElement>> mSignalSlotList; // This pointer will be null if dom.performance.enable_scheduler_timing is // false (default value) RefPtr<mozilla::PerformanceCounter> mPerformanceCounter; }; } // namespace dom
new file mode 100644 --- /dev/null +++ b/dom/base/Document.cpp @@ -0,0 +1,12879 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Base class for all our document implementations. + */ + +#include "AudioChannelService.h" +#include "mozilla/dom/Document.h" +#include "DocumentInlines.h" +#include "mozilla/AnimationComparator.h" +#include "mozilla/AntiTrackingCommon.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/AutoRestore.h" +#include "mozilla/BinarySearch.h" +#include "mozilla/CSSEnabledState.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/EffectSet.h" +#include "mozilla/EnumSet.h" +#include "mozilla/IntegerRange.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Likely.h" +#include "mozilla/PresShell.h" +#include "mozilla/StaticPrefs.h" +#include "mozilla/URLExtraData.h" +#include <algorithm> + +#include "mozilla/Logging.h" +#include "plstr.h" +#include "mozilla/Sprintf.h" + +#include "mozilla/Telemetry.h" +#include "nsIInterfaceRequestor.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsILoadContext.h" +#include "nsITextControlFrame.h" +#include "nsNumberControlFrame.h" +#include "nsUnicharUtils.h" +#include "nsContentList.h" +#include "nsCSSPseudoElements.h" +#include "nsIObserver.h" +#include "nsIBaseWindow.h" +#include "nsILayoutHistoryState.h" +#include "mozilla/css/Loader.h" +#include "mozilla/css/ImageLoader.h" +#include "nsDocShell.h" +#include "nsDocShellLoadTypes.h" +#include "nsIDocShellTreeItem.h" +#include "nsCOMArray.h" +#include "nsQueryObject.h" +#include "mozilla/Services.h" +#include "nsScreen.h" +#include "ChildIterator.h" + +#include "mozilla/AsyncEventDispatcher.h" +#include "mozilla/BasicEvents.h" +#include "mozilla/EventListenerManager.h" +#include "mozilla/EventStateManager.h" +#include "mozilla/FullscreenChange.h" +#include "mozilla/PendingAnimationTracker.h" + +#include "mozilla/dom/Attr.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/Event.h" +#include "mozilla/dom/FeaturePolicy.h" +#include "mozilla/dom/FramingChecker.h" +#include "mozilla/dom/HTMLSharedElement.h" +#include "mozilla/dom/Navigator.h" +#include "mozilla/dom/Performance.h" +#include "mozilla/dom/ServiceWorkerContainer.h" +#include "mozilla/dom/ScriptLoader.h" +#include "mozilla/dom/StyleSheetList.h" +#include "mozilla/dom/SVGUseElement.h" +#include "nsGenericHTMLElement.h" +#include "mozilla/dom/CDATASection.h" +#include "mozilla/dom/ProcessingInstruction.h" +#include "nsDOMString.h" +#include "nsNodeUtils.h" +#include "nsLayoutUtils.h" // for GetFrameForPoint +#include "nsIFrame.h" +#include "nsITabChild.h" + +#include "nsRange.h" +#include "mozilla/dom/DocumentType.h" +#include "mozilla/dom/NodeIterator.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/PromiseNativeHandler.h" +#include "mozilla/dom/TreeWalker.h" + +#include "nsIServiceManager.h" +#include "mozilla/dom/ServiceWorkerManager.h" +#include "imgLoader.h" + +#include "nsAboutProtocolUtils.h" +#include "nsCanvasFrame.h" +#include "nsContentCID.h" +#include "nsError.h" +#include "nsPresContext.h" +#include "nsThreadUtils.h" +#include "nsNodeInfoManager.h" +#include "nsIFileChannel.h" +#include "nsIMultiPartChannel.h" +#include "nsIRefreshURI.h" +#include "nsIWebNavigation.h" +#include "nsIScriptError.h" +#include "nsISimpleEnumerator.h" +#include "nsIRequestContext.h" +#include "nsStyleSheetService.h" + +#include "nsNetUtil.h" // for NS_NewURI +#include "nsIInputStreamChannel.h" +#include "nsIAuthPrompt.h" +#include "nsIAuthPrompt2.h" + +#include "nsIScriptSecurityManager.h" +#include "nsIPermissionManager.h" +#include "nsIPrincipal.h" +#include "ExpandedPrincipal.h" +#include "mozilla/NullPrincipal.h" + +#include "nsIDOMWindow.h" +#include "nsPIDOMWindow.h" +#include "nsFocusManager.h" +#include "nsICookieService.h" + +#include "nsBidiUtils.h" + +#include "nsContentCreatorFunctions.h" + +#include "nsIScriptContext.h" +#include "nsBindingManager.h" +#include "nsHTMLDocument.h" +#include "nsIRequest.h" +#include "mozilla/dom/BlobURLProtocolHandler.h" + +#include "nsCharsetSource.h" +#include "nsIParser.h" +#include "nsIContentSink.h" + +#include "mozilla/EventDispatcher.h" +#include "mozilla/EventStates.h" +#include "mozilla/InternalMutationEvent.h" +#include "nsDOMCID.h" + +#include "jsapi.h" +#include "nsIXPConnect.h" +#include "xpcpublic.h" +#include "nsCCUncollectableMarker.h" +#include "nsIContentPolicy.h" +#include "nsContentPolicyUtils.h" +#include "nsICategoryManager.h" +#include "nsIDocumentLoaderFactory.h" +#include "nsIDocumentLoader.h" +#include "nsIContentViewer.h" +#include "nsIXMLContentSink.h" +#include "nsIPrompt.h" +#include "nsIPropertyBag2.h" +#include "mozilla/dom/PageTransitionEvent.h" +#include "mozilla/dom/StyleRuleChangeEvent.h" +#include "mozilla/dom/StyleSheetChangeEvent.h" +#include "mozilla/dom/StyleSheetApplicableStateChangeEvent.h" +#include "nsJSUtils.h" +#include "nsFrameLoader.h" +#include "nsEscape.h" +#include "nsObjectLoadingContent.h" +#include "nsHtml5TreeOpExecutor.h" +#include "mozilla/dom/HTMLFormElement.h" +#include "mozilla/dom/HTMLLinkElement.h" +#include "mozilla/dom/HTMLMediaElement.h" +#include "mozilla/dom/HTMLIFrameElement.h" +#include "mozilla/dom/HTMLImageElement.h" +#include "mozilla/dom/HTMLTextAreaElement.h" +#include "mozilla/dom/MediaSource.h" + +#include "mozAutoDocUpdate.h" +#include "nsGlobalWindow.h" +#include "mozilla/Encoding.h" +#include "nsDOMNavigationTiming.h" + +#include "mozilla/SMILAnimationController.h" +#include "imgIContainer.h" +#include "nsSVGUtils.h" + +#include "nsRefreshDriver.h" + +// FOR CSP (autogenerated by xpidl) +#include "nsIContentSecurityPolicy.h" +#include "mozilla/dom/nsCSPContext.h" +#include "mozilla/dom/nsCSPService.h" +#include "mozilla/dom/nsCSPUtils.h" +#include "nsHTMLStyleSheet.h" +#include "nsHTMLCSSStyleSheet.h" +#include "mozilla/dom/DOMImplementation.h" +#include "mozilla/dom/ShadowRoot.h" +#include "mozilla/dom/Comment.h" +#include "nsTextNode.h" +#include "mozilla/dom/Link.h" +#include "mozilla/dom/HTMLCollectionBinding.h" +#include "mozilla/dom/HTMLElementBinding.h" +#include "nsXULAppAPI.h" +#include "mozilla/dom/Touch.h" +#include "mozilla/dom/TouchEvent.h" + +#include "mozilla/Preferences.h" + +#include "imgILoader.h" +#include "imgRequestProxy.h" +#include "nsWrapperCacheInlines.h" +#include "nsSandboxFlags.h" +#include "mozilla/dom/AnimatableBinding.h" +#include "mozilla/dom/AnonymousContent.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/ClientInfo.h" +#include "mozilla/dom/ClientState.h" +#include "mozilla/dom/DocumentFragment.h" +#include "mozilla/dom/DocumentL10n.h" +#include "mozilla/dom/DocumentTimeline.h" +#include "mozilla/dom/Event.h" +#include "mozilla/dom/HTMLBodyElement.h" +#include "mozilla/dom/HTMLInputElement.h" +#include "mozilla/dom/ImageTracker.h" +#include "mozilla/dom/MediaQueryList.h" +#include "mozilla/dom/NodeFilterBinding.h" +#include "mozilla/OwningNonNull.h" +#include "mozilla/dom/TabChild.h" +#include "mozilla/dom/WebComponentsBinding.h" +#include "mozilla/dom/CustomElementRegistryBinding.h" +#include "mozilla/dom/CustomElementRegistry.h" +#include "mozilla/dom/ServiceWorkerDescriptor.h" +#include "mozilla/dom/TimeoutManager.h" +#include "mozilla/ExtensionPolicyService.h" +#include "nsFrame.h" +#include "nsDOMCaretPosition.h" +#include "nsViewportInfo.h" +#include "mozilla/StaticPtr.h" +#include "nsITextControlElement.h" +#include "nsIEditor.h" +#include "nsIHttpChannelInternal.h" +#include "nsISecurityConsoleMessage.h" +#include "nsCharSeparatedTokenizer.h" +#include "mozilla/dom/XPathEvaluator.h" +#include "mozilla/dom/XPathNSResolverBinding.h" +#include "mozilla/dom/XPathResult.h" +#include "nsIDocumentEncoder.h" +#include "nsIDocumentActivity.h" +#include "nsIStructuredCloneContainer.h" +#include "nsIMutableArray.h" +#include "mozilla/dom/DOMStringList.h" +#include "nsWindowSizes.h" +#include "mozilla/dom/Location.h" +#include "mozilla/dom/FontFaceSet.h" +#include "gfxPrefs.h" +#include "nsISupportsPrimitives.h" +#include "mozilla/ServoStyleSet.h" +#include "mozilla/StyleSheet.h" +#include "mozilla/StyleSheetInlines.h" +#include "mozilla/dom/SVGDocument.h" +#include "mozilla/dom/SVGSVGElement.h" +#include "mozilla/dom/DocGroup.h" +#include "mozilla/dom/TabGroup.h" +#ifdef MOZ_XUL +#include "mozilla/dom/XULBroadcastManager.h" +#include "mozilla/dom/XULPersist.h" +#include "mozilla/dom/TreeBoxObject.h" +#include "nsIXULWindow.h" +#include "nsXULCommandDispatcher.h" +#include "nsXULPopupManager.h" +#include "nsIDocShellTreeOwner.h" +#endif +#include "nsIPresShellInlines.h" + +#include "mozilla/DocLoadingTimelineMarker.h" + +#include "mozilla/dom/WindowGlobalChild.h" + +#include "nsISpeculativeConnect.h" + +#include "mozilla/MediaManager.h" + +#include "nsIURIClassifier.h" +#include "nsIURIMutator.h" +#include "mozilla/DocumentStyleRootIterator.h" +#include "mozilla/PendingFullscreenEvent.h" +#include "mozilla/RestyleManager.h" +#include "mozilla/ClearOnShutdown.h" +#include "nsHTMLTags.h" +#include "NodeUbiReporting.h" +#include "nsICookieService.h" +#include "mozilla/net/ChannelEventQueue.h" +#include "mozilla/net/RequestContextService.h" +#include "StorageAccessPermissionRequest.h" +#include "mozilla/dom/WindowProxyHolder.h" + +#define XML_DECLARATION_BITS_DECLARATION_EXISTS (1 << 0) +#define XML_DECLARATION_BITS_ENCODING_EXISTS (1 << 1) +#define XML_DECLARATION_BITS_STANDALONE_EXISTS (1 << 2) +#define XML_DECLARATION_BITS_STANDALONE_YES (1 << 3) + +namespace mozilla { +namespace dom { + +typedef nsTArray<Link*> LinkArray; + +static LazyLogModule gDocumentLeakPRLog("DocumentLeak"); +static LazyLogModule gCspPRLog("CSP"); +static LazyLogModule gUserInteractionPRLog("UserInteraction"); + +static nsresult GetHttpChannelHelper(nsIChannel* aChannel, + nsIHttpChannel** aHttpChannel) { + nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel); + if (httpChannel) { + httpChannel.forget(aHttpChannel); + return NS_OK; + } + + nsCOMPtr<nsIMultiPartChannel> multipart = do_QueryInterface(aChannel); + if (!multipart) { + *aHttpChannel = nullptr; + return NS_OK; + } + + nsCOMPtr<nsIChannel> baseChannel; + nsresult rv = multipart->GetBaseChannel(getter_AddRefs(baseChannel)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + httpChannel = do_QueryInterface(baseChannel); + httpChannel.forget(aHttpChannel); + + return NS_OK; +} + +//////////////////////////////////////////////////////////////////// +// PrincipalFlashClassifier + +// Classify the flash based on the document principal. +// The usage of this class is as follows: +// +// 1) Call AsyncClassify() as early as possible to asynchronously do +// classification against all the flash blocking related tables +// via nsIURIClassifier.asyncClassifyLocalWithTables. +// +// 2) At any time you need the classification result, call Result() +// and it is guaranteed to give you the result. Note that you have +// to specify "aIsThirdParty" to the function so please make sure +// you can already correctly decide if the document is third-party. +// +// Behind the scenes, the sync classification API +// (nsIURIClassifier.classifyLocalWithTable) may be called as a fallback to +// synchronously get the result if the asyncClassifyLocalWithTables hasn't +// been done yet. +// +// 3) You can call Result() as many times as you want and only the first time +// it may unfortunately call the blocking sync API. The subsequent call +// will just return the result that came out at the first time. +// +class PrincipalFlashClassifier final : public nsIURIClassifierCallback { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIURICLASSIFIERCALLBACK + + PrincipalFlashClassifier(); + + // Fire async classification based on the given principal. + void AsyncClassify(nsIPrincipal* aPrincipal); + + // Would block if the result hasn't come out. + mozilla::dom::FlashClassification ClassifyMaybeSync(nsIPrincipal* aPrincipal, + bool aIsThirdParty); + + private: + ~PrincipalFlashClassifier() = default; + + void Reset(); + bool EnsureUriClassifier(); + mozilla::dom::FlashClassification CheckIfClassifyNeeded( + nsIPrincipal* aPrincipal); + mozilla::dom::FlashClassification Resolve(bool aIsThirdParty); + mozilla::dom::FlashClassification AsyncClassifyInternal( + nsIPrincipal* aPrincipal); + void GetClassificationTables(bool aIsThirdParty, nsACString& aTables); + + // For the fallback sync classification. + nsCOMPtr<nsIURI> mClassificationURI; + + nsCOMPtr<nsIURIClassifier> mUriClassifier; + bool mAsyncClassified; + nsTArray<nsCString> mMatchedTables; + mozilla::dom::FlashClassification mResult; +}; + +} // namespace dom +} // namespace mozilla + +extern bool sDisablePrefetchHTTPSPref; + +#define NAME_NOT_VALID ((nsSimpleContentList*)1) + +nsIdentifierMapEntry::nsIdentifierMapEntry( + const nsIdentifierMapEntry::AtomOrString& aKey) + : mKey(aKey) {} + +nsIdentifierMapEntry::nsIdentifierMapEntry( + const nsIdentifierMapEntry::AtomOrString* aKey) + : mKey(aKey ? *aKey : nullptr) {} + +nsIdentifierMapEntry::~nsIdentifierMapEntry() {} + +nsIdentifierMapEntry::nsIdentifierMapEntry(nsIdentifierMapEntry&& aOther) + : PLDHashEntryHdr(std::move(aOther)), + mKey(std::move(aOther.mKey)), + mIdContentList(std::move(aOther.mIdContentList)), + mNameContentList(std::move(aOther.mNameContentList)), + mChangeCallbacks(std::move(aOther.mChangeCallbacks)), + mImageElement(std::move(aOther.mImageElement)) {} + +void nsIdentifierMapEntry::Traverse( + nsCycleCollectionTraversalCallback* aCallback) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCallback, + "mIdentifierMap mNameContentList"); + aCallback->NoteXPCOMChild(static_cast<nsINodeList*>(mNameContentList)); + + if (mImageElement) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCallback, + "mIdentifierMap mImageElement element"); + nsIContent* imageElement = mImageElement; + aCallback->NoteXPCOMChild(imageElement); + } +} + +bool nsIdentifierMapEntry::IsEmpty() { + return mIdContentList.IsEmpty() && !mNameContentList && !mChangeCallbacks && + !mImageElement; +} + +bool nsIdentifierMapEntry::HasNameElement() const { + return mNameContentList && mNameContentList->Length() != 0; +} + +Element* nsIdentifierMapEntry::GetIdElement() { + return mIdContentList.SafeElementAt(0); +} + +Element* nsIdentifierMapEntry::GetImageIdElement() { + return mImageElement ? mImageElement.get() : GetIdElement(); +} + +void nsIdentifierMapEntry::AddContentChangeCallback( + Document::IDTargetObserver aCallback, void* aData, bool aForImage) { + if (!mChangeCallbacks) { + mChangeCallbacks = new nsTHashtable<ChangeCallbackEntry>; + } + + ChangeCallback cc = {aCallback, aData, aForImage}; + mChangeCallbacks->PutEntry(cc); +} + +void nsIdentifierMapEntry::RemoveContentChangeCallback( + Document::IDTargetObserver aCallback, void* aData, bool aForImage) { + if (!mChangeCallbacks) return; + ChangeCallback cc = {aCallback, aData, aForImage}; + mChangeCallbacks->RemoveEntry(cc); + if (mChangeCallbacks->Count() == 0) { + mChangeCallbacks = nullptr; + } +} + +void nsIdentifierMapEntry::FireChangeCallbacks(Element* aOldElement, + Element* aNewElement, + bool aImageOnly) { + if (!mChangeCallbacks) return; + + for (auto iter = mChangeCallbacks->ConstIter(); !iter.Done(); iter.Next()) { + nsIdentifierMapEntry::ChangeCallbackEntry* entry = iter.Get(); + // Don't fire image changes for non-image observers, and don't fire element + // changes for image observers when an image override is active. + if (entry->mKey.mForImage ? (mImageElement && !aImageOnly) : aImageOnly) { + continue; + } + + if (!entry->mKey.mCallback(aOldElement, aNewElement, entry->mKey.mData)) { + iter.Remove(); + } + } +} + +namespace { + +struct PositionComparator { + Element* const mElement; + explicit PositionComparator(Element* const aElement) : mElement(aElement) {} + + int operator()(void* aElement) const { + Element* curElement = static_cast<Element*>(aElement); + MOZ_DIAGNOSTIC_ASSERT(mElement != curElement); + if (nsContentUtils::PositionIsBefore(mElement, curElement)) { + return -1; + } + return 1; + } +}; + +} // namespace + +void nsIdentifierMapEntry::AddIdElement(Element* aElement) { + MOZ_ASSERT(aElement, "Must have element"); + MOZ_ASSERT(!mIdContentList.Contains(nullptr), "Why is null in our list?"); + + // Common case + if (mIdContentList.IsEmpty()) { + mIdContentList.AppendElement(aElement); + FireChangeCallbacks(nullptr, aElement); + return; + } + +#ifdef DEBUG + Element* currentElement = mIdContentList.ElementAt(0); +#endif + + // We seem to have multiple content nodes for the same id, or XUL is messing + // with us. Search for the right place to insert the content. + + size_t idx; + BinarySearchIf(mIdContentList, 0, mIdContentList.Length(), + PositionComparator(aElement), &idx); + + mIdContentList.InsertElementAt(idx, aElement); + + if (idx == 0) { + Element* oldElement = mIdContentList.SafeElementAt(1); + NS_ASSERTION(currentElement == oldElement, "How did that happen?"); + FireChangeCallbacks(oldElement, aElement); + } +} + +void nsIdentifierMapEntry::RemoveIdElement(Element* aElement) { + MOZ_ASSERT(aElement, "Missing element"); + + // This should only be called while the document is in an update. + // Assertions near the call to this method guarantee this. + + // This could fire in OOM situations + // Only assert this in HTML documents for now as XUL does all sorts of weird + // crap. + NS_ASSERTION(!aElement->OwnerDoc()->IsHTMLDocument() || + mIdContentList.Contains(aElement), + "Removing id entry that doesn't exist"); + + // XXXbz should this ever Compact() I guess when all the content is gone + // we'll just get cleaned up in the natural order of things... + Element* currentElement = mIdContentList.SafeElementAt(0); + mIdContentList.RemoveElement(aElement); + if (currentElement == aElement) { + FireChangeCallbacks(currentElement, mIdContentList.SafeElementAt(0)); + } +} + +void nsIdentifierMapEntry::SetImageElement(Element* aElement) { + Element* oldElement = GetImageIdElement(); + mImageElement = aElement; + Element* newElement = GetImageIdElement(); + if (oldElement != newElement) { + FireChangeCallbacks(oldElement, newElement, true); + } +} + +namespace mozilla { +namespace dom { + +class SimpleHTMLCollection final : public nsSimpleContentList, + public nsIHTMLCollection { + public: + explicit SimpleHTMLCollection(nsINode* aRoot) : nsSimpleContentList(aRoot) {} + + NS_DECL_ISUPPORTS_INHERITED + + virtual nsINode* GetParentObject() override { + return nsSimpleContentList::GetParentObject(); + } + virtual uint32_t Length() override { return nsSimpleContentList::Length(); } + virtual Element* GetElementAt(uint32_t aIndex) override { + return mElements.SafeElementAt(aIndex)->AsElement(); + } + + virtual Element* GetFirstNamedElement(const nsAString& aName, + bool& aFound) override { + aFound = false; + RefPtr<nsAtom> name = NS_Atomize(aName); + for (uint32_t i = 0; i < mElements.Length(); i++) { + MOZ_DIAGNOSTIC_ASSERT(mElements[i]); + Element* element = mElements[i]->AsElement(); + if (element->GetID() == name || + (element->HasName() && + element->GetParsedAttr(nsGkAtoms::name)->GetAtomValue() == name)) { + aFound = true; + return element; + } + } + return nullptr; + } + + virtual void GetSupportedNames(nsTArray<nsString>& aNames) override { + AutoTArray<nsAtom*, 8> atoms; + for (uint32_t i = 0; i < mElements.Length(); i++) { + MOZ_DIAGNOSTIC_ASSERT(mElements[i]); + Element* element = mElements[i]->AsElement(); + + nsAtom* id = element->GetID(); + MOZ_ASSERT(id != nsGkAtoms::_empty); + if (id && !atoms.Contains(id)) { + atoms.AppendElement(id); + } + + if (element->HasName()) { + nsAtom* name = element->GetParsedAttr(nsGkAtoms::name)->GetAtomValue(); + MOZ_ASSERT(name && name != nsGkAtoms::_empty); + if (name && !atoms.Contains(name)) { + atoms.AppendElement(name); + } + } + } + + nsString* names = aNames.AppendElements(atoms.Length()); + for (uint32_t i = 0; i < atoms.Length(); i++) { + atoms[i]->ToString(names[i]); + } + } + + virtual JSObject* GetWrapperPreserveColorInternal() override { + return nsWrapperCache::GetWrapperPreserveColor(); + } + virtual void PreserveWrapperInternal( + nsISupports* aScriptObjectHolder) override { + nsWrapperCache::PreserveWrapper(aScriptObjectHolder); + } + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) override { + return HTMLCollection_Binding::Wrap(aCx, this, aGivenProto); + } + + using nsBaseContentList::Item; + + private: + virtual ~SimpleHTMLCollection() {} +}; + +NS_IMPL_ISUPPORTS_INHERITED(SimpleHTMLCollection, nsSimpleContentList, + nsIHTMLCollection) + +} // namespace dom +} // namespace mozilla + +void nsIdentifierMapEntry::AddNameElement(nsINode* aNode, Element* aElement) { + if (!mNameContentList) { + mNameContentList = new SimpleHTMLCollection(aNode); + } + + mNameContentList->AppendElement(aElement); +} + +void nsIdentifierMapEntry::RemoveNameElement(Element* aElement) { + if (mNameContentList) { + mNameContentList->RemoveElement(aElement); + } +} + +bool nsIdentifierMapEntry::HasIdElementExposedAsHTMLDocumentProperty() { + Element* idElement = GetIdElement(); + return idElement && + nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(idElement); +} + +size_t nsIdentifierMapEntry::SizeOfExcludingThis( + MallocSizeOf aMallocSizeOf) const { + return mKey.mString.SizeOfExcludingThisIfUnshared(aMallocSizeOf); +} + +// Helper structs for the content->subdoc map + +class SubDocMapEntry : public PLDHashEntryHdr { + public: + // Both of these are strong references + Element* mKey; // must be first, to look like PLDHashEntryStub + Document* mSubDocument; +}; + +class nsOnloadBlocker final : public nsIRequest { + public: + nsOnloadBlocker() {} + + NS_DECL_ISUPPORTS + NS_DECL_NSIREQUEST + + private: + ~nsOnloadBlocker() {} +}; + +NS_IMPL_ISUPPORTS(nsOnloadBlocker, nsIRequest) + +NS_IMETHODIMP +nsOnloadBlocker::GetName(nsACString& aResult) { + aResult.AssignLiteral("about:document-onload-blocker"); + return NS_OK; +} + +NS_IMETHODIMP +nsOnloadBlocker::IsPending(bool* _retval) { + *_retval = true; + return NS_OK; +} + +NS_IMETHODIMP +nsOnloadBlocker::GetStatus(nsresult* status) { + *status = NS_OK; + return NS_OK; +} + +NS_IMETHODIMP +nsOnloadBlocker::Cancel(nsresult status) { return NS_OK; } +NS_IMETHODIMP +nsOnloadBlocker::Suspend(void) { return NS_OK; } +NS_IMETHODIMP +nsOnloadBlocker::Resume(void) { return NS_OK; } + +NS_IMETHODIMP +nsOnloadBlocker::GetLoadGroup(nsILoadGroup** aLoadGroup) { + *aLoadGroup = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsOnloadBlocker::SetLoadGroup(nsILoadGroup* aLoadGroup) { return NS_OK; } + +NS_IMETHODIMP +nsOnloadBlocker::GetLoadFlags(nsLoadFlags* aLoadFlags) { + *aLoadFlags = nsIRequest::LOAD_NORMAL; + return NS_OK; +} + +NS_IMETHODIMP +nsOnloadBlocker::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } + +// ================================================================== + +namespace mozilla { +namespace dom { + +ExternalResourceMap::ExternalResourceMap() : mHaveShutDown(false) {} + +Document* ExternalResourceMap::RequestResource( + nsIURI* aURI, nsIURI* aReferrer, uint32_t aReferrerPolicy, + nsINode* aRequestingNode, Document* aDisplayDocument, + ExternalResourceLoad** aPendingLoad) { + // If we ever start allowing non-same-origin loads here, we might need to do + // something interesting with aRequestingPrincipal even for the hashtable + // gets. + MOZ_ASSERT(aURI, "Must have a URI"); + MOZ_ASSERT(aRequestingNode, "Must have a node"); + *aPendingLoad = nullptr; + if (mHaveShutDown) { + return nullptr; + } + + // First, make sure we strip the ref from aURI. + nsCOMPtr<nsIURI> clone; + nsresult rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(clone)); + if (NS_FAILED(rv) || !clone) { + return nullptr; + } + + ExternalResource* resource; + mMap.Get(clone, &resource); + if (resource) { + return resource->mDocument; + } + + RefPtr<PendingLoad>& loadEntry = mPendingLoads.GetOrInsert(clone); + if (loadEntry) { + RefPtr<PendingLoad> load(loadEntry); + load.forget(aPendingLoad); + return nullptr; + } + + RefPtr<PendingLoad> load(new PendingLoad(aDisplayDocument)); + loadEntry = load; + + if (NS_FAILED(load->StartLoad(clone, aReferrer, aReferrerPolicy, + aRequestingNode))) { + // Make sure we don't thrash things by trying this load again, since + // chances are it failed for good reasons (security check, etc). + AddExternalResource(clone, nullptr, nullptr, aDisplayDocument); + } else { + load.forget(aPendingLoad); + } + + return nullptr; +} + +void ExternalResourceMap::EnumerateResources(Document::SubDocEnumFunc aCallback, + void* aData) { + for (auto iter = mMap.Iter(); !iter.Done(); iter.Next()) { + ExternalResourceMap::ExternalResource* resource = iter.UserData(); + if (resource->mDocument && !aCallback(resource->mDocument, aData)) { + break; + } + } +} + +void ExternalResourceMap::Traverse( + nsCycleCollectionTraversalCallback* aCallback) const { + // mPendingLoads will get cleared out as the requests complete, so + // no need to worry about those here. + for (auto iter = mMap.ConstIter(); !iter.Done(); iter.Next()) { + ExternalResourceMap::ExternalResource* resource = iter.UserData(); + + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCallback, + "mExternalResourceMap.mMap entry" + "->mDocument"); + aCallback->NoteXPCOMChild(ToSupports(resource->mDocument)); + + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCallback, + "mExternalResourceMap.mMap entry" + "->mViewer"); + aCallback->NoteXPCOMChild(resource->mViewer); + + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCallback, + "mExternalResourceMap.mMap entry" + "->mLoadGroup"); + aCallback->NoteXPCOMChild(resource->mLoadGroup); + } +} + +void ExternalResourceMap::HideViewers() { + for (auto iter = mMap.Iter(); !iter.Done(); iter.Next()) { + nsCOMPtr<nsIContentViewer> viewer = iter.UserData()->mViewer; + if (viewer) { + viewer->Hide(); + } + } +} + +void ExternalResourceMap::ShowViewers() { + for (auto iter = mMap.Iter(); !iter.Done(); iter.Next()) { + nsCOMPtr<nsIContentViewer> viewer = iter.UserData()->mViewer; + if (viewer) { + viewer->Show(); + } + } +} + +void TransferZoomLevels(Document* aFromDoc, Document* aToDoc) { + MOZ_ASSERT(aFromDoc && aToDoc, "transferring zoom levels from/to null doc"); + + nsPresContext* fromCtxt = aFromDoc->GetPresContext(); + if (!fromCtxt) return; + + nsPresContext* toCtxt = aToDoc->GetPresContext(); + if (!toCtxt) return; + + toCtxt->SetFullZoom(fromCtxt->GetFullZoom()); + toCtxt->SetBaseMinFontSize(fromCtxt->BaseMinFontSize()); + toCtxt->SetTextZoom(fromCtxt->TextZoom()); + toCtxt->SetOverrideDPPX(fromCtxt->GetOverrideDPPX()); +} + +void TransferShowingState(Document* aFromDoc, Document* aToDoc) { + MOZ_ASSERT(aFromDoc && aToDoc, "transferring showing state from/to null doc"); + + if (aFromDoc->IsShowing()) { + aToDoc->OnPageShow(true, nullptr); + } +} + +nsresult ExternalResourceMap::AddExternalResource(nsIURI* aURI, + nsIContentViewer* aViewer, + nsILoadGroup* aLoadGroup, + Document* aDisplayDocument) { + MOZ_ASSERT(aURI, "Unexpected call"); + MOZ_ASSERT((aViewer && aLoadGroup) || (!aViewer && !aLoadGroup), + "Must have both or neither"); + + RefPtr<PendingLoad> load; + mPendingLoads.Remove(aURI, getter_AddRefs(load)); + + nsresult rv = NS_OK; + + nsCOMPtr<Document> doc; + if (aViewer) { + doc = aViewer->GetDocument(); + NS_ASSERTION(doc, "Must have a document"); + + if (doc->IsXULDocument()) { + // We don't handle XUL stuff here yet. + rv = NS_ERROR_NOT_AVAILABLE; + } else { + doc->SetDisplayDocument(aDisplayDocument); + + // Make sure that hiding our viewer will tear down its presentation. + aViewer->SetSticky(false); + + rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0)); + if (NS_SUCCEEDED(rv)) { + rv = aViewer->Open(nullptr, nullptr); + } + } + + if (NS_FAILED(rv)) { + doc = nullptr; + aViewer = nullptr; + aLoadGroup = nullptr; + } + } + + ExternalResource* newResource = new ExternalResource(); + mMap.Put(aURI, newResource); + + newResource->mDocument = doc; + newResource->mViewer = aViewer; + newResource->mLoadGroup = aLoadGroup; + if (doc) { + TransferZoomLevels(aDisplayDocument, doc); + TransferShowingState(aDisplayDocument, doc); + } + + const nsTArray<nsCOMPtr<nsIObserver>>& obs = load->Observers(); + for (uint32_t i = 0; i < obs.Length(); ++i) { + obs[i]->Observe(ToSupports(doc), "external-resource-document-created", + nullptr); + } + + return rv; +} + +NS_IMPL_ISUPPORTS(ExternalResourceMap::PendingLoad, nsIStreamListener, + nsIRequestObserver) + +NS_IMETHODIMP +ExternalResourceMap::PendingLoad::OnStartRequest(nsIRequest* aRequest, + nsISupports* aContext) { + ExternalResourceMap& map = mDisplayDocument->ExternalResourceMap(); + if (map.HaveShutDown()) { + return NS_BINDING_ABORTED; + } + + nsCOMPtr<nsIContentViewer> viewer; + nsCOMPtr<nsILoadGroup> loadGroup; + nsresult rv = + SetupViewer(aRequest, getter_AddRefs(viewer), getter_AddRefs(loadGroup)); + + // Make sure to do this no matter what + nsresult rv2 = + map.AddExternalResource(mURI, viewer, loadGroup, mDisplayDocument); + if (NS_FAILED(rv)) { + return rv; + } + if (NS_FAILED(rv2)) { + mTargetListener = nullptr; + return rv2; + } + + return mTargetListener->OnStartRequest(aRequest, aContext); +} + +nsresult ExternalResourceMap::PendingLoad::SetupViewer( + nsIRequest* aRequest, nsIContentViewer** aViewer, + nsILoadGroup** aLoadGroup) { + MOZ_ASSERT(!mTargetListener, "Unexpected call to OnStartRequest"); + *aViewer = nullptr; + *aLoadGroup = nullptr; + + nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest)); + NS_ENSURE_TRUE(chan, NS_ERROR_UNEXPECTED); + + nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest)); + if (httpChannel) { + bool requestSucceeded; + if (NS_FAILED(httpChannel->GetRequestSucceeded(&requestSucceeded)) || + !requestSucceeded) { + // Bail out on this load, since it looks like we have an HTTP error page + return NS_BINDING_ABORTED; + } + } + + nsAutoCString type; + chan->GetContentType(type); + + nsCOMPtr<nsILoadGroup> loadGroup; + chan->GetLoadGroup(getter_AddRefs(loadGroup)); + + // Give this document its own loadgroup + nsCOMPtr<nsILoadGroup> newLoadGroup = + do_CreateInstance(NS_LOADGROUP_CONTRACTID); + NS_ENSURE_TRUE(newLoadGroup, NS_ERROR_OUT_OF_MEMORY); + newLoadGroup->SetLoadGroup(loadGroup); + + nsCOMPtr<nsIInterfaceRequestor> callbacks; + loadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks)); + + nsCOMPtr<nsIInterfaceRequestor> newCallbacks = + new LoadgroupCallbacks(callbacks); + newLoadGroup->SetNotificationCallbacks(newCallbacks); + + // This is some serious hackery cribbed from docshell + nsCOMPtr<nsICategoryManager> catMan = + do_GetService(NS_CATEGORYMANAGER_CONTRACTID); + NS_ENSURE_TRUE(catMan, NS_ERROR_NOT_AVAILABLE); + nsCString contractId; + nsresult rv = + catMan->GetCategoryEntry("Gecko-Content-Viewers", type, contractId); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory = + do_GetService(contractId.get()); + NS_ENSURE_TRUE(docLoaderFactory, NS_ERROR_NOT_AVAILABLE); + + nsCOMPtr<nsIContentViewer> viewer; + nsCOMPtr<nsIStreamListener> listener; + rv = docLoaderFactory->CreateInstance( + "external-resource", chan, newLoadGroup, type, nullptr, nullptr, + getter_AddRefs(listener), getter_AddRefs(viewer)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(viewer, NS_ERROR_UNEXPECTED); + + nsCOMPtr<nsIParser> parser = do_QueryInterface(listener); + if (!parser) { + /// We don't want to deal with the various fake documents yet + return NS_ERROR_NOT_IMPLEMENTED; + } + + // We can't handle HTML and other weird things here yet. + nsIContentSink* sink = parser->GetContentSink(); + nsCOMPtr<nsIXMLContentSink> xmlSink = do_QueryInterface(sink); + if (!xmlSink) { + return NS_ERROR_NOT_IMPLEMENTED; + } + + listener.swap(mTargetListener); + viewer.forget(aViewer); + newLoadGroup.forget(aLoadGroup); + return NS_OK; +} + +NS_IMETHODIMP +ExternalResourceMap::PendingLoad::OnDataAvailable(nsIRequest* aRequest, + nsISupports* aContext, + nsIInputStream* aStream, + uint64_t aOffset, + uint32_t aCount) { + // mTargetListener might be null if SetupViewer or AddExternalResource failed. + NS_ENSURE_TRUE(mTargetListener, NS_ERROR_FAILURE); + if (mDisplayDocument->ExternalResourceMap().HaveShutDown()) { + return NS_BINDING_ABORTED; + } + return mTargetListener->OnDataAvailable(aRequest, aContext, aStream, aOffset, + aCount); +} + +NS_IMETHODIMP +ExternalResourceMap::PendingLoad::OnStopRequest(nsIRequest* aRequest, + nsISupports* aContext, + nsresult aStatus) { + // mTargetListener might be null if SetupViewer or AddExternalResource failed + if (mTargetListener) { + nsCOMPtr<nsIStreamListener> listener; + mTargetListener.swap(listener); + return listener->OnStopRequest(aRequest, aContext, aStatus); + } + + return NS_OK; +} + +nsresult ExternalResourceMap::PendingLoad::StartLoad(nsIURI* aURI, + nsIURI* aReferrer, + uint32_t aReferrerPolicy, + nsINode* aRequestingNode) { + MOZ_ASSERT(aURI, "Must have a URI"); + MOZ_ASSERT(aRequestingNode, "Must have a node"); + + nsCOMPtr<nsILoadGroup> loadGroup = + aRequestingNode->OwnerDoc()->GetDocumentLoadGroup(); + + nsresult rv = NS_OK; + nsCOMPtr<nsIChannel> channel; + rv = NS_NewChannel(getter_AddRefs(channel), aURI, aRequestingNode, + nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS, + nsIContentPolicy::TYPE_OTHER, + nullptr, // aPerformanceStorage + loadGroup); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel)); + if (httpChannel) { + rv = httpChannel->SetReferrerWithPolicy(aReferrer, aReferrerPolicy); + Unused << NS_WARN_IF(NS_FAILED(rv)); + } + + mURI = aURI; + + return channel->AsyncOpen2(this); +} + +NS_IMPL_ISUPPORTS(ExternalResourceMap::LoadgroupCallbacks, + nsIInterfaceRequestor) + +#define IMPL_SHIM(_i) \ + NS_IMPL_ISUPPORTS(ExternalResourceMap::LoadgroupCallbacks::_i##Shim, _i) + +IMPL_SHIM(nsILoadContext) +IMPL_SHIM(nsIProgressEventSink) +IMPL_SHIM(nsIChannelEventSink) +IMPL_SHIM(nsISecurityEventSink) +IMPL_SHIM(nsIApplicationCacheContainer) + +#undef IMPL_SHIM + +#define IID_IS(_i) aIID.Equals(NS_GET_IID(_i)) + +#define TRY_SHIM(_i) \ + PR_BEGIN_MACRO \ + if (IID_IS(_i)) { \ + nsCOMPtr<_i> real = do_GetInterface(mCallbacks); \ + if (!real) { \ + return NS_NOINTERFACE; \ + } \ + nsCOMPtr<_i> shim = new _i##Shim(this, real); \ + shim.forget(aSink); \ + return NS_OK; \ + } \ + PR_END_MACRO + +NS_IMETHODIMP +ExternalResourceMap::LoadgroupCallbacks::GetInterface(const nsIID& aIID, + void** aSink) { + if (mCallbacks && (IID_IS(nsIPrompt) || IID_IS(nsIAuthPrompt) || + IID_IS(nsIAuthPrompt2) || IID_IS(nsITabChild))) { + return mCallbacks->GetInterface(aIID, aSink); + } + + *aSink = nullptr; + + TRY_SHIM(nsILoadContext); + TRY_SHIM(nsIProgressEventSink); + TRY_SHIM(nsIChannelEventSink); + TRY_SHIM(nsISecurityEventSink); + TRY_SHIM(nsIApplicationCacheContainer); + + return NS_NOINTERFACE; +} + +#undef TRY_SHIM +#undef IID_IS + +ExternalResourceMap::ExternalResource::~ExternalResource() { + if (mViewer) { + mViewer->Close(nullptr); + mViewer->Destroy(); + } +} + +// ================================================================== +// = +// ================================================================== + +// If we ever have an nsIDocumentObserver notification for stylesheet title +// changes we should update the list from that instead of overriding +// EnsureFresh. +class DOMStyleSheetSetList final : public DOMStringList { + public: + explicit DOMStyleSheetSetList(Document* aDocument); + + void Disconnect() { mDocument = nullptr; } + + virtual void EnsureFresh() override; + + protected: + Document* mDocument; // Our document; weak ref. It'll let us know if it + // dies. +}; + +DOMStyleSheetSetList::DOMStyleSheetSetList(Document* aDocument) + : mDocument(aDocument) { + NS_ASSERTION(mDocument, "Must have document!"); +} + +void DOMStyleSheetSetList::EnsureFresh() { + MOZ_ASSERT(NS_IsMainThread()); + + mNames.Clear(); + + if (!mDocument) { + return; // Spec says "no exceptions", and we have no style sets if we have + // no document, for sure + } + + size_t count = mDocument->SheetCount(); + nsAutoString title; + for (size_t index = 0; index < count; index++) { + StyleSheet* sheet = mDocument->SheetAt(index); + NS_ASSERTION(sheet, "Null sheet in sheet list!"); + sheet->GetTitle(title); + if (!title.IsEmpty() && !mNames.Contains(title) && !Add(title)) { + return; + } + } +} + +// ================================================================== +Document::SelectorCache::SelectorCache(nsIEventTarget* aEventTarget) + : nsExpirationTracker<SelectorCacheKey, 4>(1000, "Document::SelectorCache", + aEventTarget) {} + +Document::SelectorCache::~SelectorCache() { AgeAllGenerations(); } + +void Document::SelectorCache::NotifyExpired(SelectorCacheKey* aSelector) { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aSelector); + + // There is no guarantee that this method won't be re-entered when selector + // matching is ongoing because "memory-pressure" could be notified immediately + // when OOM happens according to the design of nsExpirationTracker. + // The perfect solution is to delete the |aSelector| and its + // RawServoSelectorList in mTable asynchronously. + // We remove these objects synchronously for now because NotifyExpired() will + // never be triggered by "memory-pressure" which is not implemented yet in + // the stage 2 of mozalloc_handle_oom(). + // Once these objects are removed asynchronously, we should update the warning + // added in mozalloc_handle_oom() as well. + RemoveObject(aSelector); + mTable.Remove(aSelector->mKey); + delete aSelector; +} + +struct Document::FrameRequest { + FrameRequest(FrameRequestCallback& aCallback, int32_t aHandle) + : mCallback(&aCallback), mHandle(aHandle) {} + + // Conversion operator so that we can append these to a + // FrameRequestCallbackList + operator const RefPtr<FrameRequestCallback>&() const { return mCallback; } + + // Comparator operators to allow RemoveElementSorted with an + // integer argument on arrays of FrameRequest + bool operator==(int32_t aHandle) const { return mHandle == aHandle; } + bool operator<(int32_t aHandle) const { return mHandle < aHandle; } + + RefPtr<FrameRequestCallback> mCallback; + int32_t mHandle; +}; + +// ================================================================== +// = +// ================================================================== +Document::Document(const char* aContentType) + : nsINode(nullptr), + DocumentOrShadowRoot(*this), + mReferrerPolicySet(false), + mReferrerPolicy(mozilla::net::RP_Unset), + mBlockAllMixedContent(false), + mBlockAllMixedContentPreloads(false), + mUpgradeInsecureRequests(false), + mUpgradeInsecurePreloads(false), + mCharacterSet(WINDOWS_1252_ENCODING), + mCharacterSetSource(0), + mParentDocument(nullptr), + mCachedRootElement(nullptr), + mNodeInfoManager(nullptr), +#ifdef DEBUG + mStyledLinksCleared(false), +#endif + mBidiEnabled(false), + mMathMLEnabled(false), + mIsInitialDocumentInWindow(false), + mIgnoreDocGroupMismatches(false), + mLoadedAsData(false), + mLoadedAsInteractiveData(false), + mMayStartLayout(true), + mHaveFiredTitleChange(false), + mIsShowing(false), + mVisible(true), + mRemovedFromDocShell(false), + // mAllowDNSPrefetch starts true, so that we can always reliably && it + // with various values that might disable it. Since we never prefetch + // unless we get a window, and in that case the docshell value will get + // &&-ed in, this is safe. + mAllowDNSPrefetch(true), + mIsStaticDocument(false), + mCreatingStaticClone(false), + mInUnlinkOrDeletion(false), + mHasHadScriptHandlingObject(false), + mIsBeingUsedAsImage(false), + mIsSyntheticDocument(false), + mHasLinksToUpdateRunnable(false), + mFlushingPendingLinkUpdates(false), + mMayHaveDOMMutationObservers(false), + mMayHaveAnimationObservers(false), + mHasMixedActiveContentLoaded(false), + mHasMixedActiveContentBlocked(false), + mHasMixedDisplayContentLoaded(false), + mHasMixedDisplayContentBlocked(false), + mHasMixedContentObjectSubrequest(false), + mHasCSP(false), + mHasUnsafeEvalCSP(false), + mHasUnsafeInlineCSP(false), + mBFCacheDisallowed(false), + mHasHadDefaultView(false), + mStyleSheetChangeEventsEnabled(false), + mIsSrcdocDocument(false), + mDidDocumentOpen(false), + mHasDisplayDocument(false), + mFontFaceSetDirty(true), + mGetUserFontSetCalled(false), + mDidFireDOMContentLoaded(true), + mHasScrollLinkedEffect(false), + mFrameRequestCallbacksScheduled(false), + mIsTopLevelContentDocument(false), + mIsContentDocument(false), + mDidCallBeginLoad(false), + mAllowPaymentRequest(false), + mEncodingMenuDisabled(false), + mIsSVGGlyphsDocument(false), + mInDestructor(false), + mIsGoingAway(false), + mInXBLUpdate(false), + mNeedsReleaseAfterStackRefCntRelease(false), + mStyleSetFilled(false), + mSSApplicableStateNotificationPending(false), + mMayHaveTitleElement(false), + mDOMLoadingSet(false), + mDOMInteractiveSet(false), + mDOMCompleteSet(false), + mAutoFocusFired(false), + mScrolledToRefAlready(false), + mChangeScrollPosWhenScrollingToRef(false), + mHasWarnedAboutBoxObjects(false), + mDelayFrameLoaderInitialization(false), + mSynchronousDOMContentLoaded(false), + mMaybeServiceWorkerControlled(false), + mAllowZoom(false), + mValidScaleFloat(false), + mValidMaxScale(false), + mScaleStrEmpty(false), + mWidthStrEmpty(false), + mParserAborted(false), + mReportedUseCounters(false), + mHasReportedShadowDOMUsage(false), + mDocTreeHadAudibleMedia(false), + mDocTreeHadPlayRevoked(false), +#ifdef DEBUG + mWillReparent(false), +#endif + mHasDelayedRefreshEvent(false), + mPendingFullscreenRequests(0), + mXMLDeclarationBits(0), + mOnloadBlockCount(0), + mAsyncOnloadBlockCount(0), + mCompatMode(eCompatibility_FullStandards), + mReadyState(ReadyState::READYSTATE_UNINITIALIZED), +#ifdef MOZILLA_INTERNAL_API + mVisibilityState(dom::VisibilityState::Hidden), +#else + mDummy(0), +#endif + mType(eUnknown), + mDefaultElementType(0), + mAllowXULXBL(eTriUnset), + mBidiOptions(IBMBIDI_DEFAULT_BIDI_OPTIONS), + mSandboxFlags(0), + mPartID(0), + mMarkedCCGeneration(0), + mPresShell(nullptr), + mSubtreeModifiedDepth(0), + mPreloadPictureDepth(0), + mEventsSuppressed(0), + mIgnoreDestructiveWritesCounter(0), + mFrameRequestCallbackCounter(0), + mStaticCloneCount(0), + mWindow(nullptr), + mBFCacheEntry(nullptr), + mInSyncOperationCount(0), + mBlockDOMContentLoaded(0), + mUseCounters(0), + mChildDocumentUseCounters(0), + mNotifiedPageForUseCounter(0), + mUserHasInteracted(false), + mHasUserInteractionTimerScheduled(false), + mUserGestureActivated(false), + mStackRefCnt(0), + mUpdateNestLevel(0), + mViewportType(Unknown), + mViewportOverflowType(ViewportOverflowType::NoOverflow), + mSubDocuments(nullptr), + mHeaderData(nullptr), + mPrincipalFlashClassifier(new PrincipalFlashClassifier()), + mFlashClassification(FlashClassification::Unclassified), + mBoxObjectTable(nullptr), + mCurrentOrientationAngle(0), + mCurrentOrientationType(OrientationType::Portrait_primary), + mServoRestyleRootDirtyBits(0), + mThrowOnDynamicMarkupInsertionCounter(0), + mIgnoreOpensDuringUnloadCounter(0), + mDocLWTheme(Doc_Theme_Uninitialized), + mSavedResolution(1.0f) { + MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p created", this)); + + SetIsInDocument(); + SetIsConnected(true); + + if (StaticPrefs::layout_css_use_counters_enabled()) { + mStyleUseCounters.reset(Servo_UseCounters_Create()); + } + + SetContentTypeInternal(nsDependentCString(aContentType)); + + // Start out mLastStyleSheetSet as null, per spec + SetDOMStringToNull(mLastStyleSheetSet); + + // void state used to differentiate an empty source from an unselected source + mPreloadPictureFoundSource.SetIsVoid(true); +} + +void Document::ClearAllBoxObjects() { + if (mBoxObjectTable) { + for (auto iter = mBoxObjectTable->Iter(); !iter.Done(); iter.Next()) { + nsPIBoxObject* boxObject = iter.UserData(); + if (boxObject) { + boxObject->Clear(); + } + } + delete mBoxObjectTable; + mBoxObjectTable = nullptr; + } +} + +bool Document::IsAboutPage() const { + nsCOMPtr<nsIPrincipal> principal = NodePrincipal(); + nsCOMPtr<nsIURI> uri; + principal->GetURI(getter_AddRefs(uri)); + bool isAboutScheme = true; + if (uri) { + uri->SchemeIs("about", &isAboutScheme); + } + return isAboutScheme; +} + +void Document::ConstructUbiNode(void* storage) { + JS::ubi::Concrete<Document>::construct(storage, this); +} + +Document::~Document() { + MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p destroyed", this)); + MOZ_ASSERT(!IsTopLevelContentDocument() || !IsResourceDoc(), + "Can't be top-level and a resource doc at the same time"); + + NS_ASSERTION(!mIsShowing, "Destroying a currently-showing document"); + + if (IsTopLevelContentDocument()) { + // don't report for about: pages + if (!IsAboutPage()) { + // Record the page load + uint32_t pageLoaded = 1; + Accumulate(Telemetry::MIXED_CONTENT_UNBLOCK_COUNTER, pageLoaded); + // Record the mixed content status of the docshell in Telemetry + enum { + NO_MIXED_CONTENT = 0, // There is no Mixed Content on the page + MIXED_DISPLAY_CONTENT = + 1, // The page attempted to load Mixed Display Content + MIXED_ACTIVE_CONTENT = + 2, // The page attempted to load Mixed Active Content + MIXED_DISPLAY_AND_ACTIVE_CONTENT = + 3 // The page attempted to load Mixed Display & Mixed Active + // Content + }; + + bool mixedActiveLoaded = GetHasMixedActiveContentLoaded(); + bool mixedActiveBlocked = GetHasMixedActiveContentBlocked(); + + bool mixedDisplayLoaded = GetHasMixedDisplayContentLoaded(); + bool mixedDisplayBlocked = GetHasMixedDisplayContentBlocked(); + + bool hasMixedDisplay = (mixedDisplayBlocked || mixedDisplayLoaded); + bool hasMixedActive = (mixedActiveBlocked || mixedActiveLoaded); + + uint32_t mixedContentLevel = NO_MIXED_CONTENT; + if (hasMixedDisplay && hasMixedActive) { + mixedContentLevel = MIXED_DISPLAY_AND_ACTIVE_CONTENT; + } else if (hasMixedActive) { + mixedContentLevel = MIXED_ACTIVE_CONTENT; + } else if (hasMixedDisplay) { + mixedContentLevel = MIXED_DISPLAY_CONTENT; + } + Accumulate(Telemetry::MIXED_CONTENT_PAGE_LOAD, mixedContentLevel); + + // record mixed object subrequest telemetry + if (mHasMixedContentObjectSubrequest) { + /* mixed object subrequest loaded on page*/ + Accumulate(Telemetry::MIXED_CONTENT_OBJECT_SUBREQUEST, 1); + } else { + /* no mixed object subrequests loaded on page*/ + Accumulate(Telemetry::MIXED_CONTENT_OBJECT_SUBREQUEST, 0); + } + + // record CSP telemetry on this document + if (mHasCSP) { + Accumulate(Telemetry::CSP_DOCUMENTS_COUNT, 1); + } + if (mHasUnsafeInlineCSP) { + Accumulate(Telemetry::CSP_UNSAFE_INLINE_DOCUMENTS_COUNT, 1); + } + if (mHasUnsafeEvalCSP) { + Accumulate(Telemetry::CSP_UNSAFE_EVAL_DOCUMENTS_COUNT, 1); + } + + if (MOZ_UNLIKELY(mMathMLEnabled)) { + ScalarAdd(Telemetry::ScalarID::MATHML_DOC_COUNT, 1); + } + + ScalarAdd(Telemetry::ScalarID::MEDIA_PAGE_COUNT, 1); + if (mDocTreeHadAudibleMedia) { + ScalarAdd(Telemetry::ScalarID::MEDIA_PAGE_HAD_MEDIA_COUNT, 1); + } + if (mDocTreeHadPlayRevoked) { + ScalarAdd(Telemetry::ScalarID::MEDIA_PAGE_HAD_PLAY_REVOKED_COUNT, 1); + } + + if (IsHTMLDocument()) { + switch (GetCompatibilityMode()) { + case eCompatibility_FullStandards: + Telemetry::AccumulateCategorical( + Telemetry::LABELS_QUIRKS_MODE::FullStandards); + break; + case eCompatibility_AlmostStandards: + Telemetry::AccumulateCategorical( + Telemetry::LABELS_QUIRKS_MODE::AlmostStandards); + break; + case eCompatibility_NavQuirks: + Telemetry::AccumulateCategorical( + Telemetry::LABELS_QUIRKS_MODE::NavQuirks); + break; + default: + MOZ_ASSERT_UNREACHABLE("Unknown quirks mode"); + break; + } + } + } + } + + ReportUseCounters(); + + mInDestructor = true; + mInUnlinkOrDeletion = true; + + mozilla::DropJSObjects(this); + + // Clear mObservers to keep it in sync with the mutationobserver list + mObservers.Clear(); + + mIntersectionObservers.Clear(); + + if (mStyleSheetSetList) { + mStyleSheetSetList->Disconnect(); + } + + if (mAnimationController) { + mAnimationController->Disconnect(); + } + + MOZ_ASSERT(mTimelines.isEmpty()); + + mParentDocument = nullptr; + + // Kill the subdocument map, doing this will release its strong + // references, if any. + delete mSubDocuments; + mSubDocuments = nullptr; + + // Destroy link map now so we don't waste time removing + // links one by one + DestroyElementMaps(); + + nsAutoScriptBlocker scriptBlocker; + + // Invalidate cached array of child nodes + InvalidateChildNodes(); + + // We should not have child nodes when destructor is called, + // since child nodes keep their owner document alive. + MOZ_ASSERT(!HasChildren()); + + mCachedRootElement = nullptr; + + for (auto& sheets : mAdditionalSheets) { + for (StyleSheet* sheet : sheets) { + sheet->ClearAssociatedDocumentOrShadowRoot(); + } + } + + if (mAttrStyleSheet) { + mAttrStyleSheet->SetOwningDocument(nullptr); + } + + if (mListenerManager) { + mListenerManager->Disconnect(); + UnsetFlags(NODE_HAS_LISTENERMANAGER); + } + + if (mScriptLoader) { + mScriptLoader->DropDocumentReference(); + } + + if (mCSSLoader) { + // Could be null here if Init() failed or if we have been unlinked. + mCSSLoader->DropDocumentReference(); + } + + if (mStyleImageLoader) { + mStyleImageLoader->DropDocumentReference(); + } + + if (mXULBroadcastManager) { + mXULBroadcastManager->DropDocumentReference(); + } + + if (mXULPersist) { + mXULPersist->DropDocumentReference(); + } + + delete mHeaderData; + + ClearAllBoxObjects(); + + mPendingTitleChangeEvent.Revoke(); + + mPlugins.Clear(); + + MOZ_ASSERT(mDOMMediaQueryLists.isEmpty(), + "must not have media query lists left"); + + if (mNodeInfoManager) { + mNodeInfoManager->DropDocumentReference(); + } + + if (mDocGroup) { + mDocGroup->RemoveDocument(this); + } + + UnlinkOriginalDocumentIfStatic(); +} + +NS_INTERFACE_TABLE_HEAD(Document) + NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY + NS_INTERFACE_TABLE_BEGIN + NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(Document, nsISupports, nsINode) + NS_INTERFACE_TABLE_ENTRY(Document, nsINode) + NS_INTERFACE_TABLE_ENTRY(Document, Document) + NS_INTERFACE_TABLE_ENTRY(Document, nsIScriptObjectPrincipal) + NS_INTERFACE_TABLE_ENTRY(Document, mozilla::dom::EventTarget) + NS_INTERFACE_TABLE_ENTRY(Document, nsISupportsWeakReference) + NS_INTERFACE_TABLE_ENTRY(Document, nsIRadioGroupContainer) + NS_INTERFACE_TABLE_ENTRY(Document, nsIMutationObserver) + NS_INTERFACE_TABLE_ENTRY(Document, nsIApplicationCacheContainer) + NS_INTERFACE_TABLE_END + NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(Document) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(Document) +NS_IMETHODIMP_(MozExternalRefCountType) +Document::Release() { + MOZ_ASSERT(0 != mRefCnt, "dup release"); + NS_ASSERT_OWNINGTHREAD(Document); + nsISupports* base = NS_CYCLE_COLLECTION_CLASSNAME(Document)::Upcast(this); + bool shouldDelete = false; + nsrefcnt count = mRefCnt.decr(base, &shouldDelete); + NS_LOG_RELEASE(this, count, "Document"); + if (count == 0) { + if (mStackRefCnt && !mNeedsReleaseAfterStackRefCntRelease) { + mNeedsReleaseAfterStackRefCntRelease = true; + NS_ADDREF_THIS(); + return mRefCnt.get(); + } + mRefCnt.incr(base); + nsNodeUtils::LastRelease(this); + mRefCnt.decr(base); + if (shouldDelete) { + mRefCnt.stabilizeForDeletion(); + DeleteCycleCollectable(); + } + } + return count; +} + +NS_IMETHODIMP_(void) +Document::DeleteCycleCollectable() { delete this; } + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(Document) + if (Element::CanSkip(tmp, aRemovingAllowed)) { + EventListenerManager* elm = tmp->GetExistingListenerManager(); + if (elm) { + elm->MarkForCC(); + } + return true; + } +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(Document) + return Element::CanSkipInCC(tmp); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(Document) + return Element::CanSkipThis(tmp); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END + +static const char* kNSURIs[] = {"([none])", "(xmlns)", "(xml)", "(xhtml)", + "(XLink)", "(XSLT)", "(XBL)", "(MathML)", + "(RDF)", "(XUL)"}; + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document) + if (MOZ_UNLIKELY(cb.WantDebugInfo())) { + char name[512]; + nsAutoCString loadedAsData; + if (tmp->IsLoadedAsData()) { + loadedAsData.AssignLiteral("data"); + } else { + loadedAsData.AssignLiteral("normal"); + } + uint32_t nsid = tmp->GetDefaultNamespaceID(); + nsAutoCString uri; + if (tmp->mDocumentURI) uri = tmp->mDocumentURI->GetSpecOrDefault(); + if (nsid < ArrayLength(kNSURIs)) { + SprintfLiteral(name, "Document %s %s %s", loadedAsData.get(), + kNSURIs[nsid], uri.get()); + } else { + SprintfLiteral(name, "Document %s %s", loadedAsData.get(), uri.get()); + } + cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name); + } else { + NS_IMPL_CYCLE_COLLECTION_DESCRIBE(Document, tmp->mRefCnt.get()) + } + + if (!nsINode::Traverse(tmp, cb)) { + return NS_SUCCESS_INTERRUPTED_TRAVERSE; + } + + if (tmp->mMaybeEndOutermostXBLUpdateRunner) { + // The cached runnable keeps a reference to the document object.. + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME( + cb, "mMaybeEndOutermostXBLUpdateRunner.mObj"); + cb.NoteXPCOMChild(ToSupports(tmp)); + } + + for (auto iter = tmp->mIdentifierMap.ConstIter(); !iter.Done(); iter.Next()) { + iter.Get()->Traverse(&cb); + } + + tmp->mExternalResourceMap.Traverse(&cb); + + // Traverse all Document pointer members. + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSecurityInfo) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDisplayDocument) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFontFaceSet) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReadyForIdle) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentL10n) + + // Traverse all Document nsCOMPtrs. + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParser) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScriptGlobalObject) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListenerManager) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStyleSheets) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheetSetList) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScriptLoader) + + DocumentOrShadowRoot::Traverse(tmp, cb); + + // The boxobject for an element will only exist as long as it's in the + // document, so we'll traverse the table here instead of from the element. + if (tmp->mBoxObjectTable) { + for (auto iter = tmp->mBoxObjectTable->Iter(); !iter.Done(); iter.Next()) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mBoxObjectTable entry"); + cb.NoteXPCOMChild(iter.UserData()); + } + } + + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChannel) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLayoutHistoryState) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnloadBlocker) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMImplementation) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImageMaps) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOrientationPendingPromise) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOriginalDocument) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCachedEncoder) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStateObjectCached) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentTimeline) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingAnimationTracker) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTemplateContentsOwner) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildrenCollection) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImages); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEmbeds); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLinks); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mForms); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScripts); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mApplets); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnchors); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnonymousContents) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCommandDispatcher) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFeaturePolicy) + + // Traverse all our nsCOMArrays. + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages) + + for (uint32_t i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFrameRequestCallbacks[i]"); + cb.NoteXPCOMChild(tmp->mFrameRequestCallbacks[i].mCallback); + } + + // Traverse animation components + if (tmp->mAnimationController) { + tmp->mAnimationController->Traverse(&cb); + } + + if (tmp->mSubDocuments) { + for (auto iter = tmp->mSubDocuments->Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast<SubDocMapEntry*>(iter.Get()); + + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSubDocuments entry->mKey"); + cb.NoteXPCOMChild(entry->mKey); + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, + "mSubDocuments entry->mSubDocument"); + cb.NoteXPCOMChild(ToSupports(entry->mSubDocument)); + } + } + + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCSSLoader) + + // We own only the items in mDOMMediaQueryLists that have listeners; + // this reference is managed by their AddListener and RemoveListener + // methods. + for (MediaQueryList* mql = tmp->mDOMMediaQueryLists.getFirst(); mql; + mql = static_cast<LinkedListElement<MediaQueryList>*>(mql)->getNext()) { + if (mql->HasListeners() && + NS_SUCCEEDED(mql->CheckInnerWindowCorrectness())) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mDOMMediaQueryLists item"); + cb.NoteXPCOMChild(mql); + } + } +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_CLASS(Document) + +NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Document) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document) + tmp->mInUnlinkOrDeletion = true; + + // Clear out our external resources + tmp->mExternalResourceMap.Shutdown(); + + nsAutoScriptBlocker scriptBlocker; + + nsINode::Unlink(tmp); + + while (tmp->HasChildren()) { + // Hold a strong ref to the node when we remove it, because we may be + // the last reference to it. + // If this code changes, change the corresponding code in Document's + // unlink impl and ContentUnbinder::UnbindSubtree. + nsCOMPtr<nsIContent> child = tmp->GetLastChild(); + tmp->DisconnectChild(child); + child->UnbindFromTree(); + } + + tmp->UnlinkOriginalDocumentIfStatic(); + + tmp->mCachedRootElement = nullptr; // Avoid a dangling pointer + NS_IMPL_CYCLE_COLLECTION_UNLINK(mDisplayDocument) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mMaybeEndOutermostXBLUpdateRunner) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMImplementation) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mImageMaps) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedEncoder) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentTimeline) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingAnimationTracker) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mTemplateContentsOwner) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildrenCollection) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mImages); + NS_IMPL_CYCLE_COLLECTION_UNLINK(mEmbeds); + NS_IMPL_CYCLE_COLLECTION_UNLINK(mLinks); + NS_IMPL_CYCLE_COLLECTION_UNLINK(mForms); + NS_IMPL_CYCLE_COLLECTION_UNLINK(mScripts); + NS_IMPL_CYCLE_COLLECTION_UNLINK(mApplets); + NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnchors); + NS_IMPL_CYCLE_COLLECTION_UNLINK(mOrientationPendingPromise) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mFontFaceSet) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mReadyForIdle); + NS_IMPL_CYCLE_COLLECTION_UNLINK(mCommandDispatcher) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentL10n); + NS_IMPL_CYCLE_COLLECTION_UNLINK(mFeaturePolicy) + + tmp->mParentDocument = nullptr; + + NS_IMPL_CYCLE_COLLECTION_UNLINK(mPreloadingImages) + + NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntersectionObservers) + + tmp->ClearAllBoxObjects(); + + if (tmp->mListenerManager) { + tmp->mListenerManager->Disconnect(); + tmp->UnsetFlags(NODE_HAS_LISTENERMANAGER); + tmp->mListenerManager = nullptr; + } + + NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStyleSheets) + + if (tmp->mStyleSheetSetList) { + tmp->mStyleSheetSetList->Disconnect(); + tmp->mStyleSheetSetList = nullptr; + } + + delete tmp->mSubDocuments; + tmp->mSubDocuments = nullptr; + + tmp->mFrameRequestCallbacks.Clear(); + MOZ_RELEASE_ASSERT(!tmp->mFrameRequestCallbacksScheduled, + "How did we get here without our presshell going away " + "first?"); + + DocumentOrShadowRoot::Unlink(tmp); + + // Document has a pretty complex destructor, so we're going to + // assume that *most* cycles you actually want to break somewhere + // else, and not unlink an awful lot here. + + tmp->mIdentifierMap.Clear(); + tmp->mExpandoAndGeneration.OwnerUnlinked(); + + if (tmp->mAnimationController) { + tmp->mAnimationController->Unlink(); + } + + tmp->mPendingTitleChangeEvent.Revoke(); + + if (tmp->mCSSLoader) { + tmp->mCSSLoader->DropDocumentReference(); + NS_IMPL_CYCLE_COLLECTION_UNLINK(mCSSLoader) + } + + // We own only the items in mDOMMediaQueryLists that have listeners; + // this reference is managed by their AddListener and RemoveListener + // methods. + for (MediaQueryList* mql = tmp->mDOMMediaQueryLists.getFirst(); mql;) { + MediaQueryList* next = + static_cast<LinkedListElement<MediaQueryList>*>(mql)->getNext(); + mql->Disconnect(); + mql = next; + } + + tmp->mInUnlinkOrDeletion = false; +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +nsresult Document::Init() { + if (mCSSLoader || mStyleImageLoader || mNodeInfoManager || mScriptLoader) { + return NS_ERROR_ALREADY_INITIALIZED; + } + + // Force initialization. + nsINode::nsSlots* slots = Slots(); + + // Prepend self as mutation-observer whether we need it or not (some + // subclasses currently do, other don't). This is because the code in + // nsNodeUtils always notifies the first observer first, expecting the + // first observer to be the document. + slots->mMutationObservers.PrependElementUnlessExists( + static_cast<nsIMutationObserver*>(this)); + + mOnloadBlocker = new nsOnloadBlocker(); + mCSSLoader = new mozilla::css::Loader(this); + // Assume we're not quirky, until we know otherwise + mCSSLoader->SetCompatibilityMode(eCompatibility_FullStandards); + + mStyleImageLoader = new mozilla::css::ImageLoader(this); + + mNodeInfoManager = new nsNodeInfoManager(); + nsresult rv = mNodeInfoManager->Init(this); + NS_ENSURE_SUCCESS(rv, rv); + + // mNodeInfo keeps NodeInfoManager alive! + mNodeInfo = mNodeInfoManager->GetDocumentNodeInfo(); + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_OUT_OF_MEMORY); + MOZ_ASSERT(mNodeInfo->NodeType() == DOCUMENT_NODE, + "Bad NodeType in aNodeInfo"); + + NS_ASSERTION(OwnerDoc() == this, "Our nodeinfo is busted!"); + + // If after creation the owner js global is not set for a document + // we use the default compartment for this document, instead of creating + // wrapper in some random compartment when the document is exposed to js + // via some events. + nsCOMPtr<nsIGlobalObject> global = + xpc::NativeGlobal(xpc::PrivilegedJunkScope()); + NS_ENSURE_TRUE(global, NS_ERROR_FAILURE); + mScopeObject = do_GetWeakReference(global); + MOZ_ASSERT(mScopeObject); + + mScriptLoader = new dom::ScriptLoader(this); + + // we need to create a policy here so getting the policy within + // ::Policy() can *always* return a non null policy + mFeaturePolicy = new FeaturePolicy(this); + mFeaturePolicy->SetDefaultOrigin(NodePrincipal()); + + mozilla::HoldJSObjects(this); + + return NS_OK; +} + +void Document::DeleteAllProperties() { PropertyTable().DeleteAllProperties(); } + +void Document::DeleteAllPropertiesFor(nsINode* aNode) { + PropertyTable().DeleteAllPropertiesFor(aNode); +} + +bool Document::IsVisibleConsideringAncestors() const { + const Document* parent = this; + do { + if (!parent->IsVisible()) { + return false; + } + } while ((parent = parent->GetParentDocument())); + + return true; +} + +void Document::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) { + nsCOMPtr<nsIURI> uri; + nsCOMPtr<nsIPrincipal> principal; + if (aChannel) { + // Note: this code is duplicated in XULDocument::StartDocumentLoad and + // nsScriptSecurityManager::GetChannelResultPrincipal. + // Note: this should match nsDocShell::OnLoadingSite + NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); + + bool isWyciwyg = false; + uri->SchemeIs("wyciwyg", &isWyciwyg); + if (isWyciwyg) { + nsCOMPtr<nsIURI> cleanURI; + nsresult rv = + nsContentUtils::RemoveWyciwygScheme(uri, getter_AddRefs(cleanURI)); + if (NS_SUCCEEDED(rv)) { + uri = cleanURI; + } + } + + nsIScriptSecurityManager* securityManager = + nsContentUtils::GetSecurityManager(); + if (securityManager) { + securityManager->GetChannelResultPrincipal(aChannel, + getter_AddRefs(principal)); + } + } + + principal = MaybeDowngradePrincipal(principal); + + ResetToURI(uri, aLoadGroup, principal); + + // Note that, since mTiming does not change during a reset, the + // navigationStart time remains unchanged and therefore any future new + // timeline will have the same global clock time as the old one. + mDocumentTimeline = nullptr; + + nsCOMPtr<nsIPropertyBag2> bag = do_QueryInterface(aChannel); + if (bag) { + nsCOMPtr<nsIURI> baseURI; + bag->GetPropertyAsInterface(NS_LITERAL_STRING("baseURI"), + NS_GET_IID(nsIURI), getter_AddRefs(baseURI)); + if (baseURI) { + mDocumentBaseURI = baseURI; + mChromeXHRDocBaseURI = nullptr; + } + } + + mChannel = aChannel; +} + +/** + * Determine whether the principal is allowed access to the localization system. + * We don't want the web to ever see this but all our UI including in content + * pages should pass this test. + */ +bool PrincipalAllowsL10n(nsIPrincipal* principal) { + // The system principal is always allowed. + if (nsContentUtils::IsSystemPrincipal(principal)) { + return true; + } + + nsCOMPtr<nsIURI> uri; + nsresult rv = principal->GetURI(getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, false); + + bool hasFlags; + + // Allow access to uris that cannot be loaded by web content. + rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DANGEROUS_TO_LOAD, + &hasFlags); + NS_ENSURE_SUCCESS(rv, false); + if (hasFlags) { + return true; + } + + // UI resources also get access. + rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE, + &hasFlags); + NS_ENSURE_SUCCESS(rv, false); + return hasFlags; +} + +void Document::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, + nsIPrincipal* aPrincipal) { + MOZ_ASSERT(aURI, "Null URI passed to ResetToURI"); + + MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, + ("DOCUMENT %p ResetToURI %s", this, aURI->GetSpecOrDefault().get())); + + mSecurityInfo = nullptr; + + nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup); + if (!aLoadGroup || group != aLoadGroup) { + mDocumentLoadGroup = nullptr; + } + + // Delete references to sub-documents and kill the subdocument map, + // if any. It holds strong references + delete mSubDocuments; + mSubDocuments = nullptr; + + // Destroy link map now so we don't waste time removing + // links one by one + DestroyElementMaps(); + + bool oldVal = mInUnlinkOrDeletion; + mInUnlinkOrDeletion = true; + { // Scope for update + MOZ_AUTO_DOC_UPDATE(this, true); + + // Invalidate cached array of child nodes + InvalidateChildNodes(); + + while (HasChildren()) { + nsCOMPtr<nsIContent> content = GetLastChild(); + nsIContent* previousSibling = content->GetPreviousSibling(); + DisconnectChild(content); + if (content == mCachedRootElement) { + // Immediately clear mCachedRootElement, now that it's been removed + // from mChildren, so that GetRootElement() will stop returning this + // now-stale value. + mCachedRootElement = nullptr; + } + nsNodeUtils::ContentRemoved(this, content, previousSibling); + content->UnbindFromTree(); + } + MOZ_ASSERT(!mCachedRootElement, + "After removing all children, there should be no root elem"); + } + mInUnlinkOrDeletion = oldVal; + + // Reset our stylesheets + ResetStylesheetsToURI(aURI); + + // Release the listener manager + if (mListenerManager) { + mListenerManager->Disconnect(); + mListenerManager = nullptr; + } + + // Release the stylesheets list. + mDOMStyleSheets = nullptr; + + // Release our principal after tearing down the document, rather than before. + // This ensures that, during teardown, the document and the dying window + // (which already nulled out its document pointer and cached the principal) + // have matching principals. + SetPrincipal(nullptr); + + // Clear the original URI so SetDocumentURI sets it. + mOriginalURI = nullptr; + + SetDocumentURI(aURI); + mChromeXHRDocURI = nullptr; + // If mDocumentBaseURI is null, Document::GetBaseURI() returns + // mDocumentURI. + mDocumentBaseURI = nullptr; + mChromeXHRDocBaseURI = nullptr; + + if (aLoadGroup) { + mDocumentLoadGroup = do_GetWeakReference(aLoadGroup); + // there was an assertion here that aLoadGroup was not null. This + // is no longer valid: nsDocShell::SetDocument does not create a + // load group, and it works just fine + + // XXXbz what does "just fine" mean exactly? And given that there + // is no nsDocShell::SetDocument, what is this talking about? + + if (IsContentDocument()) { + // Inform the associated request context about this load start so + // any of its internal load progress flags gets reset. + nsCOMPtr<nsIRequestContextService> rcsvc = + mozilla::net::RequestContextService::GetOrCreate(); + if (rcsvc) { + nsCOMPtr<nsIRequestContext> rc; + rcsvc->GetRequestContextFromLoadGroup(aLoadGroup, getter_AddRefs(rc)); + if (rc) { + rc->BeginLoad(); + } + } + } + } + + mLastModified.Truncate(); + // XXXbz I guess we're assuming that the caller will either pass in + // a channel with a useful type or call SetContentType? + SetContentTypeInternal(EmptyCString()); + mContentLanguage.Truncate(); + mBaseTarget.Truncate(); + mReferrer.Truncate(); + + mXMLDeclarationBits = 0; + + // Now get our new principal + if (aPrincipal) { + SetPrincipal(aPrincipal); + } else { + nsIScriptSecurityManager* securityManager = + nsContentUtils::GetSecurityManager(); + if (securityManager) { + nsCOMPtr<nsILoadContext> loadContext(mDocumentContainer); + + if (!loadContext && aLoadGroup) { + nsCOMPtr<nsIInterfaceRequestor> cbs; + aLoadGroup->GetNotificationCallbacks(getter_AddRefs(cbs)); + loadContext = do_GetInterface(cbs); + } + + MOZ_ASSERT(loadContext, + "must have a load context or pass in an explicit principal"); + + nsCOMPtr<nsIPrincipal> principal; + nsresult rv = securityManager->GetLoadContextCodebasePrincipal( + mDocumentURI, loadContext, getter_AddRefs(principal)); + if (NS_SUCCEEDED(rv)) { + SetPrincipal(principal); + } + } + } + + if (mFontFaceSet) { + mFontFaceSet->RefreshStandardFontLoadPrincipal(); + } + + // Refresh the principal on the realm. + if (nsPIDOMWindowInner* win = GetInnerWindow()) { + nsGlobalWindowInner::Cast(win)->RefreshRealmPrincipal(); + } +} + +already_AddRefed<nsIPrincipal> Document::MaybeDowngradePrincipal( + nsIPrincipal* aPrincipal) { + if (!aPrincipal) { + return nullptr; + } + + // We can't load a document with an expanded principal. If we're given one, + // automatically downgrade it to the last principal it subsumes (which is the + // extension principal, in the case of extension content scripts). + auto* basePrin = BasePrincipal::Cast(aPrincipal); + if (basePrin->Is<ExpandedPrincipal>()) { + MOZ_DIAGNOSTIC_ASSERT(false, + "Should never try to create a document with " + "an expanded principal"); + + auto* expanded = basePrin->As<ExpandedPrincipal>(); + return do_AddRef(expanded->AllowList().LastElement()); + } + + if (nsContentUtils::IsSystemPrincipal(aPrincipal)) { + // We basically want the parent document here, but because this is very + // early in the load, GetParentDocument() returns null, so we use the + // docshell hierarchy to get this information instead. + if (mDocumentContainer) { + nsCOMPtr<nsIDocShellTreeItem> parentDocShellItem; + mDocumentContainer->GetParent(getter_AddRefs(parentDocShellItem)); + nsCOMPtr<nsIDocShell> parentDocShell = + do_QueryInterface(parentDocShellItem); + if (parentDocShell) { + nsCOMPtr<Document> parentDoc; + parentDoc = parentDocShell->GetDocument(); + if (!parentDoc || + !nsContentUtils::IsSystemPrincipal(parentDoc->NodePrincipal())) { + nsCOMPtr<nsIPrincipal> nullPrincipal = + do_CreateInstance("@mozilla.org/nullprincipal;1"); + return nullPrincipal.forget(); + } + } + } + } + nsCOMPtr<nsIPrincipal> principal(aPrincipal); + return principal.forget(); +} + +void Document::RemoveDocStyleSheetsFromStyleSets() { + // The stylesheets should forget us + for (StyleSheet* sheet : Reversed(mStyleSheets)) { + sheet->ClearAssociatedDocumentOrShadowRoot(); + + if (sheet->IsApplicable()) { + nsCOMPtr<nsIPresShell> shell = GetShell(); + if (shell) { + shell->StyleSet()->RemoveDocStyleSheet(sheet); + } + } + // XXX Tell observers? + } +} + +void Document::RemoveStyleSheetsFromStyleSets( + const nsTArray<RefPtr<StyleSheet>>& aSheets, SheetType aType) { + // The stylesheets should forget us + for (StyleSheet* sheet : Reversed(aSheets)) { + sheet->ClearAssociatedDocumentOrShadowRoot(); + + if (sheet->IsApplicable()) { + nsCOMPtr<nsIPresShell> shell = GetShell(); + if (shell) { + shell->StyleSet()->RemoveStyleSheet(aType, sheet); + } + } + // XXX Tell observers? + } +} + +void Document::ResetStylesheetsToURI(nsIURI* aURI) { + MOZ_ASSERT(aURI); + + if (mStyleSetFilled) { + // Skip removing style sheets from the style set if we know we haven't + // filled the style set. (This allows us to avoid calling + // GetStyleBackendType() too early.) + RemoveDocStyleSheetsFromStyleSets(); + RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eAgentSheet], + SheetType::Agent); + RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eUserSheet], + SheetType::User); + RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eAuthorSheet], + SheetType::Doc); + + if (nsStyleSheetService* sheetService = + nsStyleSheetService::GetInstance()) { + RemoveStyleSheetsFromStyleSets(*sheetService->AuthorStyleSheets(), + SheetType::Doc); + } + + mStyleSetFilled = false; + } + + // Release all the sheets + mStyleSheets.Clear(); + for (auto& sheets : mAdditionalSheets) { + sheets.Clear(); + } + + // NOTE: We don't release the catalog sheets. It doesn't really matter + // now, but it could in the future -- in which case not releasing them + // is probably the right thing to do. + + // Now reset our inline style and attribute sheets. + if (mAttrStyleSheet) { + mAttrStyleSheet->Reset(); + mAttrStyleSheet->SetOwningDocument(this); + } else { + mAttrStyleSheet = new nsHTMLStyleSheet(this); + } + + if (!mStyleAttrStyleSheet) { + mStyleAttrStyleSheet = new nsHTMLCSSStyleSheet(); + } + + // Now set up our style sets + if (nsIPresShell* shell = GetShell()) { + FillStyleSet(shell->StyleSet()); + if (shell->StyleSet()->StyleSheetsHaveChanged()) { + shell->ApplicableStylesChanged(); + } + } +} + +static void AppendSheetsToStyleSet(ServoStyleSet* aStyleSet, + const nsTArray<RefPtr<StyleSheet>>& aSheets, + SheetType aType) { + for (StyleSheet* sheet : Reversed(aSheets)) { + aStyleSet->AppendStyleSheet(aType, sheet); + } +} + +void Document::FillStyleSet(ServoStyleSet* aStyleSet) { + MOZ_ASSERT(aStyleSet, "Must have a style set"); + MOZ_ASSERT(aStyleSet->SheetCount(SheetType::Doc) == 0, + "Style set already has document sheets?"); + + MOZ_ASSERT(!mStyleSetFilled); + + for (StyleSheet* sheet : Reversed(mStyleSheets)) { + if (sheet->IsApplicable()) { + aStyleSet->AddDocStyleSheet(sheet, this); + } + } + + if (nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance()) { + nsTArray<RefPtr<StyleSheet>>& sheets = *sheetService->AuthorStyleSheets(); + for (StyleSheet* sheet : sheets) { + aStyleSet->AppendStyleSheet(SheetType::Doc, sheet); + } + } + + AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eAgentSheet], + SheetType::Agent); + AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eUserSheet], + SheetType::User); + AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eAuthorSheet], + SheetType::Doc); + + mStyleSetFilled = true; +} + +static void WarnIfSandboxIneffective(nsIDocShell* aDocShell, + uint32_t aSandboxFlags, + nsIChannel* aChannel) { + // If the document is sandboxed (via the HTML5 iframe sandbox + // attribute) and both the allow-scripts and allow-same-origin + // keywords are supplied, the sandboxed document can call into its + // parent document and remove its sandboxing entirely - we print a + // warning to the web console in this case. + if (aSandboxFlags & SANDBOXED_NAVIGATION && + !(aSandboxFlags & SANDBOXED_SCRIPTS) && + !(aSandboxFlags & SANDBOXED_ORIGIN)) { + nsCOMPtr<nsIDocShellTreeItem> parentAsItem; + aDocShell->GetSameTypeParent(getter_AddRefs(parentAsItem)); + nsCOMPtr<nsIDocShell> parentDocShell = do_QueryInterface(parentAsItem); + if (!parentDocShell) { + return; + } + + // Don't warn if our parent is not the top-level document. + nsCOMPtr<nsIDocShellTreeItem> grandParentAsItem; + parentDocShell->GetSameTypeParent(getter_AddRefs(grandParentAsItem)); + if (grandParentAsItem) { + return; + } + + nsCOMPtr<nsIChannel> parentChannel; + parentDocShell->GetCurrentDocumentChannel(getter_AddRefs(parentChannel)); + if (!parentChannel) { + return; + } + nsresult rv = nsContentUtils::CheckSameOrigin(aChannel, parentChannel); + if (NS_FAILED(rv)) { + return; + } + + nsCOMPtr<Document> parentDocument = parentDocShell->GetDocument(); + nsCOMPtr<nsIURI> iframeUri; + parentChannel->GetURI(getter_AddRefs(iframeUri)); + nsContentUtils::ReportToConsole( + nsIScriptError::warningFlag, NS_LITERAL_CSTRING("Iframe Sandbox"), + parentDocument, nsContentUtils::eSECURITY_PROPERTIES, + "BothAllowScriptsAndSameOriginPresent", nullptr, 0, iframeUri); + } +} + +bool Document::IsSynthesized() { + nsCOMPtr<nsILoadInfo> loadInfo = mChannel ? mChannel->GetLoadInfo() : nullptr; + return loadInfo && loadInfo->GetServiceWorkerTaintingSynthesized(); +} + +// static +bool Document::IsCallerChromeOrAddon(JSContext* aCx, JSObject* aObject) { + nsIPrincipal* principal = nsContentUtils::SubjectPrincipal(aCx); + return principal && (nsContentUtils::IsSystemPrincipal(principal) || + principal->GetIsAddonOrExpandedAddonPrincipal()); +} + +nsresult Document::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel, + nsILoadGroup* aLoadGroup, + nsISupports* aContainer, + nsIStreamListener** aDocListener, + bool aReset, nsIContentSink* aSink) { + if (MOZ_LOG_TEST(gDocumentLeakPRLog, LogLevel::Debug)) { + nsCOMPtr<nsIURI> uri; + aChannel->GetURI(getter_AddRefs(uri)); + MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, + ("DOCUMENT %p StartDocumentLoad %s", this, + uri ? uri->GetSpecOrDefault().get() : "")); + } + + MOZ_ASSERT( + NodePrincipal()->GetAppId() != nsIScriptSecurityManager::UNKNOWN_APP_ID, + "Document should never have UNKNOWN_APP_ID"); + + MOZ_ASSERT(GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED, + "Bad readyState"); + SetReadyStateInternal(READYSTATE_LOADING); + + if (nsCRT::strcmp(kLoadAsData, aCommand) == 0) { + mLoadedAsData = true; + // We need to disable script & style loading in this case. + // We leave them disabled even in EndLoad(), and let anyone + // who puts the document on display to worry about enabling. + + // Do not load/process scripts when loading as data + ScriptLoader()->SetEnabled(false); + + // styles + CSSLoader()->SetEnabled( + false); // Do not load/process styles when loading as data + } else if (nsCRT::strcmp("external-resource", aCommand) == 0) { + // Allow CSS, but not scripts + ScriptLoader()->SetEnabled(false); + } + + mMayStartLayout = false; + MOZ_ASSERT(!mReadyForIdle, + "We should never hit DOMContentLoaded before this point"); + + if (aReset) { + Reset(aChannel, aLoadGroup); + } + + nsAutoCString contentType; + nsCOMPtr<nsIPropertyBag2> bag = do_QueryInterface(aChannel); + if ((bag && NS_SUCCEEDED(bag->GetPropertyAsACString( + NS_LITERAL_STRING("contentType"), contentType))) || + NS_SUCCEEDED(aChannel->GetContentType(contentType))) { + // XXX this is only necessary for viewsource: + nsACString::const_iterator start, end, semicolon; + contentType.BeginReading(start); + contentType.EndReading(end); + semicolon = start; + FindCharInReadable(';', semicolon, end); + SetContentTypeInternal(Substring(start, semicolon)); + } + + RetrieveRelevantHeaders(aChannel); + + mChannel = aChannel; + nsCOMPtr<nsIInputStreamChannel> inStrmChan = do_QueryInterface(mChannel); + if (inStrmChan) { + bool isSrcdocChannel; + inStrmChan->GetIsSrcdocChannel(&isSrcdocChannel); + if (isSrcdocChannel) { + mIsSrcdocDocument = true; + } + } + + if (mChannel) { + nsLoadFlags loadFlags; + mChannel->GetLoadFlags(&loadFlags); + bool isDocument = false; + mChannel->GetIsDocument(&isDocument); + if (loadFlags & nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE && isDocument && + IsSynthesized() && XRE_IsContentProcess()) { + ContentChild::UpdateCookieStatus(mChannel); + } + } + + // If this document is being loaded by a docshell, copy its sandbox flags + // to the document, and store the fullscreen enabled flag. These are + // immutable after being set here. + nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aContainer); + + // If this is an error page, don't inherit sandbox flags from docshell + nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo(); + if (docShell && !(loadInfo && loadInfo->GetLoadErrorPage())) { + nsresult rv = docShell->GetSandboxFlags(&mSandboxFlags); + NS_ENSURE_SUCCESS(rv, rv); + WarnIfSandboxIneffective(docShell, mSandboxFlags, GetChannel()); + } + + // The CSP directive upgrade-insecure-requests not only applies to the + // toplevel document, but also to nested documents. Let's propagate that + // flag from the parent to the nested document. + nsCOMPtr<nsIDocShellTreeItem> treeItem = this->GetDocShell(); + if (treeItem) { + nsCOMPtr<nsIDocShellTreeItem> sameTypeParent; + treeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent)); + if (sameTypeParent) { + Document* doc = sameTypeParent->GetDocument(); + mBlockAllMixedContent = doc->GetBlockAllMixedContent(false); + // if the parent document makes use of block-all-mixed-content + // then subdocument preloads should always be blocked. + mBlockAllMixedContentPreloads = + mBlockAllMixedContent || doc->GetBlockAllMixedContent(true); + + mUpgradeInsecureRequests = doc->GetUpgradeInsecureRequests(false); + // if the parent document makes use of upgrade-insecure-requests + // then subdocument preloads should always be upgraded. + mUpgradeInsecurePreloads = + mUpgradeInsecureRequests || doc->GetUpgradeInsecureRequests(true); + } + } + + // If this is not a data document, set CSP. + if (!mLoadedAsData) { + nsresult rv = InitCSP(aChannel); + NS_ENSURE_SUCCESS(rv, rv); + } + + // Initialize FeaturePolicy + nsresult rv = InitFeaturePolicy(aChannel); + NS_ENSURE_SUCCESS(rv, rv); + + // XFO needs to be checked after CSP because it is ignored if + // the CSP defines frame-ancestors. + if (!FramingChecker::CheckFrameOptions(aChannel, docShell, NodePrincipal())) { + MOZ_LOG(gCspPRLog, LogLevel::Debug, + ("XFO doesn't like frame's ancestry, not loading.")); + // stop! ERROR page! + aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION); + } + + // Perform a async flash classification based on the doc principal + // in an early stage to reduce the blocking time. + mFlashClassification = FlashClassification::Unclassified; + mPrincipalFlashClassifier->AsyncClassify(GetPrincipal()); + + return NS_OK; +} + +void Document::SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages) { + for (uint32_t i = 0; i < aMessages.Length(); ++i) { + nsAutoString messageTag; + aMessages[i]->GetTag(messageTag); + + nsAutoString category; + aMessages[i]->GetCategory(category); + + nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, + NS_ConvertUTF16toUTF8(category), this, + nsContentUtils::eSECURITY_PROPERTIES, + NS_ConvertUTF16toUTF8(messageTag).get()); + } +} + +void Document::ApplySettingsFromCSP(bool aSpeculative) { + nsresult rv = NS_OK; + if (!aSpeculative) { + // 1) apply settings from regular CSP + nsCOMPtr<nsIContentSecurityPolicy> csp; + rv = NodePrincipal()->GetCsp(getter_AddRefs(csp)); + NS_ENSURE_SUCCESS_VOID(rv); + if (csp) { + // Set up 'block-all-mixed-content' if not already inherited + // from the parent context or set by any other CSP. + if (!mBlockAllMixedContent) { + rv = csp->GetBlockAllMixedContent(&mBlockAllMixedContent); + NS_ENSURE_SUCCESS_VOID(rv); + } + if (!mBlockAllMixedContentPreloads) { + mBlockAllMixedContentPreloads = mBlockAllMixedContent; + } + + // Set up 'upgrade-insecure-requests' if not already inherited + // from the parent context or set by any other CSP. + if (!mUpgradeInsecureRequests) { + rv = csp->GetUpgradeInsecureRequests(&mUpgradeInsecureRequests); + NS_ENSURE_SUCCESS_VOID(rv); + } + if (!mUpgradeInsecurePreloads) { + mUpgradeInsecurePreloads = mUpgradeInsecureRequests; + } + } + return; + } + + // 2) apply settings from speculative csp + nsCOMPtr<nsIContentSecurityPolicy> preloadCsp; + rv = NodePrincipal()->GetPreloadCsp(getter_AddRefs(preloadCsp)); + NS_ENSURE_SUCCESS_VOID(rv); + if (preloadCsp) { + if (!mBlockAllMixedContentPreloads) { + rv = preloadCsp->GetBlockAllMixedContent(&mBlockAllMixedContentPreloads); + NS_ENSURE_SUCCESS_VOID(rv); + } + if (!mUpgradeInsecurePreloads) { + rv = preloadCsp->GetUpgradeInsecureRequests(&mUpgradeInsecurePreloads); + NS_ENSURE_SUCCESS_VOID(rv); + } + } +} + +nsresult Document::InitCSP(nsIChannel* aChannel) { + MOZ_ASSERT(!mScriptGlobalObject, + "CSP must be initialized before mScriptGlobalObject is set!"); + if (!StaticPrefs::security_csp_enable()) { + MOZ_LOG(gCspPRLog, LogLevel::Debug, + ("CSP is disabled, skipping CSP init for document %p", this)); + return NS_OK; + } + + nsAutoCString tCspHeaderValue, tCspROHeaderValue; + + nsCOMPtr<nsIHttpChannel> httpChannel; + nsresult rv = GetHttpChannelHelper(aChannel, getter_AddRefs(httpChannel)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + if (httpChannel) { + Unused << httpChannel->GetResponseHeader( + NS_LITERAL_CSTRING("content-security-policy"), tCspHeaderValue); + + Unused << httpChannel->GetResponseHeader( + NS_LITERAL_CSTRING("content-security-policy-report-only"), + tCspROHeaderValue); + } + NS_ConvertASCIItoUTF16 cspHeaderValue(tCspHeaderValue); + NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue); + + // Check if this is a document from a WebExtension. + nsCOMPtr<nsIPrincipal> principal = NodePrincipal(); + auto addonPolicy = BasePrincipal::Cast(principal)->AddonPolicy(); + + // Check if this is a signed content to apply default CSP. + bool applySignedContentCSP = false; + nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo(); + if (loadInfo && loadInfo->GetVerifySignedContent()) { + applySignedContentCSP = true; + } + + // If there's no CSP to apply, go ahead and return early + if (!addonPolicy && !applySignedContentCSP && cspHeaderValue.IsEmpty() && + cspROHeaderValue.IsEmpty()) { + if (MOZ_LOG_TEST(gCspPRLog, LogLevel::Debug)) { + nsCOMPtr<nsIURI> chanURI; + aChannel->GetURI(getter_AddRefs(chanURI)); + nsAutoCString aspec; + chanURI->GetAsciiSpec(aspec); + MOZ_LOG(gCspPRLog, LogLevel::Debug, + ("no CSP for document, %s", aspec.get())); + } + + return NS_OK; + } + + MOZ_LOG(gCspPRLog, LogLevel::Debug, + ("Document is an add-on or CSP header specified %p", this)); + + nsCOMPtr<nsIContentSecurityPolicy> csp; + rv = principal->EnsureCSP(this, getter_AddRefs(csp)); + NS_ENSURE_SUCCESS(rv, rv); + + // ----- if the doc is an addon, apply its CSP. + if (addonPolicy) { + nsCOMPtr<nsIAddonPolicyService> aps = + do_GetService("@mozilla.org/addons/policy-service;1"); + + nsAutoString addonCSP; + Unused << ExtensionPolicyService::GetSingleton().GetBaseCSP(addonCSP); + csp->AppendPolicy(addonCSP, false, false); + + csp->AppendPolicy(addonPolicy->ContentSecurityPolicy(), false, false); + } + + // ----- if the doc is a signed content, apply the default CSP. + // Note that when the content signing becomes a standard, we might have + // to restrict this enforcement to "remote content" only. + if (applySignedContentCSP) { + nsAutoString signedContentCSP; + Preferences::GetString("security.signed_content.CSP.default", + signedContentCSP); + csp->AppendPolicy(signedContentCSP, false, false); + } + + // ----- if there's a full-strength CSP header, apply it. + if (!cspHeaderValue.IsEmpty()) { + rv = CSP_AppendCSPFromHeader(csp, cspHeaderValue, false); + NS_ENSURE_SUCCESS(rv, rv); + } + + // ----- if there's a report-only CSP header, apply it. + if (!cspROHeaderValue.IsEmpty()) { + rv = CSP_AppendCSPFromHeader(csp, cspROHeaderValue, true); + NS_ENSURE_SUCCESS(rv, rv); + } + + // ----- Enforce sandbox policy if supplied in CSP header + // The document may already have some sandbox flags set (e.g. if the document + // is an iframe with the sandbox attribute set). If we have a CSP sandbox + // directive, intersect the CSP sandbox flags with the existing flags. This + // corresponds to the _least_ permissive policy. + uint32_t cspSandboxFlags = SANDBOXED_NONE; + rv = csp->GetCSPSandboxFlags(&cspSandboxFlags); + NS_ENSURE_SUCCESS(rv, rv); + + // Probably the iframe sandbox attribute already caused the creation of a + // new NullPrincipal. Only create a new NullPrincipal if CSP requires so + // and no one has been created yet. + bool needNewNullPrincipal = (cspSandboxFlags & SANDBOXED_ORIGIN) && + !(mSandboxFlags & SANDBOXED_ORIGIN); + + mSandboxFlags |= cspSandboxFlags; + + if (needNewNullPrincipal) { + principal = NullPrincipal::CreateWithInheritedAttributes(principal); + principal->SetCsp(csp); + SetPrincipal(principal); + } + + // ----- Enforce frame-ancestor policy on any applied policies + nsCOMPtr<nsIDocShell> docShell(mDocumentContainer); + if (docShell) { + bool safeAncestry = false; + + // PermitsAncestry sends violation reports when necessary + rv = csp->PermitsAncestry(docShell, &safeAncestry); + + if (NS_FAILED(rv) || !safeAncestry) { + MOZ_LOG(gCspPRLog, LogLevel::Debug, + ("CSP doesn't like frame's ancestry, not loading.")); + // stop! ERROR page! + aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION); + } + } + ApplySettingsFromCSP(false); + return NS_OK; +} + +nsresult Document::InitFeaturePolicy(nsIChannel* aChannel) { + MOZ_ASSERT(mFeaturePolicy, "we should only call init once"); + + mFeaturePolicy->ResetDeclaredPolicy(); + + if (!StaticPrefs::dom_security_featurePolicy_enabled()) { + return NS_OK; + } + + mFeaturePolicy->SetDefaultOrigin(NodePrincipal()); + + RefPtr<FeaturePolicy> parentPolicy = nullptr; + if (mDocumentContainer) { + nsPIDOMWindowOuter* containerWindow = mDocumentContainer->GetWindow(); + if (containerWindow) { + nsCOMPtr<nsINode> node = containerWindow->GetFrameElementInternal(); + HTMLIFrameElement* iframe = HTMLIFrameElement::FromNodeOrNull(node); + if (iframe) { + parentPolicy = iframe->Policy(); + } + } + } + + if (parentPolicy) { + // Let's inherit the policy from the parent HTMLIFrameElement if it exists. + mFeaturePolicy->InheritPolicy(parentPolicy); + } + + // We don't want to parse the http Feature-Policy header if this pref is off. + if (!StaticPrefs::dom_security_featurePolicy_header_enabled()) { + return NS_OK; + } + + nsCOMPtr<nsIHttpChannel> httpChannel; + nsresult rv = GetHttpChannelHelper(aChannel, getter_AddRefs(httpChannel)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + if (!httpChannel) { + return NS_OK; + } + + // query the policy from the header + nsAutoCString value; + rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Feature-Policy"), + value); + if (NS_SUCCEEDED(rv)) { + mFeaturePolicy->SetDeclaredPolicy(this, NS_ConvertUTF8toUTF16(value), + NodePrincipal(), nullptr); + } + + return NS_OK; +} + +void Document::StopDocumentLoad() { + if (mParser) { + mParserAborted = true; + mParser->Terminate(); + } +} + +void Document::SetDocumentURI(nsIURI* aURI) { + nsCOMPtr<nsIURI> oldBase = GetDocBaseURI(); + mDocumentURI = aURI; + nsIURI* newBase = GetDocBaseURI(); + + bool equalBases = false; + // Changing just the ref of a URI does not change how relative URIs would + // resolve wrt to it, so we can treat the bases as equal as long as they're + // equal ignoring the ref. + if (oldBase && newBase) { + oldBase->EqualsExceptRef(newBase, &equalBases); + } else { + equalBases = !oldBase && !newBase; + } + + // If this is the first time we're setting the document's URI, set the + // document's original URI. + if (!mOriginalURI) mOriginalURI = mDocumentURI; + + // If changing the document's URI changed the base URI of the document, we + // need to refresh the hrefs of all the links on the page. + if (!equalBases) { + RefreshLinkHrefs(); + } + + // Tell our WindowGlobalParent that the document's URI has been changed. + nsPIDOMWindowInner* inner = GetInnerWindow(); + WindowGlobalChild* wgc = inner ? inner->GetWindowGlobalChild() : nullptr; + if (wgc) { + Unused << wgc->SendUpdateDocumentURI(mDocumentURI); + } +} + +static void GetFormattedTimeString(PRTime aTime, + nsAString& aFormattedTimeString) { + PRExplodedTime prtime; + PR_ExplodeTime(aTime, PR_LocalTimeParameters, &prtime); + // "MM/DD/YYYY hh:mm:ss" + char formatedTime[24]; + if (SprintfLiteral(formatedTime, "%02d/%02d/%04d %02d:%02d:%02d", + prtime.tm_month + 1, prtime.tm_mday, int(prtime.tm_year), + prtime.tm_hour, prtime.tm_min, prtime.tm_sec)) { + CopyASCIItoUTF16(nsDependentCString(formatedTime), aFormattedTimeString); + } else { + // If we for whatever reason failed to find the last modified time + // (or even the current time), fall back to what NS4.x returned. + aFormattedTimeString.AssignLiteral(u"01/01/1970 00:00:00"); + } +} + +void Document::GetLastModified(nsAString& aLastModified) const { + if (!mLastModified.IsEmpty()) { + aLastModified.Assign(mLastModified); + } else { + GetFormattedTimeString(PR_Now(), aLastModified); + } +} + +static void IncrementExpandoGeneration(Document& aDoc) { + ++aDoc.mExpandoAndGeneration.generation; +} + +void Document::AddToNameTable(Element* aElement, nsAtom* aName) { + MOZ_ASSERT( + nsGenericHTMLElement::ShouldExposeNameAsHTMLDocumentProperty(aElement), + "Only put elements that need to be exposed as document['name'] in " + "the named table."); + + nsIdentifierMapEntry* entry = mIdentifierMap.PutEntry(aName); + + // Null for out-of-memory + if (entry) { + if (!entry->HasNameElement() && + !entry->HasIdElementExposedAsHTMLDocumentProperty()) { + IncrementExpandoGeneration(*this); + } + entry->AddNameElement(this, aElement); + } +} + +void Document::RemoveFromNameTable(Element* aElement, nsAtom* aName) { + // Speed up document teardown + if (mIdentifierMap.Count() == 0) return; + + nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aName); + if (!entry) // Could be false if the element was anonymous, hence never added + return; + + entry->RemoveNameElement(aElement); + if (!entry->HasNameElement() && + !entry->HasIdElementExposedAsHTMLDocumentProperty()) { + IncrementExpandoGeneration(*this); + } +} + +void Document::AddToIdTable(Element* aElement, nsAtom* aId) { + nsIdentifierMapEntry* entry = mIdentifierMap.PutEntry(aId); + + if (entry) { /* True except on OOM */ + if (nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(aElement) && + !entry->HasNameElement() && + !entry->HasIdElementExposedAsHTMLDocumentProperty()) { + IncrementExpandoGeneration(*this); + } + entry->AddIdElement(aElement); + } +} + +void Document::RemoveFromIdTable(Element* aElement, nsAtom* aId) { + NS_ASSERTION(aId, "huhwhatnow?"); + + // Speed up document teardown + if (mIdentifierMap.Count() == 0) { + return; + } + + nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aId); + if (!entry) // Can be null for XML elements with changing ids. + return; + + entry->RemoveIdElement(aElement); + if (nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(aElement) && + !entry->HasNameElement() && + !entry->HasIdElementExposedAsHTMLDocumentProperty()) { + IncrementExpandoGeneration(*this); + } + if (entry->IsEmpty()) { + mIdentifierMap.RemoveEntry(entry); + } +} + +void Document::SetPrincipal(nsIPrincipal* aNewPrincipal) { + if (aNewPrincipal && mAllowDNSPrefetch && sDisablePrefetchHTTPSPref) { + nsCOMPtr<nsIURI> uri; + aNewPrincipal->GetURI(getter_AddRefs(uri)); + bool isHTTPS; + if (!uri || NS_FAILED(uri->SchemeIs("https", &isHTTPS)) || isHTTPS) { + mAllowDNSPrefetch = false; + } + } + mNodeInfoManager->SetDocumentPrincipal(aNewPrincipal); + +#ifdef DEBUG + // Validate that the docgroup is set correctly by calling its getter and + // triggering its sanity check. + // + // If we're setting the principal to null, we don't want to perform the check, + // as the document is entering an intermediate state where it does not have a + // principal. It will be given another real principal shortly which we will + // check. It's not unsafe to have a document which has a null principal in the + // same docgroup as another document, so this should not be a problem. + if (aNewPrincipal) { + GetDocGroup(); + } +#endif +} + +mozilla::dom::DocGroup* Document::GetDocGroup() const { +#ifdef DEBUG + // Sanity check that we have an up-to-date and accurate docgroup + if (mDocGroup) { + nsAutoCString docGroupKey; + + // GetKey() can fail, e.g. after the TLD service has shut down. + nsresult rv = mozilla::dom::DocGroup::GetKey(NodePrincipal(), docGroupKey); + if (NS_SUCCEEDED(rv)) { + MOZ_ASSERT(mDocGroup->MatchesKey(docGroupKey)); + } + // XXX: Check that the TabGroup is correct as well! + } +#endif + + return mDocGroup; +} + +nsresult Document::Dispatch(TaskCategory aCategory, + already_AddRefed<nsIRunnable>&& aRunnable) { + // Note that this method may be called off the main thread. + if (mDocGroup) { + return mDocGroup->Dispatch(aCategory, std::move(aRunnable)); + } + return DispatcherTrait::Dispatch(aCategory, std::move(aRunnable)); +} + +nsISerialEventTarget* Document::EventTargetFor(TaskCategory aCategory) const { + if (mDocGroup) { + return mDocGroup->EventTargetFor(aCategory); + } + return DispatcherTrait::EventTargetFor(aCategory); +} + +AbstractThread* Document::AbstractMainThreadFor( + mozilla::TaskCategory aCategory) { + MOZ_ASSERT(NS_IsMainThread()); + if (mDocGroup) { + return mDocGroup->AbstractMainThreadFor(aCategory); + } + return DispatcherTrait::AbstractMainThreadFor(aCategory); +} + +void Document::NoteScriptTrackingStatus(const nsACString& aURL, + bool aIsTracking) { + if (aIsTracking) { + mTrackingScripts.PutEntry(aURL); + } else { + MOZ_ASSERT(!mTrackingScripts.Contains(aURL)); + } +} + +bool Document::IsScriptTracking(const nsACString& aURL) const { + return mTrackingScripts.Contains(aURL); +} + +NS_IMETHODIMP +Document::GetApplicationCache(nsIApplicationCache** aApplicationCache) { + NS_IF_ADDREF(*aApplicationCache = mApplicationCache); + return NS_OK; +} + +NS_IMETHODIMP +Document::SetApplicationCache(nsIApplicationCache* aApplicationCache) { + mApplicationCache = aApplicationCache; + return NS_OK; +} + +void Document::GetContentType(nsAString& aContentType) { + CopyUTF8toUTF16(GetContentTypeInternal(), aContentType); +} + +void Document::SetContentType(const nsAString& aContentType) { + SetContentTypeInternal(NS_ConvertUTF16toUTF8(aContentType)); +} + +bool Document::GetAllowPlugins() { + // First, we ask our docshell if it allows plugins. + nsCOMPtr<nsIDocShell> docShell(mDocumentContainer); + + if (docShell) { + bool allowPlugins = false; + docShell->GetAllowPlugins(&allowPlugins); + if (!allowPlugins) { + return false; + } + + // If the docshell allows plugins, we check whether + // we are sandboxed and plugins should not be allowed. + if (mSandboxFlags & SANDBOXED_PLUGINS) { + return false; + } + } + + FlashClassification classification = DocumentFlashClassification(); + if (classification == FlashClassification::Denied) { + return false; + } + + return true; +} + +void Document::InitializeLocalization(nsTArray<nsString>& aResourceIds) { + MOZ_ASSERT(!mDocumentL10n, "mDocumentL10n should not be initialized yet"); + + DocumentL10n* l10n = new DocumentL10n(this); + MOZ_ALWAYS_TRUE(l10n->Init(aResourceIds)); + mDocumentL10n = l10n; +} + +DocumentL10n* Document::GetL10n() { return mDocumentL10n; } + +bool Document::DocumentSupportsL10n(JSContext* aCx, JSObject* aObject) { + nsCOMPtr<nsIPrincipal> callerPrincipal = + nsContentUtils::SubjectPrincipal(aCx); + return PrincipalAllowsL10n(callerPrincipal); +} + +void Document::LocalizationLinkAdded(Element* aLinkElement) { + if (!PrincipalAllowsL10n(NodePrincipal())) { + return; + } + + nsAutoString href; + aLinkElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href); + // If the link is added after the DocumentL10n instance + // has been initialized, just pass the resource ID to it. + if (mDocumentL10n) { + AutoTArray<nsString, 1> resourceIds; + resourceIds.AppendElement(href); + mDocumentL10n->AddResourceIds(resourceIds); + } else if (mReadyState >= READYSTATE_INTERACTIVE) { + // Otherwise, if the document has already been parsed + // we need to lazily initialize the localization. + AutoTArray<nsString, 1> resourceIds; + resourceIds.AppendElement(href); + InitializeLocalization(resourceIds); + mDocumentL10n->TriggerInitialDocumentTranslation(); + } else { + // Otherwise, we're still parsing the document. + // In that case, add it to the pending list. This list + // will be resolved once the end of l10n resource + // container is reached. + mL10nResources.AppendElement(href); + } +} +