diff --git a/README.md b/README.md index b8513c6..7127c9a 100644 --- a/README.md +++ b/README.md @@ -398,6 +398,14 @@ In both cases, this method returns a new selection containing the appended eleme The specified *name* may have a namespace prefix, such as `svg:text` to specify a `text` attribute in the SVG namespace. See [namespaces](#namespaces) for the map of supported namespaces; additional namespaces can be registered by adding to the map. If no namespace is specified, the namespace will be inherited from the parent element; or, if the name is one of the known prefixes, the corresponding namespace will be used (for example, `svg` implies `svg:svg`). +# selection.insertAfter(type) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/insert.js) + +Shorthand for inserting a new element after each of the current selection’s nodes. + +# selection.insertBefore(type) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/insert.js) + +Shorthand for inserting a new element before each of the current selection’s nodes. + # selection.remove() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/remove.js) Removes the selected elements from the document. Returns this selection (the removed elements) which are now detached from the DOM. There is not currently a dedicated API to add removed elements back to the document; however, you can pass a function to [*selection*.append](#selection_append) or [*selection*.insert](#selection_insert) to re-add elements. diff --git a/src/selection/insert.js b/src/selection/insert.js index bccdaf3..ff4353d 100644 --- a/src/selection/insert.js +++ b/src/selection/insert.js @@ -5,16 +5,8 @@ function constantNull() { return null; } -function selectThis() { - return this; -} - -function selectNextSibling() { - return this.nextSibling; -} - -export default function(name, before) { - var create = typeof name === "function" ? name : creator(name), +export default function insert(name, before) { + const create = typeof name === "function" ? name : creator(name), select = before == null ? constantNull : typeof before === "function" ? before : selector(before); return this.select(function() { return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); @@ -22,9 +14,15 @@ export default function(name, before) { } export function insertBefore(name) { - return this.insert(name, selectThis); + const create = typeof name === "function" ? name : creator(name); + return this.select(function() { + return this.parentNode.insertBefore(create.apply(this, arguments), this); + }); } export function insertAfter(name) { - return this.insert(name, selectNextSibling); + const create = typeof name === "function" ? name : creator(name); + return this.select(function() { + return this.parentNode.insertBefore(create.apply(this, arguments), this.nextSibling); + }); } diff --git a/test/selection/insertAfter-test.js b/test/selection/insertAfter-test.js new file mode 100644 index 0000000..2e849b7 --- /dev/null +++ b/test/selection/insertAfter-test.js @@ -0,0 +1,24 @@ +import assert from "assert"; +import {selectAll} from "../../src/index.js"; +import {assertSelection} from "../asserts.js"; +import it from "../jsdom.js"; + +it("selection.insertAfter(name) inserts a new element of the specified name after each selected element", "
one
two
", () => { + const one = document.querySelector("#one"); + const two = document.querySelector("#two"); + const selection = selectAll([one, two]).data([1, 2]).insertAfter("span").text(function(d) { return `(after ${d})`; }); + const three = document.querySelector("span:nth-child(2)"); + const four = document.querySelector("span:last-child"); + assertSelection(selection, {groups: [[three, four]], parents: [null]}); + assert.equal(document.querySelector("div").textContent, "one(after 1)two(after 2)"); +}); + +it("selection.insertAfter(function) inserts the returned element after each selected element", "
one
two
", () => { + const one = document.querySelector("#one"); + const two = document.querySelector("#two"); + const selection = selectAll([one, two]).data([1, 2]).insertAfter(function(d) { const a = document.createElement("SPAN"); a.textContent = `(after ${d})`; return a; }); + const three = document.querySelector("span:nth-child(2)"); + const four = document.querySelector("span:last-child"); + assertSelection(selection, {groups: [[three, four]], parents: [null]}); + assert.equal(document.querySelector("div").textContent, "one(after 1)two(after 2)"); +}); diff --git a/test/selection/insertBefore-test.js b/test/selection/insertBefore-test.js new file mode 100644 index 0000000..3649fa2 --- /dev/null +++ b/test/selection/insertBefore-test.js @@ -0,0 +1,24 @@ +import assert from "assert"; +import {selectAll} from "../../src/index.js"; +import {assertSelection} from "../asserts.js"; +import it from "../jsdom.js"; + +it("selection.insertBefore(name) inserts a new element of the specified name before each selected element", "
one
two
", () => { + const one = document.querySelector("#one"); + const two = document.querySelector("#two"); + const selection = selectAll([one, two]).data([1, 2]).insertBefore("span").text(function(d) { return `(before ${d})`; }); + const three = document.querySelector("span:first-child"); + const four = document.querySelector("span:nth-child(3)"); + assertSelection(selection, {groups: [[three, four]], parents: [null]}); + assert.equal(document.querySelector("div").textContent, "(before 1)one(before 2)two"); +}); + +it("selection.insertBefore(function) inserts the returned element before each selected element", "
one
two
", () => { + const one = document.querySelector("#one"); + const two = document.querySelector("#two"); + const selection = selectAll([one, two]).data([1, 2]).insertBefore(function(d) { const a = document.createElement("SPAN"); a.textContent = `(before ${d})`; return a; }); + const three = document.querySelector("span:first-child"); + const four = document.querySelector("span:nth-child(3)"); + assertSelection(selection, {groups: [[three, four]], parents: [null]}); + assert.equal(document.querySelector("div").textContent, "(before 1)one(before 2)two"); +});