diff --git a/README.md b/README.md index 5a01568..6e923e5 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,50 @@ Note that the `:nth-child` pseudo-class is a one-based index rather than a zero- The returned selection may not preserve the index of the original selection, as some elements may be removed; you can use [*selection*.select](#selection_select) to preserve the index, if needed. +# d3.matcher(selector) + +Given the specified *selector*, returns a function which returns true if `this` element [matches](https://developer.mozilla.org/en-US/docs/Web/API/Element/matches) the specified selector. This method is used internally by [*selection*.filter](#selection_filter). For example, this: + +```js +var div = selection.filter("div"); +``` + +Is equivalent to: + +```js +var div = selection.filter(d3.matcher("div")); +``` + +(Although D3 is not a compatibility layer, this implementation does support vendor-prefixed implementations due to the recent standardization of *element*.matches.) + +# d3.selector(selector) + +Given the specified *selector*, returns a function which returns the first descendant of `this` element that matches the specified selector. This method is used internally by [*selection*.select](#selection_select). For example, this: + +```js +var div = selection.select("div"); +``` + +Is equivalent to: + +```js +var div = selection.select(d3.selector("div")); +``` + +# d3.selectorAll(selector) + +Given the specified *selector*, returns a function which returns all descendants of `this` element that match the specified selector. This method is used internally by [*selection*.selectAll](#selection_selectAll). For example, this: + +```js +var div = selection.selectAll("div"); +``` + +Is equivalent to: + +```js +var div = selection.selectAll(d3.selectorAll("div")); +``` + ### Modifying Elements After selecting elements, use the selection’s transformation methods to affect document content. Selection methods return the current selection, allowing the concise application of multiple methods on a given selection via method chaining. For example, to set the name attribute and color style of an anchor element: @@ -274,6 +318,22 @@ selection.each(function() { }); ``` +# d3.creator(name) + +Given the specified element *name*, returns a function which creates an element of the given name, assuming that `this` is the parent element. This method is used internally by [*selection*.append](#selection_append) to create new elements. For example, this: + +```js +selection.append("div"); +``` + +Is equivalent to: + +```js +selection.append(d3.creator("div")); +``` + +See [namespace](#namespace) for details on supported namespace prefixes, such as for SVG elements. + ### Joining Data For an introduction to D3’s data joins, see [Thinking With Joins](http://bost.ocks.org/mike/join/). Also see the [General Update Pattern](http://bl.ocks.org/mbostock/3808218) examples. diff --git a/index.js b/index.js index 0d66fbb..5829784 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,13 @@ +export {default as creator} from "./src/creator"; +export {default as matcher} from "./src/matcher"; export {default as mouse} from "./src/mouse"; export {default as namespace} from "./src/namespace"; export {default as namespaces} from "./src/namespaces"; export {default as select} from "./src/select"; export {default as selectAll} from "./src/selectAll"; export {default as selection} from "./src/selection/index"; +export {default as selector} from "./src/selector"; +export {default as selectorAll} from "./src/selectorAll"; export {default as touch} from "./src/touch"; export {default as touches} from "./src/touches"; export {event} from "./src/selection/on"; diff --git a/package.json b/package.json index e2e0cdd..d1bfba5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "d3-selection", - "version": "0.6.6", + "version": "0.6.7", "description": "Data-driven DOM manipulation: select elements and join them to data.", "keywords": [ "d3", diff --git a/test/creator-test.js b/test/creator-test.js new file mode 100644 index 0000000..a530fd6 --- /dev/null +++ b/test/creator-test.js @@ -0,0 +1,24 @@ +var tape = require("tape"), + jsdom = require("jsdom"), + d3 = require("../"); + +tape("d3.creator(name).call(element) returns a new element with the given name", function(test) { + var document = jsdom.jsdom(""); + test.deepEqual(type(d3.creator("h1").call(document.body)), {namespace: "http://www.w3.org/1999/xhtml", name: "H1"}); + test.deepEqual(type(d3.creator("xhtml:h1").call(document.body)), {namespace: "http://www.w3.org/1999/xhtml", name: "H1"}); + test.deepEqual(type(d3.creator("svg").call(document.body)), {namespace: "http://www.w3.org/2000/svg", name: "svg"}); + test.deepEqual(type(d3.creator("g").call(document.body)), {namespace: "http://www.w3.org/1999/xhtml", name: "G"}); + test.end(); +}); + +tape("d3.creator(name).call(element) can inherit the namespace from the given element", function(test) { + var document = jsdom.jsdom(""), + svg = document.querySelector("svg"); + test.deepEqual(type(d3.creator("g").call(document.body)), {namespace: "http://www.w3.org/1999/xhtml", name: "G"}); + test.deepEqual(type(d3.creator("g").call(svg)), {namespace: "http://www.w3.org/2000/svg", name: "g"}); + test.end(); +}); + +function type(element) { + return {namespace: element.namespaceURI, name: element.tagName}; +} diff --git a/test/matcher-test.js b/test/matcher-test.js new file mode 100644 index 0000000..9bc9af3 --- /dev/null +++ b/test/matcher-test.js @@ -0,0 +1,13 @@ +var tape = require("tape"), + jsdom = require("jsdom"), + d3 = require("../"); + +tape("d3.matcher(selector).call(element) returns true if the element matches the selector", function(test) { + var document = jsdom.jsdom(""); + test.equal(d3.matcher("body").call(document.body), true); + test.equal(d3.matcher(".foo").call(document.body), true); + test.equal(d3.matcher("body.foo").call(document.body), true); + test.equal(d3.matcher("h1").call(document.body), false); + test.equal(d3.matcher("body.bar").call(document.body), false); + test.end(); +}); diff --git a/test/selector-test.js b/test/selector-test.js new file mode 100644 index 0000000..b828579 --- /dev/null +++ b/test/selector-test.js @@ -0,0 +1,13 @@ +var tape = require("tape"), + jsdom = require("jsdom"), + d3 = require("../"); + +tape("d3.selector(selector).call(element) returns the first element that matches the selector", function(test) { + var document = jsdom.jsdom(""); + test.equal(d3.selector("body").call(document.documentElement), document.body); + test.equal(d3.selector(".foo").call(document.documentElement), document.body); + test.equal(d3.selector("body.foo").call(document.documentElement), document.body); + test.equal(d3.selector("h1").call(document.documentElement), null); + test.equal(d3.selector("body.bar").call(document.documentElement), null); + test.end(); +}); diff --git a/test/selectorAll-test.js b/test/selectorAll-test.js new file mode 100644 index 0000000..9b4d7fd --- /dev/null +++ b/test/selectorAll-test.js @@ -0,0 +1,17 @@ +var tape = require("tape"), + jsdom = require("jsdom"), + d3 = require("../"); + +tape("d3.selectorAll(selector).call(element) returns all elements that match the selector", function(test) { + var document = jsdom.jsdom("
"), + body = document.body, + div = document.querySelector("div"); + test.deepEqual(d3.selectorAll("body").call(document.documentElement), [body]); + test.deepEqual(d3.selectorAll(".foo").call(document.documentElement), [body, div]); + test.deepEqual(d3.selectorAll("div.foo").call(document.documentElement), [div]); + test.deepEqual(d3.selectorAll("div").call(document.documentElement), [div]); + test.deepEqual(d3.selectorAll("div,body").call(document.documentElement), [body,div]); + test.deepEqual(d3.selectorAll("h1").call(document.documentElement), []); + test.deepEqual(d3.selectorAll("body.bar").call(document.documentElement), []); + test.end(); +});