Bug 1313986 - Part 2. Add CreateAnonymousElement with nsIAtom. r=masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Thu, 24 Nov 2016 16:12:04 +0900
changeset 443428 9585214aa678c16905250265a75b817c90246fcc
parent 443365 8cb81a89f11d4092f2adaa8822733f861a71ace1
child 443429 e09c2b2b41481dd6608d9c816676030d8aae1ed6
push id36983
push userm_kato@ga2.so-net.ne.jp
push dateThu, 24 Nov 2016 10:40:25 +0000
reviewersmasayuki
bugs1313986
milestone53.0a1
Bug 1313986 - Part 2. Add CreateAnonymousElement with nsIAtom. r=masayuki I would like to nsIAtom and mozilla::dom::Element version of CreateAnonymousElement to clean up code. When getting/setting attirubte, editor sometimes use string, not nsGkAtoms. We should use new mozilla::dom::Element methods. Also, we should add _moz_anonclass to atom list that uses on editor. MozReview-Commit-ID: ICaAWVPjcej
dom/base/nsGkAtomList.h
editor/libeditor/HTMLAnonymousNodeEditor.cpp
editor/libeditor/HTMLEditor.h
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -31,16 +31,17 @@
 // Generic atoms
 //---------------------------------------------------------------------------
 
 GK_ATOM(_empty, "")
 GK_ATOM(moz, "_moz")
 GK_ATOM(mozframetype, "mozframetype")
 GK_ATOM(_moz_abspos, "_moz_abspos")
 GK_ATOM(_moz_activated, "_moz_activated")
+GK_ATOM(_moz_anonclass, "_moz_anonclass")
 GK_ATOM(_moz_resizing, "_moz_resizing")
 GK_ATOM(mozallowfullscreen, "mozallowfullscreen")
 GK_ATOM(moztype, "_moz-type")
 GK_ATOM(mozdirty, "_moz_dirty")
 GK_ATOM(mozdisallowselectionprint, "mozdisallowselectionprint")
 GK_ATOM(mozdonotsend, "moz-do-not-send")
 GK_ATOM(mozeditorbogusnode, "_moz_editor_bogus_node")
 GK_ATOM(mozgeneratedcontentbefore, "_moz_generated_content_before")
--- a/editor/libeditor/HTMLAnonymousNodeEditor.cpp
+++ b/editor/libeditor/HTMLAnonymousNodeEditor.cpp
@@ -160,69 +160,100 @@ ElementDeletionObserver::NodeWillBeDestr
 
   NS_RELEASE_THIS();
 }
 
 // Returns in *aReturn an anonymous nsDOMElement of type aTag,
 // child of aParentNode. If aIsCreatedHidden is true, the class
 // "hidden" is added to the created element. If aAnonClass is not
 // the empty string, it becomes the value of the attribute "_moz_anonclass"
-nsresult
+NS_IMETHODIMP
 HTMLEditor::CreateAnonymousElement(const nsAString& aTag,
                                    nsIDOMNode* aParentNode,
                                    const nsAString& aAnonClass,
                                    bool aIsCreatedHidden,
                                    nsIDOMElement** aReturn)
 {
-  NS_ENSURE_ARG_POINTER(aParentNode);
   NS_ENSURE_ARG_POINTER(aReturn);
   *aReturn = nullptr;
 
-  nsCOMPtr<nsIContent> parentContent( do_QueryInterface(aParentNode) );
-  NS_ENSURE_TRUE(parentContent, NS_OK);
+  nsCOMPtr<nsIAtom> atom = NS_Atomize(aTag);
+  RefPtr<Element> element =
+    CreateAnonymousElement(atom, aParentNode, aAnonClass, aIsCreatedHidden);
+  if (NS_WARN_IF(!element)) {
+    return NS_ERROR_FAILURE;
+  }
+  nsCOMPtr<nsIDOMElement> newElement =
+    static_cast<nsIDOMElement*>(GetAsDOMNode(element));
+  newElement.forget(aReturn);
+  return NS_OK;
+}
+
+already_AddRefed<Element>
+HTMLEditor::CreateAnonymousElement(nsIAtom* aTag,
+                                   nsIDOMNode* aParentNode,
+                                   const nsAString& aAnonClass,
+                                   bool aIsCreatedHidden)
+{
+  if (NS_WARN_IF(!aParentNode)) {
+    return nullptr;
+  }
+
+  nsCOMPtr<nsIContent> parentContent = do_QueryInterface(aParentNode);
+  if (NS_WARN_IF(!parentContent)) {
+    return nullptr;
+  }
 
   nsCOMPtr<nsIDocument> doc = GetDocument();
-  NS_ENSURE_TRUE(doc, NS_ERROR_NULL_POINTER);
+  if (NS_WARN_IF(!doc)) {
+    return nullptr;
+  }
 
   // Get the pres shell
   nsCOMPtr<nsIPresShell> ps = GetPresShell();
-  NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
+  if (NS_WARN_IF(!ps)) {
+    return nullptr;
+  }
 
   // Create a new node through the element factory
-  nsCOMPtr<nsIAtom> tagAtom = NS_Atomize(aTag);
-  nsCOMPtr<Element> newContent = CreateHTMLContent(tagAtom);
-  NS_ENSURE_STATE(newContent);
-
-  nsCOMPtr<nsIDOMElement> newElement = do_QueryInterface(newContent);
-  NS_ENSURE_TRUE(newElement, NS_ERROR_FAILURE);
+  RefPtr<Element> newContent = CreateHTMLContent(aTag);
+  if (NS_WARN_IF(!newContent)) {
+    return nullptr;
+  }
 
   // add the "hidden" class if needed
   if (aIsCreatedHidden) {
-    nsresult rv = newElement->SetAttribute(NS_LITERAL_STRING("class"),
-                                           NS_LITERAL_STRING("hidden"));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsresult rv =
+      newContent->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
+                          NS_LITERAL_STRING("hidden"), true);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return nullptr;
+    }
   }
 
   // add an _moz_anonclass attribute if needed
   if (!aAnonClass.IsEmpty()) {
-    nsresult rv = newElement->SetAttribute(NS_LITERAL_STRING("_moz_anonclass"),
-                                           aAnonClass);
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsresult rv =
+      newContent->SetAttr(kNameSpaceID_None, nsGkAtoms::_moz_anonclass,
+                          aAnonClass, true);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return nullptr;
+    }
   }
 
   {
     nsAutoScriptBlocker scriptBlocker;
 
     // establish parenthood of the element
     newContent->SetIsNativeAnonymousRoot();
     nsresult rv =
       newContent->BindToTree(doc, parentContent, parentContent, true);
     if (NS_FAILED(rv)) {
       newContent->UnbindFromTree();
-      return rv;
+      return nullptr;
     }
   }
 
   ElementDeletionObserver* observer =
     new ElementDeletionObserver(newContent, parentContent);
   NS_ADDREF(observer); // NodeWillBeDestroyed releases.
   parentContent->AddMutationObserver(observer);
   newContent->AddMutationObserver(observer);
@@ -234,18 +265,17 @@ HTMLEditor::CreateAnonymousElement(const
   // ok.
   newContent->SetProperty(nsGkAtoms::restylableAnonymousNode,
 			  reinterpret_cast<void*>(true));
 #endif // DEBUG
 
   // display the element
   ps->RecreateFramesFor(newContent);
 
-  newElement.forget(aReturn);
-  return NS_OK;
+  return newContent.forget();
 }
 
 // Removes event listener and calls DeleteRefToAnonymousNode.
 void
 HTMLEditor::RemoveListenerAndDeleteRef(const nsAString& aEvent,
                                        nsIDOMEventListener* aListener,
                                        bool aUseCapture,
                                        Element* aElement,
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -1093,13 +1093,32 @@ private:
   typedef enum { eInserted, eAppended } InsertedOrAppended;
   void DoContentInserted(nsIDocument* aDocument, nsIContent* aContainer,
                          nsIContent* aChild, int32_t aIndexInContainer,
                          InsertedOrAppended aInsertedOrAppended);
   already_AddRefed<Element> GetElementOrParentByTagName(
                               const nsAString& aTagName, nsINode* aNode);
   already_AddRefed<Element> CreateElementWithDefaults(
                               const nsAString& aTagName);
+  /**
+   * Returns an anonymous Element of type aTag,
+   * child of aParentNode. If aIsCreatedHidden is true, the class
+   * "hidden" is added to the created element. If aAnonClass is not
+   * the empty string, it becomes the value of the attribute "_moz_anonclass"
+   * @return a Element
+   * @param aTag             [IN] desired type of the element to create
+   * @param aParentNode      [IN] the parent node of the created anonymous
+   *                              element
+   * @param aAnonClass       [IN] contents of the _moz_anonclass attribute
+   * @param aIsCreatedHidden [IN] a boolean specifying if the class "hidden"
+   *                              is to be added to the created anonymous
+   *                              element
+   */
+  already_AddRefed<Element> CreateAnonymousElement(
+                              nsIAtom* aTag,
+                              nsIDOMNode* aParentNode,
+                              const nsAString& aAnonClass,
+                              bool aIsCreatedHidden);
 };
 
 } // namespace mozilla
 
 #endif // #ifndef mozilla_HTMLEditor_h