diff --git a/accessible/base/NotificationController.cpp b/accessible/base/NotificationController.cpp index f2ecee82cfb7..d5a678e32141 100644 --- a/accessible/base/NotificationController.cpp +++ b/accessible/base/NotificationController.cpp @@ -13,7 +13,6 @@ #include "TextUpdater.h" #include "mozilla/dom/BrowserChild.h" -#include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/Element.h" #include "mozilla/PresShell.h" #include "mozilla/Telemetry.h" @@ -767,10 +766,11 @@ void NotificationController::WillRefresh(mozilla::TimeStamp aTime) { continue; } - BrowsingContext* bc = childDoc->DocumentNode()->GetBrowsingContext(); - if (bc && !bc->IsCached() && bc->GetEmbedderElement()) { - Accessible* outerDocAcc = - mDocument->GetAccessible(bc->GetEmbedderElement()); + nsIContent* ownerContent = + mDocument->DocumentNode()->FindContentForSubDocument( + childDoc->DocumentNode()); + if (ownerContent) { + Accessible* outerDocAcc = mDocument->GetAccessible(ownerContent); if (outerDocAcc && outerDocAcc->AppendChild(childDoc)) { if (mDocument->AppendChildDocument(childDoc)) { newChildDocs.AppendElement(std::move(mHangingChildDocuments[idx])); diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 73445fb4fb2b..a3b63c2e46ff 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -6724,6 +6724,22 @@ Document* Document::GetSubDocumentFor(nsIContent* aContent) const { return nullptr; } +Element* Document::FindContentForSubDocument(Document* aDocument) const { + NS_ENSURE_TRUE(aDocument, nullptr); + + if (!mSubDocuments) { + return nullptr; + } + + for (auto iter = mSubDocuments->Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + if (entry->mSubDocument == aDocument) { + return entry->mKey; + } + } + return nullptr; +} + bool Document::IsNodeOfType(uint32_t aFlags) const { return false; } Element* Document::GetRootElement() const { @@ -7508,17 +7524,15 @@ void Document::DispatchContentLoadedEvents() { // target_frame is the [i]frame element that will be used as the // target for the event. It's the [i]frame whose content is done // loading. - nsCOMPtr target_frame; + nsCOMPtr target_frame; - if (BrowsingContext* bc = GetBrowsingContext()) { - if (!bc->IsCached()) { - target_frame = bc->GetEmbedderElement(); - } + if (mParentDocument) { + target_frame = mParentDocument->FindContentForSubDocument(this); } - if (target_frame && target_frame->IsInComposedDoc()) { - nsCOMPtr parent = target_frame->OwnerDoc(); - while (parent) { + if (target_frame) { + nsCOMPtr parent = mParentDocument; + do { RefPtr event; if (parent) { IgnoredErrorResult ignored; @@ -7549,7 +7563,7 @@ void Document::DispatchContentLoadedEvents() { } parent = parent->GetInProcessParentDocument(); - } + } while (parent); } // If the document has a manifest attribute, fire a MozApplicationManifest @@ -14483,10 +14497,7 @@ bool Document::ApplyFullscreen(UniquePtr aRequest) { break; } Document* parent = child->GetInProcessParentDocument(); - BrowsingContext* bc = child->GetBrowsingContext(); - Element* element = - bc && !bc->IsCached() ? bc->GetEmbedderElement() : nullptr; - + Element* element = parent->FindContentForSubDocument(child); if (!element) { // We've reached the root.No more changes need to be made // to the top layer stacks of documents further up the tree. diff --git a/dom/base/Document.h b/dom/base/Document.h index 71328a90197c..6ad82c390e98 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h @@ -1254,6 +1254,11 @@ class Document : public nsINode, */ Document* GetSubDocumentFor(nsIContent* aContent) const; + /** + * Find the content node for which aDocument is a sub document. + */ + Element* FindContentForSubDocument(Document* aDocument) const; + /** * Return the doctype for this document. */ diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 5c24f5bc76ce..f7a2db0d9381 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -2320,8 +2320,9 @@ nsINode* nsContentUtils::GetCrossDocParentNode(nsINode* aChild) { return parent; } - BrowsingContext* bc = aChild->AsDocument()->GetBrowsingContext(); - return bc && !bc->IsCached() ? bc->GetEmbedderElement() : nullptr; + Document* doc = aChild->AsDocument(); + Document* parentDoc = doc->GetInProcessParentDocument(); + return parentDoc ? parentDoc->FindContentForSubDocument(doc) : nullptr; } nsINode* nsContentUtils::GetNearestInProcessCrossDocParentNode( diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index 2f2441c44a7b..c8182255b01d 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -5123,6 +5123,9 @@ void nsGlobalWindowOuter::FocusOuter(CallerType aCallerType) { return; } + // Don't look for a presshell if we're a root chrome window that's got + // about:blank loaded. We don't want to focus our widget in that case. + // XXXbz should we really be checking for IsInitialDocument() instead? RefPtr parent; BrowsingContext* bc = GetBrowsingContext(); if (bc) { @@ -5145,10 +5148,13 @@ void nsGlobalWindowOuter::FocusOuter(CallerType aCallerType) { } return; } - if (!bc->IsCached()) { - if (Element* frame = bc->GetEmbedderElement()) { - nsContentUtils::RequestFrameFocus(*frame, canFocus, aCallerType); - } + nsCOMPtr parentdoc = parent->GetDocument(); + if (!parentdoc) { + return; + } + + if (Element* frame = parentdoc->FindContentForSubDocument(mDoc)) { + nsContentUtils::RequestFrameFocus(*frame, canFocus, aCallerType); } return; } diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index 3c1aa5b73451..b82fc863426e 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -4501,15 +4501,12 @@ void EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, // content associated with our subdocument. EnsureDocument(mPresContext); if (Document* parentDoc = mDocument->GetInProcessParentDocument()) { - if (RefPtr bc = mDocument->GetBrowsingContext()) { - if (!bc->IsCached()) { - if (nsCOMPtr docContent = bc->GetEmbedderElement()) { - if (PresShell* parentPresShell = parentDoc->GetPresShell()) { - RefPtr parentESM = - parentPresShell->GetPresContext()->EventStateManager(); - parentESM->NotifyMouseOver(aMouseEvent, docContent); - } - } + if (nsCOMPtr docContent = + parentDoc->FindContentForSubDocument(mDocument)) { + if (PresShell* parentPresShell = parentDoc->GetPresShell()) { + RefPtr parentESM = + parentPresShell->GetPresContext()->EventStateManager(); + parentESM->NotifyMouseOver(aMouseEvent, docContent); } } } diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 72bac3f7e9bc..5f8826a6a3ad 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -680,8 +680,8 @@ nsresult nsPresContext::Init(nsDeviceContext* aDeviceContext) { // XXX the document can change in AttachPresShell, does this work? dom::BrowsingContext* browsingContext = mDocument->GetBrowsingContext(); if (browsingContext && !browsingContext->IsTop()) { - MOZ_ASSERT(!browsingContext->IsCached()); - Element* containingElement = browsingContext->GetEmbedderElement(); + Element* containingElement = + parent->FindContentForSubDocument(mDocument); if (!containingElement->IsXULElement() || !containingElement->HasAttr(kNameSpaceID_None, nsGkAtoms::forceOwnRefreshDriver)) { diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 7d75d0523cb1..1d2110fc8771 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -821,16 +821,12 @@ bool nsComputedDOMStyle::NeedsToFlushStyle(nsCSSPropertyID aPropID) const { // If parent document is there, also needs to check if there is some change // that needs to flush this document (e.g. size change for iframe). while (doc->StyleOrLayoutObservablyDependsOnParentDocumentLayout()) { - if (BrowsingContext* bc = doc->GetBrowsingContext()) { - if (Element* element = bc->GetEmbedderElement()) { - MOZ_ASSERT(!bc->IsCached()); - if (ElementNeedsRestyle(element, nullptr, mayNeedToFlushLayout)) { - return true; - } - } + Document* parentDocument = doc->GetInProcessParentDocument(); + Element* element = parentDocument->FindContentForSubDocument(doc); + if (ElementNeedsRestyle(element, nullptr, mayNeedToFlushLayout)) { + return true; } - - doc = doc->GetInProcessParentDocument(); + doc = parentDocument; } return false;