Bug 799078. Part 1: Expose nsContentUtils::FindPresShellForDocument. r=matspal
authorRobert O'Callahan <robert@ocallahan.org>
Tue, 09 Oct 2012 00:23:11 +1300
changeset 110385 0c8ac346e41bac80534be22964967550785a0607
parent 110384 fa3a84d645fc4a44ee064e6397f334ef54aee1e1
child 110386 256882fd63c766115eaf8623cdf73f8688f9c7e4
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersmatspal
bugs799078
milestone19.0a1
Bug 799078. Part 1: Expose nsContentUtils::FindPresShellForDocument. r=matspal
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1818,21 +1818,32 @@ public:
    * Utility method for getElementsByClassName.  aRootNode is the node (either
    * document or element), which getElementsByClassName was called on.
    */
   static nsresult GetElementsByClassName(nsINode* aRootNode,
                                          const nsAString& aClasses,
                                          nsIDOMNodeList** aReturn);
 
   /**
+   * Returns a presshell for this document, if there is one. This will be
+   * aDoc's direct presshell if there is one, otherwise we'll look at all
+   * ancestor documents to try to find a presshell, so for example this can
+   * still find a presshell for documents in display:none frames that have
+   * no presentation. So you have to be careful how you use this presshell ---
+   * getting generic data like a device context or widget from it is OK, but it
+   * might not be this document's actual presentation.
+   */
+  static nsIPresShell* FindPresShellForDocument(nsIDocument* aDoc);
+
+  /**
    * Returns the widget for this document if there is one. Looks at all ancestor
    * documents to try to find a widget, so for example this can still find a
    * widget for documents in display:none frames that have no presentation.
    */
-  static nsIWidget *WidgetForDocument(nsIDocument *aDoc);
+  static nsIWidget* WidgetForDocument(nsIDocument* aDoc);
 
   /**
    * Returns a layer manager to use for the given document. Basically we
    * look up the document hierarchy for the first document which has
    * a presentation with an associated widget, and use that widget's
    * layer manager.
    *
    * @param aDoc the document for which to return a layer manager.
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -6519,45 +6519,55 @@ nsContentUtils::PlatformToDOMLineBreaks(
                              NS_LITERAL_STRING("\n").get());
 
     // Mac linebreaks: Map any remaining CR to LF:
     aString.ReplaceSubstring(NS_LITERAL_STRING("\r").get(),
                              NS_LITERAL_STRING("\n").get());
   }
 }
 
-nsIWidget *
-nsContentUtils::WidgetForDocument(nsIDocument *aDoc)
+nsIPresShell*
+nsContentUtils::FindPresShellForDocument(nsIDocument* aDoc)
 {
   nsIDocument* doc = aDoc;
   nsIDocument* displayDoc = doc->GetDisplayDocument();
   if (displayDoc) {
     doc = displayDoc;
   }
 
   nsIPresShell* shell = doc->GetShell();
+  if (shell) {
+    return shell;
+  }
+
   nsCOMPtr<nsISupports> container = doc->GetContainer();
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = do_QueryInterface(container);
-  while (!shell && docShellTreeItem) {
+  while (docShellTreeItem) {
     // We may be in a display:none subdocument, or we may not have a presshell
     // created yet.
     // Walk the docshell tree to find the nearest container that has a presshell,
-    // and find the root widget from that.
+    // and return that.
     nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(docShellTreeItem);
     nsCOMPtr<nsIPresShell> presShell;
     docShell->GetPresShell(getter_AddRefs(presShell));
     if (presShell) {
-      shell = presShell;
-    } else {
-      nsCOMPtr<nsIDocShellTreeItem> parent;
-      docShellTreeItem->GetParent(getter_AddRefs(parent));
-      docShellTreeItem = parent;
+      return presShell;
     }
-  }
-
+    nsCOMPtr<nsIDocShellTreeItem> parent;
+    docShellTreeItem->GetParent(getter_AddRefs(parent));
+    docShellTreeItem = parent;
+  }
+
+  return nullptr;
+}
+
+nsIWidget*
+nsContentUtils::WidgetForDocument(nsIDocument* aDoc)
+{
+  nsIPresShell* shell = FindPresShellForDocument(aDoc);
   if (shell) {
     nsIViewManager* VM = shell->GetViewManager();
     if (VM) {
       nsIView* rootView = VM->GetRootView();
       if (rootView) {
         nsIView* displayRoot = nsIViewManager::GetDisplayRootFor(rootView);
         if (displayRoot) {
           return displayRoot->GetNearestWidget(nullptr);