Expose GetBodyContent and use it to avoid performance hit of nsIDOMHTMLDocument::GetBody. b=331530 r+sr=sicking a=schrep
authordbaron@dbaron.org
Tue, 19 Feb 2008 10:47:34 -0800
changeset 11877 3ad9dc3958348518a26dc7b8d815cebff3572409
parent 11876 4a945f737c689e6159b1d5d9fee96249a097af10
child 11878 10a28f38a6b0903475be5a0c70181258da3c3a8e
push idunknown
push userunknown
push dateunknown
reviewersschrep
bugs331530
milestone1.9b4pre
Expose GetBodyContent and use it to avoid performance hit of nsIDOMHTMLDocument::GetBody. b=331530 r+sr=sicking a=schrep
content/html/document/src/htmldocument.gqi
content/html/document/src/nsHTMLDocument.cpp
content/html/document/src/nsHTMLDocument.h
content/html/document/src/nsIHTMLDocument.h
layout/base/nsCSSRendering.cpp
layout/generic/nsGfxScrollFrame.cpp
--- a/content/html/document/src/htmldocument.gqi
+++ b/content/html/document/src/htmldocument.gqi
@@ -2,16 +2,16 @@
 
 %import-idl "nsIDOMHTMLDocument.idl"
 %import-idl "nsIDOMNSHTMLDocument.idl"
 
 %{C++
 #include "nsHTMLDocument.h"
 %}
 
-%pseudo-iid nsIHTMLDocument 61e989a8-70cd-4582-845e-6e5e12559a83
+%pseudo-iid nsIHTMLDocument 48546d61-6097-462b-89b1-57e2221444dc
 
 NS_INTERFACE_MAP_BEGIN(nsHTMLDocument, nsDocument)
   NS_INTERFACE_MAP_ENTRY(nsIHTMLDocument)
   NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLDocument)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLDocument)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(HTMLDocument)
 NS_INTERFACE_MAP_END
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -3556,16 +3556,22 @@ nsHTMLDocument::ResolveName(const nsAStr
     }
   }
 
   return NS_OK;
 }
 
 //----------------------------
 
+/* virtual */ nsIContent*
+nsHTMLDocument::GetBodyContentExternal()
+{
+  return GetBodyContent();
+}
+
 nsIContent*
 nsHTMLDocument::GetBodyContent()
 {
   // Loop backwards because any non-elements, such as doctypes and PIs
   // are likely to appear before the root element.
   PRUint32 i;
   for (i = mChildren.ChildCount(); i > 0; --i) {
     nsIContent* html = mChildren.ChildAt(i - 1);
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -207,16 +207,18 @@ public:
     return mEditingState;
   }
 
   virtual void DisableCookieAccess()
   {
     mDisableCookieAccess = PR_TRUE;
   }
 
+  virtual nsIContent* GetBodyContentExternal();
+
   void EndUpdate(nsUpdateType aUpdateType);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLDocument, nsDocument)
 
   virtual already_AddRefed<nsIParser> GetFragmentParser() {
     return mFragmentParser.forget();
   }
   virtual void SetFragmentParser(nsIParser* aParser) {
--- a/content/html/document/src/nsIHTMLDocument.h
+++ b/content/html/document/src/nsIHTMLDocument.h
@@ -49,19 +49,21 @@ class nsIDOMHTMLFormElement;
 class nsIDOMHTMLMapElement;
 class nsHTMLStyleSheet;
 class nsIStyleSheet;
 class nsICSSLoader;
 class nsIContent;
 class nsIDOMHTMLBodyElement;
 class nsIScriptElement;
 
+// Update htmldocument.gqi when updating this IID!
+// 48546d61-6097-462b-89b1-57e2221444dc
 #define NS_IHTMLDOCUMENT_IID \
-{ 0x61e989a8, 0x70cd, 0x4582, \
-  { 0x84, 0x5e, 0x6e, 0x5e, 0x12, 0x55, 0x9a, 0x83 } }
+{ 0x48546d61, 0x6097, 0x462b, \
+  { 0x89, 0xb1, 0x57, 0xe2, 0x22, 0x14, 0x44, 0xdc } }
 
 /**
  * HTML document extensions to nsIDocument.
  */
 class nsIHTMLDocument : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IHTMLDOCUMENT_IID)
@@ -168,13 +170,19 @@ public:
    */
   virtual nsresult GetDocumentAllResult(const nsAString& aID,
                                         nsISupports** aResult) = 0;
 
   /**
    * Disables getting and setting cookies
    */
   virtual void DisableCookieAccess() = 0;
+
+  /**
+   * Get the first <body> child of the root <html>, but don't do
+   * anything <frameset>-related (like nsIDOMHTMLDocument::GetBody).
+   */
+  virtual nsIContent* GetBodyContentExternal() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIHTMLDocument, NS_IHTMLDOCUMENT_IID)
 
 #endif /* nsIHTMLDocument_h___ */
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -60,18 +60,17 @@
 #include "imgIRequest.h"
 #include "imgIContainer.h"
 #include "gfxIImageFrame.h"
 #include "nsCSSRendering.h"
 #include "nsCSSColorUtils.h"
 #include "nsITheme.h"
 #include "nsThemeConstants.h"
 #include "nsIServiceManager.h"
-#include "nsIDOMHTMLBodyElement.h"
-#include "nsIDOMHTMLDocument.h"
+#include "nsIHTMLDocument.h"
 #include "nsLayoutUtils.h"
 #include "nsINameSpaceManager.h"
 
 #include "gfxContext.h"
 
 #define BORDER_FULL    0        //entire side
 #define BORDER_INSIDE  1        //inside half
 #define BORDER_OUTSIDE 2        //outside half
@@ -3142,21 +3141,19 @@ FindCanvasBackground(nsIFrame* aForFrame
     }
 
     // Check if we need to do propagation from BODY rather than HTML.
     if (result->IsTransparent()) {
       nsIContent* content = topFrame->GetContent();
       if (content) {
         // Use |GetOwnerDoc| so it works during destruction.
         nsIDocument* document = content->GetOwnerDoc();
-        nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(document);
+        nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(document);
         if (htmlDoc) {
-          nsCOMPtr<nsIDOMHTMLElement> body;
-          htmlDoc->GetBody(getter_AddRefs(body));
-          nsCOMPtr<nsIContent> bodyContent = do_QueryInterface(body);
+          nsIContent* bodyContent = htmlDoc->GetBodyContentExternal();
           // We need to null check the body node (bug 118829) since
           // there are cases, thanks to the fix for bug 5569, where we
           // will reflow a document with no body.  In particular, if a
           // SCRIPT element in the head blocks the parser and then has a
           // SCRIPT that does "document.location.href = 'foo'", then
           // nsParser::Terminate will call |DidBuildModel| methods
           // through to the content sink, which will call |StartLayout|
           // and thus |InitialReflow| on the pres shell.  See bug 119351
@@ -3210,23 +3207,21 @@ FindElementBackground(nsIFrame* aForFram
   if (!parentFrame)
     return PR_TRUE; // no parent to look at
 
   if (content->Tag() != nsGkAtoms::body)
     return PR_TRUE; // not frame for <BODY> element
 
   // We should only look at the <html> background if we're in an HTML document
   nsIDocument* document = content->GetOwnerDoc();
-  nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(document);
+  nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(document);
   if (!htmlDoc)
     return PR_TRUE;
 
-  nsCOMPtr<nsIDOMHTMLElement> body;
-  htmlDoc->GetBody(getter_AddRefs(body));
-  nsCOMPtr<nsIContent> bodyContent = do_QueryInterface(body);
+  nsIContent* bodyContent = htmlDoc->GetBodyContentExternal();
   if (bodyContent != content)
     return PR_TRUE; // this wasn't the background that was propagated
 
   const nsStyleBackground* htmlBG = parentFrame->GetStyleBackground();
   return !htmlBG->IsTransparent();
 }
 
 PRBool
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -65,17 +65,17 @@
 #include "nsIURI.h"
 #include "nsGUIEvent.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsISupportsPrimitives.h"
 #include "nsAutoPtr.h"
 #include "nsPresState.h"
 #include "nsIGlobalHistory3.h"
 #include "nsDocShellCID.h"
-#include "nsIDOMHTMLDocument.h"
+#include "nsIHTMLDocument.h"
 #include "nsEventDispatcher.h"
 #include "nsContentUtils.h"
 #include "nsLayoutUtils.h"
 #ifdef ACCESSIBILITY
 #include "nsIAccessibilityService.h"
 #endif
 #include "nsDisplayList.h"
 #include "nsBidiUtils.h"
@@ -2102,21 +2102,19 @@ nsGfxScrollFrameInner::IsLTR() const
   // XXX This is a bit on the slow side.
   if (mIsRoot) {
     // If we're the root scrollframe, we need the root element's style data.
     nsPresContext *presContext = mOuter->PresContext();
     nsIDocument *document = presContext->Document();
     nsIContent *root = document->GetRootContent();
 
     // But for HTML we want the body element.
-    nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(document);
+    nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(document);
     if (htmlDoc) {
-      nsCOMPtr<nsIDOMHTMLElement> body;
-      htmlDoc->GetBody(getter_AddRefs(body));
-      nsCOMPtr<nsIContent> bodyContent = do_QueryInterface(body);
+      nsIContent *bodyContent = htmlDoc->GetBodyContentExternal();
       if (bodyContent)
         root = bodyContent; // we can trust the document to hold on to it
     }
 
     if (root) {
       nsIFrame *rootsFrame =
         presContext->PresShell()->GetPrimaryFrameFor(root);
       if (rootsFrame)