Bug 811259 - Patch1: Implement Element.insertAdjacentText and Element.insertAdjacentElement. r=smaug
MozReview-Commit-ID: g54gUOBop7
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -3641,16 +3641,63 @@ Element::InsertAdjacentHTML(const nsAStr
static_cast<nsINode*>(this)->AppendChild(*fragment, aError);
break;
case eAfterEnd:
destination->InsertBefore(*fragment, GetNextSibling(), aError);
break;
}
}
+nsINode*
+Element::InsertAdjacent(const nsAString& aWhere,
+ nsINode* aNode,
+ ErrorResult& aError)
+{
+ if (aWhere.LowerCaseEqualsLiteral("beforebegin")) {
+ nsCOMPtr<nsINode> parent = GetParentNode();
+ if (!parent) {
+ return nullptr;
+ }
+ parent->InsertBefore(*aNode, this, aError);
+ } else if (aWhere.LowerCaseEqualsLiteral("afterbegin")) {
+ static_cast<nsINode*>(this)->InsertBefore(*aNode, GetFirstChild(), aError);
+ } else if (aWhere.LowerCaseEqualsLiteral("beforeend")) {
+ static_cast<nsINode*>(this)->AppendChild(*aNode, aError);
+ } else if (aWhere.LowerCaseEqualsLiteral("afterend")) {
+ nsCOMPtr<nsINode> parent = GetParentNode();
+ if (!parent) {
+ return nullptr;
+ }
+ parent->InsertBefore(*aNode, GetNextSibling(), aError);
+ } else {
+ aError.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+ return nullptr;
+ }
+
+ return aError.Failed() ? nullptr : aNode;
+}
+
+Element*
+Element::InsertAdjacentElement(const nsAString& aWhere,
+ Element& aElement,
+ ErrorResult& aError) {
+ nsINode* newNode = InsertAdjacent(aWhere, &aElement, aError);
+ MOZ_ASSERT(!newNode || newNode->IsElement());
+
+ return newNode ? newNode->AsElement() : nullptr;
+}
+
+void
+Element::InsertAdjacentText(
+ const nsAString& aWhere, const nsAString& aData, ErrorResult& aError)
+{
+ RefPtr<nsTextNode> textNode = OwnerDoc()->CreateTextNode(aData);
+ InsertAdjacent(aWhere, textNode, aError);
+}
+
nsIEditor*
Element::GetEditorInternal()
{
nsCOMPtr<nsITextControlElement> textCtrl = do_QueryInterface(this);
return textCtrl ? textCtrl->GetTextEditor() : nullptr;
}
nsresult
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -674,16 +674,36 @@ public:
already_AddRefed<nsIHTMLCollection>
GetElementsByTagName(const nsAString& aQualifiedName);
already_AddRefed<nsIHTMLCollection>
GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
ErrorResult& aError);
already_AddRefed<nsIHTMLCollection>
GetElementsByClassName(const nsAString& aClassNames);
+
+private:
+ /**
+ * Implement the algorithm specified at
+ * https://dom.spec.whatwg.org/#insert-adjacent for both
+ * |insertAdjacentElement()| and |insertAdjacentText()| APIs.
+ */
+ nsINode* InsertAdjacent(const nsAString& aWhere,
+ nsINode* aNode,
+ ErrorResult& aError);
+
+public:
+ Element* InsertAdjacentElement(const nsAString& aWhere,
+ Element& aElement,
+ ErrorResult& aError);
+
+ void InsertAdjacentText(const nsAString& aWhere,
+ const nsAString& aData,
+ ErrorResult& aError);
+
void SetPointerCapture(int32_t aPointerId, ErrorResult& aError)
{
bool activeState = false;
if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) {
aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
return;
}
if (!IsInDoc()) {
--- a/dom/webidl/Element.webidl
+++ b/dom/webidl/Element.webidl
@@ -66,16 +66,22 @@ interface Element : Node {
[Pure]
HTMLCollection getElementsByTagName(DOMString localName);
[Throws, Pure]
HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
[Pure]
HTMLCollection getElementsByClassName(DOMString classNames);
+ [Throws, Pure]
+ Element? insertAdjacentElement(DOMString where, Element element); // historical
+
+ [Throws]
+ void insertAdjacentText(DOMString where, DOMString data); // historical
+
/**
* The ratio of font-size-inflated text font size to computed font
* size for this element. This will query the element for its primary frame,
* and then use this to get font size inflation information about the frame.
* This will be 1.0 if font size inflation is not enabled, and -1.0 if an
* error occurred during the retrieval of the font size inflation.
*
* @note The font size inflation ratio that is returned is actually the