Fix for bug 564585 (Use WrapNativeParent if we can in nsNodeSH::PreCreate). r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Sun, 09 May 2010 21:33:00 +0200
changeset 47802 8951841a4cdad53edea3f4a2379987b3e19fb3b0
parent 47801 b33cf100643543be53fcc1f91863caf93e4a163d
child 47803 b800bdbea872f334e77cc71c7b2fc9e1e305d84a
child 47806 66ed85eff8efe277fac5e24272a8a1bac8ce7a84
push id14424
push userpvanderbeken@mozilla.com
push dateFri, 16 Jul 2010 13:09:01 +0000
treeherdermozilla-central@8951841a4cda [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs564585
milestone2.0b2pre
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
Fix for bug 564585 (Use WrapNativeParent if we can in nsNodeSH::PreCreate). r=bz.
accessible/src/base/nsAccessible.cpp
content/html/content/src/nsHTMLLegendElement.cpp
content/html/content/src/nsHTMLLegendElement.h
dom/base/nsDOMClassInfo.cpp
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -2183,19 +2183,17 @@ nsAccessible::GetRelationByType(PRUint32
     }
 
   case nsIAccessibleRelation::RELATION_DEFAULT_BUTTON:
     {
       if (mContent->IsHTML()) {
         // HTML form controls implements nsIFormControl interface.
         nsCOMPtr<nsIFormControl> control(do_QueryInterface(mContent));
         if (control) {
-          nsCOMPtr<nsIDOMHTMLFormElement> htmlform;
-          control->GetForm(getter_AddRefs(htmlform));
-          nsCOMPtr<nsIForm> form(do_QueryInterface(htmlform));
+          nsCOMPtr<nsIForm> form(do_QueryInterface(control->GetFormElement()));
           if (form) {
             nsCOMPtr<nsIContent> formContent =
               do_QueryInterface(form->GetDefaultSubmitElement());
             return nsRelUtils::AddTargetFromContent(aRelationType, aRelation,
                                                     formContent);
           }
         }
       }
--- a/content/html/content/src/nsHTMLLegendElement.cpp
+++ b/content/html/content/src/nsHTMLLegendElement.cpp
@@ -30,92 +30,29 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-#include "nsIDOMHTMLLegendElement.h"
+#include "nsHTMLLegendElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMEventTarget.h"
-#include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIForm.h"
 #include "nsIFormControl.h"
 #include "nsIEventStateManager.h"
 #include "nsIDocument.h"
 #include "nsPIDOMWindow.h"
 #include "nsFocusManager.h"
 #include "nsIFrame.h"
 
-class nsHTMLLegendElement : public nsGenericHTMLElement,
-                            public nsIDOMHTMLLegendElement
-{
-public:
-  nsHTMLLegendElement(nsINodeInfo *aNodeInfo);
-  virtual ~nsHTMLLegendElement();
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
-
-  // nsIDOMHTMLLegendElement
-  NS_DECL_NSIDOMHTMLLEGENDELEMENT
-
-  // nsGenericHTMLElement
-  NS_IMETHODIMP Focus();
-
-  virtual void PerformAccesskey(PRBool aKeyCausesActivation,
-                                PRBool aIsTrustedEvent);
-
-  // nsIContent
-  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                              nsIContent* aBindingParent,
-                              PRBool aCompileEventHandlers);
-  virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
-                              PRBool aNullParent = PR_TRUE);
-  virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
-                                nsIAtom* aAttribute,
-                                const nsAString& aValue,
-                                nsAttrValue& aResult);
-  virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
-                                              PRInt32 aModType) const;
-  nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
-                   const nsAString& aValue, PRBool aNotify)
-  {
-    return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
-  }
-  virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
-                           nsIAtom* aPrefix, const nsAString& aValue,
-                           PRBool aNotify);
-  virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
-                             PRBool aNotify);
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-protected:
-  /**
-   * Get the fieldset content element that contains this legend.
-   * Returns null if there is no fieldset containing this legend.
-   */
-  nsIContent* GetFieldSet();
-};
-
-
 NS_IMPL_NS_NEW_HTML_ELEMENT(Legend)
 
 
 nsHTMLLegendElement::nsHTMLLegendElement(nsINodeInfo *aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
@@ -142,21 +79,19 @@ NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLA
 
 
 NS_IMPL_ELEMENT_CLONE(nsHTMLLegendElement)
 
 
 NS_IMETHODIMP
 nsHTMLLegendElement::GetForm(nsIDOMHTMLFormElement** aForm)
 {
-  *aForm = nsnull;
+  Element *form = GetFormElement();
 
-  nsCOMPtr<nsIFormControl> fieldsetControl = do_QueryInterface(GetFieldSet());
-
-  return fieldsetControl ? fieldsetControl->GetForm(aForm) : NS_OK;
+  return form ? CallQueryInterface(form, aForm) : NS_OK;
 }
 
 
 NS_IMPL_STRING_ATTR(nsHTMLLegendElement, AccessKey, accesskey)
 NS_IMPL_STRING_ATTR(nsHTMLLegendElement, Align, align)
 
 // this contains center, because IE4 does
 static const nsAttrValue::EnumTable kAlignTable[] = {
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/nsHTMLLegendElement.h
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mats Palmgren <mats.palmgren@bredband.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef nsHTMLLegendElement_h___
+#define nsHTMLLegendElement_h___
+
+#include "nsIDOMHTMLLegendElement.h"
+#include "nsGenericHTMLElement.h"
+
+class nsHTMLLegendElement : public nsGenericHTMLElement,
+                            public nsIDOMHTMLLegendElement
+{
+public:
+  nsHTMLLegendElement(nsINodeInfo *aNodeInfo);
+  virtual ~nsHTMLLegendElement();
+
+  static nsHTMLLegendElement* FromContent(nsIContent *aContent)
+  {
+    if (aContent->IsHTML() && aContent->Tag() == nsGkAtoms::legend)
+      return static_cast<nsHTMLLegendElement*>(aContent);
+    return nsnull;
+  }
+
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+
+  // nsIDOMNode
+  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+
+  // nsIDOMElement
+  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
+
+  // nsIDOMHTMLElement
+  NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
+
+  // nsIDOMHTMLLegendElement
+  NS_DECL_NSIDOMHTMLLEGENDELEMENT
+
+  // nsGenericHTMLElement
+  NS_IMETHODIMP Focus();
+
+  virtual void PerformAccesskey(PRBool aKeyCausesActivation,
+                                PRBool aIsTrustedEvent);
+
+  // nsIContent
+  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
+                              nsIContent* aBindingParent,
+                              PRBool aCompileEventHandlers);
+  virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
+                              PRBool aNullParent = PR_TRUE);
+  virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
+                                nsIAtom* aAttribute,
+                                const nsAString& aValue,
+                                nsAttrValue& aResult);
+  virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
+                                              PRInt32 aModType) const;
+  nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                   const nsAString& aValue, PRBool aNotify)
+  {
+    return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
+  }
+  virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                           nsIAtom* aPrefix, const nsAString& aValue,
+                           PRBool aNotify);
+  virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
+                             PRBool aNotify);
+
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+
+  mozilla::dom::Element *GetFormElement()
+  {
+    nsCOMPtr<nsIFormControl> fieldsetControl = do_QueryInterface(GetFieldSet());
+
+    return fieldsetControl ? fieldsetControl->GetFormElement() : nsnull;
+  }
+
+protected:
+  /**
+   * Get the fieldset content element that contains this legend.
+   * Returns null if there is no fieldset containing this legend.
+   */
+  nsIContent* GetFieldSet();
+};
+
+#endif /* nsHTMLLegendElement_h___ */
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -472,16 +472,17 @@
 #include "nsIDOMSimpleGestureEvent.h"
 
 #include "nsIDOMNSMouseEvent.h"
 
 #include "nsIEventListenerService.h"
 #include "nsIFrameMessageManager.h"
 #include "mozilla/dom/Element.h"
 #include "nsHTMLSelectElement.h"
+#include "nsHTMLLegendElement.h"
 
 using namespace mozilla::dom;
 
 #include "mozilla/dom/indexedDB/IDBFactory.h"
 #include "mozilla/dom/indexedDB/IDBRequest.h"
 #include "mozilla/dom/indexedDB/IDBDatabase.h"
 #include "mozilla/dom/indexedDB/IDBEvents.h"
 #include "mozilla/dom/indexedDB/IDBObjectStore.h"
@@ -7470,19 +7471,18 @@ nsNodeSH::PreCreate(nsISupports *nativeO
   // Event handling is possible only if (1). If (2) event handling is prevented.
   // If document has never had a script handling object,
   // untrusted scripts (3) shouldn't touch it!
   PRBool hasHadScriptHandlingObject = PR_FALSE;
   NS_ENSURE_STATE(doc->GetScriptHandlingObject(hasHadScriptHandlingObject) ||
                   hasHadScriptHandlingObject ||
                   IsPrivilegedScript());
 
-  nsISupports *native_parent;
-
-  PRBool slimWrappers = PR_TRUE;
+  nsINode *native_parent;
+
   PRBool nodeIsElement = node->IsElement();
   if (nodeIsElement && node->AsElement()->IsXUL()) {
     // For XUL elements, use the parent, if any.
     native_parent = node->GetParent();
 
     if (!native_parent) {
       native_parent = doc;
     }
@@ -7502,73 +7502,70 @@ nsNodeSH::PreCreate(nsISupports *nativeO
         if (form_control) {
           Element *form = form_control->GetFormElement();
 
           if (form) {
             // Found a form, use it.
             native_parent = form;
           }
         }
-      // Legend isn't an HTML form control but should have its fieldset form
-      // as scope parent at least for backward compatibility.
-      } else if (node->AsElement()->IsHTML() &&
-                 node->AsElement()->Tag() == nsGkAtoms::legend) {
-        nsCOMPtr<nsIDOMHTMLLegendElement> legend(do_QueryInterface(node));
-
+      }
+      else {
+        // Legend isn't an HTML form control but should have its fieldset form
+        // as scope parent at least for backward compatibility.
+        nsHTMLLegendElement *legend =
+          nsHTMLLegendElement::FromContent(node->AsElement());
         if (legend) {
-          nsCOMPtr<nsIDOMHTMLFormElement> form;
-          legend->GetForm(getter_AddRefs(form));
+          Element *form = legend->GetFormElement();
 
           if (form) {
             native_parent = form;
           }
         }
       }
     }
   } else {
     // We're called for a document object; set the parent to be the
     // document's global object, if there is one
 
     // Get the scope object from the document.
-    native_parent = doc->GetScopeObject();
-
-    if (!native_parent) {
+    nsISupports *scope = doc->GetScopeObject();
+
+    if (scope) {
+        jsval v;
+        nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
+        nsresult rv = WrapNative(cx, globalObj, scope, nsnull, PR_FALSE, &v,
+                                 getter_AddRefs(holder));
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        holder->GetJSObject(parentObj);
+    }
+    else {
       // No global object reachable from this document, use the
       // global object that was passed to this method.
 
       *parentObj = globalObj;
-
-      return node->IsInNativeAnonymousSubtree() ?
-        NS_SUCCESS_CHROME_ACCESS_ONLY : NS_OK;
-    }
-
-    slimWrappers = PR_FALSE;
+    }
+
+    // No slim wrappers for a document's scope object.
+    return node->IsInNativeAnonymousSubtree() ?
+      NS_SUCCESS_CHROME_ACCESS_ONLY : NS_OK;
   }
 
   // XXXjst: Maybe we need to find the global to use from the
   // nsIScriptGlobalObject that's reachable from the node we're about
   // to wrap here? But that's not always reachable, let's use
   // globalObj for now...
 
-  if (native_parent == doc && (*parentObj = doc->GetWrapper()))
-    return node->IsInNativeAnonymousSubtree() ?
-      NS_SUCCESS_CHROME_ACCESS_ONLY :
-      (slimWrappers ? NS_SUCCESS_ALLOW_SLIM_WRAPPERS : NS_OK);
-
-  jsval v;
-  nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-  nsresult rv = WrapNative(cx, globalObj, native_parent, PR_FALSE, &v,
-                           getter_AddRefs(holder));
+  nsresult rv = WrapNativeParent(cx, globalObj, native_parent, native_parent,
+                                 parentObj);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *parentObj = JSVAL_TO_OBJECT(v);
-
   return node->IsInNativeAnonymousSubtree() ?
-    NS_SUCCESS_CHROME_ACCESS_ONLY :
-    (slimWrappers ? NS_SUCCESS_ALLOW_SLIM_WRAPPERS : NS_OK);
+    NS_SUCCESS_CHROME_ACCESS_ONLY : NS_SUCCESS_ALLOW_SLIM_WRAPPERS;
 }
 
 NS_IMETHODIMP
 nsNodeSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                       JSObject *obj, jsval id, jsval *vp, PRBool *_retval)
 {
   nsNodeSH::PreserveWrapper(GetNative(wrapper, obj));
   return nsEventReceiverSH::AddProperty(wrapper, cx, obj, id, vp, _retval);