Skip to content

Commit

Permalink
New methods.
Browse files Browse the repository at this point in the history
       add <- appendChild, insertBefore
    remove <- removeChild
    parent <- parentNode
     child <- firstChild, lastChild, childNodes[i]
  previous <- previousSibling
      next <- nextSibling
        on <- addEventListener
       off <- removeEventListener

Also, n$(string) will create an "offscreen" element, and n$(null) will return
null. This commit also rewrites the NNS to use traditional JavaScript prototypes
to avoid creating any per-instance closures. This seems prudent given that NNS
objects should be cheap to create. A minimized version of nns.js is also
included.
  • Loading branch information
Mike Bostock committed Jul 16, 2010
1 parent c210c5f commit 64cd2e0
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 28 deletions.
13 changes: 13 additions & 0 deletions Makefile
@@ -0,0 +1,13 @@
JS_COMPILER = \
java -jar /Library/Google/Compiler/compiler-20100201.jar \
--charset UTF-8

all: nns.min.js

nns.min.js: nns.js Makefile
rm -f $@
$(JS_COMPILER) < nns.js >> $@
chmod a-w $@

clean:
rm nns.min.js
111 changes: 83 additions & 28 deletions nns.js
@@ -1,14 +1,61 @@
function n$(e) {
var n$ = (function() {

var o = {
add: function(n) {
n = n$.qualify(n);
return n$(e.appendChild(n.space == null
? document.createElement(n.local)
: document.createElementNS(n.space, n.local)));
function create(n) {
n = qualify(n);
return n.space == null
? document.createElement(n.local)
: document.createElementNS(n.space, n.local);
}

function qualify(n) {
var i = n.indexOf(":");
return {
space: n$.prefix[n.substring(0, i)],
local: n.substring(i + 1)
};
}

function $n(o) {
return o && o.element || o;
}

function N$(e) {
this.element = e;
}

N$.prototype = {

add: function(c, s) {
return n$($n(this).insertBefore(
typeof c == "string" ? create(c) : $n(c),
arguments.length == 1 ? null : $n(s)));
},

remove: function(c) {
$n(this).removeChild($n(c));
return this;
},

parent: function() {
return n$($n(this).parentNode);
},

child: function(i) {
var children = $n(this).childNodes;
return n$(children[i < 0 ? children.length - i - 1 : i]);
},

previous: function() {
return n$($n(this).previousSibling);
},

next: function() {
return n$($n(this).nextSibling);
},

attr: function(n, v) {
n = n$.qualify(n);
var e = $n(this);
n = qualify(n);
if (arguments.length == 1) {
return n.space == null
? e.getAttribute(n.local)
Expand All @@ -21,34 +68,42 @@ function n$(e) {
if (v == null) e.removeAttributeNS(n.space, n.local);
else e.setAttributeNS(n.space, n.local, v);
}
return o;
return this;
},

style: function(n, v, p) {
if (arguments.length == 1) return e.style.getPropertyValue(n);
if (v == null) e.style.removeProperty(n);
else e.style.setProperty(n, v, arguments.length == 3 ? p : null);
return o;
var style = $n(this).style;
if (arguments.length == 1) return style.getPropertyValue(n);
if (v == null) style.removeProperty(n);
else style.setProperty(n, v, arguments.length == 3 ? p : null);
return this;
},

on: function(t, l, c) {
$n(this).addEventListener(t, l, arguments.length == 3 ? c : false);
return this;
},

off: function(t, l, c) {
$n(this).removeEventListener(t, l, arguments.length == 3 ? c : false);
return this;
},

text: function(v) {
var t = e.firstChild;
var t = $n(this).firstChild;
if (!arguments.length) return t && t.nodeValue;
if (t) t.nodeValue = v;
else if (v != null) t = e.appendChild(document.createTextNode(v));
return o;
},
element: e
};
else if (v != null) t = $n(this).appendChild(document.createTextNode(v));
return this;
}
}

return o;
}
function n$(e) {
return e == null || e.element ? e : new N$(typeof e == "string" ? create(e) : e);
}

n$.qualify = function(n) {
var i = n.indexOf(":");
return {
space: n$.prefix[n.substring(0, i)],
local: n.substring(i + 1)
};
};
return n$;
})();

n$.prefix = {
svg: "http://www.w3.org/2000/svg",
Expand Down
4 changes: 4 additions & 0 deletions nns.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions tests/null.html
@@ -0,0 +1,43 @@
<html>
<head>
<script type="text/javascript" src="../nns.js"></script>
</head>
<body>
<script type="text/javascript">

var svg = n$(document.body).add("svg:svg")
.attr("width", 200)
.attr("height", 200)
.style("font", "12pt Helvetica Neue")
.style("text-rendering", "optimizeLegibility");

svg.add("svg:rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "none")
.attr("stroke", "black");

svg.add("svg:text")
.attr("x", "50%")
.attr("y", "25%")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text("n$(null): " + (n$(null) === null ? "PASS" : "FAIL"));

svg.add("svg:text")
.attr("x", "50%")
.attr("y", "50%")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text("n$(undefined): " + (n$(undefined) === undefined ? "PASS" : "FAIL"));

svg.add("svg:text")
.attr("x", "50%")
.attr("y", "75%")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text("n$(): " + (n$() == undefined ? "PASS" : "FAIL"));

</script>
</body>
</html>
31 changes: 31 additions & 0 deletions tests/offscreen.html
@@ -0,0 +1,31 @@
<html>
<head>
<script type="text/javascript" src="../nns.js"></script>
</head>
<body>
<script type="text/javascript">

var svg = n$(document.body).add("svg:svg")
.attr("width", 200)
.attr("height", 200)
.style("font", "36pt Helvetica Neue")
.style("text-rendering", "optimizeLegibility");

svg.add("svg:rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "none")
.attr("stroke", "black");

var text = n$("svg:text")
.attr("x", "50%")
.attr("y", "50%")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text("PASS");

svg.add(text);

</script>
</body>
</html>
36 changes: 36 additions & 0 deletions tests/resolve.html
@@ -0,0 +1,36 @@
<html>
<head>
<script type="text/javascript" src="../nns.js"></script>
</head>
<body>
<script type="text/javascript">

var svg = n$(document.body).add("svg:svg")
.attr("width", 200)
.attr("height", 200)
.style("font", "24pt Helvetica Neue")
.style("text-rendering", "optimizeLegibility");

svg.add("svg:rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "none")
.attr("stroke", "black");

n$(svg).add("svg:text")
.attr("x", "50%")
.attr("y", "33%")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text("PASS");

svg.add(n$("svg:text"))
.attr("x", "50%")
.attr("y", "67%")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text("PASS");

</script>
</body>
</html>

0 comments on commit 64cd2e0

Please sign in to comment.