aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/element.rs46
-rw-r--r--components/script/dom/webidls/Element.webidl4
-rw-r--r--tests/wpt/metadata/MANIFEST.json6
-rw-r--r--tests/wpt/web-platform-tests/dom/nodes/insert-adjacent.html79
4 files changed, 135 insertions, 0 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index cceb6cbf095..4c0e03d6f93 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -1168,6 +1168,35 @@ impl Element {
let node = self.upcast::<Node>();
node.owner_doc().element_attr_will_change(self);
}
+
+ // https://dom.spec.whatwg.org/#insert-adjacent
+ pub fn insert_adjacent(&self, where_: DOMString, node: &Node)
+ -> Fallible<Option<Root<Node>>> {
+ let self_node = self.upcast::<Node>();
+ match &*where_ {
+ "beforebegin" => {
+ if let Some(parent) = self_node.GetParentNode() {
+ Node::pre_insert(node, &parent, Some(self_node)).map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+ "afterbegin" => {
+ Node::pre_insert(node, &self_node, self_node.GetFirstChild().r()).map(Some)
+ }
+ "beforeend" => {
+ Node::pre_insert(node, &self_node, None).map(Some)
+ }
+ "afterend" => {
+ if let Some(parent) = self_node.GetParentNode() {
+ Node::pre_insert(node, &parent, self_node.GetNextSibling().r()).map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+ _ => Err(Error::Syntax)
+ }
+ }
}
impl ElementMethods for Element {
@@ -1620,6 +1649,23 @@ impl ElementMethods for Element {
}
}
}
+
+ // https://dom.spec.whatwg.org/#dom-element-insertadjacentelement
+ fn InsertAdjacentElement(&self, where_: DOMString, element: &Element)
+ -> Fallible<Option<Root<Element>>> {
+ let inserted_node = try!(self.insert_adjacent(where_, element.upcast()));
+ Ok(inserted_node.map(|node| Root::downcast(node).unwrap()))
+ }
+
+ // https://dom.spec.whatwg.org/#dom-element-insertadjacenttext
+ fn InsertAdjacentText(&self, where_: DOMString, data: DOMString)
+ -> ErrorResult {
+ // Step 1.
+ let text = Text::new(data, &document_from_node(self));
+
+ // Step 2.
+ self.insert_adjacent(where_, text.upcast()).map(|_| ())
+ }
}
pub fn fragment_affecting_attributes() -> [Atom; 3] {
diff --git a/components/script/dom/webidls/Element.webidl b/components/script/dom/webidls/Element.webidl
index c5c395536ac..9bc5ff64597 100644
--- a/components/script/dom/webidls/Element.webidl
+++ b/components/script/dom/webidls/Element.webidl
@@ -70,6 +70,10 @@ interface Element : Node {
HTMLCollection getElementsByTagName(DOMString localName);
HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
HTMLCollection getElementsByClassName(DOMString classNames);
+ [Throws]
+ Element? insertAdjacentElement(DOMString where_, Element element);
+ [Throws]
+ void insertAdjacentText(DOMString where_, DOMString data);
};
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-element-interface
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index b317fc48432..7c59ea14ade 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -34800,6 +34800,12 @@
"url": "/XMLHttpRequest/responseurl.html"
}
],
+ "dom/nodes/insert-adjacent.html": [
+ {
+ "path": "dom/nodes/insert-adjacent.html",
+ "url": "/dom/nodes/insert-adjacent.html"
+ }
+ ],
"html/semantics/forms/textfieldselection/selection-after-content-change.html": [
{
"path": "html/semantics/forms/textfieldselection/selection-after-content-change.html",
diff --git a/tests/wpt/web-platform-tests/dom/nodes/insert-adjacent.html b/tests/wpt/web-platform-tests/dom/nodes/insert-adjacent.html
new file mode 100644
index 00000000000..247b7d1742b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/dom/nodes/insert-adjacent.html
@@ -0,0 +1,79 @@
+<!doctype html>
+<meta charset="utf-8">
+<title></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+#element {
+ display: none;
+}
+</style>
+
+<div id="element"></div>
+<div id="log"></div>
+
+<script>
+var possiblePositions = {
+ 'beforebegin': 'previousSibling'
+ , 'afterbegin': 'firstChild'
+ , 'beforeend': 'lastChild'
+ , 'afterend': 'nextSibling'
+}
+var texts = {
+ 'beforebegin': 'raclette'
+ , 'afterbegin': 'tartiflette'
+ , 'beforeend': 'lasagne'
+ , 'afterend': 'gateau aux pommes'
+}
+
+var el = document.querySelector('#element');
+
+Object.keys(possiblePositions).forEach(function(position) {
+ var div = document.createElement('h3');
+ test(function() {
+ div.id = texts[position];
+ el.insertAdjacentElement(position, div);
+ assert_equals(el[possiblePositions[position]].id, texts[position]);
+ }, 'insertAdjacentElement(' + position + ', ' + div + ' )');
+
+ test(function() {
+ el.insertAdjacentText(position, texts[position]);
+ assert_equals(el[possiblePositions[position]].textContent, texts[position]);
+ }, 'insertAdjacentText(' + position + ', ' + texts[position] + ' )');
+});
+
+test(function() {
+ assert_throws(new TypeError(), function() {
+ el.insertAdjacentElement('afterbegin',
+ document.implementation.createDocumentType("html"))
+ })
+}, 'invalid object argument insertAdjacentElement')
+test(function() {
+ var el = document.implementation.createHTMLDocument().documentElement;
+ assert_throws("HIERARCHY_REQUEST_ERR", function() {
+ el.insertAdjacentElement('beforebegin', document.createElement('banane'))
+ })
+}, 'invalid caller object insertAdjacentElement')
+test(function() {
+ var el = document.implementation.createHTMLDocument().documentElement;
+ assert_throws("HIERARCHY_REQUEST_ERR", function() {
+ el.insertAdjacentText('beforebegin', 'tomate farcie')
+ })
+}, 'invalid caller object insertAdjacentText')
+test(function() {
+ var div = document.createElement('h3');
+ assert_throws("SYNTAX_ERR", function() {
+ el.insertAdjacentElement('heeeee', div)
+ })
+}, "invalid syntax for insertAdjacentElement")
+test(function() {
+ assert_throws("SYNTAX_ERR", function() {
+ el.insertAdjacentText('hoooo', 'magret de canard')
+ })
+}, "invalid syntax for insertAdjacentText")
+test(function() {
+ var div = document.createElement('div');
+ assert_equals(div.insertAdjacentElement("beforebegin", el), null);
+}, 'insertAdjacentText should return null');
+
+</script>