Bug 314095 - Eliminate nsIContent::GetDocument, r=jst
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Fri, 22 Aug 2014 23:11:27 +0300
changeset 201266 9684e1598f4e07da0f86f1c26cae92d97836298a
parent 201265 3d51132a0099aed9bd4dfc16584eff231253a35e
child 201267 c4a6a177da57f4000bf56e0d38ca7ebe329fc093
push id27366
push userryanvm@gmail.com
push dateMon, 25 Aug 2014 15:49:45 +0000
treeherdermozilla-central@4ca2bd0722d9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs314095
milestone34.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
Bug 314095 - Eliminate nsIContent::GetDocument, r=jst
accessible/generic/Accessible.cpp
accessible/tests/mochitest/actions/test_general.xul
content/base/public/nsIContent.h
content/base/src/Element.cpp
content/base/src/nsFrameLoader.cpp
content/base/src/nsObjectLoadingContent.cpp
content/html/content/src/HTMLAnchorElement.cpp
content/html/content/src/HTMLBodyElement.cpp
content/html/content/src/HTMLFormElement.cpp
content/html/content/src/HTMLInputElement.cpp
content/html/content/src/HTMLLabelElement.cpp
content/html/content/src/HTMLTextAreaElement.cpp
content/html/content/src/nsFormSubmission.cpp
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
content/xul/content/src/nsXULPopupListener.cpp
content/xul/document/src/XULDocument.cpp
content/xul/document/src/nsXULCommandDispatcher.cpp
content/xul/templates/src/nsXULContentBuilder.cpp
content/xul/templates/src/nsXULTemplateBuilder.cpp
content/xul/templates/src/nsXULTemplateBuilder.h
content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
content/xul/templates/src/nsXULTreeBuilder.cpp
dom/base/nsGlobalWindow.cpp
dom/events/EventStateManager.cpp
dom/plugins/base/nsNPAPIPluginInstance.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/forms/nsFileControlFrame.cpp
layout/generic/nsBlockFrame.cpp
layout/inspector/inDOMUtils.cpp
layout/inspector/inLayoutUtils.cpp
layout/printing/nsPrintEngine.cpp
layout/xul/nsDocElementBoxFrame.cpp
layout/xul/nsListBoxBodyFrame.cpp
layout/xul/nsMenuBarFrame.cpp
layout/xul/nsMenuFrame.cpp
layout/xul/nsXULPopupManager.cpp
layout/xul/nsXULTooltipListener.cpp
layout/xul/tree/nsTreeBodyFrame.cpp
layout/xul/tree/nsTreeContentView.cpp
security/manager/boot/src/nsSecureBrowserUIImpl.cpp
widget/cocoa/nsMenuBarX.mm
widget/cocoa/nsMenuItemIconX.mm
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -1282,17 +1282,17 @@ Accessible::NativeAttributes()
   // 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->GetDocument();
+    nsIDocument* doc = startContent->GetComposedDoc();
     if (!doc)
       break;
 
     nsAccUtils::SetLiveContainerAttributes(attributes, startContent,
                                            nsCoreUtils::GetRoleContent(doc));
 
     // Allow ARIA live region markup from outer documents to override
     nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = doc->GetDocShell();
--- a/accessible/tests/mochitest/actions/test_general.xul
+++ b/accessible/tests/mochitest/actions/test_general.xul
@@ -19,17 +19,17 @@
   <script type="application/javascript"
           src="../actions.js" />
 
   <script type="application/javascript">
   <![CDATA[
     if (navigator.platform.startsWith("Mac")) {
       SimpleTest.expectAssertions(0, 1);
     } else {
-      SimpleTest.expectAssertions(1);
+      SimpleTest.expectAssertions(0, 1);
     }
 
     function doTest()
     {
       var actionsArray = [
         {
           ID: "menu",
           actionName: "click",
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -34,18 +34,18 @@ struct IMEState;
 enum nsLinkState {
   eLinkState_Unvisited  = 1,
   eLinkState_Visited    = 2,
   eLinkState_NotLink    = 3 
 };
 
 // IID for the nsIContent interface
 #define NS_ICONTENT_IID \
-{ 0x329f4c0f, 0x369d, 0x4f35, \
-  { 0x9a, 0x49, 0xd6, 0xa3, 0xaf, 0xb4, 0x34, 0x9f } }
+{ 0x697a2fe1, 0x5549, 0x48e7, \
+  { 0x9a, 0x1a, 0xc2, 0x9d, 0xab, 0x14, 0xe2, 0x39 } }
 
 /**
  * A node of content in a document's content model. This interface
  * is supported by all content objects.
  */
 class nsIContent : public nsINode {
 public:
   typedef mozilla::widget::IMEState IMEState;
@@ -107,26 +107,16 @@ public:
    *        parent node of the content is being destroyed.
    * @param aNullParent Whether to null out the parent pointer as well.  This
    *        is usually desirable.  This argument should only be false while
    *        recursively calling UnbindFromTree when a subtree is detached.
    * @note This method is safe to call on nodes that are not bound to a tree.
    */
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) = 0;
-  
-  /**
-   * DEPRECATED - Use GetCurrentDoc or GetOwnerDoc.
-   * Get the document for this content.
-   * @return the document
-   */
-  nsIDocument *GetDocument() const
-  {
-    return GetCurrentDoc();
-  }
 
   enum {
     /**
      * All XBL flattened tree children of the node, as well as :before and
      * :after anonymous content and native anonymous children.
      *
      * @note the result children order is
      *   1. :before generated node
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -1645,17 +1645,17 @@ Element::GetExistingAttrNameFromQName(co
 }
 
 // static
 bool
 Element::ShouldBlur(nsIContent *aContent)
 {
   // Determine if the current element is focused, if it is not focused
   // then we should not try to blur
-  nsIDocument *document = aContent->GetDocument();
+  nsIDocument* document = aContent->GetComposedDoc();
   if (!document)
     return false;
 
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(document->GetWindow());
   if (!window)
     return false;
 
   nsCOMPtr<nsPIDOMWindow> focusedFrame;
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -1886,17 +1886,17 @@ nsFrameLoader::CheckForRecursiveLoad(nsI
 
   return NS_OK;
 }
 
 nsresult
 nsFrameLoader::GetWindowDimensions(nsIntRect& aRect)
 {
   // Need to get outer window position here
-  nsIDocument* doc = mOwnerContent->GetDocument();
+  nsIDocument* doc = mOwnerContent->GetComposedDoc();
   if (!doc) {
     return NS_ERROR_FAILURE;
   }
 
   if (doc->IsResourceDoc()) {
     return NS_ERROR_FAILURE;
   }
 
@@ -2060,17 +2060,20 @@ nsFrameLoader::SetClampScrollPosition(bo
   return NS_OK;
 }
 
 bool
 nsFrameLoader::TryRemoteBrowser()
 {
   NS_ASSERTION(!mRemoteBrowser, "TryRemoteBrowser called with a remote browser already?");
 
-  nsIDocument* doc = mOwnerContent->GetDocument();
+  //XXXsmaug Per spec (2014/08/21) frameloader should not work in case the
+  //         element isn't in document, only in shadow dom, but that will change
+  //         https://www.w3.org/Bugs/Public/show_bug.cgi?id=26365#c0
+  nsIDocument* doc = mOwnerContent->GetComposedDoc();
   if (!doc) {
     return false;
   }
 
   if (doc->IsResourceDoc()) {
     // Don't allow subframe loads in external reference documents
     return false;
   }
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -317,17 +317,17 @@ public:
 };
 
 NS_IMETHODIMP
 nsPluginCrashedEvent::Run()
 {
   LOG(("OBJLC [%p]: Firing plugin crashed event\n",
        mContent.get()));
 
-  nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
+  nsCOMPtr<nsIDocument> doc = mContent->GetComposedDoc();
   if (!doc) {
     NS_WARNING("Couldn't get document for PluginCrashed event!");
     return NS_OK;
   }
 
   ErrorResult rv;
   nsRefPtr<Event> event =
     doc->CreateEvent(NS_LITERAL_STRING("customevent"), rv);
--- a/content/html/content/src/HTMLAnchorElement.cpp
+++ b/content/html/content/src/HTMLAnchorElement.cpp
@@ -194,17 +194,17 @@ bool
 HTMLAnchorElement::IsHTMLFocusable(bool aWithMouse,
                                    bool *aIsFocusable, int32_t *aTabIndex)
 {
   if (nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
     return true;
   }
 
   // cannot focus links if there is no link handler
-  nsIDocument* doc = GetCurrentDoc();
+  nsIDocument* doc = GetComposedDoc();
   if (doc) {
     nsIPresShell* presShell = doc->GetShell();
     if (presShell) {
       nsPresContext* presContext = presShell->GetPresContext();
       if (presContext && !presContext->GetLinkHandler()) {
         *aIsFocusable = false;
         return false;
       }
--- a/content/html/content/src/HTMLBodyElement.cpp
+++ b/content/html/content/src/HTMLBodyElement.cpp
@@ -448,17 +448,17 @@ HTMLBodyElement::GetAssociatedEditor()
   }
 
   // Make sure this is the actual body of the document
   if (!IsCurrentBodyElement()) {
     return nullptr;
   }
 
   // For designmode, try to get document's editor
-  nsPresContext* presContext = GetPresContext();
+  nsPresContext* presContext = GetPresContext(eForComposedDoc);
   if (!presContext) {
     return nullptr;
   }
 
   nsCOMPtr<nsIDocShell> docShell = presContext->GetDocShell();
   if (!docShell) {
     return nullptr;
   }
--- a/content/html/content/src/HTMLFormElement.cpp
+++ b/content/html/content/src/HTMLFormElement.cpp
@@ -242,17 +242,16 @@ NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(HTMLForm
 NS_IMPL_BOOL_ATTR(HTMLFormElement, NoValidate, novalidate)
 NS_IMPL_STRING_ATTR(HTMLFormElement, Name, name)
 NS_IMPL_STRING_ATTR(HTMLFormElement, Target, target)
 
 void
 HTMLFormElement::Submit(ErrorResult& aRv)
 {
   // Send the submit event
-  nsRefPtr<nsPresContext> presContext = GetPresContext();
   if (mPendingSubmission) {
     // aha, we have a pending submission that was not flushed
     // (this happens when form.submit() is called twice)
     // we have to delete it and build a new one since values
     // might have changed inbetween (we emulate IE here, that's all)
     mPendingSubmission = nullptr;
   }
 
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -3183,17 +3183,17 @@ HTMLInputElement::Select()
 
   FocusTristate state = FocusState();
   if (state == eUnfocusable) {
     return NS_OK;
   }
 
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
 
-  nsRefPtr<nsPresContext> presContext = GetPresContext();
+  nsRefPtr<nsPresContext> presContext = GetPresContext(eForComposedDoc);
   if (state == eInactiveWindow) {
     if (fm)
       fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
     SelectAll(presContext);
     return NS_OK;
   }
 
   if (DispatchSelectEvent(presContext) && fm) {
@@ -3956,17 +3956,18 @@ HTMLInputElement::PostHandleEvent(EventC
               !aVisitor.mEvent->AsFocusEvent()->fromRaise &&
               SelectTextFieldOnFocus()) {
             nsIDocument* document = GetCurrentDoc();
             if (document) {
               uint32_t lastFocusMethod;
               fm->GetLastFocusMethod(document->GetWindow(), &lastFocusMethod);
               if (lastFocusMethod &
                   (nsIFocusManager::FLAG_BYKEY | nsIFocusManager::FLAG_BYMOVEFOCUS)) {
-                nsRefPtr<nsPresContext> presContext = GetPresContext();
+                nsRefPtr<nsPresContext> presContext =
+                  GetPresContext(eForComposedDoc);
                 if (DispatchSelectEvent(presContext)) {
                   SelectAll(presContext);
                 }
               }
             }
           }
           break;
         }
--- a/content/html/content/src/HTMLLabelElement.cpp
+++ b/content/html/content/src/HTMLLabelElement.cpp
@@ -211,17 +211,17 @@ void
 HTMLLabelElement::PerformAccesskey(bool aKeyCausesActivation,
                                    bool aIsTrustedEvent)
 {
   if (!aKeyCausesActivation) {
     nsRefPtr<Element> element = GetLabeledElement();
     if (element)
       element->PerformAccesskey(aKeyCausesActivation, aIsTrustedEvent);
   } else {
-    nsPresContext *presContext = GetPresContext();
+    nsPresContext *presContext = GetPresContext(eForUncomposedDoc);
     if (!presContext)
       return;
 
     // Click on it if the users prefs indicate to do so.
     WidgetMouseEvent event(aIsTrustedEvent, NS_MOUSE_CLICK,
                            nullptr, WidgetMouseEvent::eReal);
     event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD;
 
--- a/content/html/content/src/HTMLTextAreaElement.cpp
+++ b/content/html/content/src/HTMLTextAreaElement.cpp
@@ -122,17 +122,17 @@ HTMLTextAreaElement::Select()
 
   FocusTristate state = FocusState();
   if (state == eUnfocusable) {
     return NS_OK;
   }
 
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
 
-  nsRefPtr<nsPresContext> presContext = GetPresContext();
+  nsRefPtr<nsPresContext> presContext = GetPresContext(eForComposedDoc);
   if (state == eInactiveWindow) {
     if (fm)
       fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
     SelectAll(presContext);
     return NS_OK;
   }
 
   nsEventStatus status = nsEventStatus_eIgnore;
--- a/content/html/content/src/nsFormSubmission.cpp
+++ b/content/html/content/src/nsFormSubmission.cpp
@@ -793,17 +793,17 @@ GetSubmitCharset(nsGenericHTMLElement* a
         if (EncodingUtils::FindEncodingForLabel(uCharset, oCharset))
           return;
       }
       offset = spPos + 1;
     } while (spPos != -1);
   }
   // if there are no accept-charset or all the charset are not supported
   // Get the charset from document
-  nsIDocument* doc = aForm->GetDocument();
+  nsIDocument* doc = aForm->GetComposedDoc();
   if (doc) {
     oCharset = doc->GetDocumentCharacterSet();
   }
 }
 
 static void
 GetEnumAttr(nsGenericHTMLElement* aContent,
             nsIAtom* atom, int32_t* aValue)
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -286,17 +286,18 @@ static const nsAttrValue::EnumTable kDir
   { "rtl", eDir_RTL },
   { "auto", eDir_Auto },
   { 0 }
 };
 
 void
 nsGenericHTMLElement::GetAccessKeyLabel(nsString& aLabel)
 {
-  nsPresContext *presContext = GetPresContext();
+  //XXXsmaug We shouldn't need PresContext for this.
+  nsPresContext *presContext = GetPresContext(eForComposedDoc);
 
   if (presContext) {
     nsAutoString suffix;
     GetAccessKey(suffix);
     if (!suffix.IsEmpty() && 
         presContext->EventStateManager()->GetAccessKeyLabelPrefix(aLabel)) {
       aLabel.Append(suffix);
     }
@@ -1106,22 +1107,22 @@ nsGenericHTMLElement::GetFormControlFram
         return form_frame;
       }
     }
   }
 
   return nullptr;
 }
 
-// XXX This creates a dependency between content and frames
 nsPresContext*
-nsGenericHTMLElement::GetPresContext()
+nsGenericHTMLElement::GetPresContext(PresContextFor aFor)
 {
   // Get the document
-  nsIDocument* doc = GetDocument();
+  nsIDocument* doc = (aFor == eForComposedDoc) ?
+    GetComposedDoc() : GetUncomposedDoc();
   if (doc) {
     // Get presentation shell.
     nsIPresShell *presShell = doc->GetShell();
     if (presShell) {
       return presShell->GetPresContext();
     }
   }
 
@@ -2704,17 +2705,17 @@ nsGenericHTMLElement::RegUnRegAccessKey(
   // first check to see if we have an access key
   nsAutoString accessKey;
   GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, accessKey);
   if (accessKey.IsEmpty()) {
     return;
   }
 
   // We have an access key, so get the ESM from the pres context.
-  nsPresContext *presContext = GetPresContext();
+  nsPresContext* presContext = GetPresContext(eForUncomposedDoc);
 
   if (presContext) {
     EventStateManager* esm = presContext->EventStateManager();
 
     // Register or unregister as appropriate.
     if (aDoReg) {
       esm->RegisterAccessKey(this, (uint32_t)accessKey.First());
     } else {
@@ -2722,17 +2723,17 @@ nsGenericHTMLElement::RegUnRegAccessKey(
     }
   }
 }
 
 void
 nsGenericHTMLElement::PerformAccesskey(bool aKeyCausesActivation,
                                        bool aIsTrustedEvent)
 {
-  nsPresContext *presContext = GetPresContext();
+  nsPresContext* presContext = GetPresContext(eForUncomposedDoc);
   if (!presContext)
     return;
 
   // It's hard to say what HTML4 wants us to do in all cases.
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm) {
     fm->SetFocus(this, nsIFocusManager::FLAG_BYKEY);
   }
@@ -2936,17 +2937,17 @@ nsGenericHTMLFormElementWithState::nsGen
 nsresult
 nsGenericHTMLFormElementWithState::GenerateStateKey()
 {
   // Keep the key if already computed
   if (!mStateKey.IsVoid()) {
     return NS_OK;
   }
 
-  nsIDocument* doc = GetDocument();
+  nsIDocument* doc = GetUncomposedDoc();
   if (!doc) {
     return NS_OK;
   }
 
   // Generate the state key
   nsresult rv = nsContentUtils::GenerateStateKey(this, doc, mStateKey);
 
   if (NS_FAILED(rv)) {
@@ -2984,17 +2985,17 @@ nsGenericHTMLFormElementWithState::GetPr
   }
 
   return result;
 }
 
 already_AddRefed<nsILayoutHistoryState>
 nsGenericHTMLFormElementWithState::GetLayoutHistory(bool aRead)
 {
-  nsCOMPtr<nsIDocument> doc = GetDocument();
+  nsCOMPtr<nsIDocument> doc = GetUncomposedDoc();
   if (!doc) {
     return nullptr;
   }
 
   //
   // Get the history
   //
   nsCOMPtr<nsILayoutHistoryState> history = doc->GetLayoutHistoryState();
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -824,17 +824,22 @@ public:
    * @see GetAttributeMappingFunction
    */
   static void MapScrollingAttributeInto(const nsMappedAttributes* aAttributes,
                                         nsRuleData* aData);
   /**
    * Get the presentation context for this content node.
    * @return the presentation context
    */
-  nsPresContext* GetPresContext();
+  enum PresContextFor
+  {
+    eForComposedDoc,
+    eForUncomposedDoc
+  };
+  nsPresContext* GetPresContext(PresContextFor aFor);
 
   // Form Helper Routines
   /**
    * Find an ancestor of this content node which is a form (could be null)
    * @param aCurrentForm the current form for this node.  If this is
    *        non-null, and no ancestor form is found, and the current form is in
    *        a connected subtree with the node, the current form will be
    *        returned.  This is needed to handle cases when HTML elements have a
--- a/content/xul/content/src/nsXULPopupListener.cpp
+++ b/content/xul/content/src/nsXULPopupListener.cpp
@@ -350,17 +350,17 @@ nsXULPopupListener::LaunchPopup(nsIDOMEv
     aEvent->StopPropagation();
     aEvent->PreventDefault();
   }
 
   if (identifier.IsEmpty())
     return rv;
 
   // Try to find the popup content and the document.
-  nsCOMPtr<nsIDocument> document = mElement->GetDocument();
+  nsCOMPtr<nsIDocument> document = mElement->GetComposedDoc();
   if (!document) {
     NS_WARNING("No document!");
     return NS_ERROR_FAILURE;
   }
 
   // Handle the _child case for popups and context menus
   nsCOMPtr<nsIContent> popup;
   if (identifier.EqualsLiteral("_child")) {
@@ -381,20 +381,24 @@ nsXULPopupListener::LaunchPopup(nsIDOMEv
           if (childContent->NodeInfo()->Equals(nsGkAtoms::menupopup,
                                                kNameSpaceID_XUL)) {
             popup.swap(childContent);
             break;
           }
         }
       }
     }
-  } else if (!(popup = document->GetElementById(identifier))) {
+  } else if (!mElement->IsInUncomposedDoc() ||
+             !(popup = document->GetElementById(identifier))) {
+    // XXXsmaug Should we try to use ShadowRoot::GetElementById in case
+    //          mElement is in shadow DOM?
+    //
     // Use getElementById to obtain the popup content and gracefully fail if 
     // we didn't find any popup content in the document. 
-    NS_ERROR("GetElementById had some kind of spasm.");
+    NS_WARNING("GetElementById had some kind of spasm.");
     return rv;
   }
 
   // return if no popup was found or the popup is the element itself.
   if (!popup || popup == mElement)
     return NS_OK;
 
   // Submenus can't be used as context menus or popups, bug 288763.
--- a/content/xul/document/src/XULDocument.cpp
+++ b/content/xul/document/src/XULDocument.cpp
@@ -3998,17 +3998,19 @@ XULDocument::OverlayForwardReference::Me
 
         nsIAtom *idAtom = currContent->GetID();
 
         nsIContent *elementInDocument = nullptr;
         if (idAtom) {
             nsDependentAtomString id(idAtom);
 
             if (!id.IsEmpty()) {
-                nsIDocument *doc = aTargetNode->GetDocument();
+                nsIDocument *doc = aTargetNode->GetUncomposedDoc();
+                //XXXsmaug should we use ShadowRoot::GetElementById()
+                //         if doc is null?
                 if (!doc) return NS_ERROR_FAILURE;
 
                 elementInDocument = doc->GetElementById(id);
             }
         }
 
         // The item has an 'id' attribute set, and we need to check with
         // the actual document to see if an item with this id exists at
--- a/content/xul/document/src/nsXULCommandDispatcher.cpp
+++ b/content/xul/document/src/nsXULCommandDispatcher.cpp
@@ -391,45 +391,29 @@ nsXULCommandDispatcher::UpdateCommands(c
       return NS_ERROR_UNEXPECTED;
 
     updaters.AppendObject(content);
   }
 
   for (int32_t u = 0; u < updaters.Count(); u++) {
     nsIContent* content = updaters[u];
 
-    nsCOMPtr<nsIDocument> document = content->GetDocument();
-
-    NS_ASSERTION(document != nullptr, "element has no document");
-    if (! document)
-      continue;
-
 #ifdef DEBUG
     if (PR_LOG_TEST(gCommandLog, PR_LOG_NOTICE)) {
       nsAutoCString aeventnameC; 
       CopyUTF16toUTF8(aEventName, aeventnameC);
       PR_LOG(gCommandLog, PR_LOG_NOTICE,
              ("xulcmd[%p] update %p event=%s",
               this, content,
               aeventnameC.get()));
     }
 #endif
 
-    nsCOMPtr<nsIPresShell> shell = document->GetShell();
-    if (shell) {
-      // Retrieve the context in which our DOM event will fire.
-      nsRefPtr<nsPresContext> context = shell->GetPresContext();
-
-      // Handle the DOM event
-      nsEventStatus status = nsEventStatus_eIgnore;
-
-      WidgetEvent event(true, NS_XUL_COMMAND_UPDATE);
-
-      EventDispatcher::Dispatch(content, context, &event, nullptr, &status);
-    }
+    WidgetEvent event(true, NS_XUL_COMMAND_UPDATE);
+    EventDispatcher::Dispatch(content, nullptr, &event);
   }
   return NS_OK;
 }
 
 bool
 nsXULCommandDispatcher::Matches(const nsString& aList, 
                                 const nsAString& aElement)
 {
--- a/content/xul/templates/src/nsXULContentBuilder.cpp
+++ b/content/xul/templates/src/nsXULContentBuilder.cpp
@@ -1337,34 +1337,34 @@ nsXULContentBuilder::RemoveGeneratedCont
 }
 
 nsresult
 nsXULContentBuilder::GetElementsForResult(nsIXULTemplateResult* aResult,
                                           nsCOMArray<nsIContent>& aElements)
 {
     // if the root has been removed from the document, just return
     // since there won't be any generated content any more
-    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetDocument());
+    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetComposedDoc());
     if (! xuldoc)
         return NS_OK;
 
     nsAutoString id;
     aResult->GetId(id);
 
     xuldoc->GetElementsForID(id, aElements);
 
     return NS_OK;
 }
 
 nsresult
 nsXULContentBuilder::CreateElement(int32_t aNameSpaceID,
                                    nsIAtom* aTag,
                                    Element** aResult)
 {
-    nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
+    nsCOMPtr<nsIDocument> doc = mRoot->GetComposedDoc();
     NS_ASSERTION(doc != nullptr, "not initialized");
     if (! doc)
         return NS_ERROR_NOT_INITIALIZED;
 
     nsRefPtr<mozilla::dom::NodeInfo> nodeInfo =
         doc->NodeInfoManager()->GetNodeInfo(aTag, nullptr, aNameSpaceID,
                                             nsIDOMNode::ELEMENT_NODE);
 
@@ -1452,17 +1452,17 @@ nsXULContentBuilder::HasGeneratedContent
     }
     else {
         const char* uri;
         aResource->GetValueConst(&uri);
 
         NS_ConvertUTF8toUTF16 refID(uri);
 
         // just return if the node is no longer in a document
-        nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetDocument());
+        nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetComposedDoc());
         if (! xuldoc)
             return NS_OK;
 
         nsCOMArray<nsIContent> elements;
         xuldoc->GetElementsForID(refID, elements);
 
         uint32_t cnt = elements.Count();
 
@@ -1571,17 +1571,17 @@ nsXULContentBuilder::GetInsertionLocatio
 {
     *aLocations = nullptr;
 
     nsAutoString ref;
     nsresult rv = aResult->GetBindingFor(mRefVariable, ref);
     if (NS_FAILED(rv))
         return false;
 
-    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetDocument());
+    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetComposedDoc());
     if (! xuldoc)
         return false;
 
     *aLocations = new nsCOMArray<nsIContent>;
     NS_ENSURE_TRUE(*aLocations, false);
 
     xuldoc->GetElementsForID(ref, **aLocations);
     uint32_t count = (*aLocations)->Count();
@@ -1712,17 +1712,17 @@ nsresult
 nsXULContentBuilder::OpenContainer(nsIContent* aElement)
 {
     if (aElement != mRoot) {
         if (mFlags & eDontRecurse)
             return NS_OK;
 
         bool rightBuilder = false;
 
-        nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(aElement->GetDocument());
+        nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(aElement->GetComposedDoc());
         if (! xuldoc)
             return NS_OK;
 
         // See if we're responsible for this element
         nsIContent* content = aElement;
         do {
             nsCOMPtr<nsIXULTemplateBuilder> builder;
             xuldoc->GetTemplateBuilderFor(content, getter_AddRefs(builder));
@@ -1751,17 +1751,17 @@ nsXULContentBuilder::CloseContainer(nsIC
 }
 
 nsresult
 nsXULContentBuilder::RebuildAll()
 {
     NS_ENSURE_TRUE(mRoot, NS_ERROR_NOT_INITIALIZED);
 
     // Bail out early if we are being torn down.
-    nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
+    nsCOMPtr<nsIDocument> doc = mRoot->GetComposedDoc();
     if (!doc)
         return NS_OK;
 
     if (mQueriesCompiled)
         Uninit(false);
 
     nsresult rv = CompileQueries();
     if (NS_FAILED(rv))
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -432,17 +432,17 @@ nsXULTemplateBuilder::Refresh()
 }
 
 NS_IMETHODIMP
 nsXULTemplateBuilder::Init(nsIContent* aElement)
 {
     NS_ENSURE_TRUE(aElement, NS_ERROR_NULL_POINTER);
     mRoot = aElement;
 
-    nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
+    nsCOMPtr<nsIDocument> doc = mRoot->GetComposedDoc();
     NS_ASSERTION(doc, "element has no document");
     if (! doc)
         return NS_ERROR_UNEXPECTED;
 
     bool shouldDelay;
     nsresult rv = LoadDataSources(doc, &shouldDelay);
 
     if (NS_SUCCEEDED(rv)) {
@@ -1366,17 +1366,17 @@ nsXULTemplateBuilder::LoadDataSourceUrls
 
 nsresult
 nsXULTemplateBuilder::InitHTMLTemplateRoot()
 {
     // Use XPConnect and the JS APIs to whack mDB and this as the
     // 'database' and 'builder' properties onto aElement.
     nsresult rv;
 
-    nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
+    nsCOMPtr<nsIDocument> doc = mRoot->GetComposedDoc();
     NS_ASSERTION(doc, "no document");
     if (! doc)
         return NS_ERROR_UNEXPECTED;
 
     nsCOMPtr<nsIScriptGlobalObject> global =
       do_QueryInterface(doc->GetWindow());
     if (! global)
         return NS_ERROR_UNEXPECTED;
@@ -1630,17 +1630,17 @@ nsXULTemplateBuilder::GetTemplateRoot(ns
     //     <foo template="MyTemplate">...</foo>
     //     <template id="MyTemplate">...</template>
     //   </window>
     //
     nsAutoString templateID;
     mRoot->GetAttr(kNameSpaceID_None, nsGkAtoms::_template, templateID);
 
     if (! templateID.IsEmpty()) {
-        nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mRoot->GetDocument());
+        nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mRoot->GetComposedDoc());
         if (! domDoc)
             return NS_OK;
 
         nsCOMPtr<nsIDOMElement> domElement;
         domDoc->GetElementById(templateID, getter_AddRefs(domElement));
 
         if (domElement) {
             nsCOMPtr<nsIContent> content = do_QueryInterface(domElement);
--- a/content/xul/templates/src/nsXULTemplateBuilder.h
+++ b/content/xul/templates/src/nsXULTemplateBuilder.h
@@ -113,17 +113,17 @@ public:
 
     virtual nsresult
     RebuildAll() = 0; // must be implemented by subclasses
 
     void RunnableRebuild() { Rebuild(); }
     void RunnableLoadAndRebuild() {
       Uninit(false);  // Reset results
 
-      nsCOMPtr<nsIDocument> doc = mRoot ? mRoot->GetDocument() : nullptr;
+      nsCOMPtr<nsIDocument> doc = mRoot ? mRoot->GetComposedDoc() : nullptr;
       if (doc) {
         bool shouldDelay;
         LoadDataSources(doc, &shouldDelay);
         if (!shouldDelay) {
           Rebuild();
         }
       }
     }
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
@@ -1231,17 +1231,17 @@ nsXULTemplateQueryProcessorRDF::CompileE
             nsAutoString tagstr;
             condition->GetAttr(kNameSpaceID_None, nsGkAtoms::tag, tagstr);
 
             nsCOMPtr<nsIAtom> tag;
             if (! tagstr.IsEmpty()) {
                 tag = do_GetAtom(tagstr);
             }
 
-            nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(condition->GetDocument());
+            nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(condition->GetComposedDoc());
             if (! doc)
                 return NS_ERROR_FAILURE;
 
             idnode->SetTag(tag, doc);
             continue;
         }
 
         TestNode* testnode = nullptr;
--- a/content/xul/templates/src/nsXULTreeBuilder.cpp
+++ b/content/xul/templates/src/nsXULTreeBuilder.cpp
@@ -805,17 +805,17 @@ nsXULTreeBuilder::ToggleOpenState(int32_
         if (observer)
             observer->OnToggleOpenState(aIndex);
     }
 
     if (mLocalStore && mRoot) {
         bool isOpen;
         IsContainerOpen(aIndex, &isOpen);
 
-        nsIDocument* doc = mRoot->GetDocument();
+        nsIDocument* doc = mRoot->GetComposedDoc();
         if (!doc) {
             return NS_ERROR_FAILURE;
         }
 
         nsIURI* docURI = doc->GetDocumentURI();
         nsTreeRows::Row& row = *(mRows[aIndex]);
         nsAutoString nodeid;
         nsresult rv = row.mMatch->mResult->GetId(nodeid);
@@ -1283,17 +1283,17 @@ nsXULTreeBuilder::EnsureSortVariables()
     return NS_OK;
 }
 
 nsresult
 nsXULTreeBuilder::RebuildAll()
 {
     NS_ENSURE_TRUE(mRoot, NS_ERROR_NOT_INITIALIZED);
 
-    nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
+    nsCOMPtr<nsIDocument> doc = mRoot->GetComposedDoc();
 
     // Bail out early if we are being torn down.
     if (!doc)
         return NS_OK;
 
     if (! mQueryProcessor)
         return NS_OK;
 
@@ -1705,17 +1705,17 @@ nsXULTreeBuilder::IsContainerOpen(nsIXUL
   if ((mFlags & eDontRecurse) && aResult != mRootResult) {
     return false;
   }
 
   if (!mLocalStore) {
     return false;
   }
 
-  nsIDocument* doc = mRoot->GetDocument();
+  nsIDocument* doc = mRoot->GetComposedDoc();
   if (!doc) {
     return false;
   }
 
   nsIURI* docURI = doc->GetDocumentURI();
 
   nsAutoString nodeid;
   nsresult rv = aResult->GetId(nodeid);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -9642,17 +9642,17 @@ nsGlobalWindow::GetPrivateParent()
   nsCOMPtr<nsIDOMWindow> parent;
   GetParent(getter_AddRefs(parent));
 
   if (static_cast<nsIDOMWindow *>(this) == parent.get()) {
     nsCOMPtr<nsIContent> chromeElement(do_QueryInterface(mChromeEventHandler));
     if (!chromeElement)
       return nullptr;             // This is ok, just means a null parent.
 
-    nsIDocument* doc = chromeElement->GetDocument();
+    nsIDocument* doc = chromeElement->GetComposedDoc();
     if (!doc)
       return nullptr;             // This is ok, just means a null parent.
 
     return doc->GetWindow();
   }
 
   if (parent) {
     return static_cast<nsGlobalWindow *>
@@ -9674,17 +9674,17 @@ nsGlobalWindow::GetPrivateRoot()
     return outer->GetPrivateRoot();
   }
 
   nsCOMPtr<nsIDOMWindow> top;
   GetTop(getter_AddRefs(top));
 
   nsCOMPtr<nsIContent> chromeElement(do_QueryInterface(mChromeEventHandler));
   if (chromeElement) {
-    nsIDocument* doc = chromeElement->GetDocument();
+    nsIDocument* doc = chromeElement->GetComposedDoc();
     if (doc) {
       nsIDOMWindow *parent = doc->GetWindow();
       if (parent) {
         parent->GetTop(getter_AddRefs(top));
       }
     }
   }
 
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -4758,17 +4758,18 @@ EventStateManager::ContentRemoved(nsIDoc
    * the current link. We want to make sure that the UI gets informed when they
    * are actually removed from the DOM.
    */
   if (aContent->IsHTML() &&
       (aContent->Tag() == nsGkAtoms::a || aContent->Tag() == nsGkAtoms::area) &&
       (aContent->AsElement()->State().HasAtLeastOneOfStates(NS_EVENT_STATE_FOCUS |
                                                             NS_EVENT_STATE_HOVER))) {
     nsGenericHTMLElement* element = static_cast<nsGenericHTMLElement*>(aContent);
-    element->LeaveLink(element->GetPresContext());
+    element->LeaveLink(
+      element->GetPresContext(nsGenericHTMLElement::eForComposedDoc));
   }
 
   IMEStateManager::OnRemoveContent(mPresContext, aContent);
 
   // inform the focus manager that the content is being removed. If this
   // content is focused, the focus will be removed without firing events.
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm)
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -1677,17 +1677,17 @@ public:
 
   NS_IMETHOD Run();
 };
 
 NS_IMETHODIMP
 CarbonEventModelFailureEvent::Run()
 {
   nsString type = NS_LITERAL_STRING("npapi-carbon-event-model-failure");
-  nsContentUtils::DispatchTrustedEvent(mContent->GetDocument(), mContent,
+  nsContentUtils::DispatchTrustedEvent(mContent->GetComposedDoc(), mContent,
                                        type, true, true);
   return NS_OK;
 }
 
 void
 nsNPAPIPluginInstance::CarbonNPAPIFailure()
 {
   nsCOMPtr<nsIDOMElement> element;
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -6682,17 +6682,17 @@ nsCSSFrameConstructor::GetRangeInsertion
   bool multiple = false;
   nsContainerFrame* insertionPoint = GetInsertionPoint(aContainer, nullptr, &multiple);
   if (!insertionPoint && !multiple)
     return nullptr; // Don't build the frames.
 
   bool hasInsertion = false;
   if (!multiple) {
     // XXXbz XBL2/sXBL issue
-    nsIDocument* document = aStartChild->GetDocument();
+    nsIDocument* document = aStartChild->GetComposedDoc();
     // XXXbz how would |document| be null here?
     if (document && aStartChild->GetXBLInsertionParent()) {
       hasInsertion = true;
     }
   }
 
   if (multiple || hasInsertion) {
     // We have an insertion point.  There are some additional tests we need to do
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -70,17 +70,17 @@ nsFileControlFrame::DestroyFrom(nsIFrame
 
   mMouseListener->ForgetFrame();
   nsBlockFrame::DestroyFrom(aDestructRoot);
 }
 
 nsresult
 nsFileControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
-  nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
+  nsCOMPtr<nsIDocument> doc = mContent->GetComposedDoc();
 
   // Create and setup the file picking button.
   mBrowse = doc->CreateHTMLElement(nsGkAtoms::button);
   // NOTE: SetIsNativeAnonymousRoot() has to be called before setting any
   // attribute.
   mBrowse->SetIsNativeAnonymousRoot();
   mBrowse->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
                    NS_LITERAL_STRING("button"), false);
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -6295,24 +6295,25 @@ a11y::AccType
 nsBlockFrame::AccessibleType()
 {
   // block frame may be for <hr>
   if (mContent->Tag() == nsGkAtoms::hr) {
     return a11y::eHTMLHRType;
   }
 
   if (!HasBullet() || !PresContext()) {
+    //XXXsmaug What if we're in the shadow dom?
     if (!mContent->GetParent()) {
       // Don't create accessible objects for the root content node, they are redundant with
       // the nsDocAccessible object created with the document node
       return a11y::eNoType;
     }
     
     nsCOMPtr<nsIDOMHTMLDocument> htmlDoc =
-      do_QueryInterface(mContent->GetDocument());
+      do_QueryInterface(mContent->GetComposedDoc());
     if (htmlDoc) {
       nsCOMPtr<nsIDOMHTMLElement> body;
       htmlDoc->GetBody(getter_AddRefs(body));
       if (SameCOMIdentity(body, mContent)) {
         // Don't create accessible objects for the body, they are redundant with
         // the nsDocAccessible object created with the document node
         return a11y::eNoType;
       }
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -938,17 +938,17 @@ inDOMUtils::GetRuleNodeForElement(dom::E
                                   nsStyleContext** aStyleContext,
                                   nsRuleNode** aRuleNode)
 {
   MOZ_ASSERT(aElement);
 
   *aRuleNode = nullptr;
   *aStyleContext = nullptr;
 
-  nsIDocument* doc = aElement->GetDocument();
+  nsIDocument* doc = aElement->GetComposedDoc();
   NS_ENSURE_TRUE(doc, NS_ERROR_UNEXPECTED);
 
   nsIPresShell *presShell = doc->GetShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_UNEXPECTED);
 
   nsPresContext *presContext = presShell->GetPresContext();
   NS_ENSURE_TRUE(presContext, NS_ERROR_UNEXPECTED);
 
--- a/layout/inspector/inLayoutUtils.cpp
+++ b/layout/inspector/inLayoutUtils.cpp
@@ -73,17 +73,17 @@ inLayoutUtils::GetEventStateManagerFor(n
   return shell->GetPresContext()->EventStateManager();
 }
 
 nsIDOMDocument*
 inLayoutUtils::GetSubDocumentFor(nsIDOMNode* aNode)
 {
   nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
   if (content) {
-    nsCOMPtr<nsIDocument> doc = content->GetDocument();
+    nsCOMPtr<nsIDocument> doc = content->GetComposedDoc();
     if (doc) {
       nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(doc->GetSubDocumentFor(content)));
 
       return domdoc;
     }
   }
 
   return nullptr;
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -1321,17 +1321,17 @@ nsPrintEngine::CheckForChildFrameSets(ns
 // all the Frames and IFrames, then sets the "mFrameType" data member
 // which tells us what type of PO we have
 void
 nsPrintEngine::MapContentForPO(nsPrintObject*   aPO,
                                nsIContent*      aContent)
 {
   NS_PRECONDITION(aPO && aContent, "Null argument");
 
-  nsIDocument* doc = aContent->GetDocument();
+  nsIDocument* doc = aContent->GetComposedDoc();
 
   NS_ASSERTION(doc, "Content without a document from a document tree?");
 
   nsIDocument* subDoc = doc->GetSubDocumentFor(aContent);
 
   if (subDoc) {
     nsCOMPtr<nsIDocShell> docShell(subDoc->GetDocShell());
 
--- a/layout/xul/nsDocElementBoxFrame.cpp
+++ b/layout/xul/nsDocElementBoxFrame.cpp
@@ -78,17 +78,17 @@ nsDocElementBoxFrame::DestroyFrom(nsIFra
   nsContentUtils::DestroyAnonymousContent(&mPopupgroupContent);
   nsContentUtils::DestroyAnonymousContent(&mTooltipContent);
   nsBoxFrame::DestroyFrom(aDestructRoot);
 }
 
 nsresult
 nsDocElementBoxFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
-  nsIDocument* doc = mContent->GetDocument();
+  nsIDocument* doc = mContent->GetComposedDoc();
   if (!doc) {
     // The page is currently being torn down.  Why bother.
     return NS_ERROR_FAILURE;
   }
   nsNodeInfoManager *nodeInfoManager = doc->NodeInfoManager();
 
   // create the top-secret popupgroup node. shhhhh!
   nsRefPtr<NodeInfo> nodeInfo;
--- a/layout/xul/nsListBoxBodyFrame.cpp
+++ b/layout/xul/nsListBoxBodyFrame.cpp
@@ -796,17 +796,17 @@ nsListBoxBodyFrame::ScrollToIndex(int32_
 
   if (!weak.IsAlive()) {
     return NS_OK;
   }
 
   // This change has to happen immediately.
   // Flush any pending reflow commands.
   // XXXbz why, exactly?
-  mContent->GetDocument()->FlushPendingNotifications(Flush_Layout);
+  mContent->GetComposedDoc()->FlushPendingNotifications(Flush_Layout);
 
   return NS_OK;
 }
 
 nsresult
 nsListBoxBodyFrame::InternalPositionChangedCallback()
 {
   nsListScrollSmoother* smoother = GetSmoother();
@@ -869,17 +869,17 @@ nsListBoxBodyFrame::DoInternalPositionCh
 
   nsRefPtr<nsPresContext> presContext(PresContext());
   nsBoxLayoutState state(presContext);
 
   // begin timing how long it takes to scroll a row
   PRTime start = PR_Now();
 
   nsWeakFrame weakThis(this);
-  mContent->GetDocument()->FlushPendingNotifications(Flush_Layout);
+  mContent->GetComposedDoc()->FlushPendingNotifications(Flush_Layout);
   if (!weakThis.IsAlive()) {
     return NS_OK;
   }
 
   {
     nsAutoScriptBlocker scriptBlocker;
 
     int32_t visibleRows = 0;
--- a/layout/xul/nsMenuBarFrame.cpp
+++ b/layout/xul/nsMenuBarFrame.cpp
@@ -67,17 +67,17 @@ nsMenuBarFrame::Init(nsIContent*       a
   nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
 
   // Create the menu bar listener.
   mMenuBarListener = new nsMenuBarListener(this);
   NS_ADDREF(mMenuBarListener);
 
   // Hook up the menu bar as a key listener on the whole document.  It will see every
   // key press that occurs, but after everyone else does.
-  mTarget = aContent->GetDocument();
+  mTarget = aContent->GetComposedDoc();
 
   // Also hook up the listener to the window listening for focus events. This is so we can keep proper
   // state as the user alt-tabs through processes.
 
   mTarget->AddEventListener(NS_LITERAL_STRING("keypress"), mMenuBarListener, false);
   mTarget->AddEventListener(NS_LITERAL_STRING("keydown"), mMenuBarListener, false);
   mTarget->AddEventListener(NS_LITERAL_STRING("keyup"), mMenuBarListener, false);
 
--- a/layout/xul/nsMenuFrame.cpp
+++ b/layout/xul/nsMenuFrame.cpp
@@ -1029,20 +1029,22 @@ nsMenuFrame::BuildAcceleratorText(bool a
 
   // See if we have a key node and use that instead.
   nsAutoString keyValue;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::key, keyValue);
   if (keyValue.IsEmpty())
     return;
 
   // Turn the document into a DOM document so we can use getElementById
-  nsIDocument *document = mContent->GetDocument();
+  nsIDocument *document = mContent->GetUncomposedDoc();
   if (!document)
     return;
 
+  //XXXsmaug If mContent is in shadow dom, should we use
+  //         ShadowRoot::GetElementById()?
   nsIContent *keyElement = document->GetElementById(keyValue);
   if (!keyElement) {
 #ifdef DEBUG
     nsAutoString label;
     mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::label, label);
     nsAutoString msg = NS_LITERAL_STRING("Key '") +
                        keyValue +
                        NS_LITERAL_STRING("' of menu item '") +
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -1747,21 +1747,21 @@ nsXULPopupManager::SetCaptureState(nsICo
 void
 nsXULPopupManager::UpdateKeyboardListeners()
 {
   nsCOMPtr<EventTarget> newTarget;
   bool isForMenu = false;
   nsMenuChainItem* item = GetTopVisibleMenu();
   if (item) {
     if (!item->IgnoreKeys())
-      newTarget = item->Content()->GetDocument();
+      newTarget = item->Content()->GetComposedDoc();
     isForMenu = item->PopupType() == ePopupTypeMenu;
   }
   else if (mActiveMenuBar) {
-    newTarget = mActiveMenuBar->GetContent()->GetDocument();
+    newTarget = mActiveMenuBar->GetContent()->GetComposedDoc();
     isForMenu = true;
   }
 
   if (mKeyListener != newTarget) {
     if (mKeyListener) {
       mKeyListener->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, true);
       mKeyListener->RemoveEventListener(NS_LITERAL_STRING("keydown"), this, true);
       mKeyListener->RemoveEventListener(NS_LITERAL_STRING("keyup"), this, true);
--- a/layout/xul/nsXULTooltipListener.cpp
+++ b/layout/xul/nsXULTooltipListener.cpp
@@ -326,17 +326,17 @@ void
 nsXULTooltipListener::CheckTreeBodyMove(nsIDOMMouseEvent* aMouseEvent)
 {
   nsCOMPtr<nsIContent> sourceNode = do_QueryReferent(mSourceNode);
   if (!sourceNode)
     return;
 
   // get the boxObject of the documentElement of the document the tree is in
   nsCOMPtr<nsIBoxObject> bx;
-  nsIDocument* doc = sourceNode->GetDocument();
+  nsIDocument* doc = sourceNode->GetComposedDoc();
   if (doc) {
     ErrorResult ignored;
     bx = doc->GetBoxObjectFor(doc->GetRootElement(), ignored);
   }
 
   nsCOMPtr<nsITreeBoxObject> obx;
   GetSourceTreeBoxObject(getter_AddRefs(obx));
   if (bx && obx) {
@@ -382,21 +382,22 @@ nsXULTooltipListener::ShowTooltip()
 
   // get the tooltip content designated for the target node
   nsCOMPtr<nsIContent> tooltipNode;
   GetTooltipFor(sourceNode, getter_AddRefs(tooltipNode));
   if (!tooltipNode || sourceNode == tooltipNode)
     return NS_ERROR_FAILURE; // the target node doesn't need a tooltip
 
   // set the node in the document that triggered the tooltip and show it
-  nsCOMPtr<nsIDOMXULDocument> xulDoc(do_QueryInterface(tooltipNode->GetDocument()));
+  nsCOMPtr<nsIDOMXULDocument> xulDoc =
+    do_QueryInterface(tooltipNode->GetComposedDoc());
   if (xulDoc) {
     // Make sure the target node is still attached to some document. 
     // It might have been deleted.
-    if (sourceNode->GetDocument()) {
+    if (sourceNode->IsInComposedDoc()) {
 #ifdef MOZ_XUL
       if (!mIsSourceTree) {
         mLastTreeRow = -1;
         mLastTreeCol = nullptr;
       }
 #endif
 
       mCurrentTooltip = do_GetWeakReference(tooltipNode);
@@ -408,17 +409,17 @@ nsXULTooltipListener::ShowTooltip()
         return NS_OK;
 
       // listen for popuphidden on the tooltip node, so that we can
       // be sure DestroyPopup is called even if someone else closes the tooltip
       currentTooltip->AddSystemEventListener(NS_LITERAL_STRING("popuphiding"), 
                                              this, false, false);
 
       // listen for mousedown, mouseup, keydown, and DOMMouseScroll events at document level
-      nsIDocument* doc = sourceNode->GetDocument();
+      nsIDocument* doc = sourceNode->GetComposedDoc();
       if (doc) {
         // Probably, we should listen to untrusted events for hiding tooltips
         // on content since tooltips might disturb something of web
         // applications.  If we don't specify the aWantsUntrusted of
         // AddSystemEventListener(), the event target sets it to TRUE if the
         // target is in content.
         doc->AddSystemEventListener(NS_LITERAL_STRING("DOMMouseScroll"),
                                     this, true);
@@ -550,17 +551,17 @@ GetImmediateChild(nsIContent* aContent, 
 
 nsresult
 nsXULTooltipListener::FindTooltip(nsIContent* aTarget, nsIContent** aTooltip)
 {
   if (!aTarget)
     return NS_ERROR_NULL_POINTER;
 
   // before we go on, make sure that target node still has a window
-  nsIDocument *document = aTarget->GetDocument();
+  nsIDocument *document = aTarget->GetComposedDoc();
   if (!document) {
     NS_WARNING("Unable to retrieve the tooltip node document.");
     return NS_ERROR_FAILURE;
   }
   nsPIDOMWindow *window = document->GetWindow();
   if (!window) {
     return NS_OK;
   }
@@ -590,18 +591,20 @@ nsXULTooltipListener::FindTooltip(nsICon
   aTarget->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltip, tooltipId);
 
   // if tooltip == _child, look for first <tooltip> child
   if (tooltipId.EqualsLiteral("_child")) {
     GetImmediateChild(aTarget, nsGkAtoms::tooltip, aTooltip);
     return NS_OK;
   }
 
-  if (!tooltipId.IsEmpty()) {
+  if (!tooltipId.IsEmpty() && aTarget->IsInUncomposedDoc()) {
     // tooltip must be an id, use getElementById to find it
+    //XXXsmaug If aTarget is in shadow dom, should we use
+    //         ShadowRoot::GetElementById()?
     nsCOMPtr<nsIContent> tooltipEl = document->GetElementById(tooltipId);
 
     if (tooltipEl) {
 #ifdef MOZ_XUL
       mNeedTitletip = false;
 #endif
       tooltipEl.forget(aTooltip);
       return NS_OK;
@@ -653,17 +656,17 @@ nsXULTooltipListener::DestroyTooltip()
   nsCOMPtr<nsIDOMEventListener> kungFuDeathGrip(this);
   nsCOMPtr<nsIContent> currentTooltip = do_QueryReferent(mCurrentTooltip);
   if (currentTooltip) {
     // release tooltip before removing listener to prevent our destructor from
     // being called recursively (bug 120863)
     mCurrentTooltip = nullptr;
 
     // clear out the tooltip node on the document
-    nsCOMPtr<nsIDocument> doc = currentTooltip->GetDocument();
+    nsCOMPtr<nsIDocument> doc = currentTooltip->GetComposedDoc();
     if (doc) {
       // remove the mousedown and keydown listener from document
       doc->RemoveSystemEventListener(NS_LITERAL_STRING("DOMMouseScroll"), this,
                                      true);
       doc->RemoveSystemEventListener(NS_LITERAL_STRING("mousedown"), this,
                                      true);
       doc->RemoveSystemEventListener(NS_LITERAL_STRING("mouseup"), this, true);
       doc->RemoveSystemEventListener(NS_LITERAL_STRING("keydown"), this, true);
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -314,17 +314,17 @@ nsTreeBodyFrame::DestroyFrom(nsIFrame* a
 }
 
 void
 nsTreeBodyFrame::EnsureBoxObject()
 {
   if (!mTreeBoxObject) {
     nsIContent* parent = GetBaseElement();
     if (parent) {
-      nsIDocument* nsDoc = parent->GetDocument();
+      nsIDocument* nsDoc = parent->GetComposedDoc();
       if (!nsDoc) // there may be no document, if we're called from Destroy()
         return;
       ErrorResult ignored;
       nsCOMPtr<nsIBoxObject> box =
         nsDoc->GetBoxObjectFor(parent->AsElement(), ignored);
       // Ensure that we got a native box object.
       nsCOMPtr<nsPIBoxObject> pBox = do_QueryInterface(box);
       if (pBox) {
@@ -2166,17 +2166,17 @@ nsTreeBodyFrame::GetImage(int32_t aRowIn
 
     listener->AddCell(aRowIndex, aCol);
     nsCOMPtr<imgINotificationObserver> imgNotificationObserver = listener;
 
     nsRefPtr<imgRequestProxy> imageRequest;
     if (styleRequest) {
       styleRequest->Clone(imgNotificationObserver, getter_AddRefs(imageRequest));
     } else {
-      nsIDocument* doc = mContent->GetDocument();
+      nsIDocument* doc = mContent->GetComposedDoc();
       if (!doc)
         // The page is currently being torn down.  Why bother.
         return NS_ERROR_FAILURE;
 
       nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
 
       nsCOMPtr<nsIURI> srcURI;
       nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(srcURI),
--- a/layout/xul/tree/nsTreeContentView.cpp
+++ b/layout/xul/tree/nsTreeContentView.cpp
@@ -483,17 +483,17 @@ nsTreeContentView::SetTree(nsITreeBoxObj
     }
     nsCOMPtr<nsIDOMElement> element;
     boxObject->GetElement(getter_AddRefs(element));
 
     mRoot = do_QueryInterface(element);
     NS_ENSURE_STATE(mRoot);
 
     // Add ourselves to document's observers.
-    nsIDocument* document = mRoot->GetDocument();
+    nsIDocument* document = mRoot->GetComposedDoc();
     if (document) {
       document->AddObserver(this);
       mDocument = document;
     }
 
     nsCOMPtr<nsIDOMElement> bodyElement;
     mBoxObject->GetTreeBody(getter_AddRefs(bodyElement));
     if (bodyElement) {
--- a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp
+++ b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp
@@ -399,17 +399,17 @@ nsSecureBrowserUIImpl::Notify(nsIDOMHTML
 {
   // Return NS_OK unless we want to prevent this form from submitting.
   *cancelSubmit = false;
   if (!aWindow || !actionURL || !aDOMForm)
     return NS_OK;
   
   nsCOMPtr<nsIContent> formNode = do_QueryInterface(aDOMForm);
 
-  nsCOMPtr<nsIDocument> document = formNode->GetDocument();
+  nsCOMPtr<nsIDocument> document = formNode->GetComposedDoc();
   if (!document) return NS_OK;
 
   nsIPrincipal *principal = formNode->NodePrincipal();
   
   if (!principal)
   {
     *cancelSubmit = true;
     return NS_OK;
--- a/widget/cocoa/nsMenuBarX.mm
+++ b/widget/cocoa/nsMenuBarX.mm
@@ -465,17 +465,17 @@ void nsMenuBarX::HideItem(nsIDOMDocument
       NS_IF_ADDREF(*outHiddenNode);
     }
   }
 }
 
 // Do what is necessary to conform to the Aqua guidelines for menus.
 void nsMenuBarX::AquifyMenuBar()
 {
-  nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mContent->GetDocument()));
+  nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mContent->GetComposedDoc()));
   if (domDoc) {
     // remove the "About..." item and its separator
     HideItem(domDoc, NS_LITERAL_STRING("aboutSeparator"), nullptr);
     HideItem(domDoc, NS_LITERAL_STRING("aboutName"), getter_AddRefs(mAboutItemContent));
     if (!sAboutItemContent)
       sAboutItemContent = mAboutItemContent;
 
     // Hide the software update menu item, since it belongs in the application
@@ -507,17 +507,17 @@ void nsMenuBarX::AquifyMenuBar()
 }
 
 // for creating menu items destined for the Application menu
 NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsMenuX* inMenu, const nsAString& nodeID, SEL action,
                                                 int tag, NativeMenuItemTarget* target)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
-  nsCOMPtr<nsIDocument> doc = inMenu->Content()->GetDocument();
+  nsCOMPtr<nsIDocument> doc = inMenu->Content()->GetUncomposedDoc();
   if (!doc)
     return nil;
 
   nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(doc));
   if (!domdoc)
     return nil;
 
   // Get information from the gecko menu item
--- a/widget/cocoa/nsMenuItemIconX.mm
+++ b/widget/cocoa/nsMenuItemIconX.mm
@@ -174,17 +174,17 @@ nsMenuItemIconX::GetIconURI(nsIURI** aIc
   nsresult rv;
   nsCOMPtr<nsIDOMCSSValue> cssValue;
   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssStyleDecl;
   nsCOMPtr<nsIDOMCSSPrimitiveValue> primitiveValue;
   uint16_t primitiveType;
   if (!hasImageAttr) {
     // If the content node has no "image" attribute, get the
     // "list-style-image" property from CSS.
-    nsCOMPtr<nsIDocument> document = mContent->GetDocument();
+    nsCOMPtr<nsIDocument> document = mContent->GetComposedDoc();
     if (!document)
       return NS_ERROR_FAILURE;
 
     nsCOMPtr<nsPIDOMWindow> window = document->GetWindow();
     if (!window)
       return NS_ERROR_FAILURE;
 
     nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mContent);