Bug 1074738 - GetCurrentDoc fixes in content/base, r=wchen
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Thu, 02 Oct 2014 21:45:44 +0300
changeset 231977 929d78de0f8a7ea4d0e0e2d9e91e363ec2aadd4b
parent 231976 086b51f4ba0b61befd338d38aae0ad5de0504848
child 231978 a9bf2deaec5d9e5db349ad0984bde2ae35799d53
push idunknown
push userunknown
push dateunknown
reviewerswchen
bugs1074738
milestone35.0a1
Bug 1074738 - GetCurrentDoc fixes in content/base, r=wchen
content/base/public/Element.h
content/base/src/Element.cpp
content/base/src/FragmentOrElement.cpp
content/base/src/Link.cpp
content/base/src/nsCCUncollectableMarker.cpp
content/base/src/nsContentList.cpp
content/base/src/nsContentSink.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsDocument.cpp
content/base/src/nsDocumentEncoder.cpp
content/base/src/nsFrameLoader.cpp
content/base/src/nsGenericDOMDataNode.cpp
content/base/src/nsINode.cpp
content/base/src/nsImageLoadingContent.cpp
content/base/src/nsMappedAttributeElement.cpp
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsRange.cpp
content/base/src/nsReferencedElement.cpp
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -1270,16 +1270,31 @@ private:
 
   nsIScrollableFrame* GetScrollFrame(nsIFrame **aStyledFrame = nullptr,
                                      bool aFlushLayout = true);
 
   // Data members
   EventStates mState;
 };
 
+class RemoveFromBindingManagerRunnable : public nsRunnable
+{
+public:
+  RemoveFromBindingManagerRunnable(nsBindingManager* aManager,
+                                   nsIContent* aContent,
+                                   nsIDocument* aDoc);
+
+  NS_IMETHOD Run();
+private:
+  virtual ~RemoveFromBindingManagerRunnable();
+  nsRefPtr<nsBindingManager> mManager;
+  nsRefPtr<nsIContent> mContent;
+  nsCOMPtr<nsIDocument> mDoc;
+};
+
 class DestinationInsertionPointList : public nsINodeList
 {
 public:
   explicit DestinationInsertionPointList(Element* aElement);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(DestinationInsertionPointList)
 
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -425,17 +425,17 @@ Element::WrapObject(JSContext *aCx)
     }
   }
 
   nsIDocument* doc;
   if (HasFlag(NODE_FORCE_XBL_BINDINGS)) {
     doc = OwnerDoc();
   }
   else {
-    doc = GetCurrentDoc();
+    doc = GetComposedDoc();
   }
 
   if (!doc) {
     // There's no baseclass that cares about this call so we just
     // return here.
     return obj;
   }
 
@@ -588,17 +588,17 @@ void
 Element::ScrollIntoView()
 {
   ScrollIntoView(true, ScrollOptions());
 }
 
 void
 Element::ScrollIntoView(bool aTop, const ScrollOptions &aOptions)
 {
-  nsIDocument *document = GetCurrentDoc();
+  nsIDocument *document = GetComposedDoc();
   if (!document) {
     return;
   }
 
   // Get the presentation shell
   nsCOMPtr<nsIPresShell> presShell = document->GetShell();
   if (!presShell) {
     return;
@@ -762,17 +762,17 @@ Element::GetClientRects()
 void
 Element::AddToIdTable(nsIAtom* aId)
 {
   NS_ASSERTION(HasID(), "Node doesn't have an ID?");
   if (IsInShadowTree()) {
     ShadowRoot* containingShadow = GetContainingShadow();
     containingShadow->AddToIdTable(this, aId);
   } else {
-    nsIDocument* doc = GetCurrentDoc();
+    nsIDocument* doc = GetUncomposedDoc();
     if (doc && (!IsInAnonymousSubtree() || doc->IsXUL())) {
       doc->AddToIdTable(this, aId);
     }
   }
 }
 
 void
 Element::RemoveFromIdTable()
@@ -785,17 +785,17 @@ Element::RemoveFromIdTable()
   if (IsInShadowTree()) {
     ShadowRoot* containingShadow = GetContainingShadow();
     // Check for containingShadow because it may have
     // been deleted during unlinking.
     if (containingShadow) {
       containingShadow->RemoveFromIdTable(this, id);
     }
   } else {
-    nsIDocument* doc = GetCurrentDoc();
+    nsIDocument* doc = GetUncomposedDoc();
     if (doc && (!IsInAnonymousSubtree() || doc->IsXUL())) {
       doc->RemoveFromIdTable(this, id);
     }
   }
 }
 
 already_AddRefed<ShadowRoot>
 Element::CreateShadowRoot(ErrorResult& aError)
@@ -1192,19 +1192,19 @@ Element::GetElementsByClassName(const ns
 nsresult
 Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                     nsIContent* aBindingParent,
                     bool aCompileEventHandlers)
 {
   NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
   NS_PRECONDITION((NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc()),
                   "Must have the same owner document");
-  NS_PRECONDITION(!aParent || aDocument == aParent->GetCurrentDoc(),
+  NS_PRECONDITION(!aParent || aDocument == aParent->GetUncomposedDoc(),
                   "aDocument must be current doc of aParent");
-  NS_PRECONDITION(!GetCurrentDoc(), "Already have a document.  Unbind first!");
+  NS_PRECONDITION(!GetUncomposedDoc(), "Already have a document.  Unbind first!");
   // Note that as we recurse into the kids, they'll have a non-null parent.  So
   // only assert if our parent is _changing_ while we have a parent.
   NS_PRECONDITION(!GetParent() || aParent == GetParent(),
                   "Already have a parent.  Unbind first!");
   NS_PRECONDITION(!GetBindingParent() ||
                   aBindingParent == GetBindingParent() ||
                   (!aBindingParent && aParent &&
                    aParent->GetBindingParent() == GetBindingParent()),
@@ -1401,66 +1401,63 @@ Element::BindToTree(nsIDocument* aDocume
                              aCompileEventHandlers);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   // XXXbz script execution during binding can trigger some of these
   // postcondition asserts....  But we do want that, since things will
   // generally be quite broken when that happens.
-  NS_POSTCONDITION(aDocument == GetCurrentDoc(), "Bound to wrong document");
+  NS_POSTCONDITION(aDocument == GetUncomposedDoc(), "Bound to wrong document");
   NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
   NS_POSTCONDITION(aBindingParent == GetBindingParent(),
                    "Bound to wrong binding parent");
 
   return NS_OK;
 }
 
-class RemoveFromBindingManagerRunnable : public nsRunnable {
-public:
-  RemoveFromBindingManagerRunnable(nsBindingManager* aManager,
-                                   Element* aElement,
-                                   nsIDocument* aDoc):
-    mManager(aManager), mElement(aElement), mDoc(aDoc)
-  {}
-
-  NS_IMETHOD Run()
-  {
-    // It may be the case that the element was removed from the
-    // DOM, causing this runnable to be created, then inserted back
-    // into the document before the this runnable had a chance to
-    // tear down the binding. Only tear down the binding if the element
-    // is still no longer in the DOM. nsXBLService::LoadBinding tears
-    // down the old binding if the element is inserted back into the
-    // DOM and loads a different binding.
-    if (!mElement->IsInDoc()) {
-      mManager->RemovedFromDocumentInternal(mElement, mDoc);
-    }
-
-    return NS_OK;
+RemoveFromBindingManagerRunnable::RemoveFromBindingManagerRunnable(nsBindingManager* aManager,
+                                                                   nsIContent* aContent,
+                                                                   nsIDocument* aDoc):
+  mManager(aManager), mContent(aContent), mDoc(aDoc)
+{}
+
+RemoveFromBindingManagerRunnable::~RemoveFromBindingManagerRunnable() {}
+
+NS_IMETHODIMP
+RemoveFromBindingManagerRunnable::Run()
+{
+  // It may be the case that the element was removed from the
+  // DOM, causing this runnable to be created, then inserted back
+  // into the document before the this runnable had a chance to
+  // tear down the binding. Only tear down the binding if the element
+  // is still no longer in the DOM. nsXBLService::LoadBinding tears
+  // down the old binding if the element is inserted back into the
+  // DOM and loads a different binding.
+  if (!mContent->IsInComposedDoc()) {
+    mManager->RemovedFromDocumentInternal(mContent, mDoc);
   }
 
-private:
-  nsRefPtr<nsBindingManager> mManager;
-  nsRefPtr<Element> mElement;
-  nsCOMPtr<nsIDocument> mDoc;
-};
+  return NS_OK;
+}
+
 
 void
 Element::UnbindFromTree(bool aDeep, bool aNullParent)
 {
-  NS_PRECONDITION(aDeep || (!GetCurrentDoc() && !GetBindingParent()),
+  NS_PRECONDITION(aDeep || (!GetUncomposedDoc() && !GetBindingParent()),
                   "Shallow unbind won't clear document and binding parent on "
                   "kids!");
 
   RemoveFromIdTable();
 
   // Make sure to unbind this node before doing the kids
-  nsIDocument *document =
-    HasFlag(NODE_FORCE_XBL_BINDINGS) ? OwnerDoc() : GetCurrentDoc();
+  nsIDocument* document =
+    HasFlag(NODE_FORCE_XBL_BINDINGS) || IsInShadowTree() ?
+      OwnerDoc() : GetUncomposedDoc();
 
   if (aNullParent) {
     if (IsFullScreenAncestor()) {
       // The element being removed is an ancestor of the full-screen element,
       // exit full-screen state.
       nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                       NS_LITERAL_CSTRING("DOM"), OwnerDoc(),
                                       nsContentUtils::eDOM_PROPERTIES,
@@ -1597,17 +1594,17 @@ nsresult
 Element::SetSMILOverrideStyleRule(css::StyleRule* aStyleRule,
                                            bool aNotify)
 {
   Element::nsDOMSlots *slots = DOMSlots();
 
   slots->mSMILOverrideStyleRule = aStyleRule;
 
   if (aNotify) {
-    nsIDocument* doc = GetCurrentDoc();
+    nsIDocument* doc = GetComposedDoc();
     // Only need to request a restyle if we're in a document.  (We might not
     // be in a document, if we're clearing animation effects on a target node
     // that's been detached since the previous animation sample.)
     if (doc) {
       nsCOMPtr<nsIPresShell> shell = doc->GetShell();
       if (shell) {
         shell->RestyleForAnimation(this,
           eRestyle_StyleAttribute | eRestyle_ChangeAnimationPhase);
@@ -2015,17 +2012,17 @@ Element::SetAttrAndNotify(int32_t aNames
                           nsAttrValue& aParsedValue,
                           uint8_t aModType,
                           bool aFireMutation,
                           bool aNotify,
                           bool aCallAfterSetAttr)
 {
   nsresult rv;
 
-  nsIDocument* document = GetCurrentDoc();
+  nsIDocument* document = GetComposedDoc();
   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
 
   nsMutationGuard::DidMutate();
 
   // Copy aParsedValue for later use since it will be lost when we call
   // SetAndTakeMappedAttr below
   nsAttrValue aValueForAfterSetAttr;
   if (aCallAfterSetAttr) {
@@ -2228,17 +2225,17 @@ Element::UnsetAttr(int32_t aNameSpaceID,
   int32_t index = mAttrsAndChildren.IndexOfAttr(aName, aNameSpaceID);
   if (index < 0) {
     return NS_OK;
   }
 
   nsresult rv = BeforeSetAttr(aNameSpaceID, aName, nullptr, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsIDocument *document = GetCurrentDoc();
+  nsIDocument *document = GetComposedDoc();
   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
 
   if (aNotify) {
     nsNodeUtils::AttributeWillChange(this, aNameSpaceID, aName,
                                      nsIDOMMutationEvent::REMOVAL);
   }
 
   bool hasMutationListeners = aNotify &&
@@ -2617,17 +2614,17 @@ Element::PostHandleEventForLinks(EventCh
 
   switch (aVisitor.mEvent->message) {
   case NS_MOUSE_BUTTON_DOWN:
     {
       if (aVisitor.mEvent->AsMouseEvent()->button ==
             WidgetMouseEvent::eLeftButton) {
         // don't make the link grab the focus if there is no link handler
         nsILinkHandler *handler = aVisitor.mPresContext->GetLinkHandler();
-        nsIDocument *document = GetCurrentDoc();
+        nsIDocument *document = GetComposedDoc();
         if (handler && document) {
           nsIFocusManager* fm = nsFocusManager::GetFocusManager();
           if (fm) {
             aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
             nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(this);
             fm->SetFocus(elem, nsIFocusManager::FLAG_BYMOUSE |
                                nsIFocusManager::FLAG_NOSCROLL);
           }
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -198,17 +198,17 @@ nsIContent::GetDesiredIMEState()
   // textarea) must override this method, so, we don't need to worry about
   // that here.
   nsIContent *editableAncestor = GetEditingHost();
 
   // This is in another editable content, use the result of it.
   if (editableAncestor && editableAncestor != this) {
     return editableAncestor->GetDesiredIMEState();
   }
-  nsIDocument* doc = GetCurrentDoc();
+  nsIDocument* doc = GetComposedDoc();
   if (!doc) {
     return IMEState(IMEState::DISABLED);
   }
   nsIPresShell* ps = doc->GetShell();
   if (!ps) {
     return IMEState(IMEState::DISABLED);
   }
   nsPresContext* pc = ps->GetPresContext();
@@ -233,20 +233,20 @@ nsIContent::HasIndependentSelection()
 }
 
 dom::Element*
 nsIContent::GetEditingHost()
 {
   // If this isn't editable, return nullptr.
   NS_ENSURE_TRUE(IsEditableInternal(), nullptr);
 
-  nsIDocument* doc = GetCurrentDoc();
+  nsIDocument* doc = GetComposedDoc();
   NS_ENSURE_TRUE(doc, nullptr);
   // If this is in designMode, we should return <body>
-  if (doc->HasFlag(NODE_IS_EDITABLE)) {
+  if (doc->HasFlag(NODE_IS_EDITABLE) && !IsInShadowTree()) {
     return doc->GetBodyElement();
   }
 
   nsIContent* content = this;
   for (dom::Element* parent = GetParentElement();
        parent && parent->HasFlag(NODE_IS_EDITABLE);
        parent = content->GetParentElement()) {
     content = parent;
@@ -1496,17 +1496,19 @@ FragmentOrElement::RemoveBlackMarkedNode
 bool
 FragmentOrElement::CanSkipInCC(nsINode* aNode)
 {
   // Don't try to optimize anything during shutdown.
   if (nsCCUncollectableMarker::sGeneration == 0) {
     return false;
   }
 
-  nsIDocument* currentDoc = aNode->GetCurrentDoc();
+  //XXXsmaug Need to figure out in which cases Shadow DOM can be optimized out
+  //         from the CC graph.
+  nsIDocument* currentDoc = aNode->GetUncomposedDoc();
   if (currentDoc &&
       nsCCUncollectableMarker::InGeneration(currentDoc->GetMarkedCCGeneration())) {
     return !NeedsScriptTraverse(aNode);
   }
 
   // Bail out early if aNode is somewhere in anonymous content,
   // or otherwise unusual.
   if (aNode->UnoptimizableCCNode()) {
@@ -1673,17 +1675,17 @@ bool
 FragmentOrElement::CanSkip(nsINode* aNode, bool aRemovingAllowed)
 {
   // Don't try to optimize anything during shutdown.
   if (nsCCUncollectableMarker::sGeneration == 0) {
     return false;
   }
 
   bool unoptimizable = aNode->UnoptimizableCCNode();
-  nsIDocument* currentDoc = aNode->GetCurrentDoc();
+  nsIDocument* currentDoc = aNode->GetUncomposedDoc();
   if (currentDoc &&
       nsCCUncollectableMarker::InGeneration(currentDoc->GetMarkedCCGeneration()) &&
       (!unoptimizable || NodeHasActiveFrame(currentDoc, aNode) ||
        OwnedByBindingManager(currentDoc, aNode))) {
     MarkNodeChildren(aNode);
     return true;
   }
 
@@ -1802,17 +1804,17 @@ bool
 FragmentOrElement::CanSkipThis(nsINode* aNode)
 {
   if (nsCCUncollectableMarker::sGeneration == 0) {
     return false;
   }
   if (aNode->IsBlack()) {
     return true;
   }
-  nsIDocument* c = aNode->GetCurrentDoc();
+  nsIDocument* c = aNode->GetUncomposedDoc();
   return 
     ((c && nsCCUncollectableMarker::InGeneration(c->GetMarkedCCGeneration())) ||
      aNode->InCCBlackTree()) && !NeedsScriptTraverse(aNode);
 }
 
 void
 FragmentOrElement::InitCCCallbacks()
 {
--- a/content/base/src/Link.cpp
+++ b/content/base/src/Link.cpp
@@ -72,34 +72,34 @@ Link::LinkState() const
   // We are a constant method, but we are just lazily doing things and have to
   // track that state.  Cast away that constness!
   Link *self = const_cast<Link *>(this);
 
   Element *element = self->mElement;
 
   // If we have not yet registered for notifications and need to,
   // due to our href changing, register now!
-  if (!mRegistered && mNeedsRegistration && element->IsInDoc()) {
+  if (!mRegistered && mNeedsRegistration && element->IsInComposedDoc()) {
     // Only try and register once.
     self->mNeedsRegistration = false;
 
     nsCOMPtr<nsIURI> hrefURI(GetURI());
 
     // Assume that we are not visited until we are told otherwise.
     self->mLinkState = eLinkState_Unvisited;
 
     // Make sure the href attribute has a valid link (bug 23209).
     // If we have a good href, register with History if available.
     if (mHistory && hrefURI) {
       nsresult rv = mHistory->RegisterVisitedCallback(hrefURI, self);
       if (NS_SUCCEEDED(rv)) {
         self->mRegistered = true;
 
         // And make sure we are in the document's link map.
-        element->GetCurrentDoc()->AddStyleRelevantLink(self);
+        element->GetComposedDoc()->AddStyleRelevantLink(self);
       }
     }
   }
 
   // Otherwise, return our known state.
   if (mLinkState == eLinkState_Visited) {
     return NS_EVENT_STATE_VISITED;
   }
@@ -464,17 +464,17 @@ Link::ResetLinkState(bool aNotify, bool 
   } else {
     defaultState = eLinkState_NotLink;
   }
 
   // If !mNeedsRegstration, then either we've never registered, or we're
   // currently registered; in either case, we should remove ourself
   // from the doc and the history.
   if (!mNeedsRegistration && mLinkState != eLinkState_NotLink) {
-    nsIDocument *doc = mElement->GetCurrentDoc();
+    nsIDocument *doc = mElement->GetComposedDoc();
     if (doc && (mRegistered || mLinkState == eLinkState_Visited)) {
       // Tell the document to forget about this link if we've registered
       // with it before.
       doc->ForgetLink(this);
     }
 
     UnregisterFromHistory();
   }
--- a/content/base/src/nsCCUncollectableMarker.cpp
+++ b/content/base/src/nsCCUncollectableMarker.cpp
@@ -73,17 +73,17 @@ nsCCUncollectableMarker::Init()
   sInited = true;
 
   return NS_OK;
 }
 
 static void
 MarkUserData(void* aNode, nsIAtom* aKey, void* aValue, void* aData)
 {
-  nsIDocument* d = static_cast<nsINode*>(aNode)->GetCurrentDoc();
+  nsIDocument* d = static_cast<nsINode*>(aNode)->GetUncomposedDoc();
   if (d && nsCCUncollectableMarker::InGeneration(d->GetMarkedCCGeneration())) {
     Element::MarkUserData(aNode, aKey, aValue, aData);
   }
 }
 
 static void
 MarkChildMessageManagers(nsIMessageBroadcaster* aMM)
 {
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -426,20 +426,20 @@ nsContentList::nsContentList(nsINode* aR
   }
   else {
     mMatchAll = false;
   }
   mRootNode->AddMutationObserver(this);
 
   // We only need to flush if we're in an non-HTML document, since the
   // HTML5 parser doesn't need flushing.  Further, if we're not in a
-  // document at all right now (in the GetCurrentDoc() sense), we're
+  // document at all right now (in the GetUncomposedDoc() sense), we're
   // not parser-created and don't need to be flushing stuff under us
   // to get our kids right.
-  nsIDocument* doc = mRootNode->GetCurrentDoc();
+  nsIDocument* doc = mRootNode->GetUncomposedDoc();
   mFlushesNeeded = doc && !doc->IsHTML();
 }
 
 nsContentList::nsContentList(nsINode* aRootNode,
                              nsContentListMatchFunc aFunc,
                              nsContentListDestroyFunc aDestroyFunc,
                              void* aData,
                              bool aDeep,
@@ -459,20 +459,20 @@ nsContentList::nsContentList(nsINode* aR
     mDeep(aDeep),
     mFuncMayDependOnAttr(aFuncMayDependOnAttr)
 {
   NS_ASSERTION(mRootNode, "Must have root");
   mRootNode->AddMutationObserver(this);
 
   // We only need to flush if we're in an non-HTML document, since the
   // HTML5 parser doesn't need flushing.  Further, if we're not in a
-  // document at all right now (in the GetCurrentDoc() sense), we're
+  // document at all right now (in the GetUncomposedDoc() sense), we're
   // not parser-created and don't need to be flushing stuff under us
   // to get our kids right.
-  nsIDocument* doc = mRootNode->GetCurrentDoc();
+  nsIDocument* doc = mRootNode->GetUncomposedDoc();
   mFlushesNeeded = doc && !doc->IsHTML();
 }
 
 nsContentList::~nsContentList()
 {
   RemoveFromHashtable();
   if (mRootNode) {
     mRootNode->RemoveMutationObserver(this);
@@ -502,17 +502,17 @@ nsContentList::Length(bool aDoFlush)
   return mElements.Length();
 }
 
 nsIContent *
 nsContentList::Item(uint32_t aIndex, bool aDoFlush)
 {
   if (mRootNode && aDoFlush && mFlushesNeeded) {
     // XXX sXBL/XBL2 issue
-    nsIDocument* doc = mRootNode->GetCurrentDoc();
+    nsIDocument* doc = mRootNode->GetUncomposedDoc();
     if (doc) {
       // Flush pending content changes Bug 4891.
       doc->FlushPendingNotifications(Flush_ContentAndNotify);
     }
   }
 
   if (mState != LIST_UP_TO_DATE)
     PopulateSelf(std::min(aIndex, UINT32_MAX - 1) + 1);
@@ -999,17 +999,17 @@ nsContentList::RemoveFromHashtable()
   }
 }
 
 void
 nsContentList::BringSelfUpToDate(bool aDoFlush)
 {
   if (mRootNode && aDoFlush && mFlushesNeeded) {
     // XXX sXBL/XBL2 issue
-    nsIDocument* doc = mRootNode->GetCurrentDoc();
+    nsIDocument* doc = mRootNode->GetUncomposedDoc();
     if (doc) {
       // Flush pending content changes Bug 4891.
       doc->FlushPendingNotifications(Flush_ContentAndNotify);
     }
   }
 
   if (mState != LIST_UP_TO_DATE)
     PopulateSelf(uint32_t(-1));
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -1178,17 +1178,17 @@ nsContentSink::StartLayout(bool aIgnoreP
   // frameset document, disable the scroll bars on the views.
 
   mDocument->SetScrollToRef(mDocument->GetDocumentURI());
 }
 
 void
 nsContentSink::NotifyAppend(nsIContent* aContainer, uint32_t aStartIndex)
 {
-  if (aContainer->GetCurrentDoc() != mDocument) {
+  if (aContainer->GetUncomposedDoc() != mDocument) {
     // aContainer is not actually in our document anymore.... Just bail out of
     // here; notifying on our document for this append would be wrong.
     return;
   }
 
   mInNotification++;
   
   {
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -2448,27 +2448,28 @@ nsContentUtils::GenerateStateKey(nsICont
   if (aContent->IsInAnonymousSubtree()) {
     return NS_OK;
   }
 
   if (IsAutocompleteOff(aContent)) {
     return NS_OK;
   }
 
-  nsCOMPtr<nsIHTMLDocument> htmlDocument(do_QueryInterface(aContent->GetCurrentDoc()));
+  nsCOMPtr<nsIHTMLDocument> htmlDocument =
+    do_QueryInterface(aContent->GetUncomposedDoc());
 
   KeyAppendInt(partID, aKey);  // first append a partID
   bool generatedUniqueKey = false;
 
   if (htmlDocument) {
     // Flush our content model so it'll be up to date
     // If this becomes unnecessary and the following line is removed,
     // please also remove the corresponding flush operation from
     // nsHtml5TreeBuilderCppSupplement.h. (Look for "See bug 497861." there.)
-    aContent->GetCurrentDoc()->FlushPendingNotifications(Flush_Content);
+    aContent->GetUncomposedDoc()->FlushPendingNotifications(Flush_Content);
 
     nsContentList *htmlForms = htmlDocument->GetForms();
     nsContentList *htmlFormControls = htmlDocument->GetFormControls();
 
     NS_ENSURE_TRUE(htmlForms && htmlFormControls, NS_ERROR_OUT_OF_MEMORY);
 
     // If we have a form control and can calculate form information, use that
     // as the key - it is more reliable than just recording position in the
@@ -2842,17 +2843,17 @@ nsContentUtils::SplitExpatName(const cha
   }
   *aLocalName = NS_NewAtom(Substring(nameStart, nameEnd)).take();
 }
 
 // static
 nsPresContext*
 nsContentUtils::GetContextForContent(const nsIContent* aContent)
 {
-  nsIDocument* doc = aContent->GetCurrentDoc();
+  nsIDocument* doc = aContent->GetComposedDoc();
   if (doc) {
     nsIPresShell *presShell = doc->GetShell();
     if (presShell) {
       return presShell->GetPresContext();
     }
   }
   return nullptr;
 }
@@ -4399,17 +4400,17 @@ nsContentUtils::SetNodeTextContent(nsICo
         }
         nsContentUtils::MaybeFireNodeRemoved(child, aContent, doc);
       }
     }
   }
 
   // Might as well stick a batch around this since we're performing several
   // mutations.
-  mozAutoDocUpdate updateBatch(aContent->GetCurrentDoc(),
+  mozAutoDocUpdate updateBatch(aContent->GetComposedDoc(),
     UPDATE_CONTENT_MODEL, true);
   nsAutoMutationBatch mb;
 
   uint32_t childCount = aContent->GetChildCount();
 
   if (aTryReuse && !aValue.IsEmpty()) {
     uint32_t removeIndex = 0;
 
@@ -6099,17 +6100,19 @@ nsContentUtils::IsFocusedContent(const n
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
 
   return fm && fm->GetFocusedContent() == aContent;
 }
 
 bool
 nsContentUtils::IsSubDocumentTabbable(nsIContent* aContent)
 {
-  nsIDocument* doc = aContent->GetCurrentDoc();
+  //XXXsmaug Shadow DOM spec issue!
+  //         We may need to change this to GetComposedDoc().
+  nsIDocument* doc = aContent->GetUncomposedDoc();
   if (!doc) {
     return false;
   }
 
   // If the subdocument lives in another process, the frame is
   // tabbable.
   if (EventStateManager::IsRemoteTarget(aContent)) {
     return true;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -6051,17 +6051,18 @@ nsDocument::RegisterElement(JSContext* a
       JS::RootedObject wrapper(aCx);
       if ((wrapper = cache->GetWrapper())) {
         if (!JS_SetPrototype(aCx, wrapper, protoObject)) {
           continue;
         }
       }
 
       EnqueueLifecycleCallback(nsIDocument::eCreated, elem, nullptr, definition);
-      if (elem->GetCurrentDoc()) {
+      //XXXsmaug It is unclear if we should use GetComposedDoc() here.
+      if (elem->GetUncomposedDoc()) {
         // Normally callbacks can not be enqueued until the created
         // callback has been invoked, however, the attached callback
         // in element upgrade is an exception so pretend the created
         // callback has been invoked.
         elem->GetCustomElementData()->mCreatedCallbackInvoked = true;
 
         EnqueueLifecycleCallback(nsIDocument::eAttached, elem, nullptr, definition);
       }
@@ -11522,17 +11523,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSICONTENTPERMISSIONREQUEST
 
   NS_IMETHOD Run()
   {
     nsCOMPtr<Element> e = do_QueryReferent(mElement);
     nsCOMPtr<nsIDocument> d = do_QueryReferent(mDocument);
     if (!e || !d || gPendingPointerLockRequest != this ||
-        e->GetCurrentDoc() != d) {
+        e->GetUncomposedDoc() != d) {
       Handled();
       DispatchPointerLockError(d);
       return NS_OK;
     }
 
     // We're about to enter fullscreen mode.
     nsDocument* doc = static_cast<nsDocument*>(d.get());
     if (doc->mAsyncFullscreenPending ||
@@ -11637,17 +11638,17 @@ NS_IMETHODIMP
 nsPointerLockPermissionRequest::Allow(JS::HandleValue aChoices)
 {
   MOZ_ASSERT(aChoices.isUndefined());
 
   nsCOMPtr<Element> e = do_QueryReferent(mElement);
   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
   nsDocument* d = static_cast<nsDocument*>(doc.get());
   if (!e || !d || gPendingPointerLockRequest != this ||
-      e->GetCurrentDoc() != d ||
+      e->GetUncomposedDoc() != d ||
       (!mUserInputOrChromeCaller && !d->mIsApprovedForFullscreen)) {
     Handled();
     DispatchPointerLockError(d);
     return NS_OK;
   }
 
   // Mark handled here so that we don't need to call it everywhere below.
   Handled();
@@ -11704,17 +11705,17 @@ nsDocument::Observe(nsISupports *aSubjec
       // Run() method gets called again.
       nsCOMPtr<Element> el =
         do_QueryReferent(gPendingPointerLockRequest->mElement);
       nsCOMPtr<nsIDocument> doc =
         do_QueryReferent(gPendingPointerLockRequest->mDocument);
       bool userInputOrChromeCaller =
         gPendingPointerLockRequest->mUserInputOrChromeCaller;
       gPendingPointerLockRequest->Handled();
-      if (doc == this && el && el->GetCurrentDoc() == doc) {
+      if (doc == this && el && el->GetUncomposedDoc() == doc) {
         nsPointerLockPermissionRequest* clone =
           new nsPointerLockPermissionRequest(el, userInputOrChromeCaller);
         gPendingPointerLockRequest = clone;
         nsCOMPtr<nsIRunnable> r = gPendingPointerLockRequest.get();
         NS_DispatchToMainThread(r);
       }
     }
   } else if (strcmp("app-theme-changed", aTopic) == 0) {
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -327,17 +327,17 @@ IsInvisibleBreak(nsINode *aNode) {
   // if a BR node is visible without using the editor.
   Element* elt = aNode->AsElement();
   if (!elt->IsHTML(nsGkAtoms::br) ||
       !aNode->IsEditable()) {
     return false;
   }
 
   // Grab the editor associated with the document
-  nsIDocument *doc = aNode->GetCurrentDoc();
+  nsIDocument *doc = aNode->GetComposedDoc();
   if (doc) {
     nsPIDOMWindow *window = doc->GetWindow();
     if (window) {
       nsIDocShell *docShell = window->GetDocShell();
       if (docShell) {
         nsCOMPtr<nsIEditor> editor;
         docShell->GetEditor(getter_AddRefs(editor));
         nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(editor);
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -187,17 +187,17 @@ nsFrameLoader::~nsFrameLoader()
 }
 
 nsFrameLoader*
 nsFrameLoader::Create(Element* aOwner, bool aNetworkCreated)
 {
   NS_ENSURE_TRUE(aOwner, nullptr);
   nsIDocument* doc = aOwner->OwnerDoc();
   NS_ENSURE_TRUE(!doc->IsResourceDoc() &&
-                 ((!doc->IsLoadedAsData() && aOwner->GetCurrentDoc()) ||
+                 ((!doc->IsLoadedAsData() && aOwner->GetUncomposedDoc()) ||
                    doc->IsStaticDocument()),
                  nullptr);
 
   return new nsFrameLoader(aOwner, aNetworkCreated);
 }
 
 NS_IMETHODIMP
 nsFrameLoader::LoadFrame()
@@ -868,22 +868,22 @@ nsFrameLoader::ShowRemoteFrame(const nsI
     }
   }
 
   // FIXME/bug 589337: Show()/Hide() is pretty expensive for
   // cross-process layers; need to figure out what behavior we really
   // want here.  For now, hack.
   if (!mRemoteBrowserShown) {
     if (!mOwnerContent ||
-        !mOwnerContent->GetCurrentDoc()) {
+        !mOwnerContent->GetUncomposedDoc()) {
       return false;
     }
 
     nsRefPtr<layers::LayerManager> layerManager =
-      nsContentUtils::LayerManagerForDocument(mOwnerContent->GetCurrentDoc());
+      nsContentUtils::LayerManagerForDocument(mOwnerContent->GetUncomposedDoc());
     if (!layerManager) {
       // This is just not going to work.
       return false;
     }
 
     mRemoteBrowser->Show(size);
     mRemoteBrowserShown = true;
 
@@ -1068,18 +1068,18 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
   }
 
   nsCOMPtr<nsIDocument> ourParentDocument =
     ourChildDocument->GetParentDocument();
   nsCOMPtr<nsIDocument> otherParentDocument =
     otherChildDocument->GetParentDocument();
 
   // Make sure to swap docshells between the two frames.
-  nsIDocument* ourDoc = ourContent->GetCurrentDoc();
-  nsIDocument* otherDoc = otherContent->GetCurrentDoc();
+  nsIDocument* ourDoc = ourContent->GetUncomposedDoc();
+  nsIDocument* otherDoc = otherContent->GetUncomposedDoc();
   if (!ourDoc || !otherDoc) {
     // Again, how odd, given that we had docshells
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   NS_ASSERTION(ourDoc == ourParentDocument, "Unexpected parent document");
   NS_ASSERTION(otherDoc == otherParentDocument, "Unexpected parent document");
 
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -292,17 +292,17 @@ nsGenericDOMDataNode::SetTextInternal(ui
 
   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 = GetCurrentDoc();
+  nsIDocument *document = GetComposedDoc();
   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
 
   bool haveMutationListeners = aNotify &&
     nsContentUtils::HasMutationListeners(this,
       NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED,
       this);
 
   nsCOMPtr<nsIAtom> oldValue;
@@ -460,19 +460,19 @@ nsGenericDOMDataNode::ToCString(nsAStrin
 nsresult
 nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                                  nsIContent* aBindingParent,
                                  bool aCompileEventHandlers)
 {
   NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
   NS_PRECONDITION(NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc(),
                   "Must have the same owner document");
-  NS_PRECONDITION(!aParent || aDocument == aParent->GetCurrentDoc(),
+  NS_PRECONDITION(!aParent || aDocument == aParent->GetUncomposedDoc(),
                   "aDocument must be current doc of aParent");
-  NS_PRECONDITION(!GetCurrentDoc() && !IsInDoc(),
+  NS_PRECONDITION(!GetUncomposedDoc() && !IsInDoc(),
                   "Already have a document.  Unbind first!");
   // Note that as we recurse into the kids, they'll have a non-null parent.  So
   // only assert if our parent is _changing_ while we have a parent.
   NS_PRECONDITION(!GetParent() || aParent == GetParent(),
                   "Already have a parent.  Unbind first!");
   NS_PRECONDITION(!GetBindingParent() ||
                   aBindingParent == GetBindingParent() ||
                   (!aBindingParent && aParent &&
@@ -545,38 +545,34 @@ nsGenericDOMDataNode::BindToTree(nsIDocu
     // update our subtree pointer.
     SetSubtreeRootPointer(aParent->SubtreeRoot());
   }
 
   nsNodeUtils::ParentChainChanged(this);
 
   UpdateEditableState(false);
 
-  NS_POSTCONDITION(aDocument == GetCurrentDoc(), "Bound to wrong document");
+  NS_POSTCONDITION(aDocument == GetUncomposedDoc(), "Bound to wrong document");
   NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
   NS_POSTCONDITION(aBindingParent == GetBindingParent(),
                    "Bound to wrong binding parent");
 
   return NS_OK;
 }
 
 void
 nsGenericDOMDataNode::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 = GetCurrentDoc();
-  if (document) {
-    // Notify XBL- & nsIAnonymousContentCreator-generated
-    // anonymous content that the document is changing.
-    // This is needed to update the insertion point.
-    document->BindingManager()->RemovedFromDocument(this, document);
-  }
+
+  nsIDocument* document =
+    HasFlag(NODE_FORCE_XBL_BINDINGS) || IsInShadowTree() ?
+      OwnerDoc() : GetUncomposedDoc();
 
   if (aNullParent) {
     if (GetParent()) {
       NS_RELEASE(mParent);
     } else {
       mParent = nullptr;
     }
     SetParentIsContent(false);
@@ -585,16 +581,26 @@ nsGenericDOMDataNode::UnbindFromTree(boo
 
   if (aNullParent || !mParent->IsInShadowTree()) {
     UnsetFlags(NODE_IS_IN_SHADOW_TREE);
 
     // Begin keeping track of our subtree root.
     SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
   }
 
+  if (document) {
+    // Notify XBL- & nsIAnonymousContentCreator-generated
+    // anonymous content that the document is changing.
+    if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
+      nsContentUtils::AddScriptRunner(
+        new RemoveFromBindingManagerRunnable(document->BindingManager(), this,
+                                             document));
+    }
+  }
+
   nsDataSlots *slots = GetExistingDataSlots();
   if (slots) {
     slots->mBindingParent = nullptr;
     if (aNullParent || !mParent->IsInShadowTree()) {
       slots->mContainingShadow = nullptr;
     }
   }
 
@@ -850,17 +856,17 @@ nsGenericDOMDataNode::SplitData(uint32_t
 
   uint32_t cutStartOffset = aCloneAfterOriginal ? aOffset : 0;
   uint32_t cutLength = aCloneAfterOriginal ? length - aOffset : aOffset;
   rv = SubstringData(cutStartOffset, cutLength, cutText);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  nsIDocument* document = GetCurrentDoc();
+  nsIDocument* document = GetComposedDoc();
   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, true);
 
   // Use Clone for creating the new node so that the new node is of same class
   // as this node!
   nsCOMPtr<nsIContent> newContent = CloneDataNode(mNodeInfo, false);
   if (!newContent) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -194,17 +194,17 @@ nsINode::CreateSlots()
 bool
 nsINode::IsEditableInternal() const
 {
   if (HasFlag(NODE_IS_EDITABLE)) {
     // The node is in an editable contentEditable subtree.
     return true;
   }
 
-  nsIDocument *doc = GetCurrentDoc();
+  nsIDocument *doc = GetUncomposedDoc();
 
   // Check if the node is in a document and the document is in designMode.
   return doc && doc->HasFlag(NODE_IS_EDITABLE);
 }
 
 static nsIContent* GetEditorRootContent(nsIEditor* aEditor)
 {
   nsCOMPtr<nsIDOMElement> rootElement;
@@ -1331,17 +1331,17 @@ nsINode::UnoptimizableCCNode() const
           AsElement()->IsInNamespace(kNameSpaceID_XBL));
 }
 
 /* static */
 bool
 nsINode::Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb)
 {
   if (MOZ_LIKELY(!cb.WantAllTraces())) {
-    nsIDocument *currentDoc = tmp->GetCurrentDoc();
+    nsIDocument *currentDoc = tmp->GetUncomposedDoc();
     if (currentDoc &&
         nsCCUncollectableMarker::InGeneration(currentDoc->GetMarkedCCGeneration())) {
       return false;
     }
 
     if (nsCCUncollectableMarker::sGeneration) {
       // If we're black no need to traverse.
       if (tmp->IsBlack() || tmp->InCCBlackTree()) {
@@ -1493,17 +1493,17 @@ nsINode::doInsertChildAt(nsIContent* aKi
                   "Inserting node that already has parent");
   nsresult rv;
 
   // The id-handling code, and in the future possibly other code, need to
   // react to unexpected attribute changes.
   nsMutationGuard::DidMutate();
 
   // Do this before checking the child-count since this could cause mutations
-  nsIDocument* doc = GetCurrentDoc();
+  nsIDocument* doc = GetUncomposedDoc();
   mozAutoDocUpdate updateBatch(GetCrossShadowCurrentDoc(), UPDATE_CONTENT_MODEL, aNotify);
 
   if (OwnerDoc() != aKid->OwnerDoc()) {
     rv = AdoptNodeIntoOwnerDoc(this, aKid);
     NS_ENSURE_SUCCESS(rv, rv);
   } else if (OwnerDoc()->DidDocumentOpen()) {
     rv = CheckForOutdatedParent(this, aKid);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -1923,17 +1923,17 @@ nsINode::ReplaceOrInsertBefore(bool aRep
     nsCOMPtr<nsINode> kungFuDeathGrip = nodeToInsertBefore;
 
     // Removing a child can run script, via XBL destructors.
     nsMutationGuard guard;
 
     // Scope for the mutation batch and scriptblocker, so they go away
     // while kungFuDeathGrip is still alive.
     {
-      mozAutoDocUpdate batch(newContent->GetCurrentDoc(),
+      mozAutoDocUpdate batch(newContent->GetComposedDoc(),
                              UPDATE_CONTENT_MODEL, true);
       nsAutoMutationBatch mb(oldParent, true, true);
       oldParent->RemoveChildAt(removeIndex, true);
       if (nsAutoMutationBatch::GetCurrentBatch() == &mb) {
         mb.RemovalDone();
         mb.SetPrevSibling(oldParent->GetChildAt(removeIndex - 1));
         mb.SetNextSibling(oldParent->GetChildAt(removeIndex));
       }
@@ -1988,30 +1988,30 @@ nsINode::ReplaceOrInsertBefore(bool aRep
     fragChildren.emplace();
 
     // Copy the children into a separate array to avoid having to deal with
     // mutations to the fragment later on here.
     fragChildren->SetCapacity(count);
     for (nsIContent* child = newContent->GetFirstChild();
          child;
          child = child->GetNextSibling()) {
-      NS_ASSERTION(child->GetCurrentDoc() == nullptr,
+      NS_ASSERTION(child->GetComposedDoc() == nullptr,
                    "How did we get a child with a current doc?");
       fragChildren->AppendElement(child);
     }
 
     // Hold a strong ref to nodeToInsertBefore across the removals
     nsCOMPtr<nsINode> kungFuDeathGrip = nodeToInsertBefore;
 
     nsMutationGuard guard;
 
     // Scope for the mutation batch and scriptblocker, so they go away
     // while kungFuDeathGrip is still alive.
     {
-      mozAutoDocUpdate batch(newContent->GetCurrentDoc(),
+      mozAutoDocUpdate batch(newContent->GetComposedDoc(),
                              UPDATE_CONTENT_MODEL, true);
       nsAutoMutationBatch mb(newContent, false, true);
 
       for (uint32_t i = count; i > 0;) {
         newContent->RemoveChildAt(--i, true);
       }
     }
 
--- a/content/base/src/nsImageLoadingContent.cpp
+++ b/content/base/src/nsImageLoadingContent.cpp
@@ -1058,17 +1058,17 @@ nsImageLoadingContent::GetOurOwnerDoc()
 
 nsIDocument*
 nsImageLoadingContent::GetOurCurrentDoc()
 {
   nsCOMPtr<nsIContent> thisContent =
     do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
   NS_ENSURE_TRUE(thisContent, nullptr);
 
-  return thisContent->GetCurrentDoc();
+  return thisContent->GetComposedDoc();
 }
 
 nsIFrame*
 nsImageLoadingContent::GetOurPrimaryFrame()
 {
   nsCOMPtr<nsIContent> thisContent =
     do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
   return thisContent->GetPrimaryFrame();
--- a/content/base/src/nsMappedAttributeElement.cpp
+++ b/content/base/src/nsMappedAttributeElement.cpp
@@ -15,17 +15,17 @@ nsMappedAttributeElement::WalkContentSty
 }
 
 bool
 nsMappedAttributeElement::SetMappedAttribute(nsIDocument* aDocument,
                                              nsIAtom* aName,
                                              nsAttrValue& aValue,
                                              nsresult* aRetval)
 {
-  NS_PRECONDITION(aDocument == GetCurrentDoc(), "Unexpected document");
+  NS_PRECONDITION(aDocument == GetComposedDoc(), "Unexpected document");
   nsHTMLStyleSheet* sheet = aDocument ?
     aDocument->GetAttributeStyleSheet() : nullptr;
 
   *aRetval = mAttrsAndChildren.SetAndTakeMappedAttr(aName, aValue,
                                                     this, sheet);
   return true;
 }
 
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -204,19 +204,19 @@ CheckPluginStopEvent::Run()
          ", no action", this));
     objLC->mPendingCheckPluginStopEvent = nullptr;
     return NS_OK;
   }
 
   // In an active document, but still no frame. Flush layout to see if we can
   // regain a frame now.
   LOG(("OBJLC [%p]: CheckPluginStopEvent - No frame, flushing layout", this));
-  nsIDocument* currentDoc = content->GetCurrentDoc();
-  if (currentDoc) {
-    currentDoc->FlushPendingNotifications(Flush_Layout);
+  nsIDocument* composedDoc = content->GetComposedDoc();
+  if (composedDoc) {
+    composedDoc->FlushPendingNotifications(Flush_Layout);
     if (objLC->mPendingCheckPluginStopEvent != this) {
       LOG(("OBJLC [%p]: CheckPluginStopEvent - superseded in layout flush",
            this));
       return NS_OK;
     } else if (content->GetPrimaryFrame()) {
       LOG(("OBJLC [%p]: CheckPluginStopEvent - frame gained in layout flush",
            this));
       objLC->mPendingCheckPluginStopEvent = nullptr;
@@ -234,17 +234,17 @@ CheckPluginStopEvent::Run()
 
 /**
  * Helper task for firing simple events
  */
 class nsSimplePluginEvent : public nsRunnable {
 public:
   nsSimplePluginEvent(nsIContent* aTarget, const nsAString &aEvent)
     : mTarget(aTarget)
-    , mDocument(aTarget->GetCurrentDoc())
+    , mDocument(aTarget->GetComposedDoc())
     , mEvent(aEvent)
   {
     MOZ_ASSERT(aTarget && mDocument);
   }
 
   nsSimplePluginEvent(nsIDocument* aTarget, const nsAString& aEvent)
     : mTarget(aTarget)
     , mDocument(aTarget)
@@ -656,17 +656,17 @@ nsObjectLoadingContent::IsSupportedDocum
 
   nsCOMPtr<nsIWebNavigationInfo> info(
     do_GetService(NS_WEBNAVIGATION_INFO_CONTRACTID));
   if (!info) {
     return false;
   }
 
   nsCOMPtr<nsIWebNavigation> webNav;
-  nsIDocument* currentDoc = thisContent->GetCurrentDoc();
+  nsIDocument* currentDoc = thisContent->GetComposedDoc();
   if (currentDoc) {
     webNav = do_GetInterface(currentDoc->GetWindow());
   }
 
   uint32_t supported;
   nsresult rv = info->IsTypeSupported(aMimeType, webNav, &supported);
 
   if (NS_FAILED(rv)) {
@@ -725,17 +725,17 @@ nsObjectLoadingContent::UnbindFromTree(b
     QueueCheckPluginStopEvent();
   } else if (mType != eType_Image) {
     // nsImageLoadingContent handles the image case.
     // Reset state and clear pending events
     /// XXX(johns): The implementation for GenericFrame notes that ideally we
     ///             would keep the docshell around, but trash the frameloader
     UnloadObject();
   }
-  nsIDocument* doc = thisContent->GetCurrentDoc();
+  nsIDocument* doc = thisContent->GetComposedDoc();
   if (doc && doc->IsActive()) {
     nsCOMPtr<nsIRunnable> ev = new nsSimplePluginEvent(doc,
                                                        NS_LITERAL_STRING("PluginRemoved"));
     NS_DispatchToCurrentThread(ev);
   }
 }
 
 nsObjectLoadingContent::nsObjectLoadingContent()
@@ -781,17 +781,17 @@ nsObjectLoadingContent::InstantiatePlugi
   }
 
   mInstantiating = true;
   AutoSetInstantiatingToFalse autoInstantiating(this);
 
   nsCOMPtr<nsIContent> thisContent =
     do_QueryInterface(static_cast<nsIImageLoadingContent *>(this));
 
-  nsCOMPtr<nsIDocument> doc = thisContent->GetCurrentDoc();
+  nsCOMPtr<nsIDocument> doc = thisContent->GetComposedDoc();
   if (!doc || !InActiveDocument(thisContent)) {
     NS_ERROR("Shouldn't be calling "
              "InstantiatePluginInstance without an active document");
     return NS_ERROR_FAILURE;
   }
 
   // Instantiating an instance can result in script execution, which
   // can destroy this DOM object. Don't allow that for the scope
@@ -1173,18 +1173,18 @@ nsObjectLoadingContent::OnStopRequest(ns
     js::ProfileEntry::Category::NETWORK);
 
   // Handle object not loading error because source was a tracking URL.
   // We make a note of this object node by including it in a dedicated
   // array of blocked tracking nodes under its parent document.
   if (aStatusCode == NS_ERROR_TRACKING_URI) {
     nsCOMPtr<nsIContent> thisNode =
       do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
-    if (thisNode) {
-      thisNode->GetCurrentDoc()->AddBlockedTrackingNode(thisNode);
+    if (thisNode && thisNode->IsInComposedDoc()) {
+      thisNode->GetComposedDoc()->AddBlockedTrackingNode(thisNode);
     }
   }
 
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   if (aRequest != mChannel) {
     return NS_BINDING_ABORTED;
   }
@@ -2655,17 +2655,17 @@ nsObjectLoadingContent::NotifyStateChang
   // manually notify object state changes.
   thisContent->AsElement()->UpdateState(false);
 
   if (!aNotify) {
     // We're done here
     return;
   }
 
-  nsIDocument* doc = thisContent->GetCurrentDoc();
+  nsIDocument* doc = thisContent->GetComposedDoc();
   if (!doc) {
     return; // Nothing to do
   }
 
   EventStates newState = ObjectState();
 
   if (newState != aOldState) {
     // This will trigger frame construction
@@ -3344,17 +3344,17 @@ nsObjectLoadingContent::GetContentDocume
 {
   nsCOMPtr<nsIContent> thisContent =
     do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
 
   if (!thisContent->IsInDoc()) {
     return nullptr;
   }
 
-  // XXXbz should this use GetCurrentDoc()?  sXBL/XBL2 issue!
+  // XXXbz should this use GetComposedDoc()?  sXBL/XBL2 issue!
   nsIDocument *sub_doc = thisContent->OwnerDoc()->GetSubDocumentFor(thisContent);
   if (!sub_doc) {
     return nullptr;
   }
 
   // Return null for cross-origin contentDocument.
   if (!nsContentUtils::SubjectPrincipal()->SubsumesConsideringDomain(sub_doc->NodePrincipal())) {
     return nullptr;
--- a/content/base/src/nsRange.cpp
+++ b/content/base/src/nsRange.cpp
@@ -1079,25 +1079,25 @@ nsRange::IsValidBoundary(nsINode* aNode)
       if (root) {
         return root;
       }
     }
   }
 
   // Elements etc. must be in document or in document fragment,
   // text nodes in document, in document fragment or in attribute.
-  nsINode* root = aNode->GetCurrentDoc();
+  nsINode* root = aNode->GetUncomposedDoc();
   if (root) {
     return root;
   }
 
   root = aNode->SubtreeRoot();
 
   NS_ASSERTION(!root->IsNodeOfType(nsINode::eDOCUMENT),
-               "GetCurrentDoc should have returned a doc");
+               "GetUncomposedDoc should have returned a doc");
 
   // We allow this because of backward compatibility.
   return root;
 }
 
 void
 nsRange::SetStart(nsINode& aNode, uint32_t aOffset, ErrorResult& aRv)
 {
--- a/content/base/src/nsReferencedElement.cpp
+++ b/content/base/src/nsReferencedElement.cpp
@@ -42,17 +42,17 @@ nsReferencedElement::Reset(nsIContent* a
     // assumes UTF-8 and doesn't handle UTF-8 errors.
     // https://bugzilla.mozilla.org/show_bug.cgi?id=951082
     CopyUTF8toUTF16(refPart, ref);
   }
   if (ref.IsEmpty())
     return;
 
   // Get the current document
-  nsIDocument *doc = aFromContent->GetCurrentDoc();
+  nsIDocument *doc = aFromContent->GetComposedDoc();
   if (!doc)
     return;
 
   nsIContent* bindingParent = aFromContent->GetBindingParent();
   if (bindingParent) {
     nsXBLBinding* binding = bindingParent->GetXBLBinding();
     if (binding) {
       bool isEqualExceptRef;
@@ -119,17 +119,17 @@ nsReferencedElement::Reset(nsIContent* a
 
   HaveNewDocument(doc, aWatch, ref);
 }
 
 void
 nsReferencedElement::ResetWithID(nsIContent* aFromContent, const nsString& aID,
                                  bool aWatch)
 {
-  nsIDocument *doc = aFromContent->GetCurrentDoc();
+  nsIDocument *doc = aFromContent->GetComposedDoc();
   if (!doc)
     return;
 
   // XXX Need to take care of XBL/XBL2
 
   if (aWatch) {
     nsCOMPtr<nsIAtom> atom = do_GetAtom(aID);
     if (!atom)