Bug 874838 - Make CreateElem return Element. r=khuey
authorAryeh Gregor <ayg@aryeh.name>
Thu, 13 Aug 2015 07:50:00 -0400
changeset 257853 20874c0e47fa4013dc521857bb9852bd981eedbe
parent 257852 a2676b325b8ab911a43a3d99be73959a786eec8c
child 257854 bc7d2eccea1680ddd8c2f4f977f05c6a3898d917
push id29230
push userryanvm@gmail.com
push dateFri, 14 Aug 2015 19:16:25 +0000
treeherdermozilla-central@09dd35dd1193 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs874838
milestone43.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 874838 - Make CreateElem return Element. r=khuey
dom/base/DOMImplementation.cpp
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsIDocument.h
dom/xbl/nsXBLPrototypeBinding.cpp
dom/xslt/xslt/txEXSLTFunctions.cpp
dom/xslt/xslt/txMozillaTextOutput.cpp
dom/xslt/xslt/txMozillaXMLOutput.cpp
dom/xul/XULDocument.cpp
editor/libeditor/nsEditor.cpp
--- a/dom/base/DOMImplementation.cpp
+++ b/dom/base/DOMImplementation.cpp
@@ -205,49 +205,41 @@ DOMImplementation::CreateHTMLDocument(co
                          EmptyString(), EmptyString(),
                          doctype, mDocumentURI, mBaseURI,
                          mOwner->NodePrincipal(),
                          true, scriptHandlingObject,
                          DocumentFlavorLegacyGuess);
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
 
-  nsCOMPtr<nsIContent> root;
-  rv = doc->CreateElem(NS_LITERAL_STRING("html"), nullptr, kNameSpaceID_XHTML,
-                       getter_AddRefs(root));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<Element> root = doc->CreateElem(NS_LITERAL_STRING("html"), nullptr,
+                                           kNameSpaceID_XHTML);
   rv = doc->AppendChildTo(root, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIContent> head;
-  rv = doc->CreateElem(NS_LITERAL_STRING("head"), nullptr, kNameSpaceID_XHTML,
-                       getter_AddRefs(head));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<Element> head = doc->CreateElem(NS_LITERAL_STRING("head"), nullptr,
+                                           kNameSpaceID_XHTML);
   rv = root->AppendChildTo(head, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!DOMStringIsNull(aTitle)) {
-    nsCOMPtr<nsIContent> title;
-    rv = doc->CreateElem(NS_LITERAL_STRING("title"), nullptr,
-                         kNameSpaceID_XHTML, getter_AddRefs(title));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsCOMPtr<Element> title = doc->CreateElem(NS_LITERAL_STRING("title"),
+                                              nullptr, kNameSpaceID_XHTML);
     rv = head->AppendChildTo(title, false);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsRefPtr<nsTextNode> titleText = new nsTextNode(doc->NodeInfoManager());
     rv = titleText->SetText(aTitle, false);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = title->AppendChildTo(titleText, false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  nsCOMPtr<nsIContent> body;
-  rv = doc->CreateElem(NS_LITERAL_STRING("body"), nullptr, kNameSpaceID_XHTML,
-                       getter_AddRefs(body));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<Element> body = doc->CreateElem(NS_LITERAL_STRING("body"), nullptr,
+                                           kNameSpaceID_XHTML);
   rv = root->AppendChildTo(body, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // When the createHTMLDocument method is invoked,
   // use the registry of the associated document to the new instance.
   doc->UseRegistryFromDocument(mOwner);
 
   doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -5442,23 +5442,18 @@ nsIDocument::CreateElement(const nsAStri
   }
 
   bool needsLowercase = IsHTMLDocument() && !IsLowercaseASCII(aTagName);
   nsAutoString lcTagName;
   if (needsLowercase) {
     nsContentUtils::ASCIIToLower(aTagName, lcTagName);
   }
 
-  nsCOMPtr<nsIContent> content;
-  rv = CreateElem(needsLowercase ? lcTagName : aTagName,
-                  nullptr, mDefaultElementType, getter_AddRefs(content));
-  if (rv.Failed()) {
-    return nullptr;
-  }
-  return dont_AddRef(content.forget().take()->AsElement());
+  return CreateElem(needsLowercase ? lcTagName : aTagName, nullptr,
+                    mDefaultElementType);
 }
 
 void
 nsDocument::SetupCustomElement(Element* aElement,
                                uint32_t aNamespaceID,
                                const nsAString* aTypeExtension)
 {
   if (!mRegistry) {
@@ -5792,31 +5787,28 @@ nsDocument::CustomElementConstructor(JSC
   CustomElementDefinition* definition;
   if (!document->mRegistry ||
       !document->mRegistry->mCustomDefinitions.Get(&key, &definition)) {
     return true;
   }
 
   nsDependentAtomString localName(definition->mLocalName);
 
-  nsCOMPtr<nsIContent> newElement;
-  nsresult rv = document->CreateElem(localName, nullptr,
-                                     definition->mNamespaceID,
-                                     getter_AddRefs(newElement));
-  NS_ENSURE_SUCCESS(rv, true);
-
-  nsCOMPtr<Element> element = do_QueryInterface(newElement);
+  nsCOMPtr<Element> element =
+    document->CreateElem(localName, nullptr, definition->mNamespaceID);
+  NS_ENSURE_TRUE(element, true);
+
   if (definition->mLocalName != typeAtom) {
     // This element is a custom element by extension, thus we need to
     // do some special setup. For non-extended custom elements, this happens
     // when the element is created.
     document->SetupCustomElement(element, definition->mNamespaceID, &elemName);
   }
 
-  rv = nsContentUtils::WrapNative(aCx, newElement, newElement, args.rval());
+  nsresult rv = nsContentUtils::WrapNative(aCx, element, element, args.rval());
   NS_ENSURE_SUCCESS(rv, true);
 
   return true;
 }
 
 bool
 nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
 {
@@ -8595,19 +8587,19 @@ nsDocument::RetrieveRelevantHeaders(nsIC
   }
 
   mLastModified.Truncate();
   if (modDate != 0) {
     GetFormattedTimeString(modDate, mLastModified);
   }
 }
 
-nsresult
-nsDocument::CreateElem(const nsAString& aName, nsIAtom *aPrefix, int32_t aNamespaceID,
-                       nsIContent **aResult)
+already_AddRefed<Element>
+nsDocument::CreateElem(const nsAString& aName, nsIAtom *aPrefix,
+                       int32_t aNamespaceID)
 {
 #ifdef DEBUG
   nsAutoString qName;
   if (aPrefix) {
     aPrefix->ToString(qName);
     qName.Append(':');
   }
   qName.Append(aName);
@@ -8616,29 +8608,26 @@ nsDocument::CreateElem(const nsAString& 
   // nsDocument::CreateElement can call us with such a name and no prefix,
   // which would cause an error if we just used true here.
   bool nsAware = aPrefix != nullptr || aNamespaceID != GetDefaultNamespaceID();
   NS_ASSERTION(NS_SUCCEEDED(nsContentUtils::CheckQName(qName, nsAware)),
                "Don't pass invalid prefixes to nsDocument::CreateElem, "
                "check caller.");
 #endif
 
-  *aResult = nullptr;
-
   nsRefPtr<mozilla::dom::NodeInfo> nodeInfo;
   mNodeInfoManager->GetNodeInfo(aName, aPrefix, aNamespaceID,
                                 nsIDOMNode::ELEMENT_NODE,
                                 getter_AddRefs(nodeInfo));
-  NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
+  NS_ENSURE_TRUE(nodeInfo, nullptr);
 
   nsCOMPtr<Element> element;
   nsresult rv = NS_NewElement(getter_AddRefs(element), nodeInfo.forget(),
                               NOT_FROM_PARSER);
-  element.forget(aResult);
-  return rv;
+  return NS_SUCCEEDED(rv) ? element.forget() : nullptr;
 }
 
 bool
 nsDocument::IsSafeToFlush() const
 {
   nsIPresShell* shell = GetShell();
   if (!shell)
     return true;
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1006,19 +1006,19 @@ public:
 
   // nsIObserver
   NS_DECL_NSIOBSERVER
 
   NS_DECL_NSIDOMXPATHEVALUATOR
 
   virtual nsresult Init();
 
-  virtual nsresult CreateElem(const nsAString& aName, nsIAtom *aPrefix,
-                              int32_t aNamespaceID,
-                              nsIContent **aResult) override;
+  virtual already_AddRefed<Element> CreateElem(const nsAString& aName,
+                                               nsIAtom* aPrefix,
+                                               int32_t aNamespaceID) override;
 
   virtual void Sanitize() override;
 
   virtual void EnumerateSubDocuments(nsSubDocEnumFunc aCallback,
                                                  void *aData) override;
 
   virtual bool CanSavePresentation(nsIRequest *aNewRequest) override;
   virtual void Destroy() override;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -147,18 +147,18 @@ template<typename> class Sequence;
 
 template<typename, typename> class CallbackObjectHolder;
 typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder;
 
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID \
-{ 0x6d18ec0b, 0x1f68, 0x4ae6, \
-  { 0x8b, 0x3d, 0x8d, 0x7d, 0x8b, 0x8e, 0x28, 0xd4 } }
+{ 0x292450a1, 0x285e, 0x4a09, \
+  { 0x9a, 0xf9, 0x61, 0xf9, 0xb1, 0xbd, 0x27, 0xcc } }
 
 // Enum for requesting a particular type of document when creating a doc
 enum DocumentFlavor {
   DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
   DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true
   DocumentFlavorSVG, // SVGDocument
   DocumentFlavorPlain, // Just a Document
 };
@@ -1367,20 +1367,21 @@ public:
   {
     return IsXULDocument() || AllowXULXBL();
   }
 
   virtual bool IsScriptEnabled() = 0;
 
   /**
    * Create an element with the specified name, prefix and namespace ID.
+   * Returns null if element name parsing failed.
    */
-  virtual nsresult CreateElem(const nsAString& aName, nsIAtom *aPrefix,
-                              int32_t aNamespaceID,
-                              nsIContent** aResult) = 0;
+  virtual already_AddRefed<Element> CreateElem(const nsAString& aName,
+                                               nsIAtom* aPrefix,
+                                               int32_t aNamespaceID) = 0;
 
   /**
    * Get the security info (i.e. SSL state etc) that the document got
    * from the channel/document that created the content of the
    * document.
    *
    * @see nsIChannel
    */
--- a/dom/xbl/nsXBLPrototypeBinding.cpp
+++ b/dom/xbl/nsXBLPrototypeBinding.cpp
@@ -875,18 +875,18 @@ nsXBLPrototypeBinding::Read(nsIObjectInp
 
   nsAutoString baseTag;
   rv = aStream->ReadString(baseTag);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!baseTag.IsEmpty()) {
     mBaseTag = do_GetAtom(baseTag);
   }
 
-  aDocument->CreateElem(NS_LITERAL_STRING("binding"), nullptr, kNameSpaceID_XBL,
-                        getter_AddRefs(mBinding));
+  mBinding = aDocument->CreateElem(NS_LITERAL_STRING("binding"), nullptr,
+                                   kNameSpaceID_XBL);
 
   nsCOMPtr<nsIContent> child;
   rv = ReadContentNode(aStream, aDocument, aDocument->NodeInfoManager(), getter_AddRefs(child));
   NS_ENSURE_SUCCESS(rv, rv);
 
   Element* rootElement = aDocument->GetRootElement();
   if (rootElement)
     rootElement->AppendChildTo(mBinding, false);
--- a/dom/xslt/xslt/txEXSLTFunctions.cpp
+++ b/dom/xslt/xslt/txEXSLTFunctions.cpp
@@ -120,25 +120,23 @@ static nsresult
 createAndAddToResult(nsIAtom* aName, const nsSubstring& aValue,
                      txNodeSet* aResultSet, nsIContent* aResultHolder)
 {
     NS_ASSERTION(aResultHolder->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT) &&
                  aResultHolder->OwnerDoc(),
                  "invalid result-holder");
 
     nsIDocument* doc = aResultHolder->OwnerDoc();
-    nsCOMPtr<nsIContent> elem;
-    nsresult rv = doc->CreateElem(nsDependentAtomString(aName),
-                                  nullptr, kNameSpaceID_None,
-                                  getter_AddRefs(elem));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsCOMPtr<Element> elem = doc->CreateElem(nsDependentAtomString(aName),
+                                             nullptr, kNameSpaceID_None);
+    NS_ENSURE_TRUE(elem, NS_ERROR_NULL_POINTER);
 
     nsRefPtr<nsTextNode> text = new nsTextNode(doc->NodeInfoManager());
 
-    rv = text->SetText(aValue, false);
+    nsresult rv = text->SetText(aValue, false);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = elem->AppendChildTo(text, false);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = aResultHolder->AppendChildTo(elem, false);
     NS_ENSURE_SUCCESS(rv, rv);
 
--- a/dom/xslt/xslt/txMozillaTextOutput.cpp
+++ b/dom/xslt/xslt/txMozillaTextOutput.cpp
@@ -170,20 +170,19 @@ txMozillaTextOutput::createResultDocumen
     // When transforming into a non-displayed document (i.e. when there is no
     // observer) we only create a transformiix:result root element.
     if (!observer) {
         int32_t namespaceID;
         rv = nsContentUtils::NameSpaceManager()->
             RegisterNameSpace(NS_LITERAL_STRING(kTXNameSpaceURI), namespaceID);
         NS_ENSURE_SUCCESS(rv, rv);
 
-        rv = mDocument->CreateElem(nsDependentAtomString(nsGkAtoms::result),
-                                   nsGkAtoms::transformiix, namespaceID,
-                                   getter_AddRefs(mTextParent));
-        NS_ENSURE_SUCCESS(rv, rv);
+        mTextParent =
+          mDocument->CreateElem(nsDependentAtomString(nsGkAtoms::result),
+                                nsGkAtoms::transformiix, namespaceID);
 
 
         rv = mDocument->AppendChildTo(mTextParent, true);
         NS_ENSURE_SUCCESS(rv, rv);
     }
     else {
         nsCOMPtr<nsIContent> html, head, body;
         rv = createXHTMLElement(nsGkAtoms::html, getter_AddRefs(html));
--- a/dom/xslt/xslt/txMozillaXMLOutput.cpp
+++ b/dom/xslt/xslt/txMozillaXMLOutput.cpp
@@ -614,21 +614,19 @@ txMozillaXMLOutput::createTxWrapper()
     NS_ASSERTION(mDocument == mCurrentNode,
                  "creating wrapper when document isn't parent");
 
     int32_t namespaceID;
     nsresult rv = nsContentUtils::NameSpaceManager()->
         RegisterNameSpace(NS_LITERAL_STRING(kTXNameSpaceURI), namespaceID);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMPtr<nsIContent> wrapper;
-    rv = mDocument->CreateElem(nsDependentAtomString(nsGkAtoms::result),
-                               nsGkAtoms::transformiix, namespaceID,
-                               getter_AddRefs(wrapper));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsCOMPtr<Element> wrapper =
+      mDocument->CreateElem(nsDependentAtomString(nsGkAtoms::result),
+                            nsGkAtoms::transformiix, namespaceID);
 
     uint32_t i, j, childCount = mDocument->GetChildCount();
 #ifdef DEBUG
     // Keep track of the location of the current documentElement, if there is
     // one, so we can verify later
     uint32_t rootLocation = 0;
 #endif
     for (i = 0, j = 0; i < childCount; ++i) {
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -3714,21 +3714,19 @@ XULDocument::CreateTemplateBuilder(nsICo
         // Create a <treechildren> if one isn't there already.
         // XXXvarga what about attributes?
         nsCOMPtr<nsIContent> bodyContent;
         nsXULContentUtils::FindChildByTag(aElement, kNameSpaceID_XUL,
                                           nsGkAtoms::treechildren,
                                           getter_AddRefs(bodyContent));
 
         if (! bodyContent) {
-            nsresult rv =
+            bodyContent =
                 document->CreateElem(nsDependentAtomString(nsGkAtoms::treechildren),
-                                     nullptr, kNameSpaceID_XUL,
-                                     getter_AddRefs(bodyContent));
-            NS_ENSURE_SUCCESS(rv, rv);
+                                     nullptr, kNameSpaceID_XUL);
 
             aElement->AppendChildTo(bodyContent, false);
         }
     }
     else {
         // Create and initialize a content builder.
         nsCOMPtr<nsIXULTemplateBuilder> builder
             = do_CreateInstance("@mozilla.org/xul/xul-template-builder;1");
--- a/editor/libeditor/nsEditor.cpp
+++ b/editor/libeditor/nsEditor.cpp
@@ -4647,21 +4647,18 @@ nsEditor::CreateHTMLContent(nsIAtom* aTa
   // XXX Wallpaper over editor bug (editor tries to create elements with an
   //     empty nodename).
   if (aTag == nsGkAtoms::_empty) {
     NS_ERROR("Don't pass an empty tag to nsEditor::CreateHTMLContent, "
              "check caller.");
     return nullptr;
   }
 
-  nsCOMPtr<nsIContent> ret;
-  nsresult res = doc->CreateElem(nsDependentAtomString(aTag), nullptr,
-                                 kNameSpaceID_XHTML, getter_AddRefs(ret));
-  NS_ENSURE_SUCCESS(res, nullptr);
-  return dont_AddRef(ret.forget().take()->AsElement());
+  return doc->CreateElem(nsDependentAtomString(aTag), nullptr,
+                         kNameSpaceID_XHTML);
 }
 
 nsresult
 nsEditor::SetAttributeOrEquivalent(nsIDOMElement * aElement,
                                    const nsAString & aAttribute,
                                    const nsAString & aValue,
                                    bool aSuppressTransaction)
 {