Merge branch 'master' of http://github.com/mbostock/d3
This commit is contained in:
Коммит
87adc077b9
12
Makefile
12
Makefile
|
@ -94,8 +94,10 @@ d3.layout.js: \
|
|||
src/start.js \
|
||||
src/layout/layout.js \
|
||||
src/layout/chord.js \
|
||||
src/layout/force.js \
|
||||
src/layout/pie.js \
|
||||
src/layout/stack.js \
|
||||
src/layout/treemap.js \
|
||||
src/end.js
|
||||
|
||||
d3.geo.js: \
|
||||
|
@ -132,6 +134,9 @@ d3.geom.js: \
|
|||
src/geom/quadtree.js \
|
||||
src/end.js
|
||||
|
||||
tests: \
|
||||
tests/test-format.test
|
||||
|
||||
%.min.js: %.js Makefile
|
||||
@rm -f $@
|
||||
$(JS_COMPILER) --js $< --js_output_file $@
|
||||
|
@ -141,5 +146,12 @@ d3.js d3%.js: Makefile
|
|||
cat $(filter %.js,$^) > $@
|
||||
@chmod a-w $@
|
||||
|
||||
%.test: %.js %.out d3.js
|
||||
@/bin/echo -n "test: $* "
|
||||
@node $< > $*.actual
|
||||
@diff -U 3 $*.out $*.actual && rm -f $*.actual \
|
||||
&& echo '\033[1;32mPASS\033[0m' \
|
||||
|| echo test: $* '\033[1;31mFAIL\033[0m'
|
||||
|
||||
clean:
|
||||
rm -f d3*.js
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(function(){d3 = {version: "1.4.0"}; // semver
|
||||
(function(){d3 = {version: "1.5.1"}; // semver
|
||||
if (!Date.now) Date.now = function() {
|
||||
return +new Date();
|
||||
};
|
||||
|
@ -335,30 +335,45 @@ function d3_dispatch(type) {
|
|||
d3.format = function(specifier) {
|
||||
var match = d3_format_re.exec(specifier),
|
||||
fill = match[1] || " ",
|
||||
sign = d3_format_signs[match[3]] || d3_format_signs["-"],
|
||||
sign = match[3] || "",
|
||||
zfill = match[5],
|
||||
width = +match[6],
|
||||
comma = match[7],
|
||||
precision = match[8],
|
||||
type = match[9];
|
||||
if (precision) precision = precision.substring(1);
|
||||
if (zfill) fill = "0"; // TODO align = "=";
|
||||
if (zfill) {
|
||||
fill = "0"; // TODO align = "=";
|
||||
if (comma) width -= Math.floor((width - 1) / 4);
|
||||
}
|
||||
if (type == "d") precision = "0";
|
||||
return function(value) {
|
||||
var number = +value,
|
||||
negative = (number < 0) && (number = -number);
|
||||
negative = (number < 0) && (number = -number) ? "\u2212" : sign;
|
||||
|
||||
// Return the empty string for floats formatted as ints.
|
||||
if ((type == "d") && (number % 1)) return "";
|
||||
|
||||
// Convert the input value to the desired precision.
|
||||
if (precision) value = number.toFixed(precision);
|
||||
else value = "" + number;
|
||||
if (comma) {
|
||||
var i = value.lastIndexOf("."),
|
||||
f = i >= 0 ? value.substring(i) : (i = value.length, ""),
|
||||
t = [];
|
||||
while (i > 0) t.push(value.substring(i -= 3, i + 3));
|
||||
value = t.reverse().join(",") + f;
|
||||
}
|
||||
var length = (value = sign(negative, value)).length;
|
||||
|
||||
// If the fill character is 0, the sign and group is applied after the fill.
|
||||
if (zfill) {
|
||||
var length = value.length + negative.length;
|
||||
if (length < width) value = new Array(width - length + 1).join(fill) + value;
|
||||
if (comma) value = d3_format_group(value);
|
||||
value = negative + value;
|
||||
}
|
||||
|
||||
// Otherwise (e.g., space-filling), the sign and group is applied before.
|
||||
else {
|
||||
if (comma) value = d3_format_group(value);
|
||||
value = negative + value;
|
||||
var length = value.length;
|
||||
if (length < width) value = new Array(width - length + 1).join(fill) + value;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
};
|
||||
|
@ -366,11 +381,14 @@ d3.format = function(specifier) {
|
|||
// [[fill]align][sign][#][0][width][,][.precision][type]
|
||||
var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
|
||||
|
||||
var d3_format_signs = {
|
||||
"+": function(negative, value) { return (negative ? "\u2212" : "+") + value; },
|
||||
" ": function(negative, value) { return (negative ? "\u2212" : " ") + value; },
|
||||
"-": function(negative, value) { return negative ? "\u2212" + value : value; }
|
||||
};
|
||||
// Apply comma grouping for thousands.
|
||||
function d3_format_group(value) {
|
||||
var i = value.lastIndexOf("."),
|
||||
f = i >= 0 ? value.substring(i) : (i = value.length, ""),
|
||||
t = [];
|
||||
while (i > 0) t.push(value.substring(i -= 3, i + 3));
|
||||
return t.reverse().join(",") + f;
|
||||
}
|
||||
/*
|
||||
* TERMS OF USE - EASING EQUATIONS
|
||||
*
|
||||
|
|
375
d3.layout.js
375
d3.layout.js
|
@ -150,6 +150,200 @@ d3.layout.chord = function() {
|
|||
|
||||
return chord;
|
||||
};
|
||||
// A rudimentary force layout using Gauss-Seidel.
|
||||
d3.layout.force = function() {
|
||||
var force = {},
|
||||
event = d3.dispatch("tick"),
|
||||
size = [1, 1],
|
||||
alpha = .5,
|
||||
distance = 30,
|
||||
interval,
|
||||
nodes,
|
||||
links,
|
||||
distances;
|
||||
|
||||
function tick() {
|
||||
var n = distances.length,
|
||||
i, // current index
|
||||
o, // current link
|
||||
s, // current source
|
||||
t, // current target
|
||||
l, // current distance
|
||||
x, // x-distance
|
||||
y; // y-distance
|
||||
|
||||
// gauss-seidel relaxation
|
||||
for (i = 0; i < n; ++i) {
|
||||
o = distances[i];
|
||||
s = o.source;
|
||||
t = o.target;
|
||||
x = t.x - s.x;
|
||||
y = t.y - s.y;
|
||||
if (l = Math.sqrt(x * x + y * y)) {
|
||||
l = alpha / (o.distance * o.distance) * (l - distance * o.distance) / l;
|
||||
x *= l;
|
||||
y *= l;
|
||||
if (s.fixed) {
|
||||
if (t.fixed) continue;
|
||||
t.x -= x;
|
||||
t.y -= y;
|
||||
} else if (t.fixed) {
|
||||
s.x += x;
|
||||
s.y += y;
|
||||
} else {
|
||||
s.x += x;
|
||||
s.y += y;
|
||||
t.x -= x;
|
||||
t.y -= y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// simulated annealing, basically
|
||||
if ((alpha *= .99) < 1e-6) force.stop();
|
||||
|
||||
event.tick.dispatch({type: "tick"});
|
||||
}
|
||||
|
||||
force.on = function(type, listener) {
|
||||
event[type].add(listener);
|
||||
return force;
|
||||
};
|
||||
|
||||
force.nodes = function(x) {
|
||||
if (!arguments.length) return nodes;
|
||||
nodes = x;
|
||||
return force;
|
||||
};
|
||||
|
||||
force.links = function(x) {
|
||||
if (!arguments.length) return links;
|
||||
links = x;
|
||||
return force;
|
||||
};
|
||||
|
||||
force.size = function(x) {
|
||||
if (!arguments.length) return size;
|
||||
size = x;
|
||||
return force;
|
||||
};
|
||||
|
||||
force.distance = function(d) {
|
||||
if (!arguments.length) return distance;
|
||||
distance = d;
|
||||
return force;
|
||||
};
|
||||
|
||||
force.start = function() {
|
||||
var i,
|
||||
j,
|
||||
k,
|
||||
n = nodes.length,
|
||||
m = links.length,
|
||||
w = size[0],
|
||||
h = size[1],
|
||||
o;
|
||||
|
||||
var paths = [];
|
||||
for (i = 0; i < n; ++i) {
|
||||
o = nodes[i];
|
||||
o.x = o.x || Math.random() * w;
|
||||
o.y = o.y || Math.random() * h;
|
||||
o.fixed = 0;
|
||||
paths[i] = [];
|
||||
for (j = 0; j < n; ++j) {
|
||||
paths[i][j] = Infinity;
|
||||
}
|
||||
paths[i][i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < m; ++i) {
|
||||
o = links[i];
|
||||
paths[o.source][o.target] = 1;
|
||||
paths[o.target][o.source] = 1;
|
||||
o.source = nodes[o.source];
|
||||
o.target = nodes[o.target];
|
||||
}
|
||||
|
||||
// Floyd-Warshall
|
||||
for (k = 0; k < n; ++k) {
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = 0; j < n; ++j) {
|
||||
paths[i][j] = Math.min(paths[i][j], paths[i][k] + paths[k][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
distances = [];
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = i + 1; j < n; ++j) {
|
||||
distances.push({
|
||||
source: nodes[i],
|
||||
target: nodes[j],
|
||||
distance: paths[i][j] * paths[i][j]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
distances.sort(function(a, b) {
|
||||
return a.distance - b.distance;
|
||||
});
|
||||
|
||||
if (interval) clearInterval(interval);
|
||||
interval = setInterval(tick, 24);
|
||||
return force;
|
||||
};
|
||||
|
||||
force.resume = function() {
|
||||
alpha = .1;
|
||||
if (!interval) interval = setInterval(tick, 24);
|
||||
return force;
|
||||
};
|
||||
|
||||
force.stop = function() {
|
||||
interval = clearInterval(interval);
|
||||
return force;
|
||||
};
|
||||
|
||||
// use `node.call(force.drag)` to make nodes draggable
|
||||
force.drag = function() {
|
||||
var node, element;
|
||||
|
||||
this
|
||||
.on("mouseover", function(d) { d.fixed = true; })
|
||||
.on("mouseout", function(d) { if (d != node) d.fixed = false; })
|
||||
.on("mousedown", mousedown);
|
||||
|
||||
d3.select(window)
|
||||
.on("mousemove", mousemove)
|
||||
.on("mouseup", mouseup);
|
||||
|
||||
function mousedown(d) {
|
||||
(node = d).fixed = true;
|
||||
element = this;
|
||||
d3.event.preventDefault();
|
||||
}
|
||||
|
||||
function mousemove() {
|
||||
if (!node) return;
|
||||
var m = d3.svg.mouse(element);
|
||||
node.x = m[0];
|
||||
node.y = m[1];
|
||||
force.resume(); // restart annealing
|
||||
}
|
||||
|
||||
function mouseup() {
|
||||
if (!node) return;
|
||||
mousemove();
|
||||
node.fixed = false;
|
||||
node = element = null;
|
||||
}
|
||||
|
||||
return force;
|
||||
};
|
||||
|
||||
return force;
|
||||
};
|
||||
d3.layout.pie = function() {
|
||||
var value = Number,
|
||||
sort = null,
|
||||
|
@ -407,4 +601,185 @@ function d3_layout_stackMaxIndex(array) {
|
|||
function d3_layout_stackSum(p, d) {
|
||||
return p + d.y;
|
||||
}
|
||||
// Squarified Treemaps by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
|
||||
d3.layout.treemap = function() {
|
||||
var children = d3_layout_treemapChildren,
|
||||
value = d3_layout_treemapValue,
|
||||
round = Math.round,
|
||||
size = [1, 1]; // width, height
|
||||
|
||||
// Recursively compute the node depth and value.
|
||||
// Also converts the data representation into a standard tree structure.
|
||||
// Also sorts child nodes by descending value to optimize squarification.
|
||||
function sum(data, depth, nodes) {
|
||||
var datas = children.call(treemap, data, depth),
|
||||
node = {depth: depth, data: data};
|
||||
nodes.push(node);
|
||||
if (datas) {
|
||||
var i = -1,
|
||||
n = datas.length,
|
||||
c = node.children = [],
|
||||
v = 0,
|
||||
j = depth + 1;
|
||||
while (++i < n) {
|
||||
d = sum(datas[i], j, nodes);
|
||||
if (d.value > 0) { // ignore NaN, negative, etc.
|
||||
c.push(d);
|
||||
v += d.value;
|
||||
}
|
||||
}
|
||||
node.value = v;
|
||||
} else {
|
||||
node.value = value.call(treemap, data, depth);
|
||||
}
|
||||
if (!depth) scale(node, size[0] * size[1] / node.value); // root
|
||||
return node;
|
||||
}
|
||||
|
||||
// Recursively compute the node area based on value & scale.
|
||||
function scale(node, k) {
|
||||
var children = node.children;
|
||||
node.area = node.value * k;
|
||||
if (children) {
|
||||
var i = -1,
|
||||
n = children.length;
|
||||
while (++i < n) scale(children[i], k);
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively arranges the specified node's children into squarified rows.
|
||||
function squarify(node) {
|
||||
if (!node.children) return;
|
||||
var rect = {x: node.x, y: node.y, dx: node.dx, dy: node.dy},
|
||||
row = [],
|
||||
children = node.children.slice().sort(d3_layout_treemapSort),
|
||||
child,
|
||||
best = Infinity, // the best row score so far
|
||||
score, // the current row score
|
||||
u = Math.min(rect.dx, rect.dy), // initial orientation
|
||||
n;
|
||||
row.area = 0;
|
||||
while ((n = children.length) > 0) {
|
||||
row.push(child = children[n - 1]);
|
||||
row.area += child.area;
|
||||
if ((score = worst(row, u)) <= best) { // continue with this orientation
|
||||
children.pop();
|
||||
best = score;
|
||||
} else { // abort, and try a different orientation
|
||||
row.area -= row.pop().area;
|
||||
position(row, u, rect, false);
|
||||
u = Math.min(rect.dx, rect.dy);
|
||||
row.length = row.area = 0;
|
||||
best = Infinity;
|
||||
}
|
||||
}
|
||||
if (row.length) {
|
||||
position(row, u, rect, true);
|
||||
row.length = row.area = 0;
|
||||
}
|
||||
node.children.forEach(squarify);
|
||||
}
|
||||
|
||||
// Computes the score for the specified row, as the worst aspect ratio.
|
||||
function worst(row, u) {
|
||||
var s = row.area,
|
||||
r,
|
||||
rmax = 0,
|
||||
rmin = Infinity,
|
||||
i = -1,
|
||||
n = row.length;
|
||||
while (++i < n) {
|
||||
r = row[i].area;
|
||||
if (r < rmin) rmin = r;
|
||||
if (r > rmax) rmax = r;
|
||||
}
|
||||
s *= s;
|
||||
u *= u;
|
||||
return Math.max((u * rmax) / s, s / (u * rmin));
|
||||
}
|
||||
|
||||
// Positions the specified row of nodes. Modifies `rect`.
|
||||
function position(row, u, rect, flush) {
|
||||
var i = -1,
|
||||
n = row.length,
|
||||
x = rect.x,
|
||||
y = rect.y,
|
||||
v = u ? round(row.area / u) : 0,
|
||||
o;
|
||||
if (u == rect.dx) { // horizontal subdivision
|
||||
if (flush || v > rect.dy) v = rect.dy; // over+underflow
|
||||
while (++i < n) {
|
||||
o = row[i];
|
||||
o.x = x;
|
||||
o.y = y;
|
||||
o.dy = v;
|
||||
x += o.dx = round(o.area / v);
|
||||
}
|
||||
o.dx += rect.x + rect.dx - x; // rounding error
|
||||
rect.y += v;
|
||||
rect.dy -= v;
|
||||
} else { // vertical subdivision
|
||||
if (flush || v > rect.dx) v = rect.dx; // over+underflow
|
||||
while (++i < n) {
|
||||
o = row[i];
|
||||
o.x = x;
|
||||
o.y = y;
|
||||
o.dx = v;
|
||||
y += o.dy = round(o.area / v);
|
||||
}
|
||||
o.dy += rect.y + rect.dy - y; // rounding error
|
||||
rect.x += v;
|
||||
rect.dx -= v;
|
||||
}
|
||||
}
|
||||
|
||||
function treemap(d) {
|
||||
var nodes = [],
|
||||
root = sum(d, 0, nodes);
|
||||
root.x = 0;
|
||||
root.y = 0;
|
||||
root.dx = size[0];
|
||||
root.dy = size[1];
|
||||
squarify(root);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
treemap.children = function(x) {
|
||||
if (!arguments.length) return children;
|
||||
children = x;
|
||||
return treemap;
|
||||
};
|
||||
|
||||
treemap.value = function(x) {
|
||||
if (!arguments.length) return value;
|
||||
value = x;
|
||||
return treemap;
|
||||
};
|
||||
|
||||
treemap.size = function(x) {
|
||||
if (!arguments.length) return size;
|
||||
size = x;
|
||||
return treemap;
|
||||
};
|
||||
|
||||
treemap.round = function(x) {
|
||||
if (!arguments.length) return round != Number;
|
||||
round = x ? Math.round : Number;
|
||||
return treemap;
|
||||
};
|
||||
|
||||
return treemap;
|
||||
};
|
||||
|
||||
function d3_layout_treemapChildren(d) {
|
||||
return d.children;
|
||||
}
|
||||
|
||||
function d3_layout_treemapValue(d) {
|
||||
return d.value;
|
||||
}
|
||||
|
||||
function d3_layout_treemapSort(a, b) {
|
||||
return b.area - a.area;
|
||||
}
|
||||
})()
|
|
@ -1,7 +1,14 @@
|
|||
(function(){function A(a){return a.reduce(B,0)}function C(a){for(var j=1,f=0,c=a[0].y,i,e=a.length;j<e;++j)if((i=a[j].y)>c){f=j;c=i}return f}function B(a,j){return a+j.y}d3.layout={};d3.layout.chord=function(){function a(){var g={},l=[],t=d3.range(b),q=[],r,n,w,o,s;c=[];i=[];r=0;for(o=-1;++o<b;){n=0;for(s=-1;++s<b;)n+=e[o][s];l.push(n);q.push(d3.range(b));r+=n}k&&t.sort(function(x,u){return k(l[x],l[u])});m&&q.forEach(function(x,u){x.sort(function(D,E){return m(e[u][D],e[u][E])})});r=(2*Math.PI-h*
|
||||
b)/r;n=0;for(o=-1;++o<b;){w=n;for(s=-1;++s<b;){var v=t[o],y=q[o][s],z=e[v][y];g[v+"-"+y]={index:v,subindex:y,startAngle:n,endAngle:n+=z*r,value:z}}i.push({index:v,startAngle:w,endAngle:n,value:(n-w)/r});n+=h}for(o=-1;++o<b;)for(s=o-1;++s<b;){t=g[o+"-"+s];q=g[s+"-"+o];if(t.value||q.value)c.push({source:t,target:q})}p&&j()}function j(){c.sort(function(g,l){g=Math.min(g.source.value,g.target.value);l=Math.min(l.source.value,l.target.value);return p(g,l)})}var f={},c,i,e,b,h=0,k,m,p;f.matrix=function(g){if(!arguments.length)return e;
|
||||
b=(e=g)&&e.length;c=i=null;return f};f.padding=function(g){if(!arguments.length)return h;h=g;c=i=null;return f};f.sortGroups=function(g){if(!arguments.length)return k;k=g;c=i=null;return f};f.sortSubgroups=function(g){if(!arguments.length)return m;m=g;c=null;return f};f.sortChords=function(g){if(!arguments.length)return p;p=g;c&&j();return f};f.chords=function(){c||a();return c};f.groups=function(){i||a();return i};return f};d3.layout.pie=function(){function a(e){var b=+(typeof c=="function"?c.apply(this,
|
||||
arguments):c),h=(typeof i=="function"?i.apply(this,arguments):i)-c,k=d3.range(e.length);f!=null&&k.sort(function(g,l){return f(e[g],e[l])});var m=e.map(j);h/=m.reduce(function(g,l){return g+l},0);var p=k.map(function(g){return{value:d=m[g],startAngle:b,endAngle:b+=d*h}});return e.map(function(g,l){return p[k[l]]})}var j=Number,f=null,c=0,i=2*Math.PI;a.value=function(e){if(!arguments.length)return j;j=e;return a};a.sort=function(e){if(!arguments.length)return f;f=e;return a};a.startAngle=function(e){if(!arguments.length)return c;
|
||||
c=e;return a};a.endAngle=function(e){if(!arguments.length)return i;i=e;return a};return a};d3.layout.stack=function(){function a(c){var i=c.length,e=c[0].length,b,h,k,m=F[j](c);G[f](c,m);for(h=0;h<e;++h){b=1;for(k=c[m[0]][h].y0;b<i;++b)c[m[b]][h].y0=k+=c[m[b-1]][h].y}return c}var j="default",f="zero";a.order=function(c){if(!arguments.length)return j;j=c;return a};a.offset=function(c){if(!arguments.length)return f;f=c;return a};return a};var F={"inside-out":function(a){var j=a.length,f,c=a.map(C),
|
||||
i=a.map(A),e=d3.range(j).sort(function(p,g){return c[p]-c[g]}),b=0,h=0,k=[],m=[];for(a=0;a<j;a++){f=e[a];if(b<h){b+=i[f];k.push(f)}else{h+=i[f];m.push(f)}}return m.reverse().concat(k)},reverse:function(a){return d3.range(a.length).reverse()},"default":function(a){return d3.range(a.length)}},G={silhouette:function(a,j){var f=a.length,c=a[0].length,i=[],e=0,b,h,k;for(h=0;h<c;++h){for(k=b=0;b<f;b++)k+=a[b][h].y;if(k>e)e=k;i.push(k)}h=0;for(b=j[0];h<c;++h)a[b][h].y0=(e-i[h])/2},wiggle:function(a,j){var f=
|
||||
a.length,c=a[0],i=c.length,e,b,h,k,m,p=j[0],g,l,t,q,r,n;a[p][0].y0=r=n=0;for(b=1;b<i;++b){for(g=e=0;e<f;++e)g+=a[e][b].y;l=e=0;for(q=c[b].x-c[b-1].x;e<f;++e){h=0;k=j[e];for(t=(a[k][b].y-a[k][b-1].y)/(2*q);h<e;++h)t+=(a[m=j[h]][b].y-a[m][b-1].y)/q;l+=t*a[k][b].y}a[p][b].y0=r-=g?l/g*q:0;if(r<n)n=r}for(b=0;b<i;++b)a[p][b].y0-=n},zero:function(a,j){for(var f=0,c=a[0].length,i=j[0];f<c;++f)a[i][f].y0=0}}})();
|
||||
(function(){function A(c){return c.reduce(B,0)}function C(c){for(var h=1,n=0,i=c[0].y,o,l=c.length;h<l;++h)if((o=c[h].y)>i){n=h;i=o}return n}function B(c,h){return c+h.y}function D(c){return c.children}function E(c){return c.value}function F(c,h){return h.area-c.area}d3.layout={};d3.layout.chord=function(){function c(){var a={},j=[],f=d3.range(g),s=[],t,k,q,r,u;i=[];o=[];t=0;for(r=-1;++r<g;){k=0;for(u=-1;++u<g;)k+=l[r][u];j.push(k);s.push(d3.range(g));t+=k}p&&f.sort(function(y,x){return p(j[y],j[x])});
|
||||
e&&s.forEach(function(y,x){y.sort(function(G,H){return e(l[x][G],l[x][H])})});t=(2*Math.PI-m*g)/t;k=0;for(r=-1;++r<g;){q=k;for(u=-1;++u<g;){var v=f[r],w=s[r][u],z=l[v][w];a[v+"-"+w]={index:v,subindex:w,startAngle:k,endAngle:k+=z*t,value:z}}o.push({index:v,startAngle:q,endAngle:k,value:(k-q)/t});k+=m}for(r=-1;++r<g;)for(u=r-1;++u<g;){f=a[r+"-"+u];s=a[u+"-"+r];if(f.value||s.value)i.push({source:f,target:s})}b&&h()}function h(){i.sort(function(a,j){a=Math.min(a.source.value,a.target.value);j=Math.min(j.source.value,
|
||||
j.target.value);return b(a,j)})}var n={},i,o,l,g,m=0,p,e,b;n.matrix=function(a){if(!arguments.length)return l;g=(l=a)&&l.length;i=o=null;return n};n.padding=function(a){if(!arguments.length)return m;m=a;i=o=null;return n};n.sortGroups=function(a){if(!arguments.length)return p;p=a;i=o=null;return n};n.sortSubgroups=function(a){if(!arguments.length)return e;e=a;i=null;return n};n.sortChords=function(a){if(!arguments.length)return b;b=a;i&&h();return n};n.chords=function(){i||c();return i};n.groups=
|
||||
function(){o||c();return o};return n};d3.layout.force=function(){function c(){var b=e.length,a,j,f,s,t,k,q;for(a=0;a<b;++a){j=e[a];f=j.source;s=j.target;k=s.x-f.x;q=s.y-f.y;if(t=Math.sqrt(k*k+q*q)){t=o/(j.distance*j.distance)*(t-l*j.distance)/t;k*=t;q*=t;if(f.fixed){if(!s.fixed){s.x-=k;s.y-=q}}else if(s.fixed){f.x+=k;f.y+=q}else{f.x+=k;f.y+=q;s.x-=k;s.y-=q}}}if((o*=0.99)<1.0E-6)h.stop();n.tick.dispatch({type:"tick"})}var h={},n=d3.dispatch("tick"),i=[1,1],o=0.5,l=30,g,m,p,e;h.on=function(b,a){n[b].add(a);
|
||||
return h};h.nodes=function(b){if(!arguments.length)return m;m=b;return h};h.links=function(b){if(!arguments.length)return p;p=b;return h};h.size=function(b){if(!arguments.length)return i;i=b;return h};h.distance=function(b){if(!arguments.length)return l;l=b;return h};h.start=function(){var b,a,j,f=m.length;j=p.length;var s=i[0],t=i[1],k=[];for(b=0;b<f;++b){a=m[b];a.x=a.x||Math.random()*s;a.y=a.y||Math.random()*t;a.fixed=0;k[b]=[];for(a=0;a<f;++a)k[b][a]=Infinity;k[b][b]=0}for(b=0;b<j;++b){a=p[b];
|
||||
k[a.source][a.target]=1;k[a.target][a.source]=1;a.source=m[a.source];a.target=m[a.target]}for(j=0;j<f;++j)for(b=0;b<f;++b)for(a=0;a<f;++a)k[b][a]=Math.min(k[b][a],k[b][j]+k[j][a]);e=[];for(b=0;b<f;++b)for(a=b+1;a<f;++a)e.push({source:m[b],target:m[a],distance:k[b][a]*k[b][a]});e.sort(function(q,r){return q.distance-r.distance});g&&clearInterval(g);g=setInterval(c,24);return h};h.resume=function(){o=0.1;g||(g=setInterval(c,24));return h};h.stop=function(){g=clearInterval(g);return h};h.drag=function(){function b(){if(a){var f=
|
||||
d3.svg.mouse(j);a.x=f[0];a.y=f[1];h.resume()}}var a,j;this.on("mouseover",function(f){f.fixed=true}).on("mouseout",function(f){if(f!=a)f.fixed=false}).on("mousedown",function(f){(a=f).fixed=true;j=this;d3.event.preventDefault()});d3.select(window).on("mousemove",b).on("mouseup",function(){if(a){b();a.fixed=false;a=j=null}});return h};return h};d3.layout.pie=function(){function c(l){var g=+(typeof i=="function"?i.apply(this,arguments):i),m=(typeof o=="function"?o.apply(this,arguments):o)-i,p=d3.range(l.length);
|
||||
n!=null&&p.sort(function(a,j){return n(l[a],l[j])});var e=l.map(h);m/=e.reduce(function(a,j){return a+j},0);var b=p.map(function(a){return{value:d=e[a],startAngle:g,endAngle:g+=d*m}});return l.map(function(a,j){return b[p[j]]})}var h=Number,n=null,i=0,o=2*Math.PI;c.value=function(l){if(!arguments.length)return h;h=l;return c};c.sort=function(l){if(!arguments.length)return n;n=l;return c};c.startAngle=function(l){if(!arguments.length)return i;i=l;return c};c.endAngle=function(l){if(!arguments.length)return o;
|
||||
o=l;return c};return c};d3.layout.stack=function(){function c(i){var o=i.length,l=i[0].length,g,m,p,e=I[h](i);J[n](i,e);for(m=0;m<l;++m){g=1;for(p=i[e[0]][m].y0;g<o;++g)i[e[g]][m].y0=p+=i[e[g-1]][m].y}return i}var h="default",n="zero";c.order=function(i){if(!arguments.length)return h;h=i;return c};c.offset=function(i){if(!arguments.length)return n;n=i;return c};return c};var I={"inside-out":function(c){var h=c.length,n,i=c.map(C),o=c.map(A),l=d3.range(h).sort(function(b,a){return i[b]-i[a]}),g=0,
|
||||
m=0,p=[],e=[];for(c=0;c<h;c++){n=l[c];if(g<m){g+=o[n];p.push(n)}else{m+=o[n];e.push(n)}}return e.reverse().concat(p)},reverse:function(c){return d3.range(c.length).reverse()},"default":function(c){return d3.range(c.length)}},J={silhouette:function(c,h){var n=c.length,i=c[0].length,o=[],l=0,g,m,p;for(m=0;m<i;++m){for(p=g=0;g<n;g++)p+=c[g][m].y;if(p>l)l=p;o.push(p)}m=0;for(g=h[0];m<i;++m)c[g][m].y0=(l-o[m])/2},wiggle:function(c,h){var n=c.length,i=c[0],o=i.length,l,g,m,p,e,b=h[0],a,j,f,s,t,k;c[b][0].y0=
|
||||
t=k=0;for(g=1;g<o;++g){for(a=l=0;l<n;++l)a+=c[l][g].y;j=l=0;for(s=i[g].x-i[g-1].x;l<n;++l){m=0;p=h[l];for(f=(c[p][g].y-c[p][g-1].y)/(2*s);m<l;++m)f+=(c[e=h[m]][g].y-c[e][g-1].y)/s;j+=f*c[p][g].y}c[b][g].y0=t-=a?j/a*s:0;if(t<k)k=t}for(g=0;g<o;++g)c[b][g].y0-=k},zero:function(c,h){for(var n=0,i=c[0].length,o=h[0];n<i;++n)c[o][n].y0=0}};d3.layout.treemap=function(){function c(e,b,a){var j=l.call(o,e,b),f={depth:b,data:e};a.push(f);if(j){e=-1;for(var s=j.length,t=f.children=[],k=0,q=b+1;++e<s;){d=c(j[e],
|
||||
q,a);if(d.value>0){t.push(d);k+=d.value}}f.value=k}else f.value=g.call(o,e,b);b||h(f,p[0]*p[1]/f.value);return f}function h(e,b){var a=e.children;e.area=e.value*b;if(a)for(var j=-1,f=a.length;++j<f;)h(a[j],b)}function n(e){if(e.children){var b={x:e.x,y:e.y,dx:e.dx,dy:e.dy},a=[],j=e.children.slice().sort(F),f,s=Infinity,t=Math.min(b.dx,b.dy);for(a.area=0;(f=j.length)>0;){a.push(f=j[f-1]);a.area+=f.area;f=t;for(var k=a.area,q=void 0,r=0,u=Infinity,v=-1,w=a.length;++v<w;){q=a[v].area;if(q<u)u=q;if(q>
|
||||
r)r=q}k*=k;f*=f;if((f=Math.max(f*r/k,k/(f*u)))<=s){j.pop();s=f}else{a.area-=a.pop().area;i(a,t,b,false);t=Math.min(b.dx,b.dy);a.length=a.area=0;s=Infinity}}if(a.length){i(a,t,b,true);a.length=a.area=0}e.children.forEach(n)}}function i(e,b,a,j){var f=-1,s=e.length,t=a.x,k=a.y,q=b?m(e.area/b):0,r;if(b==a.dx){if(j||q>a.dy)q=a.dy;for(;++f<s;){r=e[f];r.x=t;r.y=k;r.dy=q;t+=r.dx=m(r.area/q)}r.dx+=a.x+a.dx-t;a.y+=q;a.dy-=q}else{if(j||q>a.dx)q=a.dx;for(;++f<s;){r=e[f];r.x=t;r.y=k;r.dx=q;k+=r.dy=m(r.area/q)}r.dy+=
|
||||
a.y+a.dy-k;a.x+=q;a.dx-=q}}function o(e){var b=[];e=c(e,0,b);e.x=0;e.y=0;e.dx=p[0];e.dy=p[1];n(e);return b}var l=D,g=E,m=Math.round,p=[1,1];o.children=function(e){if(!arguments.length)return l;l=e;return o};o.value=function(e){if(!arguments.length)return g;g=e;return o};o.size=function(e){if(!arguments.length)return p;p=e;return o};o.round=function(e){if(!arguments.length)return m!=Number;m=e?Math.round:Number;return o};return o}})();
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
(function(){function ua(a){for(var b=-1,d=a.length,g=[];++b<d;)g.push(a[b]);return g}function v(a){return typeof a=="function"?a:function(){return a}}function C(a,b){return function(){var d=b.apply(a,arguments);return arguments.length?a:d}}function va(a){return a==null}function da(a){return a.replace(/(^\s+)|(\s+$)/g,"").replace(/\s+/g," ")}function ea(a){arguments[0]=this;a.apply(this,arguments);return this}function wa(){var a={},b=[];a.add=function(d){for(var g=0;g<b.length;g++)if(b[g].listener==
|
||||
d)return a;b.push({listener:d,on:true});return a};a.remove=function(d){for(var g=0;g<b.length;g++){var e=b[g];if(e.listener==d){e.on=false;b=b.slice(0,g).concat(b.slice(g+1));break}}return a};a.dispatch=function(){for(var d=b,g=0,e=d.length;g<e;g++){var c=d[g];c.on&&c.listener.apply(this,arguments)}};return a}function fa(a){return function(b){return 1-a(1-b)}}function ga(a){return function(b){return 0.5*(b<0.5?a(2*b):2-a(2-2*b))}}function xa(a){return a}function R(a){return function(b){return Math.pow(b,
|
||||
a)}}function ya(a){return 1-Math.cos(a*Math.PI/2)}function za(a){return a?Math.pow(2,10*(a-1))-0.0010:0}function Aa(a){return 1-Math.sqrt(1-a*a)}function Ba(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+0.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+0.9375:7.5625*(a-=2.625/2.75)*a+0.984375}function J(a,b,d){return{r:a,g:b,b:d,toString:Ca}}function Ca(){return"#"+S(this.r)+S(this.g)+S(this.b)}function S(a){return a<16?"0"+a.toString(16):a.toString(16)}function T(a,b,d){var g=0,e=0,c=0,f,h;
|
||||
if(f=/([a-z]+)\((.*)\)/i.exec(a)){h=f[2].split(",");switch(f[1]){case "hsl":return d(parseFloat(h[0]),parseFloat(h[1])/100,parseFloat(h[2])/100);case "rgb":return b(U(h[0]),U(h[1]),U(h[2]))}}if(d=G[a])return b(d.r,d.g,d.b);if(a!=null&&a.charAt(0)=="#"){if(a.length==4){g=a.charAt(1);g+=g;e=a.charAt(2);e+=e;c=a.charAt(3);c+=c}else if(a.length==7){g=a.substring(1,3);e=a.substring(3,5);c=a.substring(5,7)}g=parseInt(g,16);e=parseInt(e,16);c=parseInt(c,16)}return b(g,e,c)}function Da(a,b,d){var g=Math.min(a/=
|
||||
255,b/=255,d/=255),e=Math.max(a,b,d),c=e-g,f=(e+g)/2;if(c){g=f<0.5?c/(e+g):c/(2-e-g);a=a==e?(b-d)/c+(b<d?6:0):b==e?(d-a)/c+2:(a-b)/c+4;a*=60}else g=a=0;return V(a,g,f)}function U(a){var b=parseFloat(a);return a.charAt(a.length-1)=="%"?Math.round(b*2.55):b}function V(a,b,d){return{h:a,s:b,l:d,toString:Ea}}function Ea(){return"hsl("+this.h+","+this.s*100+"%,"+this.l*100+"%)"}function W(a,b,d){function g(f){if(f>360)f-=360;else if(f<0)f+=360;if(f<60)return e+(c-e)*f/60;if(f<180)return c;if(f<240)return e+
|
||||
(c-e)*(240-f)/60;return e}var e,c;a%=360;if(a<0)a+=360;b=b<0?0:b>1?1:b;d=d<0?0:d>1?1:d;c=d<=0.5?d*(1+b):d+b-d*b;e=2*d-c;return J(Math.round(g(a+120)*255),Math.round(g(a)*255),Math.round(g(a-120)*255))}function y(a){function b(e){for(var c=[],f,h,i,k,j=0,o=a.length;j<o;j++){i=a[j];c.push(f=[]);f.parentNode=i.parentNode;f.parentData=i.parentData;for(var p=0,m=i.length;p<m;p++)if(k=i[p]){f.push(h=e(k));if(h&&"__data__"in k)h.__data__=k.__data__}else f.push(null)}return y(c)}function d(e){for(var c=[],
|
||||
f,h,i,k=0,j=a.length;k<j;k++){h=a[k];for(var o=0,p=h.length;o<p;o++)if(i=h[o]){c.push(f=e(i));f.parentNode=i;f.parentData=i.__data__}}return y(c)}function g(e){for(var c=0,f=a.length;c<f;c++)for(var h=a[c],i=0,k=h.length;i<k;i++){var j=h[i];if(j)return e.call(j,j.__data__,i)}return null}a.select=function(e){return b(function(c){return D(e,c)})};a.selectAll=function(e){return d(function(c){return ha(e,c)})};a.filter=function(e){for(var c=[],f,h,i,k=0,j=a.length;k<j;k++){h=a[k];c.push(f=[]);f.parentNode=
|
||||
h.parentNode;f.parentData=h.parentData;for(var o=0,p=h.length;o<p;o++)if((i=h[o])&&e.call(i,i.__data__,o))f.push(i)}return y(c)};a.map=function(e){for(var c,f,h=0,i=a.length;h<i;h++){c=a[h];for(var k=0,j=c.length;k<j;k++)if(f=c[k])f.__data__=e.call(f,f.__data__,k)}return a};a.data=function(e,c){function f(m,n){var l=0,q=m.length,r=n.length,t=Math.min(q,r),u=Math.max(q,r),s=[],z=[],w=[],x,A;if(c){t={};u=[];var E;A=n.length;for(l=0;l<q;l++){E=c.call(x=m[l],x.__data__,l);if(E in t)w[A++]=m[l];else{t[E]=
|
||||
x;u.push(E)}}for(l=0;l<r;l++){if(x=t[E=c.call(n,A=n[l],l)]){x.__data__=A;s[l]=x;z[l]=w[l]=null}else{z[l]={__data__:A};s[l]=w[l]=null}delete t[E]}for(l=0;l<q;l++)if(u[l]in t)w[l]=m[l]}else{for(;l<t;l++){x=m[l];A=n[l];if(x){x.__data__=A;s[l]=x;z[l]=w[l]=null}else{z[l]={__data__:A};s[l]=w[l]=null}}for(;l<r;l++){z[l]={__data__:n[l]};s[l]=w[l]=null}for(;l<u;l++){w[l]=m[l];z[l]=s[l]=null}}z.parentNode=s.parentNode=w.parentNode=m.parentNode;z.parentData=s.parentData=w.parentData=m.parentData;h.push(z);i.push(s);
|
||||
k.push(w)}var h=[],i=[],k=[],j=-1,o=a.length,p;if(typeof e=="function")for(;++j<o;)f(p=a[j],e.call(p,p.parentData,j));else for(;++j<o;)f(p=a[j],e);j=y(i);j.enter=function(){return Fa(h)};j.exit=function(){return y(k)};return j};a.each=function(e){for(var c=0,f=a.length;c<f;c++)for(var h=a[c],i=0,k=h.length;i<k;i++){var j=h[i];j&&e.call(j,j.__data__,i)}return a};a.empty=function(){return!g(function(){return true})};a.node=function(){return g(function(){return this})};a.attr=function(e,c){function f(){this.removeAttribute(e)}
|
||||
function h(){this.removeAttributeNS(e.space,e.local)}function i(){this.setAttribute(e,c)}function k(){this.setAttributeNS(e.space,e.local,c)}function j(){var p=c.apply(this,arguments);p==null?this.removeAttribute(e):this.setAttribute(e,p)}function o(){var p=c.apply(this,arguments);p==null?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,p)}e=d3.ns.qualify(e);if(arguments.length<2)return g(e.local?function(){return this.getAttributeNS(e.space,e.local)}:function(){return this.getAttribute(e)});
|
||||
return a.each(c==null?e.local?h:f:typeof c=="function"?e.local?o:j:e.local?k:i)};a.classed=function(e,c){function f(){var j=this.className;k.lastIndex=0;if(!k.test(j))this.className=da(j+" "+e)}function h(){var j=da(this.className.replace(k," "));this.className=j.length?j:null}function i(){(c.apply(this,arguments)?f:h).call(this)}var k=RegExp("(^|\\s+)"+d3.requote(e)+"(\\s+|$)","g");if(arguments.length<2)return g(function(){k.lastIndex=0;return k.test(this.className)});return a.each(typeof c=="function"?
|
||||
i:c?f:h)};a.style=function(e,c,f){function h(){this.style.removeProperty(e)}function i(){this.style.setProperty(e,c,f)}function k(){var j=c.apply(this,arguments);j==null?this.style.removeProperty(e):this.style.setProperty(e,j,f)}if(arguments.length<3)f=null;if(arguments.length<2)return g(function(){return window.getComputedStyle(this,null).getPropertyValue(e)});return a.each(c==null?h:typeof c=="function"?k:i)};a.property=function(e,c){function f(){delete this[e]}function h(){this[e]=c}function i(){var k=
|
||||
c.apply(this,arguments);if(k==null)delete this[e];else this[e]=k}e=d3.ns.qualify(e);if(arguments.length<2)return g(function(){return this[e]});return a.each(c==null?f:typeof c=="function"?i:h)};a.text=function(e){function c(){this.appendChild(document.createTextNode(e))}function f(){var h=e.apply(this,arguments);h!=null&&this.appendChild(document.createTextNode(h))}if(arguments.length<1)return g(function(){return this.textContent});a.each(function(){for(;this.lastChild;)this.removeChild(this.lastChild)});
|
||||
return e==null?a:a.each(typeof e=="function"?f:c)};a.html=function(e){function c(){this.innerHTML=e}function f(){this.innerHTML=e.apply(this,arguments)}if(arguments.length<1)return g(function(){return this.innerHTML});return a.each(typeof e=="function"?f:c)};a.append=function(e){function c(h){return h.appendChild(document.createElement(e))}function f(h){return h.appendChild(document.createElementNS(e.space,e.local))}e=d3.ns.qualify(e);return b(e.local?f:c)};a.insert=function(e,c){function f(i){return i.insertBefore(document.createElement(e),
|
||||
D(c,i))}function h(i){return i.insertBefore(document.createElementNS(e.space,e.local),D(c,i))}e=d3.ns.qualify(e);return b(e.local?h:f)};a.remove=function(){return b(function(e){var c=e.parentNode;c.removeChild(e);return c})};a.sort=function(e){e=Ga.apply(this,arguments);for(var c=0,f=a.length;c<f;c++){var h=a[c];h.sort(e);for(var i=1,k=h.length,j=h[0];i<k;i++){var o=h[i];if(o){j&&j.parentNode.insertBefore(o,j.nextSibling);j=o}}}return a};a.on=function(e,c){var f=e.indexOf("."),h=f==-1?e:e.substring(0,
|
||||
f),i="__on"+e;return a.each(function(k,j){function o(p){var m=d3.event;d3.event=p;try{c.call(this,k,j)}finally{d3.event=m}}this[i]&&this.removeEventListener(h,this[i],false);if(c)this.addEventListener(h,this[i]=o,false)})};a.transition=function(){return X(a)};a.call=ea;return a}function Fa(a){function b(d){for(var g=[],e,c,f,h,i=0,k=a.length;i<k;i++){f=a[i];g.push(e=[]);e.parentNode=f.parentNode;e.parentData=f.parentData;for(var j=0,o=f.length;j<o;j++)if(h=f[j]){e.push(c=d(f.parentNode));c.__data__=
|
||||
h.__data__}else e.push(null)}return y(g)}a.append=function(d){function g(c){return c.appendChild(document.createElement(d))}function e(c){return c.appendChild(document.createElementNS(d.space,d.local))}d=d3.ns.qualify(d);return b(d.local?e:g)};a.insert=function(d,g){function e(f){return f.insertBefore(document.createElement(d),D(g,f))}function c(f){return f.insertBefore(document.createElementNS(d.space,d.local),D(g,f))}d=d3.ns.qualify(d);return b(d.local?c:e)};return a}function Ga(a){if(!arguments.length)a=
|
||||
d3.ascending;return function(b,d){return a(b&&b.__data__,d&&d.__data__)}}function X(a){function b(m){var n=true,l=-1;a.each(function(){if(i[++l]!=2){var q=(m-k[l])/j[l],r=this.__transition__,t,u,s=c[l];if(q<1){n=false;if(q<0)return}else q=1;if(i[l]){if(!r||r.active!=g){i[l]=2;return}}else if(!r||r.active>g){i[l]=2;return}else{i[l]=1;h.start.dispatch.apply(this,arguments);s=c[l]={};r.active=g;for(u in e)s[u]=e[u].apply(this,arguments)}t=p(q);for(u in e)s[u].call(this,t);if(q==1){i[l]=2;if(r.active==
|
||||
g){q=r.owner;if(q==g){delete this.__transition__;f&&this.parentNode.removeChild(this)}Y=g;h.end.dispatch.apply(this,arguments);Y=0;r.owner=q}}}});return n}var d={},g=Y||++Ha,e={},c=[],f=false,h=d3.dispatch("start","end"),i=[],k=[],j=[],o,p=d3.ease("cubic-in-out");a.each(function(){(this.__transition__||(this.__transition__={})).owner=g});d.delay=function(m){var n=Infinity,l=-1;if(typeof m=="function")a.each(function(){var q=k[++l]=+m.apply(this,arguments);if(q<n)n=q});else{n=+m;a.each(function(){k[++l]=
|
||||
n})}Ia(b,n);return d};d.duration=function(m){var n=-1;if(typeof m=="function"){o=0;a.each(function(){var l=j[++n]=+m.apply(this,arguments);if(l>o)o=l})}else{o=+m;a.each(function(){j[++n]=o})}return d};d.ease=function(m){p=typeof m=="string"?d3.ease(m):m;return d};d.attrTween=function(m,n){function l(r,t){var u=n.call(this,r,t,this.getAttribute(m));return function(s){this.setAttribute(m,u(s))}}function q(r,t){var u=n.call(this,r,t,this.getAttributeNS(m.space,m.local));return function(s){this.setAttributeNS(m.space,
|
||||
m.local,u(s))}}e["attr."+m]=m.local?q:l;return d};d.attr=function(m,n){return d.attrTween(m,ia(n))};d.styleTween=function(m,n,l){if(arguments.length<3)l=null;e["style."+m]=function(q,r){var t=n.call(this,q,r,window.getComputedStyle(this,null).getPropertyValue(m));return function(u){this.style.setProperty(m,t(u),l)}};return d};d.style=function(m,n,l){if(arguments.length<3)l=null;return d.styleTween(m,ia(n),l)};d.select=function(m){var n;m=X(a.select(m)).ease(p);n=-1;m.delay(function(){return k[++n]});
|
||||
n=-1;m.duration(function(){return j[++n]});return m};d.selectAll=function(m){var n;m=X(a.selectAll(m)).ease(p);n=-1;m.delay(function(l,q){return k[q?n:++n]});n=-1;m.duration(function(l,q){return j[q?n:++n]});return m};d.remove=function(){f=true;return d};d.each=function(m,n){h[m].add(n);return d};d.call=ea;return d.delay(0).duration(250)}function ia(a){return typeof a=="function"?function(b,d,g){return d3.interpolate(g,String(a.call(this,b,d)))}:(a=String(a),function(b,d,g){return d3.interpolate(g,
|
||||
a)})}function Ia(a,b){var d=Date.now(),g=false,e=d+b,c=F;if(isFinite(b)){for(;c;){if(c.callback==a){c.then=d;c.delay=b;g=true}else{var f=c.then+c.delay;if(f<e)e=f}c=c.next}g||(F={callback:a,then:d,delay:b,next:F});if(!K){clearTimeout(Z);Z=setTimeout(Ja,Math.max(24,e-d))}}}function Ja(){K=setInterval(Ka,24);Z=0}function Ka(){for(var a,b=Date.now(),d=F;d;){a=b-d.then;if(a>d.delay)d.flush=d.callback(a);d=d.next}a=null;for(b=F;b;)b=b.flush?a?a.next=b.next:F=b.next:(a=b).next;a||(K=clearInterval(K))}function La(a){return a.innerRadius}
|
||||
function Ma(a){return a.outerRadius}function ja(a){return a.startAngle}function ka(a){return a.endAngle}function $(a,b,d,g){var e=[],c=-1,f=b.length,h=typeof d=="function",i=typeof g=="function",k;if(h&&i)for(;++c<f;)e.push([d.call(a,k=b[c],c),g.call(a,k,c)]);else if(h)for(;++c<f;)e.push([d.call(a,b[c],c),g]);else if(i)for(;++c<f;)e.push([d,g.call(a,b[c],c)]);else for(;++c<f;)e.push([d,g]);return e}function la(a){return a[0]}function ma(a){return a[1]}function H(a){var b=[],d=0,g=a.length,e=a[0];
|
||||
for(b.push(e[0],",",e[1]);++d<g;)b.push("L",(e=a[d])[0],",",e[1]);return b.join("")}function na(a,b){if(b.length<1||a.length!=b.length&&a.length!=b.length+2)return H(a);var d=a.length!=b.length,g="",e=a[0],c=a[1],f=b[0],h=f,i=1;if(d){g+="Q"+(c[0]-f[0]*2/3)+","+(c[1]-f[1]*2/3)+","+c[0]+","+c[1];e=a[1];i=2}if(b.length>1){h=b[1];c=a[i];i++;g+="C"+(e[0]+f[0])+","+(e[1]+f[1])+","+(c[0]-h[0])+","+(c[1]-h[1])+","+c[0]+","+c[1];for(e=2;e<b.length;e++,i++){c=a[i];h=b[e];g+="S"+(c[0]-h[0])+","+(c[1]-h[1])+
|
||||
","+c[0]+","+c[1]}}if(d){d=a[i];g+="Q"+(c[0]+h[0]*2/3)+","+(c[1]+h[1]*2/3)+","+d[0]+","+d[1]}return g}function oa(a,b){for(var d=[],g=(1-b)/2,e=a[0],c=a[1],f=a[2],h=2,i=a.length;++h<i;){d.push([g*(f[0]-e[0]),g*(f[1]-e[1])]);e=c;c=f;f=a[h]}d.push([g*(f[0]-e[0]),g*(f[1]-e[1])]);return d}function B(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]}function L(a,b,d){a.push("C",B(pa,b),",",B(pa,d),",",B(qa,b),",",B(qa,d),",",B(M,b),",",B(M,d))}function Na(){return 0}function Oa(a){return a.source}function Pa(a){return a.target}
|
||||
function Qa(a){return a.radius}function Ra(){return 64}function Sa(){return"circle"}d3={version:"1.4.0"};if(!Date.now)Date.now=function(){return+new Date};if(!Object.create)Object.create=function(a){function b(){}b.prototype=a;return new b};var N=function(a){return Array.prototype.slice.call(a)};try{N(document.documentElement.childNodes)}catch(eb){N=ua}d3.ascending=function(a,b){return a<b?-1:a>b?1:0};d3.descending=function(a,b){return b<a?-1:b>a?1:0};d3.min=function(a,b){var d=0,g=a.length,e=a[0],
|
||||
c;if(arguments.length==1)for(;++d<g;){if(e>(c=a[d]))e=c}else for(e=b(a[0]);++d<g;)if(e>(c=b(a[d])))e=c;return e};d3.max=function(a,b){var d=0,g=a.length,e=a[0],c;if(arguments.length==1)for(;++d<g;){if(e<(c=a[d]))e=c}else for(e=b(e);++d<g;)if(e<(c=b(a[d])))e=c;return e};d3.nest=function(){function a(h,i){if(i>=g.length)return f?f.call(d,h):c?h.sort(c):h;for(var k=-1,j=h.length,o=g[i++],p,m,n={};++k<j;)if((p=o(m=h[k]))in n)n[p].push(m);else n[p]=[m];for(p in n)n[p]=a(n[p],i);return n}function b(h,i){if(i>=
|
||||
g.length)return h;var k=[],j=e[i++],o;for(o in h)k.push({key:o,values:b(h[o],i)});j&&k.sort(function(p,m){return j(p.key,m.key)});return k}var d={},g=[],e=[],c,f;d.map=function(h){return a(h,0)};d.entries=function(h){return b(a(h,0),0)};d.key=function(h){g.push(h);return d};d.sortKeys=function(h){e[g.length-1]=h;return d};d.sortValues=function(h){c=h;return d};d.rollup=function(h){f=h;return d};return d};d3.keys=function(a){var b=[],d;for(d in a)b.push(d);return b};d3.values=function(a){var b=[],
|
||||
d;for(d in a)b.push(a[d]);return b};d3.entries=function(a){var b=[],d;for(d in a)b.push({key:d,value:a[d]});return b};d3.merge=function(a){return Array.prototype.concat.apply([],a)};d3.split=function(a,b){var d=[],g=[],e,c=-1,f=a.length;if(arguments.length<2)b=va;for(;++c<f;)if(b.call(g,e=a[c],c))g=[];else{g.length||d.push(g);g.push(e)}return d};d3.range=function(a,b,d){if(arguments.length==1){b=a;a=0}if(d==null)d=1;if((b-a)/d==Infinity)throw Error("infinite range");var g=[],e=-1,c;if(d<0)for(;(c=
|
||||
a+d*++e)>b;)g.push(c);else for(;(c=a+d*++e)<b;)g.push(c);return g};d3.requote=function(a){return a.replace(Ta,"\\$&")};var Ta=/[\\\^\$\*\+\?\[\]\(\)\.\{\}]/g;d3.xhr=function(a,b,d){var g=new XMLHttpRequest;if(arguments.length<3)d=b;else b&&g.overrideMimeType(b);g.open("GET",a,true);g.onreadystatechange=function(){if(g.readyState==4)d(g.status<300?g:null)};g.send(null)};d3.text=function(a,b,d){if(arguments.length<3){d=b;b=null}d3.xhr(a,b,function(g){d(g&&g.responseText)})};d3.json=function(a,b){d3.text(a,
|
||||
"application/json",function(d){b(d?JSON.parse(d):null)})};d3.html=function(a,b){d3.text(a,"text/html",function(d){if(d!=null){var g=document.createRange();g.selectNode(document.body);d=g.createContextualFragment(d)}b(d)})};d3.xml=function(a,b,d){if(arguments.length<3){d=b;b=null}d3.xhr(a,b,function(g){d(g&&g.responseXML)})};d3.ns={prefix:{svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},
|
||||
qualify:function(a){var b=a.indexOf(":");return b<0?a:{space:d3.ns.prefix[a.substring(0,b)],local:a.substring(b+1)}}};d3.dispatch=function(){for(var a={},b,d=0,g=arguments.length;d<g;d++){b=arguments[d];a[b]=wa(b)}return a};d3.format=function(a){a=Ua.exec(a);var b=a[1]||" ",d=ra[a[3]]||ra["-"],g=a[5],e=+a[6],c=a[7],f=a[8],h=a[9];if(f)f=f.substring(1);if(g)b="0";if(h=="d")f="0";return function(i){i=+i;var k=i<0&&(i=-i);if(h=="d"&&i%1)return"";i=f?i.toFixed(f):""+i;if(c){for(var j=i.lastIndexOf("."),
|
||||
o=j>=0?i.substring(j):(j=i.length,""),p=[];j>0;)p.push(i.substring(j-=3,j+3));i=p.reverse().join(",")+o}k=(i=d(k,i)).length;if(k<e)i=Array(e-k+1).join(b)+i;return i}};var Ua=/(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,ra={"+":function(a,b){return(a?"−":"+")+b}," ":function(a,b){return(a?"−":" ")+b},"-":function(a,b){return a?"−"+b:b}},Va=R(2),Wa=R(3),Xa={linear:function(){return xa},poly:R,quad:function(){return Va},cubic:function(){return Wa},sin:function(){return ya},
|
||||
exp:function(){return za},circle:function(){return Aa},elastic:function(a,b){var d;if(arguments.length<2)b=0.45;if(arguments.length<1){a=1;d=b/4}else d=b/(2*Math.PI)*Math.asin(1/a);return function(g){return 1+a*Math.pow(2,10*-g)*Math.sin((g-d)*2*Math.PI/b)}},back:function(a){a||(a=1.70158);return function(b){return b*b*((a+1)*b-a)}},bounce:function(){return Ba}},Ya={"in":function(a){return a},out:fa,"in-out":ga,"out-in":function(a){return ga(fa(a))}};d3.ease=function(a){var b=a.indexOf("-"),d=b>=
|
||||
d)return a;b.push({listener:d,on:true});return a};a.remove=function(d){for(var g=0;g<b.length;g++){var e=b[g];if(e.listener==d){e.on=false;b=b.slice(0,g).concat(b.slice(g+1));break}}return a};a.dispatch=function(){for(var d=b,g=0,e=d.length;g<e;g++){var c=d[g];c.on&&c.listener.apply(this,arguments)}};return a}function fa(a){for(var b=a.lastIndexOf("."),d=b>=0?a.substring(b):(b=a.length,""),g=[];b>0;)g.push(a.substring(b-=3,b+3));return g.reverse().join(",")+d}function ga(a){return function(b){return 1-
|
||||
a(1-b)}}function ha(a){return function(b){return 0.5*(b<0.5?a(2*b):2-a(2-2*b))}}function xa(a){return a}function R(a){return function(b){return Math.pow(b,a)}}function ya(a){return 1-Math.cos(a*Math.PI/2)}function za(a){return a?Math.pow(2,10*(a-1))-0.0010:0}function Aa(a){return 1-Math.sqrt(1-a*a)}function Ba(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+0.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+0.9375:7.5625*(a-=2.625/2.75)*a+0.984375}function J(a,b,d){return{r:a,g:b,b:d,toString:Ca}}
|
||||
function Ca(){return"#"+S(this.r)+S(this.g)+S(this.b)}function S(a){return a<16?"0"+a.toString(16):a.toString(16)}function T(a,b,d){var g=0,e=0,c=0,f,h;if(f=/([a-z]+)\((.*)\)/i.exec(a)){h=f[2].split(",");switch(f[1]){case "hsl":return d(parseFloat(h[0]),parseFloat(h[1])/100,parseFloat(h[2])/100);case "rgb":return b(U(h[0]),U(h[1]),U(h[2]))}}if(d=G[a])return b(d.r,d.g,d.b);if(a!=null&&a.charAt(0)=="#"){if(a.length==4){g=a.charAt(1);g+=g;e=a.charAt(2);e+=e;c=a.charAt(3);c+=c}else if(a.length==7){g=
|
||||
a.substring(1,3);e=a.substring(3,5);c=a.substring(5,7)}g=parseInt(g,16);e=parseInt(e,16);c=parseInt(c,16)}return b(g,e,c)}function Da(a,b,d){var g=Math.min(a/=255,b/=255,d/=255),e=Math.max(a,b,d),c=e-g,f=(e+g)/2;if(c){g=f<0.5?c/(e+g):c/(2-e-g);a=a==e?(b-d)/c+(b<d?6:0):b==e?(d-a)/c+2:(a-b)/c+4;a*=60}else g=a=0;return V(a,g,f)}function U(a){var b=parseFloat(a);return a.charAt(a.length-1)=="%"?Math.round(b*2.55):b}function V(a,b,d){return{h:a,s:b,l:d,toString:Ea}}function Ea(){return"hsl("+this.h+","+
|
||||
this.s*100+"%,"+this.l*100+"%)"}function W(a,b,d){function g(f){if(f>360)f-=360;else if(f<0)f+=360;if(f<60)return e+(c-e)*f/60;if(f<180)return c;if(f<240)return e+(c-e)*(240-f)/60;return e}var e,c;a%=360;if(a<0)a+=360;b=b<0?0:b>1?1:b;d=d<0?0:d>1?1:d;c=d<=0.5?d*(1+b):d+b-d*b;e=2*d-c;return J(Math.round(g(a+120)*255),Math.round(g(a)*255),Math.round(g(a-120)*255))}function y(a){function b(e){for(var c=[],f,h,i,k,j=0,o=a.length;j<o;j++){i=a[j];c.push(f=[]);f.parentNode=i.parentNode;f.parentData=i.parentData;
|
||||
for(var p=0,m=i.length;p<m;p++)if(k=i[p]){f.push(h=e(k));if(h&&"__data__"in k)h.__data__=k.__data__}else f.push(null)}return y(c)}function d(e){for(var c=[],f,h,i,k=0,j=a.length;k<j;k++){h=a[k];for(var o=0,p=h.length;o<p;o++)if(i=h[o]){c.push(f=e(i));f.parentNode=i;f.parentData=i.__data__}}return y(c)}function g(e){for(var c=0,f=a.length;c<f;c++)for(var h=a[c],i=0,k=h.length;i<k;i++){var j=h[i];if(j)return e.call(j,j.__data__,i)}return null}a.select=function(e){return b(function(c){return D(e,c)})};
|
||||
a.selectAll=function(e){return d(function(c){return ia(e,c)})};a.filter=function(e){for(var c=[],f,h,i,k=0,j=a.length;k<j;k++){h=a[k];c.push(f=[]);f.parentNode=h.parentNode;f.parentData=h.parentData;for(var o=0,p=h.length;o<p;o++)if((i=h[o])&&e.call(i,i.__data__,o))f.push(i)}return y(c)};a.map=function(e){for(var c,f,h=0,i=a.length;h<i;h++){c=a[h];for(var k=0,j=c.length;k<j;k++)if(f=c[k])f.__data__=e.call(f,f.__data__,k)}return a};a.data=function(e,c){function f(m,n){var l=0,q=m.length,r=n.length,
|
||||
t=Math.min(q,r),u=Math.max(q,r),s=[],z=[],w=[],x,A;if(c){t={};u=[];var E;A=n.length;for(l=0;l<q;l++){E=c.call(x=m[l],x.__data__,l);if(E in t)w[A++]=m[l];else{t[E]=x;u.push(E)}}for(l=0;l<r;l++){if(x=t[E=c.call(n,A=n[l],l)]){x.__data__=A;s[l]=x;z[l]=w[l]=null}else{z[l]={__data__:A};s[l]=w[l]=null}delete t[E]}for(l=0;l<q;l++)if(u[l]in t)w[l]=m[l]}else{for(;l<t;l++){x=m[l];A=n[l];if(x){x.__data__=A;s[l]=x;z[l]=w[l]=null}else{z[l]={__data__:A};s[l]=w[l]=null}}for(;l<r;l++){z[l]={__data__:n[l]};s[l]=w[l]=
|
||||
null}for(;l<u;l++){w[l]=m[l];z[l]=s[l]=null}}z.parentNode=s.parentNode=w.parentNode=m.parentNode;z.parentData=s.parentData=w.parentData=m.parentData;h.push(z);i.push(s);k.push(w)}var h=[],i=[],k=[],j=-1,o=a.length,p;if(typeof e=="function")for(;++j<o;)f(p=a[j],e.call(p,p.parentData,j));else for(;++j<o;)f(p=a[j],e);j=y(i);j.enter=function(){return Fa(h)};j.exit=function(){return y(k)};return j};a.each=function(e){for(var c=0,f=a.length;c<f;c++)for(var h=a[c],i=0,k=h.length;i<k;i++){var j=h[i];j&&e.call(j,
|
||||
j.__data__,i)}return a};a.empty=function(){return!g(function(){return true})};a.node=function(){return g(function(){return this})};a.attr=function(e,c){function f(){this.removeAttribute(e)}function h(){this.removeAttributeNS(e.space,e.local)}function i(){this.setAttribute(e,c)}function k(){this.setAttributeNS(e.space,e.local,c)}function j(){var p=c.apply(this,arguments);p==null?this.removeAttribute(e):this.setAttribute(e,p)}function o(){var p=c.apply(this,arguments);p==null?this.removeAttributeNS(e.space,
|
||||
e.local):this.setAttributeNS(e.space,e.local,p)}e=d3.ns.qualify(e);if(arguments.length<2)return g(e.local?function(){return this.getAttributeNS(e.space,e.local)}:function(){return this.getAttribute(e)});return a.each(c==null?e.local?h:f:typeof c=="function"?e.local?o:j:e.local?k:i)};a.classed=function(e,c){function f(){var j=this.className;k.lastIndex=0;if(!k.test(j))this.className=da(j+" "+e)}function h(){var j=da(this.className.replace(k," "));this.className=j.length?j:null}function i(){(c.apply(this,
|
||||
arguments)?f:h).call(this)}var k=RegExp("(^|\\s+)"+d3.requote(e)+"(\\s+|$)","g");if(arguments.length<2)return g(function(){k.lastIndex=0;return k.test(this.className)});return a.each(typeof c=="function"?i:c?f:h)};a.style=function(e,c,f){function h(){this.style.removeProperty(e)}function i(){this.style.setProperty(e,c,f)}function k(){var j=c.apply(this,arguments);j==null?this.style.removeProperty(e):this.style.setProperty(e,j,f)}if(arguments.length<3)f=null;if(arguments.length<2)return g(function(){return window.getComputedStyle(this,
|
||||
null).getPropertyValue(e)});return a.each(c==null?h:typeof c=="function"?k:i)};a.property=function(e,c){function f(){delete this[e]}function h(){this[e]=c}function i(){var k=c.apply(this,arguments);if(k==null)delete this[e];else this[e]=k}e=d3.ns.qualify(e);if(arguments.length<2)return g(function(){return this[e]});return a.each(c==null?f:typeof c=="function"?i:h)};a.text=function(e){function c(){this.appendChild(document.createTextNode(e))}function f(){var h=e.apply(this,arguments);h!=null&&this.appendChild(document.createTextNode(h))}
|
||||
if(arguments.length<1)return g(function(){return this.textContent});a.each(function(){for(;this.lastChild;)this.removeChild(this.lastChild)});return e==null?a:a.each(typeof e=="function"?f:c)};a.html=function(e){function c(){this.innerHTML=e}function f(){this.innerHTML=e.apply(this,arguments)}if(arguments.length<1)return g(function(){return this.innerHTML});return a.each(typeof e=="function"?f:c)};a.append=function(e){function c(h){return h.appendChild(document.createElement(e))}function f(h){return h.appendChild(document.createElementNS(e.space,
|
||||
e.local))}e=d3.ns.qualify(e);return b(e.local?f:c)};a.insert=function(e,c){function f(i){return i.insertBefore(document.createElement(e),D(c,i))}function h(i){return i.insertBefore(document.createElementNS(e.space,e.local),D(c,i))}e=d3.ns.qualify(e);return b(e.local?h:f)};a.remove=function(){return b(function(e){var c=e.parentNode;c.removeChild(e);return c})};a.sort=function(e){e=Ga.apply(this,arguments);for(var c=0,f=a.length;c<f;c++){var h=a[c];h.sort(e);for(var i=1,k=h.length,j=h[0];i<k;i++){var o=
|
||||
h[i];if(o){j&&j.parentNode.insertBefore(o,j.nextSibling);j=o}}}return a};a.on=function(e,c){var f=e.indexOf("."),h=f==-1?e:e.substring(0,f),i="__on"+e;return a.each(function(k,j){function o(p){var m=d3.event;d3.event=p;try{c.call(this,k,j)}finally{d3.event=m}}this[i]&&this.removeEventListener(h,this[i],false);if(c)this.addEventListener(h,this[i]=o,false)})};a.transition=function(){return X(a)};a.call=ea;return a}function Fa(a){function b(d){for(var g=[],e,c,f,h,i=0,k=a.length;i<k;i++){f=a[i];g.push(e=
|
||||
[]);e.parentNode=f.parentNode;e.parentData=f.parentData;for(var j=0,o=f.length;j<o;j++)if(h=f[j]){e.push(c=d(f.parentNode));c.__data__=h.__data__}else e.push(null)}return y(g)}a.append=function(d){function g(c){return c.appendChild(document.createElement(d))}function e(c){return c.appendChild(document.createElementNS(d.space,d.local))}d=d3.ns.qualify(d);return b(d.local?e:g)};a.insert=function(d,g){function e(f){return f.insertBefore(document.createElement(d),D(g,f))}function c(f){return f.insertBefore(document.createElementNS(d.space,
|
||||
d.local),D(g,f))}d=d3.ns.qualify(d);return b(d.local?c:e)};return a}function Ga(a){if(!arguments.length)a=d3.ascending;return function(b,d){return a(b&&b.__data__,d&&d.__data__)}}function X(a){function b(m){var n=true,l=-1;a.each(function(){if(i[++l]!=2){var q=(m-k[l])/j[l],r=this.__transition__,t,u,s=c[l];if(q<1){n=false;if(q<0)return}else q=1;if(i[l]){if(!r||r.active!=g){i[l]=2;return}}else if(!r||r.active>g){i[l]=2;return}else{i[l]=1;h.start.dispatch.apply(this,arguments);s=c[l]={};r.active=g;
|
||||
for(u in e)s[u]=e[u].apply(this,arguments)}t=p(q);for(u in e)s[u].call(this,t);if(q==1){i[l]=2;if(r.active==g){q=r.owner;if(q==g){delete this.__transition__;f&&this.parentNode.removeChild(this)}Y=g;h.end.dispatch.apply(this,arguments);Y=0;r.owner=q}}}});return n}var d={},g=Y||++Ha,e={},c=[],f=false,h=d3.dispatch("start","end"),i=[],k=[],j=[],o,p=d3.ease("cubic-in-out");a.each(function(){(this.__transition__||(this.__transition__={})).owner=g});d.delay=function(m){var n=Infinity,l=-1;if(typeof m==
|
||||
"function")a.each(function(){var q=k[++l]=+m.apply(this,arguments);if(q<n)n=q});else{n=+m;a.each(function(){k[++l]=n})}Ia(b,n);return d};d.duration=function(m){var n=-1;if(typeof m=="function"){o=0;a.each(function(){var l=j[++n]=+m.apply(this,arguments);if(l>o)o=l})}else{o=+m;a.each(function(){j[++n]=o})}return d};d.ease=function(m){p=typeof m=="string"?d3.ease(m):m;return d};d.attrTween=function(m,n){function l(r,t){var u=n.call(this,r,t,this.getAttribute(m));return function(s){this.setAttribute(m,
|
||||
u(s))}}function q(r,t){var u=n.call(this,r,t,this.getAttributeNS(m.space,m.local));return function(s){this.setAttributeNS(m.space,m.local,u(s))}}e["attr."+m]=m.local?q:l;return d};d.attr=function(m,n){return d.attrTween(m,ja(n))};d.styleTween=function(m,n,l){if(arguments.length<3)l=null;e["style."+m]=function(q,r){var t=n.call(this,q,r,window.getComputedStyle(this,null).getPropertyValue(m));return function(u){this.style.setProperty(m,t(u),l)}};return d};d.style=function(m,n,l){if(arguments.length<
|
||||
3)l=null;return d.styleTween(m,ja(n),l)};d.select=function(m){var n;m=X(a.select(m)).ease(p);n=-1;m.delay(function(){return k[++n]});n=-1;m.duration(function(){return j[++n]});return m};d.selectAll=function(m){var n;m=X(a.selectAll(m)).ease(p);n=-1;m.delay(function(l,q){return k[q?n:++n]});n=-1;m.duration(function(l,q){return j[q?n:++n]});return m};d.remove=function(){f=true;return d};d.each=function(m,n){h[m].add(n);return d};d.call=ea;return d.delay(0).duration(250)}function ja(a){return typeof a==
|
||||
"function"?function(b,d,g){return d3.interpolate(g,String(a.call(this,b,d)))}:(a=String(a),function(b,d,g){return d3.interpolate(g,a)})}function Ia(a,b){var d=Date.now(),g=false,e=d+b,c=F;if(isFinite(b)){for(;c;){if(c.callback==a){c.then=d;c.delay=b;g=true}else{var f=c.then+c.delay;if(f<e)e=f}c=c.next}g||(F={callback:a,then:d,delay:b,next:F});if(!K){clearTimeout(Z);Z=setTimeout(Ja,Math.max(24,e-d))}}}function Ja(){K=setInterval(Ka,24);Z=0}function Ka(){for(var a,b=Date.now(),d=F;d;){a=b-d.then;if(a>
|
||||
d.delay)d.flush=d.callback(a);d=d.next}a=null;for(b=F;b;)b=b.flush?a?a.next=b.next:F=b.next:(a=b).next;a||(K=clearInterval(K))}function La(a){return a.innerRadius}function Ma(a){return a.outerRadius}function ka(a){return a.startAngle}function la(a){return a.endAngle}function $(a,b,d,g){var e=[],c=-1,f=b.length,h=typeof d=="function",i=typeof g=="function",k;if(h&&i)for(;++c<f;)e.push([d.call(a,k=b[c],c),g.call(a,k,c)]);else if(h)for(;++c<f;)e.push([d.call(a,b[c],c),g]);else if(i)for(;++c<f;)e.push([d,
|
||||
g.call(a,b[c],c)]);else for(;++c<f;)e.push([d,g]);return e}function ma(a){return a[0]}function na(a){return a[1]}function H(a){var b=[],d=0,g=a.length,e=a[0];for(b.push(e[0],",",e[1]);++d<g;)b.push("L",(e=a[d])[0],",",e[1]);return b.join("")}function oa(a,b){if(b.length<1||a.length!=b.length&&a.length!=b.length+2)return H(a);var d=a.length!=b.length,g="",e=a[0],c=a[1],f=b[0],h=f,i=1;if(d){g+="Q"+(c[0]-f[0]*2/3)+","+(c[1]-f[1]*2/3)+","+c[0]+","+c[1];e=a[1];i=2}if(b.length>1){h=b[1];c=a[i];i++;g+="C"+
|
||||
(e[0]+f[0])+","+(e[1]+f[1])+","+(c[0]-h[0])+","+(c[1]-h[1])+","+c[0]+","+c[1];for(e=2;e<b.length;e++,i++){c=a[i];h=b[e];g+="S"+(c[0]-h[0])+","+(c[1]-h[1])+","+c[0]+","+c[1]}}if(d){d=a[i];g+="Q"+(c[0]+h[0]*2/3)+","+(c[1]+h[1]*2/3)+","+d[0]+","+d[1]}return g}function pa(a,b){for(var d=[],g=(1-b)/2,e=a[0],c=a[1],f=a[2],h=2,i=a.length;++h<i;){d.push([g*(f[0]-e[0]),g*(f[1]-e[1])]);e=c;c=f;f=a[h]}d.push([g*(f[0]-e[0]),g*(f[1]-e[1])]);return d}function B(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]}
|
||||
function L(a,b,d){a.push("C",B(qa,b),",",B(qa,d),",",B(ra,b),",",B(ra,d),",",B(M,b),",",B(M,d))}function Na(){return 0}function Oa(a){return a.source}function Pa(a){return a.target}function Qa(a){return a.radius}function Ra(){return 64}function Sa(){return"circle"}d3={version:"1.5.1"};if(!Date.now)Date.now=function(){return+new Date};if(!Object.create)Object.create=function(a){function b(){}b.prototype=a;return new b};var N=function(a){return Array.prototype.slice.call(a)};try{N(document.documentElement.childNodes)}catch(eb){N=
|
||||
ua}d3.ascending=function(a,b){return a<b?-1:a>b?1:0};d3.descending=function(a,b){return b<a?-1:b>a?1:0};d3.min=function(a,b){var d=0,g=a.length,e=a[0],c;if(arguments.length==1)for(;++d<g;){if(e>(c=a[d]))e=c}else for(e=b(a[0]);++d<g;)if(e>(c=b(a[d])))e=c;return e};d3.max=function(a,b){var d=0,g=a.length,e=a[0],c;if(arguments.length==1)for(;++d<g;){if(e<(c=a[d]))e=c}else for(e=b(e);++d<g;)if(e<(c=b(a[d])))e=c;return e};d3.nest=function(){function a(h,i){if(i>=g.length)return f?f.call(d,h):c?h.sort(c):
|
||||
h;for(var k=-1,j=h.length,o=g[i++],p,m,n={};++k<j;)if((p=o(m=h[k]))in n)n[p].push(m);else n[p]=[m];for(p in n)n[p]=a(n[p],i);return n}function b(h,i){if(i>=g.length)return h;var k=[],j=e[i++],o;for(o in h)k.push({key:o,values:b(h[o],i)});j&&k.sort(function(p,m){return j(p.key,m.key)});return k}var d={},g=[],e=[],c,f;d.map=function(h){return a(h,0)};d.entries=function(h){return b(a(h,0),0)};d.key=function(h){g.push(h);return d};d.sortKeys=function(h){e[g.length-1]=h;return d};d.sortValues=function(h){c=
|
||||
h;return d};d.rollup=function(h){f=h;return d};return d};d3.keys=function(a){var b=[],d;for(d in a)b.push(d);return b};d3.values=function(a){var b=[],d;for(d in a)b.push(a[d]);return b};d3.entries=function(a){var b=[],d;for(d in a)b.push({key:d,value:a[d]});return b};d3.merge=function(a){return Array.prototype.concat.apply([],a)};d3.split=function(a,b){var d=[],g=[],e,c=-1,f=a.length;if(arguments.length<2)b=va;for(;++c<f;)if(b.call(g,e=a[c],c))g=[];else{g.length||d.push(g);g.push(e)}return d};d3.range=
|
||||
function(a,b,d){if(arguments.length==1){b=a;a=0}if(d==null)d=1;if((b-a)/d==Infinity)throw Error("infinite range");var g=[],e=-1,c;if(d<0)for(;(c=a+d*++e)>b;)g.push(c);else for(;(c=a+d*++e)<b;)g.push(c);return g};d3.requote=function(a){return a.replace(Ta,"\\$&")};var Ta=/[\\\^\$\*\+\?\[\]\(\)\.\{\}]/g;d3.xhr=function(a,b,d){var g=new XMLHttpRequest;if(arguments.length<3)d=b;else b&&g.overrideMimeType(b);g.open("GET",a,true);g.onreadystatechange=function(){if(g.readyState==4)d(g.status<300?g:null)};
|
||||
g.send(null)};d3.text=function(a,b,d){if(arguments.length<3){d=b;b=null}d3.xhr(a,b,function(g){d(g&&g.responseText)})};d3.json=function(a,b){d3.text(a,"application/json",function(d){b(d?JSON.parse(d):null)})};d3.html=function(a,b){d3.text(a,"text/html",function(d){if(d!=null){var g=document.createRange();g.selectNode(document.body);d=g.createContextualFragment(d)}b(d)})};d3.xml=function(a,b,d){if(arguments.length<3){d=b;b=null}d3.xhr(a,b,function(g){d(g&&g.responseXML)})};d3.ns={prefix:{svg:"http://www.w3.org/2000/svg",
|
||||
xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},qualify:function(a){var b=a.indexOf(":");return b<0?a:{space:d3.ns.prefix[a.substring(0,b)],local:a.substring(b+1)}}};d3.dispatch=function(){for(var a={},b,d=0,g=arguments.length;d<g;d++){b=arguments[d];a[b]=wa(b)}return a};d3.format=function(a){a=Ua.exec(a);var b=a[1]||" ",d=a[3]||"",g=a[5],e=+a[6],c=a[7],f=a[8],h=a[9];if(f)f=f.substring(1);if(g){b=
|
||||
"0";if(c)e-=Math.floor((e-1)/4)}if(h=="d")f="0";return function(i){i=+i;var k=i<0&&(i=-i)?"−":d;if(h=="d"&&i%1)return"";i=f?i.toFixed(f):""+i;if(g){var j=i.length+k.length;if(j<e)i=Array(e-j+1).join(b)+i;if(c)i=fa(i);i=k+i}else{if(c)i=fa(i);i=k+i;j=i.length;if(j<e)i=Array(e-j+1).join(b)+i}return i}};var Ua=/(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,Va=R(2),Wa=R(3),Xa={linear:function(){return xa},poly:R,quad:function(){return Va},cubic:function(){return Wa},sin:function(){return ya},
|
||||
exp:function(){return za},circle:function(){return Aa},elastic:function(a,b){var d;if(arguments.length<2)b=0.45;if(arguments.length<1){a=1;d=b/4}else d=b/(2*Math.PI)*Math.asin(1/a);return function(g){return 1+a*Math.pow(2,10*-g)*Math.sin((g-d)*2*Math.PI/b)}},back:function(a){a||(a=1.70158);return function(b){return b*b*((a+1)*b-a)}},bounce:function(){return Ba}},Ya={"in":function(a){return a},out:ga,"in-out":ha,"out-in":function(a){return ha(ga(a))}};d3.ease=function(a){var b=a.indexOf("-"),d=b>=
|
||||
0?a.substring(0,b):a;b=b>=0?a.substring(b+1):"in";return Ya[b](Xa[d].apply(null,Array.prototype.slice.call(arguments,1)))};d3.event=null;d3.interpolate=function(a,b){if(typeof b=="number")return d3.interpolateNumber(+a,b);if(typeof b=="string")return b in G||/^(#|rgb\(|hsl\()/.test(b)?d3.interpolateRgb(String(a),b):d3.interpolateString(String(a),b);if(b instanceof Array)return d3.interpolateArray(a,b);return d3.interpolateObject(a,b)};d3.interpolateNumber=function(a,b){b-=a;return function(d){return a+
|
||||
b*d}};d3.interpolateRound=function(a,b){b-=a;return function(d){return Math.round(a+b*d)}};d3.interpolateString=function(a,b){var d,g,e=0,c=[],f=[],h,i;for(g=0;d=aa.exec(b);++g){d.index&&c.push(b.substring(e,d.index));f.push({i:c.length,x:d[0]});c.push(null);e=aa.lastIndex}e<b.length&&c.push(b.substring(e));g=0;for(h=f.length;(d=aa.exec(a))&&g<h;++g){i=f[g];if(i.x==d[0]){if(i.i)if(c[i.i+1]==null){c[i.i-1]+=i.x;c.splice(i.i,1);for(d=g+1;d<h;++d)f[d].i--}else{c[i.i-1]+=i.x+c[i.i+1];c.splice(i.i,2);
|
||||
for(d=g+1;d<h;++d)f[d].i-=2}else if(c[i.i+1]==null)c[i.i]=i.x;else{c[i.i]=i.x+c[i.i+1];c.splice(i.i+1,1);for(d=g+1;d<h;++d)f[d].i--}f.splice(g,1);h--;g--}else i.x=d3.interpolateNumber(parseFloat(d[0]),parseFloat(i.x))}for(;g<h;){i=f.pop();if(c[i.i+1]==null)c[i.i]=i.x;else{c[i.i]=i.x+c[i.i+1];c.splice(i.i+1,1)}h--}if(c.length==1)return c[0]==null?f[0].x:function(){return b};return function(k){for(g=0;g<h;++g)c[(i=f[g]).i]=i.x(k);return c.join("")}};d3.interpolateRgb=function(a,b){a=d3.rgb(a);b=d3.rgb(b);
|
||||
|
@ -45,7 +45,7 @@ goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#
|
|||
lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",
|
||||
navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",
|
||||
silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},ba;for(ba in G)G[ba]=T(G[ba],J,W);d3.hsl=function(a,b,d){return arguments.length==1?T(""+a,Da,V):V(+a,+b,+d)};var D=function(a,b){return b.querySelector(a)},
|
||||
ha=function(a,b){return N(b.querySelectorAll(a))};if(typeof Sizzle=="function"){D=function(a,b){return Sizzle(a,b)[0]};ha=Sizzle}var O=y([[document]]);O[0].parentNode=document.documentElement;d3.select=function(a){return typeof a=="string"?O.select(a):y([[a]])};d3.selectAll=function(a){return typeof a=="string"?O.selectAll(a):y([N(a)])};d3.transition=O.transition;var Ha=0,Y=0,F=null,Z=0,K;d3.scale={};d3.scale.linear=function(){function a(j){return k((j-d)*f)}function b(j){var o=Math.min(d,g),p=Math.max(d,
|
||||
ia=function(a,b){return N(b.querySelectorAll(a))};if(typeof Sizzle=="function"){D=function(a,b){return Sizzle(a,b)[0]};ia=Sizzle}var O=y([[document]]);O[0].parentNode=document.documentElement;d3.select=function(a){return typeof a=="string"?O.select(a):y([[a]])};d3.selectAll=function(a){return typeof a=="string"?O.selectAll(a):y([N(a)])};d3.transition=O.transition;var Ha=0,Y=0,F=null,Z=0,K;d3.scale={};d3.scale.linear=function(){function a(j){return k((j-d)*f)}function b(j){var o=Math.min(d,g),p=Math.max(d,
|
||||
g),m=p-o,n=Math.pow(10,Math.floor(Math.log(m/j)/Math.LN10));j=j/(m/n);if(j<=0.15)n*=10;else if(j<=0.35)n*=5;else if(j<=0.75)n*=2;return{start:Math.ceil(o/n)*n,stop:Math.floor(p/n)*n+n*0.5,step:n}}var d=0,g=1,e=0,c=1,f=1/(g-d),h=(g-d)/(c-e),i=d3.interpolate,k=i(e,c);a.invert=function(j){return(j-e)*h+d};a.domain=function(j){if(!arguments.length)return[d,g];d=j[0];g=j[1];f=1/(g-d);h=(g-d)/(c-e);return a};a.range=function(j){if(!arguments.length)return[e,c];e=j[0];c=j[1];h=(g-d)/(c-e);k=i(e,c);return a};
|
||||
a.rangeRound=function(j){return a.range(j).interpolate(d3.interpolateRound)};a.interpolate=function(j){if(!arguments.length)return i;k=(i=j)(e,c);return a};a.ticks=function(j){j=b(j);return d3.range(j.start,j.stop,j.step)};a.tickFormat=function(j){j=Math.max(0,-Math.floor(Math.log(b(j).step)/Math.LN10+0.01));return d3.format(",."+j+"f")};return a};d3.scale.log=function(){function a(c){return(e?-Math.log(-c):Math.log(c))/Math.LN10}function b(c){return e?-Math.pow(10,-c):Math.pow(10,c)}function d(c){return g(a(c))}
|
||||
var g=d3.scale.linear(),e=false;d.invert=function(c){return b(g.invert(c))};d.domain=function(c){if(!arguments.length)return g.domain().map(b);e=(c[0]||c[1])<0;g.domain(c.map(a));return d};d.range=C(d,g.range);d.rangeRound=C(d,g.rangeRound);d.interpolate=C(d,g.interpolate);d.ticks=function(){var c=g.domain(),f=[];if(c.every(isFinite)){var h=Math.floor(c[0]),i=Math.ceil(c[1]),k=b(c[0]);c=b(c[1]);if(e)for(f.push(b(h));h++<i;)for(var j=9;j>0;j--)f.push(b(h)*j);else{for(;h<i;h++)for(j=1;j<10;j++)f.push(b(h)*
|
||||
|
@ -57,12 +57,12 @@ c[0],i=c[1],k=i-h,j=Math.floor(k/(b.length+f));g=d3.range(h+Math.round((k-(b.len
|
|||
"#e6550d","#fd8d3c","#fdae6b","#fdd0a2","#31a354","#74c476","#a1d99b","#c7e9c0","#756bb1","#9e9ac8","#bcbddc","#dadaeb","#636363","#969696","#bdbdbd","#d9d9d9"];d3.scale.quantile=function(){function a(){for(var f=-1,h=c.length=e.length,i=g.length/h;++f<h;)c[f]=g[~~(f*i)]}function b(f){if(isNaN(f=+f))return NaN;for(var h=0,i=c.length-1;h<=i;){var k=h+i>>1,j=c[k];if(j<f)h=k+1;else if(j>f)i=k-1;else return k}return i<0?0:i}function d(f){return e[b(f)]}var g=[],e=[],c=[];d.domain=function(f){if(!arguments.length)return g;
|
||||
g=f.filter(function(h){return!isNaN(h)}).sort(d3.ascending);a();return d};d.range=function(f){if(!arguments.length)return e;e=f;a();return d};d.quantiles=function(){return c};return d};d3.scale.quantize=function(){function a(f){return c[Math.max(0,Math.min(e,Math.floor(g*(f-b))))]}var b=0,d=1,g=2,e=1,c=[0,1];a.domain=function(f){if(!arguments.length)return[b,d];b=f[0];d=f[1];g=c.length/(d-b);return a};a.range=function(f){if(!arguments.length)return c;c=f;g=c.length/(d-b);e=c.length-1;return a};return a};
|
||||
d3.svg={};d3.svg.arc=function(){function a(){var c=b.apply(this,arguments),f=d.apply(this,arguments),h=g.apply(this,arguments)+I,i=e.apply(this,arguments)+I,k=i-h,j=k<Math.PI?"0":"1",o=Math.cos(h);h=Math.sin(h);var p=Math.cos(i);i=Math.sin(i);return k>=db?c?"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+-f+"A"+f+","+f+" 0 1,1 0,"+f+"M0,"+c+"A"+c+","+c+" 0 1,1 0,"+-c+"A"+c+","+c+" 0 1,1 0,"+c+"Z":"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+-f+"A"+f+","+f+" 0 1,1 0,"+f+"Z":c?"M"+f*o+","+f*h+"A"+f+","+f+" 0 "+j+",1 "+f*p+","+
|
||||
f*i+"L"+c*p+","+c*i+"A"+c+","+c+" 0 "+j+",0 "+c*o+","+c*h+"Z":"M"+f*o+","+f*h+"A"+f+","+f+" 0 "+j+",1 "+f*p+","+f*i+"L0,0Z"}var b=La,d=Ma,g=ja,e=ka;a.innerRadius=function(c){if(!arguments.length)return b;b=v(c);return a};a.outerRadius=function(c){if(!arguments.length)return d;d=v(c);return a};a.startAngle=function(c){if(!arguments.length)return g;g=v(c);return a};a.endAngle=function(c){if(!arguments.length)return e;e=v(c);return a};a.centroid=function(){var c=(b.apply(this,arguments)+d.apply(this,
|
||||
arguments))/2,f=(g.apply(this,arguments)+e.apply(this,arguments))/2+I;return[Math.cos(f)*c,Math.sin(f)*c]};return a};var I=-Math.PI/2,db=2*Math.PI-1.0E-6;d3.svg.line=function(){function a(f){return f.length<1?null:"M"+e($(this,f,b,d),c)}var b=la,d=ma,g="linear",e=P[g],c=0.7;a.x=function(f){if(!arguments.length)return b;b=f;return a};a.y=function(f){if(!arguments.length)return d;d=f;return a};a.interpolate=function(f){if(!arguments.length)return g;e=P[g=f];return a};a.tension=function(f){if(!arguments.length)return c;
|
||||
f*i+"L"+c*p+","+c*i+"A"+c+","+c+" 0 "+j+",0 "+c*o+","+c*h+"Z":"M"+f*o+","+f*h+"A"+f+","+f+" 0 "+j+",1 "+f*p+","+f*i+"L0,0Z"}var b=La,d=Ma,g=ka,e=la;a.innerRadius=function(c){if(!arguments.length)return b;b=v(c);return a};a.outerRadius=function(c){if(!arguments.length)return d;d=v(c);return a};a.startAngle=function(c){if(!arguments.length)return g;g=v(c);return a};a.endAngle=function(c){if(!arguments.length)return e;e=v(c);return a};a.centroid=function(){var c=(b.apply(this,arguments)+d.apply(this,
|
||||
arguments))/2,f=(g.apply(this,arguments)+e.apply(this,arguments))/2+I;return[Math.cos(f)*c,Math.sin(f)*c]};return a};var I=-Math.PI/2,db=2*Math.PI-1.0E-6;d3.svg.line=function(){function a(f){return f.length<1?null:"M"+e($(this,f,b,d),c)}var b=ma,d=na,g="linear",e=P[g],c=0.7;a.x=function(f){if(!arguments.length)return b;b=f;return a};a.y=function(f){if(!arguments.length)return d;d=f;return a};a.interpolate=function(f){if(!arguments.length)return g;e=P[g=f];return a};a.tension=function(f){if(!arguments.length)return c;
|
||||
c=f;return a};return a};var P={linear:H,basis:function(a){if(a.length<3)return H(a);var b=[],d=1,g=a.length,e=a[0],c=e[0],f=e[1],h=[c,c,c,(e=a[1])[0]],i=[f,f,f,e[1]];b.push(c,",",f);for(L(b,h,i);++d<g;){e=a[d];h.shift();h.push(e[0]);i.shift();i.push(e[1]);L(b,h,i)}for(d=-1;++d<2;){h.shift();h.push(e[0]);i.shift();i.push(e[1]);L(b,h,i)}return b.join("")},"basis-closed":function(a){for(var b,d=-1,g=a.length,e=g+4,c,f=[],h=[];++d<4;){c=a[d%g];f.push(c[0]);h.push(c[1])}b=[B(M,f),",",B(M,h)];for(--d;++d<
|
||||
e;){c=a[d%g];f.shift();f.push(c[0]);h.shift();h.push(c[1]);L(b,f,h)}return b.join("")},cardinal:function(a,b){if(a.length<3)return H(a);return a[0]+na(a,oa(a,b))},"cardinal-closed":function(a,b){if(a.length<3)return H(a);return a[0]+na(a,oa([a[a.length-2]].concat(a,[a[1]]),b))}},pa=[0,2/3,1/3,0],qa=[0,1/3,2/3,0],M=[0,1/6,2/3,1/6];d3.svg.area=function(){function a(h){return h.length<1?null:"M"+c($(this,h,b,g),f)+"L"+c($(this,h,b,d).reverse(),f)+"Z"}var b=la,d=Na,g=ma,e="linear",c=P[e],f=0.7;a.x=function(h){if(!arguments.length)return b;
|
||||
e;){c=a[d%g];f.shift();f.push(c[0]);h.shift();h.push(c[1]);L(b,f,h)}return b.join("")},cardinal:function(a,b){if(a.length<3)return H(a);return a[0]+oa(a,pa(a,b))},"cardinal-closed":function(a,b){if(a.length<3)return H(a);return a[0]+oa(a,pa([a[a.length-2]].concat(a,[a[1]]),b))}},qa=[0,2/3,1/3,0],ra=[0,1/3,2/3,0],M=[0,1/6,2/3,1/6];d3.svg.area=function(){function a(h){return h.length<1?null:"M"+c($(this,h,b,g),f)+"L"+c($(this,h,b,d).reverse(),f)+"Z"}var b=ma,d=Na,g=na,e="linear",c=P[e],f=0.7;a.x=function(h){if(!arguments.length)return b;
|
||||
b=h;return a};a.y0=function(h){if(!arguments.length)return d;d=h;return a};a.y1=function(h){if(!arguments.length)return g;g=h;return a};a.interpolate=function(h){if(!arguments.length)return e;c=P[e=h];return a};a.tension=function(h){if(!arguments.length)return f;f=h;return a};return a};d3.svg.chord=function(){function a(h,i){var k=b(this,d,h,i),j=b(this,g,h,i);return"M"+k.p0+("A"+k.r+","+k.r+" 0 0,1 "+k.p1)+(k.a0==j.a0&&k.a1==j.a1?"Q 0,0 "+k.p0:"Q 0,0 "+j.p0+("A"+j.r+","+j.r+" 0 0,1 "+j.p1)+("Q 0,0 "+
|
||||
k.p0))+"Z"}function b(h,i,k,j){var o=i.call(h,k,j);i=e.call(h,o,j);k=c.call(h,o,j)+I;h=f.call(h,o,j)+I;return{r:i,a0:k,a1:h,p0:[i*Math.cos(k),i*Math.sin(k)],p1:[i*Math.cos(h),i*Math.sin(h)]}}var d=Oa,g=Pa,e=Qa,c=ja,f=ka;a.radius=function(h){if(!arguments.length)return e;e=v(h);return a};a.source=function(h){if(!arguments.length)return d;d=v(h);return a};a.target=function(h){if(!arguments.length)return g;g=v(h);return a};a.startAngle=function(h){if(!arguments.length)return c;c=v(h);return a};a.endAngle=
|
||||
k.p0))+"Z"}function b(h,i,k,j){var o=i.call(h,k,j);i=e.call(h,o,j);k=c.call(h,o,j)+I;h=f.call(h,o,j)+I;return{r:i,a0:k,a1:h,p0:[i*Math.cos(k),i*Math.sin(k)],p1:[i*Math.cos(h),i*Math.sin(h)]}}var d=Oa,g=Pa,e=Qa,c=ka,f=la;a.radius=function(h){if(!arguments.length)return e;e=v(h);return a};a.source=function(h){if(!arguments.length)return d;d=v(h);return a};a.target=function(h){if(!arguments.length)return g;g=v(h);return a};a.startAngle=function(h){if(!arguments.length)return c;c=v(h);return a};a.endAngle=
|
||||
function(h){if(!arguments.length)return f;f=v(h);return a};return a};d3.svg.mouse=function(a){var b=(a.ownerSVGElement||a).createSVGPoint();if(ca<0&&(window.scrollX||window.scrollY)){var d=d3.select(document.body).append("svg:svg").style("position","absolute").style("top",0).style("left",0),g=d[0][0].getScreenCTM();ca=!(g.f||g.e);d.remove()}if(ca){b.x=d3.event.pageX;b.y=d3.event.pageY}else{b.x=d3.event.clientX;b.y=d3.event.clientY}b=b.matrixTransform(a.getScreenCTM().inverse());return[b.x,b.y]};var ca=
|
||||
/WebKit/.test(navigator.userAgent)?-1:0;d3.svg.symbol=function(){function a(g,e){return(sa[b.call(this,g,e)]||sa.circle)(d.call(this,g,e))}var b=Sa,d=Ra;a.type=function(g){if(!arguments.length)return b;b=v(g);return a};a.size=function(g){if(!arguments.length)return d;d=v(g);return a};return a};d3.svg.symbolTypes=["circle","cross","diamond","square","triangle-down","triangle-up"];var sa={circle:function(a){a=Math.sqrt(a/Math.PI);return"M0,"+a+"A"+a+","+a+" 0 1,1 0,"+-a+"A"+a+","+a+" 0 1,1 0,"+a+"Z"},
|
||||
cross:function(a){a=Math.sqrt(a/5)/2;return"M"+-3*a+","+-a+"H"+-a+"V"+-3*a+"H"+a+"V"+-a+"H"+3*a+"V"+a+"H"+a+"V"+3*a+"H"+-a+"V"+a+"H"+-3*a+"Z"},diamond:function(a){a=Math.sqrt(a/(2*ta));var b=a*ta;return"M0,"+-a+"L"+b+",0 0,"+a+" "+-b+",0Z"},square:function(a){a=Math.sqrt(a)/2;return"M"+-a+","+-a+"L"+a+","+-a+" "+a+","+a+" "+-a+","+a+"Z"},"triangle-down":function(a){a=Math.sqrt(a/Q);var b=a*Q/2;return"M0,"+b+"L"+a+","+-b+" "+-a+","+-b+"Z"},"triangle-up":function(a){a=Math.sqrt(a/Q);var b=a*Q/2;return"M0,"+
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<title>Clustered Network</title>
|
||||
<script type="text/javascript" src="../../d3.js"></script>
|
||||
<script type="text/javascript" src="../../d3.geom.js"></script>
|
||||
<script type="text/javascript" src="layout.js"></script>
|
||||
<script type="text/javascript" src="../../d3.layout.js"></script>
|
||||
<style type="text/css">
|
||||
svg {
|
||||
border: 1px solid #ccc;
|
||||
|
@ -190,10 +190,10 @@ function init() {
|
|||
|
||||
net = network(data, net, getGroup, expand);
|
||||
|
||||
force = layout_force()
|
||||
force = d3.layout.force()
|
||||
.nodes(net.nodes)
|
||||
.links(net.links)
|
||||
.size({x: w, y: h})
|
||||
.size([w, h])
|
||||
.distance(60)
|
||||
.start();
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<title>Force-Directed Layout</title>
|
||||
<script type="text/javascript" src="../../d3.js"></script>
|
||||
<script type="text/javascript" src="layout.js"></script>
|
||||
<script type="text/javascript" src="../../d3.layout.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="force.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
@ -8,10 +8,10 @@ var vis = d3.select("#chart")
|
|||
.attr("height", h);
|
||||
|
||||
d3.json("miserables.json", function(json) {
|
||||
var force = layout_force()
|
||||
var force = d3.layout.force()
|
||||
.nodes(json.nodes)
|
||||
.links(json.links)
|
||||
.size({x: w, y: h})
|
||||
.size([w, h])
|
||||
.start();
|
||||
|
||||
var link = vis.selectAll("line.link")
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"flare": {
|
||||
"analytics": {
|
||||
"cluster": {
|
||||
"AgglomerativeCluster": 3938,
|
||||
|
@ -282,3 +283,4 @@
|
|||
"Visualization": 16540
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
.cell {
|
||||
border: solid 1px white;
|
||||
font: 10px sans-serif;
|
||||
line-height: 12px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
text-indent: 2px;
|
||||
}
|
|
@ -4,49 +4,11 @@
|
|||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<title>Treemap</title>
|
||||
<script type="text/javascript" src="../../d3.js"></script>
|
||||
<script type="text/javascript" src="layout.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
body {
|
||||
font: 10px sans-serif;
|
||||
}
|
||||
|
||||
.cell {
|
||||
position: absolute;
|
||||
background: lightsteelblue;
|
||||
border: solid 1px white;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="../../d3.layout.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="treemap.css"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
|
||||
var w = 960,
|
||||
h = 500;
|
||||
|
||||
var div = d3.select("body").append("div")
|
||||
.style("position", "relative");
|
||||
|
||||
var treemap = layout_treemap()
|
||||
.size([w, h])
|
||||
.children(function(d, i) { return typeof d.value == "object" && d3.entries(d.value); })
|
||||
.value(function(d) { return d.value; });
|
||||
|
||||
d3.json("flare.json", function(json) {
|
||||
div.data([{key: "flare", value: json}]).selectAll("div")
|
||||
.data(treemap)
|
||||
.enter().append("div")
|
||||
.attr("class", "cell")
|
||||
.style("left", function(d) { return d.x + "px"; })
|
||||
.style("top", function(d) { return d.y + "px"; })
|
||||
.style("width", function(d) { return d.dx + "px"; })
|
||||
.style("height", function(d) { return d.dy + "px"; })
|
||||
.text(function(d) { return d.data.key; });
|
||||
});
|
||||
|
||||
</script>
|
||||
<div id="chart"></div>
|
||||
<script type="text/javascript" src="treemap.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
var w = 960,
|
||||
h = 500,
|
||||
color = d3.scale.category20c();
|
||||
|
||||
var treemap = d3.layout.treemap()
|
||||
.size([w, h])
|
||||
.children(function(d) { return typeof d.value == "object" && d3.entries(d.value); })
|
||||
.value(function(d) { return d.value; });
|
||||
|
||||
var div = d3.select("#chart").append("div")
|
||||
.style("position", "relative")
|
||||
.style("width", w + "px")
|
||||
.style("height", h + "px");
|
||||
|
||||
d3.json("flare.json", function(json) {
|
||||
div.data(d3.entries(json)).selectAll("div")
|
||||
.data(treemap)
|
||||
.enter().append("div")
|
||||
.attr("class", "cell")
|
||||
.style("background", function(d) { return d.children ? color(d.data.key) : null; })
|
||||
.style("left", function(d) { return d.x + "px"; })
|
||||
.style("top", function(d) { return d.y + "px"; })
|
||||
.style("width", function(d) { return d.dx - 1 + "px"; })
|
||||
.style("height", function(d) { return d.dy - 1 + "px"; })
|
||||
.text(function(d) { return d.children ? null : d.data.key; });
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2009 John Resig, http://jquery.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,39 @@
|
|||
#!/bin/sh
|
||||
# Usage: envjs <platorm> file.js [file2.js ...]
|
||||
###########################################################################
|
||||
ENVJS_PLATFORM='node'
|
||||
|
||||
# first arguments ($1)
|
||||
# may be a platform or is a file and the default platorm is used
|
||||
if [ -n "$1" ]; then
|
||||
if [ -n "$1" ]; then ENVJS_PLATFORM="$1"; shift; fi
|
||||
fi
|
||||
|
||||
# Run envjs with the given platform
|
||||
###########################################################################
|
||||
case "$ENVJS_PLATFORM" in
|
||||
|
||||
"node")
|
||||
node envjs/node.js $@
|
||||
;;
|
||||
"rhino")
|
||||
java -Xmx512M -jar rhino/js.jar -opt -1 envjs/rhino.js $@
|
||||
;;
|
||||
"rhino-debug")
|
||||
java -cp rhino/js.jar org.mozilla.javascript.tools.debugger.Main envjs/rhino.js $@
|
||||
;;
|
||||
"spyd")
|
||||
python envjs/spydermonkey.py envjs/spydermonkey.js $@
|
||||
;;
|
||||
"rubyracer")
|
||||
ruby -rrubygems envjs/rubyracer.rb envjs/rubyracer.js $@
|
||||
;;
|
||||
"johnson")
|
||||
ruby -rrubygems envjs/johnson.rb envjs/johnson.js $@
|
||||
;;
|
||||
*)
|
||||
# platform default means $1 was actually a file
|
||||
node envjs/node.js $ENVJS_PLATFORM $@
|
||||
;;
|
||||
esac
|
||||
|
|
@ -0,0 +1,278 @@
|
|||
|
||||
/**
|
||||
* @author envjs team
|
||||
* @Console
|
||||
*/
|
||||
|
||||
var Envjs = Envjs || require('./platform/core').Envjs;
|
||||
|
||||
/*
|
||||
* Envjs console.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
//CLOSURE_START
|
||||
(function(){
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author envjs team
|
||||
* borrowed 99%-ish with love from firebug-lite
|
||||
*/
|
||||
|
||||
//leaked globally on purpose;
|
||||
try{
|
||||
console.log();
|
||||
}catch(e){
|
||||
|
||||
|
||||
function escapeHTML(value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
function objectToString(object)
|
||||
{
|
||||
try
|
||||
{
|
||||
return object+"";
|
||||
}
|
||||
catch (exc)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
|
||||
function appendText(object, html)
|
||||
{
|
||||
html.push(escapeHTML(objectToString(object)));
|
||||
}
|
||||
|
||||
function appendNull(object, html)
|
||||
{
|
||||
html.push(escapeHTML(objectToString(object)));
|
||||
}
|
||||
|
||||
function appendString(object, html)
|
||||
{
|
||||
html.push(escapeHTML(objectToString(object)));
|
||||
}
|
||||
|
||||
function appendInteger(object, html)
|
||||
{
|
||||
html.push(escapeHTML(objectToString(object)));
|
||||
}
|
||||
|
||||
function appendFloat(object, html)
|
||||
{
|
||||
html.push(escapeHTML(objectToString(object)));
|
||||
}
|
||||
|
||||
function appendFunction(object, html)
|
||||
{
|
||||
var reName = /function ?(.*?)\(/;
|
||||
var m = reName.exec(objectToString(object));
|
||||
var name = m ? m[1] : "function";
|
||||
html.push(escapeHTML(name));
|
||||
}
|
||||
|
||||
function appendObjectFormatted(object, html)
|
||||
{
|
||||
var text = objectToString(object);
|
||||
var reObject = /\[object (.*?)\]/;
|
||||
|
||||
var m = reObject.exec(text);
|
||||
html.push( m ? m[1] : text);
|
||||
}
|
||||
|
||||
function appendSelector(object, html)
|
||||
{
|
||||
|
||||
html.push(escapeHTML(object.nodeName.toLowerCase()));
|
||||
if (object.id) {
|
||||
html.push(escapeHTML(object.id));
|
||||
}
|
||||
if (object.className) {
|
||||
html.push(escapeHTML(object.className));
|
||||
}
|
||||
}
|
||||
|
||||
function appendNode(node, html)
|
||||
{
|
||||
if (node.nodeType == 1)
|
||||
{
|
||||
html.push( node.nodeName.toLowerCase());
|
||||
|
||||
for (var i = 0; i < node.attributes.length; ++i)
|
||||
{
|
||||
var attr = node.attributes[i];
|
||||
if (!attr.specified) {
|
||||
continue;
|
||||
}
|
||||
|
||||
html.push( attr.nodeName.toLowerCase(),escapeHTML(attr.nodeValue));
|
||||
}
|
||||
|
||||
if (node.firstChild)
|
||||
{
|
||||
for (var child = node.firstChild; child; child = child.nextSibling) {
|
||||
appendNode(child, html);
|
||||
}
|
||||
|
||||
html.push( node.nodeName.toLowerCase());
|
||||
}
|
||||
}
|
||||
else if (node.nodeType === 3)
|
||||
{
|
||||
html.push(escapeHTML(node.nodeValue));
|
||||
}
|
||||
}
|
||||
|
||||
function appendObject(object, html)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (object === undefined) {
|
||||
appendNull("undefined", html);
|
||||
} else if (object === null) {
|
||||
appendNull("null", html);
|
||||
} else if (typeof object == "string") {
|
||||
appendString(object, html);
|
||||
} else if (typeof object == "number") {
|
||||
appendInteger(object, html);
|
||||
} else if (typeof object == "function") {
|
||||
appendFunction(object, html);
|
||||
} else if (object.nodeType == 1) {
|
||||
appendSelector(object, html);
|
||||
} else if (typeof object == "object") {
|
||||
appendObjectFormatted(object, html);
|
||||
} else {
|
||||
appendText(object, html);
|
||||
}
|
||||
}
|
||||
catch (exc)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function parseFormat(format)
|
||||
{
|
||||
var parts = [];
|
||||
|
||||
var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
|
||||
var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
|
||||
|
||||
for (var m = reg.exec(format); m; m = reg.exec(format))
|
||||
{
|
||||
var type = m[8] ? m[8] : m[5];
|
||||
var appender = type in appenderMap ? appenderMap[type] : appendObject;
|
||||
var precision = m[3] ? parseInt(m[3], 10) : (m[4] == "." ? -1 : 0);
|
||||
|
||||
parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
|
||||
parts.push({appender: appender, precision: precision});
|
||||
|
||||
format = format.substr(m.index+m[0].length);
|
||||
}
|
||||
|
||||
parts.push(format);
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function logFormatted(objects, className)
|
||||
{
|
||||
var html = [],
|
||||
i= 0,
|
||||
object;
|
||||
|
||||
var format = objects[0];
|
||||
var objIndex = 0;
|
||||
|
||||
if (typeof(format) != "string")
|
||||
{
|
||||
format = "";
|
||||
objIndex = -1;
|
||||
}
|
||||
|
||||
var parts = parseFormat(format);
|
||||
for (i = 0; i < parts.length; ++i)
|
||||
{
|
||||
var part = parts[i];
|
||||
if (part && typeof(part) == "object")
|
||||
{
|
||||
object = objects[++objIndex];
|
||||
part.appender(object, html);
|
||||
}
|
||||
else {
|
||||
appendText(part, html);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = objIndex+1; i < objects.length; ++i)
|
||||
{
|
||||
appendText(" ", html);
|
||||
|
||||
object = objects[i];
|
||||
if (typeof(object) == "string") {
|
||||
appendText(object, html);
|
||||
} else {
|
||||
appendObject(object, html);
|
||||
}
|
||||
}
|
||||
|
||||
Envjs.log(html.join(' '));
|
||||
}
|
||||
|
||||
|
||||
Console = function(module){
|
||||
var $level,
|
||||
$logger,
|
||||
$null = function(){};
|
||||
$logger = {
|
||||
log: function(level){
|
||||
logFormatted(arguments, "");
|
||||
},
|
||||
debug: function(level){
|
||||
logFormatted(arguments, "DEBUG");
|
||||
},
|
||||
info: function(level){
|
||||
logFormatted(arguments, "INFO");
|
||||
},
|
||||
warn: function(level){
|
||||
logFormatted(arguments, "WARN");
|
||||
},
|
||||
error: function(level){
|
||||
logFormatted(arguments, "ERROR");
|
||||
},
|
||||
trace: function(){
|
||||
Envjs.trace();
|
||||
}
|
||||
};
|
||||
|
||||
return $logger;
|
||||
};
|
||||
|
||||
console = new Console();
|
||||
exports.console = console;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author john resig & the envjs team
|
||||
* @uri http://www.envjs.com/
|
||||
* @copyright 2008-2010
|
||||
* @license MIT
|
||||
*/
|
||||
//CLOSURE_END
|
||||
}());
|
|
@ -0,0 +1,695 @@
|
|||
|
||||
/**
|
||||
* DOM Style Level 2
|
||||
|
||||
Leaked globally
|
||||
|
||||
var CSS2Properties,
|
||||
CSSRule,
|
||||
CSSStyleRule,
|
||||
CSSImportRule,
|
||||
CSSMediaRule,
|
||||
CSSFontFaceRule,
|
||||
CSSPageRule,
|
||||
CSSRuleList,
|
||||
CSSStyleSheet,
|
||||
StyleSheet,
|
||||
StyleSheetList;
|
||||
|
||||
*/
|
||||
|
||||
var Envjs = Envjs || require('./platform/core').Envjs,
|
||||
Document = require('./dom').Document,
|
||||
HTMLElement = require('./html').HTMLElement;
|
||||
/*
|
||||
* Envjs css.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
//CLOSURE_START
|
||||
(function(){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author john resig
|
||||
*/
|
||||
// Helper method for extending one object with another.
|
||||
function __extend__(a,b) {
|
||||
for ( var i in b ) {
|
||||
if(b.hasOwnProperty(i)){
|
||||
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||
if ( g || s ) {
|
||||
if ( g ) { a.__defineGetter__(i, g); }
|
||||
if ( s ) { a.__defineSetter__(i, s); }
|
||||
} else {
|
||||
a[i] = b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author john resig
|
||||
*/
|
||||
//from jQuery
|
||||
function __setArray__( target, array ) {
|
||||
// Resetting the length to 0, then using the native Array push
|
||||
// is a super-fast way to populate an object with array-like properties
|
||||
target.length = 0;
|
||||
Array.prototype.push.apply( target, array );
|
||||
}
|
||||
|
||||
/**
|
||||
* @author ariel flesler
|
||||
* http://flesler.blogspot.com/2008/11/fast-trim-function-for-javascript.html
|
||||
* @param {Object} str
|
||||
*/
|
||||
function __trim__( str ){
|
||||
return (str || "").replace( /^\s+|\s+$/g, "" );
|
||||
}
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.DOM.Document').debug('available');
|
||||
});
|
||||
|
||||
/**
|
||||
* Interface DocumentStyle (introduced in DOM Level 2)
|
||||
* http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/stylesheets.html#StyleSheets-StyleSheet-DocumentStyle
|
||||
*
|
||||
* interface DocumentStyle {
|
||||
* readonly attribute StyleSheetList styleSheets;
|
||||
* };
|
||||
*
|
||||
*/
|
||||
|
||||
__extend__(Document.prototype, {
|
||||
get styleSheets() {
|
||||
if (! this._styleSheets) {
|
||||
this._styleSheets = new StyleSheetList();
|
||||
}
|
||||
return this._styleSheets;
|
||||
}
|
||||
});
|
||||
|
||||
}(/*Envjs.DOM.Document*/));
|
||||
/*
|
||||
* CSS2Properties - DOM Level 2 CSS
|
||||
* Renamed to CSSStyleDeclaration??
|
||||
*/
|
||||
|
||||
var __toCamelCase__ = function(name) {
|
||||
if (name) {
|
||||
return name.replace(/\-(\w)/g, function(all, letter) {
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
var __toDashed__ = function(camelCaseName) {
|
||||
if (camelCaseName) {
|
||||
return camelCaseName.replace(/[A-Z]/g, function(all) {
|
||||
return '-' + all.toLowerCase();
|
||||
});
|
||||
}
|
||||
return camelCaseName;
|
||||
};
|
||||
|
||||
var __cssTextToStyles__,
|
||||
__supportedStyles__;
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.CSS.CSS2Properties').debug('available');
|
||||
});
|
||||
|
||||
exports.CSS2Properties = CSS2Properties = function(element){
|
||||
//console.log('css2properties %s', __cssproperties__++);
|
||||
this.styleIndex = __supportedStyles__;//non-standard
|
||||
this.type = element.tagName;//non-standard
|
||||
__setArray__(this, []);
|
||||
__cssTextToStyles__(this, element.cssText || '');
|
||||
};
|
||||
__extend__(CSS2Properties.prototype, {
|
||||
get cssText() {
|
||||
var i, css = [];
|
||||
for (i = 0; i < this.length; ++i) {
|
||||
css.push(this[i] + ': ' + this.getPropertyValue(this[i]) + ';');
|
||||
}
|
||||
return css.join(' ');
|
||||
},
|
||||
set cssText(cssText) {
|
||||
__cssTextToStyles__(this, cssText);
|
||||
},
|
||||
getPropertyCSSValue: function(name) {
|
||||
//?
|
||||
},
|
||||
getPropertyPriority: function() {
|
||||
|
||||
},
|
||||
getPropertyValue: function(name) {
|
||||
var index, cname = __toCamelCase__(name);
|
||||
if (cname in this.styleIndex) {
|
||||
return this[cname];
|
||||
} else {
|
||||
index = Array.prototype.indexOf.apply(this, [name]);
|
||||
if (index > -1) {
|
||||
return this[index];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
item: function(index) {
|
||||
return this[index];
|
||||
},
|
||||
removeProperty: function(name) {
|
||||
this.styleIndex[name] = null;
|
||||
name = __toDashed__(name);
|
||||
var index = Array.prototype.indexOf.apply(this, [name]);
|
||||
if (index > -1) {
|
||||
Array.prototype.splice.apply(this, [1,index]);
|
||||
}
|
||||
},
|
||||
setProperty: function(name, value, priority) {
|
||||
var nval;
|
||||
name = __toCamelCase__(name);
|
||||
if (value !== undefined && name in this.styleIndex) {
|
||||
// NOTE: parseFloat('300px') ==> 300 no
|
||||
// NOTE: Number('300px') ==> Nan yes
|
||||
nval = Number(value);
|
||||
this.styleIndex[name] = isNaN(nval) ? value : nval;
|
||||
name = __toDashed__(name);
|
||||
if (Array.prototype.indexOf.apply(this, [name]) === -1 ){
|
||||
Array.prototype.push.apply(this,[name]);
|
||||
}
|
||||
}
|
||||
},
|
||||
toString: function() {
|
||||
return '[object CSS2Properties]';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
__cssTextToStyles__ = function(css2props, cssText) {
|
||||
//console.log('__cssTextToStyles__ %s %s', css2props, cssText);
|
||||
var i, style, styles = cssText.split(';');
|
||||
for (i = 0; i < styles.length; ++i) {
|
||||
style = styles[i].split(':');
|
||||
if (style.length === 2) {
|
||||
css2props.setProperty(
|
||||
style[0].replace(' ', '', 'g'),
|
||||
style[1].replace(' ', '', 'g')
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//Obviously these arent all supported but by commenting out various
|
||||
//sections this provides a single location to configure what is
|
||||
//exposed as supported.
|
||||
__supportedStyles__ = {
|
||||
azimuth: null,
|
||||
background: null,
|
||||
backgroundAttachment: null,
|
||||
backgroundColor: 'rgb(0,0,0)',
|
||||
backgroundImage: null,
|
||||
backgroundPosition: null,
|
||||
backgroundRepeat: null,
|
||||
border: null,
|
||||
borderBottom: null,
|
||||
borderBottomColor: null,
|
||||
borderBottomStyle: null,
|
||||
borderBottomWidth: null,
|
||||
borderCollapse: null,
|
||||
borderColor: null,
|
||||
borderLeft: null,
|
||||
borderLeftColor: null,
|
||||
borderLeftStyle: null,
|
||||
borderLeftWidth: null,
|
||||
borderRight: null,
|
||||
borderRightColor: null,
|
||||
borderRightStyle: null,
|
||||
borderRightWidth: null,
|
||||
borderSpacing: null,
|
||||
borderStyle: null,
|
||||
borderTop: null,
|
||||
borderTopColor: null,
|
||||
borderTopStyle: null,
|
||||
borderTopWidth: null,
|
||||
borderWidth: null,
|
||||
bottom: null,
|
||||
captionSide: null,
|
||||
clear: null,
|
||||
clip: null,
|
||||
color: null,
|
||||
content: null,
|
||||
counterIncrement: null,
|
||||
counterReset: null,
|
||||
cssFloat: null,
|
||||
cue: null,
|
||||
cueAfter: null,
|
||||
cueBefore: null,
|
||||
cursor: null,
|
||||
direction: 'ltr',
|
||||
display: null,
|
||||
elevation: null,
|
||||
emptyCells: null,
|
||||
font: null,
|
||||
fontFamily: null,
|
||||
fontSize: '1em',
|
||||
fontSizeAdjust: null,
|
||||
fontStretch: null,
|
||||
fontStyle: null,
|
||||
fontVariant: null,
|
||||
fontWeight: null,
|
||||
height: '',
|
||||
left: null,
|
||||
letterSpacing: null,
|
||||
lineHeight: null,
|
||||
listStyle: null,
|
||||
listStyleImage: null,
|
||||
listStylePosition: null,
|
||||
listStyleType: null,
|
||||
margin: null,
|
||||
marginBottom: '0px',
|
||||
marginLeft: '0px',
|
||||
marginRight: '0px',
|
||||
marginTop: '0px',
|
||||
markerOffset: null,
|
||||
marks: null,
|
||||
maxHeight: null,
|
||||
maxWidth: null,
|
||||
minHeight: null,
|
||||
minWidth: null,
|
||||
opacity: 1,
|
||||
orphans: null,
|
||||
outline: null,
|
||||
outlineColor: null,
|
||||
outlineOffset: null,
|
||||
outlineStyle: null,
|
||||
outlineWidth: null,
|
||||
overflow: null,
|
||||
overflowX: null,
|
||||
overflowY: null,
|
||||
padding: null,
|
||||
paddingBottom: '0px',
|
||||
paddingLeft: '0px',
|
||||
paddingRight: '0px',
|
||||
paddingTop: '0px',
|
||||
page: null,
|
||||
pageBreakAfter: null,
|
||||
pageBreakBefore: null,
|
||||
pageBreakInside: null,
|
||||
pause: null,
|
||||
pauseAfter: null,
|
||||
pauseBefore: null,
|
||||
pitch: null,
|
||||
pitchRange: null,
|
||||
position: null,
|
||||
quotes: null,
|
||||
richness: null,
|
||||
right: null,
|
||||
size: null,
|
||||
speak: null,
|
||||
speakHeader: null,
|
||||
speakNumeral: null,
|
||||
speakPunctuation: null,
|
||||
speechRate: null,
|
||||
stress: null,
|
||||
tableLayout: null,
|
||||
textAlign: null,
|
||||
textDecoration: null,
|
||||
textIndent: null,
|
||||
textShadow: null,
|
||||
textTransform: null,
|
||||
top: null,
|
||||
unicodeBidi: null,
|
||||
verticalAlign: null,
|
||||
visibility: '',
|
||||
voiceFamily: null,
|
||||
volume: null,
|
||||
whiteSpace: null,
|
||||
widows: null,
|
||||
width: '1px',
|
||||
wordSpacing: null,
|
||||
zIndex: 1
|
||||
};
|
||||
|
||||
var __displayMap__ = {
|
||||
DIV : 'block',
|
||||
P : 'block',
|
||||
A : 'inline',
|
||||
CODE : 'inline',
|
||||
PRE : 'block',
|
||||
SPAN : 'inline',
|
||||
TABLE : 'table',
|
||||
THEAD : 'table-header-group',
|
||||
TBODY : 'table-row-group',
|
||||
TR : 'table-row',
|
||||
TH : 'table-cell',
|
||||
TD : 'table-cell',
|
||||
UL : 'block',
|
||||
LI : 'list-item'
|
||||
};
|
||||
|
||||
var __addStyleAccessor__ = function(name){
|
||||
if (name === 'width' || name === 'height') {
|
||||
CSS2Properties.prototype.__defineGetter__(name, function() {
|
||||
if (this.display === 'none'){
|
||||
return '0px';
|
||||
}
|
||||
return this.styleIndex[name];
|
||||
});
|
||||
} else if (name === 'display') {
|
||||
//display will be set to a tagName specific value if ''
|
||||
CSS2Properties.prototype.__defineGetter__(name, function() {
|
||||
var val = this.styleIndex[name];
|
||||
val = val ? val :__displayMap__[this.type];
|
||||
return val;
|
||||
});
|
||||
} else {
|
||||
CSS2Properties.prototype.__defineGetter__(name, function() {
|
||||
return this.styleIndex[name];
|
||||
});
|
||||
}
|
||||
CSS2Properties.prototype.__defineSetter__(name, function(value) {
|
||||
this.setProperty(name, value);
|
||||
});
|
||||
};
|
||||
|
||||
for (var style in __supportedStyles__) {
|
||||
if (__supportedStyles__.hasOwnProperty(style)) {
|
||||
__addStyleAccessor__(style);
|
||||
}
|
||||
}
|
||||
|
||||
}(/*Envjs.CSS.CSS2Properties*/));
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.CSS.CSSRule').debug('available');
|
||||
});
|
||||
|
||||
/*
|
||||
* CSSRule - DOM Level 2
|
||||
*/
|
||||
exports.CSSRule = CSSRule = function(options) {
|
||||
|
||||
var $style,
|
||||
$selectorText = options.selectorText ? options.selectorText : '';
|
||||
$style = new CSS2Properties({
|
||||
cssText: options.cssText ? options.cssText : null
|
||||
});
|
||||
|
||||
return __extend__(this, {
|
||||
get style(){
|
||||
return $style;
|
||||
},
|
||||
get selectorText(){
|
||||
return $selectorText;
|
||||
},
|
||||
set selectorText(selectorText){
|
||||
$selectorText = selectorText;
|
||||
},
|
||||
toString : function(){
|
||||
return "[object CSSRule]";
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
CSSRule.STYLE_RULE = 1;
|
||||
CSSRule.IMPORT_RULE = 3;
|
||||
CSSRule.MEDIA_RULE = 4;
|
||||
CSSRule.FONT_FACE_RULE = 5;
|
||||
CSSRule.PAGE_RULE = 6;
|
||||
//CSSRule.NAMESPACE_RULE = 10;
|
||||
|
||||
|
||||
CSSStyleRule = function() {
|
||||
|
||||
};
|
||||
|
||||
CSSImportRule = function() {
|
||||
|
||||
};
|
||||
|
||||
CSSMediaRule = function() {
|
||||
|
||||
};
|
||||
|
||||
CSSFontFaceRule = function() {
|
||||
|
||||
};
|
||||
|
||||
CSSPageRule = function() {
|
||||
|
||||
};
|
||||
|
||||
|
||||
CSSRuleList = function(data) {
|
||||
this.length = 0;
|
||||
__setArray__(this, data);
|
||||
};
|
||||
|
||||
__extend__(CSSRuleList.prototype, {
|
||||
item : function(index) {
|
||||
if ((index >= 0) && (index < this.length)) {
|
||||
// bounds check
|
||||
return this[index];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
toString: function() {
|
||||
return '[object CSSRuleList]';
|
||||
}
|
||||
});
|
||||
|
||||
}(/*Envjs.CSS.CSSRuleList*/));
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.CSS.CSSStyleSheet').debug('available');
|
||||
});
|
||||
|
||||
/**
|
||||
* StyleSheet
|
||||
* http://dev.w3.org/csswg/cssom/#stylesheet
|
||||
*
|
||||
* interface StyleSheet {
|
||||
* readonly attribute DOMString type;
|
||||
* readonly attribute DOMString href;
|
||||
* readonly attribute Node ownerNode;
|
||||
* readonly attribute StyleSheet parentStyleSheet;
|
||||
* readonly attribute DOMString title;
|
||||
* [PutForwards=mediaText] readonly attribute MediaList media;
|
||||
* attribute boolean disabled;
|
||||
* };
|
||||
*/
|
||||
StyleSheet = function() {};
|
||||
|
||||
/*
|
||||
* CSSStyleSheet
|
||||
* http://dev.w3.org/csswg/cssom/#cssstylesheet
|
||||
*
|
||||
* interface CSSStyleSheet : StyleSheet {
|
||||
* readonly attribute CSSRule ownerRule;
|
||||
* readonly attribute CSSRuleList cssRules;
|
||||
* unsigned long insertRule(DOMString rule, unsigned long index);
|
||||
* void deleteRule(unsigned long index);
|
||||
* };
|
||||
*/
|
||||
exports.CSSStyleSheets = CSSStyleSheet = function(options){
|
||||
var $cssRules,
|
||||
$disabled = options.disabled ? options.disabled : false,
|
||||
$href = options.href ? options.href : null,
|
||||
$parentStyleSheet = options.parentStyleSheet ? options.parentStyleSheet : null,
|
||||
$title = options.title ? options.title : "",
|
||||
$type = "text/css";
|
||||
|
||||
function parseStyleSheet(text){
|
||||
//$debug("parsing css");
|
||||
//this is pretty ugly, but text is the entire text of a stylesheet
|
||||
var cssRules = [];
|
||||
if (!text) {
|
||||
text = '';
|
||||
}
|
||||
text = __trim__(text.replace(/\/\*(\r|\n|.)*\*\//g,""));
|
||||
// TODO: @import
|
||||
var blocks = text.split("}");
|
||||
blocks.pop();
|
||||
var i, j, len = blocks.length;
|
||||
var definition_block, properties, selectors;
|
||||
for (i=0; i<len; i++) {
|
||||
definition_block = blocks[i].split("{");
|
||||
if (definition_block.length === 2) {
|
||||
selectors = definition_block[0].split(",");
|
||||
for (j=0; j<selectors.length; j++) {
|
||||
cssRules.push(new CSSRule({
|
||||
selectorText : __trim__(selectors[j]),
|
||||
cssText : definition_block[1]
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
return cssRules;
|
||||
}
|
||||
|
||||
$cssRules = new CSSRuleList(parseStyleSheet(options.textContent));
|
||||
|
||||
return __extend__(this, {
|
||||
get cssRules(){
|
||||
return $cssRules;
|
||||
},
|
||||
get rule(){
|
||||
return $cssRules;
|
||||
},//IE - may be deprecated
|
||||
get href(){
|
||||
return $href;
|
||||
},
|
||||
get parentStyleSheet(){
|
||||
return $parentStyleSheet;
|
||||
},
|
||||
get title(){
|
||||
return $title;
|
||||
},
|
||||
get type(){
|
||||
return $type;
|
||||
},
|
||||
addRule: function(selector, style, index){/*TODO*/},
|
||||
deleteRule: function(index){/*TODO*/},
|
||||
insertRule: function(rule, index){/*TODO*/},
|
||||
//IE - may be deprecated
|
||||
removeRule: function(index){
|
||||
this.deleteRule(index);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.StyleSheetList = StyleSheetList = function() {};
|
||||
|
||||
StyleSheetList.prototype = [];
|
||||
|
||||
__extend__(StyleSheetList.prototype, {
|
||||
item : function(index) {
|
||||
if ((index >= 0) && (index < this.length)) {
|
||||
// bounds check
|
||||
return this[index];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
toString: function() {
|
||||
return '[object StyleSheetList]';
|
||||
}
|
||||
});
|
||||
|
||||
}(/*Envjs.CSS.CSSStyleSheet*/));
|
||||
/**
|
||||
* This extends HTMLElement to handle CSS-specific interfaces.
|
||||
*
|
||||
* More work / research would be needed to extend just (DOM) Element
|
||||
* for xml use and additional changes for just HTMLElement.
|
||||
*/
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.HTML.HTMLElement').debug('available');
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Replace or add the getter for 'style'
|
||||
*
|
||||
* This could be wrapped in a closure
|
||||
*/
|
||||
var $css2properties = [{}];
|
||||
|
||||
__extend__(HTMLElement.prototype, {
|
||||
get style(){
|
||||
if ( !this.css2uuid ) {
|
||||
this.css2uuid = $css2properties.length;
|
||||
$css2properties[this.css2uuid] = new CSS2Properties(this);
|
||||
}
|
||||
return $css2properties[this.css2uuid];
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Change for how 'setAttribute("style", ...)' works
|
||||
*
|
||||
* We are truly adding functionality to HtmlElement.setAttribute, not
|
||||
* replacing it. So we need to save the old one first, call it, then
|
||||
* do our stuff. If we need to do more hacks like this, HTMLElement
|
||||
* (or regular Element) needs to have a hooks array or dispatch table
|
||||
* for global changes.
|
||||
*
|
||||
* This could be wrapped in a closure if desired.
|
||||
*/
|
||||
var updateCss2Props = function(elem, values) {
|
||||
//console.log('__updateCss2Props__ %s %s', elem, values);
|
||||
if ( !elem.css2uuid ) {
|
||||
elem.css2uuid = $css2properties.length;
|
||||
$css2properties[elem.css2uuid] = new CSS2Properties(elem);
|
||||
}
|
||||
__cssTextToStyles__($css2properties[elem.css2uuid], values);
|
||||
};
|
||||
|
||||
var origSetAttribute = HTMLElement.prototype.setAttribute;
|
||||
|
||||
HTMLElement.prototype.setAttribute = function(name, value) {
|
||||
//console.log("CSS set attribute: " + name + ", " + value);
|
||||
origSetAttribute.apply(this, arguments);
|
||||
if (name === "style") {
|
||||
updateCss2Props(this, value);
|
||||
}
|
||||
};
|
||||
|
||||
var origGetAttribute = HTMLElement.prototype.getAttribute;
|
||||
|
||||
HTMLElement.prototype.getAttribute = function(name) {
|
||||
//console.log("CSS set attribute: " + name + ", " + value);
|
||||
var style;
|
||||
if (name === "style") {
|
||||
style = this.style.cssText;
|
||||
return style===""?null:style;
|
||||
}else{
|
||||
return origGetAttribute.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
}(/*Envjs.HTML.HTMLElement*/));
|
||||
|
||||
/**
|
||||
* @author john resig & the envjs team
|
||||
* @uri http://www.envjs.com/
|
||||
* @copyright 2008-2010
|
||||
* @license MIT
|
||||
*/
|
||||
//CLOSURE_END
|
||||
}());
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,720 @@
|
|||
/*
|
||||
* Envjs event.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*
|
||||
* This file simply provides the global definitions we need to
|
||||
* be able to correctly implement to core browser DOM Event interfaces.
|
||||
|
||||
- leaked globally -
|
||||
|
||||
var Event,
|
||||
MouseEvent,
|
||||
UIEvent,
|
||||
KeyboardEvent,
|
||||
MutationEvent,
|
||||
DocumentEvent,
|
||||
EventTarget,
|
||||
EventException;
|
||||
|
||||
*/
|
||||
|
||||
var Envjs = Envjs || require('./platform/core').Envjs,
|
||||
After = After || require('./platform/core').After,
|
||||
Document = Document || require('./dom').Document;
|
||||
/*
|
||||
* Envjs event.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
//CLOSURE_START
|
||||
(function(){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author john resig
|
||||
*/
|
||||
// Helper method for extending one object with another.
|
||||
function __extend__(a,b) {
|
||||
for ( var i in b ) {
|
||||
if(b.hasOwnProperty(i)){
|
||||
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||
if ( g || s ) {
|
||||
if ( g ) { a.__defineGetter__(i, g); }
|
||||
if ( s ) { a.__defineSetter__(i, s); }
|
||||
} else {
|
||||
a[i] = b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author john resig
|
||||
*/
|
||||
//from jQuery
|
||||
function __setArray__( target, array ) {
|
||||
// Resetting the length to 0, then using the native Array push
|
||||
// is a super-fast way to populate an object with array-like properties
|
||||
target.length = 0;
|
||||
Array.prototype.push.apply( target, array );
|
||||
}
|
||||
var __addEventListener__,
|
||||
__removeEventListener__,
|
||||
__dispatchEvent__,
|
||||
__captureEvent__,
|
||||
__bubbleEvent__;
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.DOM.EventTarget').debug('available');
|
||||
});
|
||||
|
||||
/**
|
||||
* @name EventTarget
|
||||
* @w3c:domlevel 2
|
||||
* @uri -//TODO: paste dom event level 2 w3c spc uri here
|
||||
*/
|
||||
exports.EventTarget = EventTarget = function(){};
|
||||
EventTarget.prototype.addEventListener = function(type, fn, phase){
|
||||
__addEventListener__(this, type, fn, phase);
|
||||
};
|
||||
EventTarget.prototype.removeEventListener = function(type, fn, phase){
|
||||
__removeEventListener__(this, type, fn, phase);
|
||||
};
|
||||
EventTarget.prototype.dispatchEvent = function(event, bubbles){
|
||||
__dispatchEvent__(this, event, bubbles);
|
||||
};
|
||||
|
||||
__extend__(Node.prototype, EventTarget.prototype);
|
||||
|
||||
var $events = [{}];
|
||||
|
||||
__addEventListener__ = function(target, type, fn, phase){
|
||||
phase = !!phase?"CAPTURING":"BUBBLING";
|
||||
if ( !target.uuid ) {
|
||||
target.uuid = $events.length+'';
|
||||
log.debug('add event uuid for %s %s', target, target.uuid);
|
||||
}
|
||||
if ( !$events[target.uuid] ) {
|
||||
log.debug('creating listener for target: %s %s', target, target.uuid);
|
||||
$events[target.uuid] = {};
|
||||
}
|
||||
if ( !$events[target.uuid][type] ){
|
||||
log.debug('creating listener for type: %s %s %s', target, target.uuid, type);
|
||||
$events[target.uuid][type] = {
|
||||
CAPTURING:[],
|
||||
BUBBLING:[]
|
||||
};
|
||||
}
|
||||
if ( $events[target.uuid][type][phase].indexOf( fn ) < 0 ){
|
||||
log.debug( 'adding event listener %s %s %s %s', target, target.uuid, type, phase);
|
||||
$events[target.uuid][type][phase].push( fn );
|
||||
}
|
||||
log.debug('registered event listeners %s', $events.length);
|
||||
};
|
||||
|
||||
__removeEventListener__ = function(target, type, fn, phase){
|
||||
phase = !!phase?"CAPTURING":"BUBBLING";
|
||||
if ( !target.uuid ) {
|
||||
log.debug('target has never had registered events %s', target);
|
||||
return;
|
||||
}
|
||||
if ( !$events[target.uuid] ) {
|
||||
log.debug('target has no registered events to remove %s %s', target, target.uuid);
|
||||
return;
|
||||
}
|
||||
if(type == '*'){
|
||||
//used to clean all event listeners for a given node
|
||||
log.debug('cleaning all event listeners for node %s %s',target, target.uuid);
|
||||
delete $events[target.uuid];
|
||||
return;
|
||||
}else if ( !$events[target.uuid][type] ){
|
||||
log.debug('target has no registered events of type %s to remove %s %s', type, target, target.uuid);
|
||||
return;
|
||||
}
|
||||
$events[target.uuid][type][phase] =
|
||||
$events[target.uuid][type][phase].filter(function(f){
|
||||
log.debug('removing event listener %s %s %s %s', target, type, phase );
|
||||
return f != fn;
|
||||
});
|
||||
};
|
||||
|
||||
var __eventuuid__ = 0;
|
||||
|
||||
__dispatchEvent__ = function(target, event, bubbles){
|
||||
|
||||
if (!event.uuid) {
|
||||
event.uuid = __eventuuid__++;
|
||||
}
|
||||
//the window scope defines the $event object, for IE(^^^) compatibility;
|
||||
//$event = event;
|
||||
|
||||
if (bubbles === undefined || bubbles === null) {
|
||||
bubbles = true;
|
||||
}
|
||||
|
||||
if (!event.target) {
|
||||
event.target = target;
|
||||
}
|
||||
|
||||
log.debug('dispatching %s %s %s %s', event.uuid, target, event.type, bubbles);
|
||||
if ( event.type && (target.nodeType || target === window )) {
|
||||
|
||||
__captureEvent__(target, event);
|
||||
|
||||
event.eventPhase = Event.AT_TARGET;
|
||||
if ( target.uuid && $events[target.uuid] && $events[target.uuid][event.type] ) {
|
||||
event.currentTarget = target;
|
||||
|
||||
log.debug('begin dispatching capturing phase %s %s', target, event.type);
|
||||
$events[target.uuid][event.type].CAPTURING.forEach(function(fn){
|
||||
log.debug('capturing event %s', target);
|
||||
var returnValue = fn.apply(target, [event]);
|
||||
if(returnValue === false){
|
||||
event.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
log.debug('begin dispatching bubbling phase %s %s', target, event.type);
|
||||
$events[target.uuid][event.type].BUBBLING.forEach(function(fn){
|
||||
log.debug('bubbling event %s', target);
|
||||
var returnValue = fn.apply(target, [event] );
|
||||
if(returnValue === false){
|
||||
event.stopPropagation();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (target["on" + event.type]) {
|
||||
target["on" + event.type](event);
|
||||
}
|
||||
if (bubbles && !event.cancelled){
|
||||
__bubbleEvent__(target, event);
|
||||
}
|
||||
if(!event._preventDefault){
|
||||
//At this point I'm guessing that just HTMLEvents are concerned
|
||||
//with default behavior being executed in a browser but I could be
|
||||
//wrong as usual. The goal is much more to filter at this point
|
||||
//what events have no need to be handled
|
||||
//console.log('triggering default behavior for %s', event.type);
|
||||
if(event.type in Envjs.defaultEventBehaviors){
|
||||
Envjs.defaultEventBehaviors[event.type](event);
|
||||
}
|
||||
}
|
||||
log.debug('deleting event %s', event.uuid);
|
||||
event.target = null;
|
||||
event = null;
|
||||
}else{
|
||||
throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR);
|
||||
}
|
||||
};
|
||||
|
||||
__captureEvent__ = function(target, event){
|
||||
var ancestorStack = [],
|
||||
parent = target.parentNode,
|
||||
stopevent = function(fn){
|
||||
var returnValue = fn( event );
|
||||
if(returnValue === false){
|
||||
event.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
event.eventPhase = Event.CAPTURING_PHASE;
|
||||
while(parent){
|
||||
if(parent.uuid && $events[parent.uuid] && $events[parent.uuid][event.type]){
|
||||
ancestorStack.push(parent);
|
||||
}
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
while(ancestorStack.length && !event.cancelled){
|
||||
event.currentTarget = ancestorStack.pop();
|
||||
if($events[event.currentTarget.uuid] && $events[event.currentTarget.uuid][event.type]){
|
||||
$events[event.currentTarget.uuid][event.type].CAPTURING.forEach(stopevent);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
__bubbleEvent__ = function(target, event){
|
||||
var parent = target.parentNode,
|
||||
stopevent = function(fn){
|
||||
var returnValue = fn( event );
|
||||
if(returnValue === false){
|
||||
event.stopPropagation();
|
||||
}
|
||||
};
|
||||
event.eventPhase = Event.BUBBLING_PHASE;
|
||||
while(parent){
|
||||
if(parent.uuid && $events[parent.uuid] && $events[parent.uuid][event.type] ){
|
||||
event.currentTarget = parent;
|
||||
$events[event.currentTarget.uuid][event.type].BUBBLING.forEach(stopevent);
|
||||
}
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
};
|
||||
|
||||
}(/*Envjs.DOM2.EventTarget*/));
|
||||
|
||||
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.DOM.Event').debug('available');
|
||||
});
|
||||
|
||||
/**
|
||||
* @class Event
|
||||
*/
|
||||
exports.Event = Event = function(options){
|
||||
// event state is kept read-only by forcing
|
||||
// a new object for each event. This may not
|
||||
// be appropriate in the long run and we'll
|
||||
// have to decide if we simply dont adhere to
|
||||
// the read-only restriction of the specification
|
||||
this._bubbles = true;
|
||||
this._cancelable = true;
|
||||
this._cancelled = false;
|
||||
this._currentTarget = null;
|
||||
this._target = null;
|
||||
this._eventPhase = Event.AT_TARGET;
|
||||
this._timeStamp = new Date().getTime();
|
||||
this._preventDefault = false;
|
||||
this._stopPropogation = false;
|
||||
};
|
||||
|
||||
__extend__(Event.prototype,{
|
||||
get bubbles(){return this._bubbles;},
|
||||
get cancelable(){return this._cancelable;},
|
||||
get currentTarget(){return this._currentTarget;},
|
||||
set currentTarget(currentTarget){ this._currentTarget = currentTarget; },
|
||||
get eventPhase(){return this._eventPhase;},
|
||||
set eventPhase(eventPhase){this._eventPhase = eventPhase;},
|
||||
get target(){return this._target;},
|
||||
set target(target){ this._target = target;},
|
||||
get timeStamp(){return this._timeStamp;},
|
||||
get type(){return this._type;},
|
||||
initEvent: function(type, bubbles, cancelable){
|
||||
this._type=type?type:'';
|
||||
this._bubbles=!!bubbles;
|
||||
this._cancelable=!!cancelable;
|
||||
},
|
||||
preventDefault: function(){
|
||||
this._preventDefault = true;
|
||||
},
|
||||
stopPropagation: function(){
|
||||
if(this._cancelable){
|
||||
this._cancelled = true;
|
||||
this._bubbles = false;
|
||||
}
|
||||
},
|
||||
get cancelled(){
|
||||
return this._cancelled;
|
||||
},
|
||||
toString: function(){
|
||||
return '[object Event]';
|
||||
}
|
||||
});
|
||||
|
||||
__extend__(Event,{
|
||||
CAPTURING_PHASE : 1,
|
||||
AT_TARGET : 2,
|
||||
BUBBLING_PHASE : 3
|
||||
});
|
||||
|
||||
}(/*Envjs.DOM.Event*/));
|
||||
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.DOM.UIEvent').debug('available');
|
||||
});
|
||||
|
||||
/**
|
||||
* @name UIEvent
|
||||
* @param {Object} options
|
||||
*/
|
||||
exports.UIEvent = UIEvent = function(options) {
|
||||
this._view = null;
|
||||
this._detail = 0;
|
||||
};
|
||||
|
||||
UIEvent.prototype = new Event();
|
||||
__extend__(UIEvent.prototype,{
|
||||
get view(){
|
||||
return this._view;
|
||||
},
|
||||
get detail(){
|
||||
return this._detail;
|
||||
},
|
||||
initUIEvent: function(type, bubbles, cancelable, windowObject, detail){
|
||||
this.initEvent(type, bubbles, cancelable);
|
||||
this._detail = 0;
|
||||
this._view = windowObject;
|
||||
}
|
||||
});
|
||||
|
||||
}(/*Envjs.DOM.UIEvent*/));
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.DOM.MouseEvent').debug('available');
|
||||
});
|
||||
|
||||
/**
|
||||
* @name MouseEvent
|
||||
* @w3c:domlevel 2
|
||||
* @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html
|
||||
*/
|
||||
exports.MouseEvent = MouseEvent = function(options) {
|
||||
this._screenX= 0;
|
||||
this._screenY= 0;
|
||||
this._clientX= 0;
|
||||
this._clientY= 0;
|
||||
this._ctrlKey= false;
|
||||
this._metaKey= false;
|
||||
this._altKey= false;
|
||||
this._button= null;
|
||||
this._relatedTarget= null;
|
||||
};
|
||||
MouseEvent.prototype = new UIEvent();
|
||||
__extend__(MouseEvent.prototype,{
|
||||
get screenX(){
|
||||
return this._screenX;
|
||||
},
|
||||
get screenY(){
|
||||
return this._screenY;
|
||||
},
|
||||
get clientX(){
|
||||
return this._clientX;
|
||||
},
|
||||
get clientY(){
|
||||
return this._clientY;
|
||||
},
|
||||
get ctrlKey(){
|
||||
return this._ctrlKey;
|
||||
},
|
||||
get altKey(){
|
||||
return this._altKey;
|
||||
},
|
||||
get shiftKey(){
|
||||
return this._shiftKey;
|
||||
},
|
||||
get metaKey(){
|
||||
return this._metaKey;
|
||||
},
|
||||
get button(){
|
||||
return this._button;
|
||||
},
|
||||
get relatedTarget(){
|
||||
return this._relatedTarget;
|
||||
},
|
||||
initMouseEvent: function(type, bubbles, cancelable, windowObject, detail,
|
||||
screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
|
||||
metaKey, button, relatedTarget){
|
||||
this.initUIEvent(type, bubbles, cancelable, windowObject, detail);
|
||||
this._screenX = screenX;
|
||||
this._screenY = screenY;
|
||||
this._clientX = clientX;
|
||||
this._clientY = clientY;
|
||||
this._ctrlKey = ctrlKey;
|
||||
this._altKey = altKey;
|
||||
this._shiftKey = shiftKey;
|
||||
this._metaKey = metaKey;
|
||||
this._button = button;
|
||||
this._relatedTarget = relatedTarget;
|
||||
}
|
||||
});
|
||||
|
||||
}(/*Envjs.DOM2.MouseEvent*/));
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.DOM.KeyboardEvent').
|
||||
debug('KeyboardEvent available');
|
||||
});
|
||||
|
||||
/**
|
||||
* Interface KeyboardEvent (introduced in DOM Level 3)
|
||||
*/
|
||||
exports.KeyboardEvent = KeyboardEvent = function(options) {
|
||||
this._keyIdentifier = 0;
|
||||
this._keyLocation = 0;
|
||||
this._ctrlKey = false;
|
||||
this._metaKey = false;
|
||||
this._altKey = false;
|
||||
this._metaKey = false;
|
||||
};
|
||||
KeyboardEvent.prototype = new UIEvent();
|
||||
|
||||
__extend__(KeyboardEvent.prototype,{
|
||||
|
||||
get ctrlKey(){
|
||||
return this._ctrlKey;
|
||||
},
|
||||
get altKey(){
|
||||
return this._altKey;
|
||||
},
|
||||
get shiftKey(){
|
||||
return this._shiftKey;
|
||||
},
|
||||
get metaKey(){
|
||||
return this._metaKey;
|
||||
},
|
||||
get button(){
|
||||
return this._button;
|
||||
},
|
||||
get relatedTarget(){
|
||||
return this._relatedTarget;
|
||||
},
|
||||
getModifiersState: function(keyIdentifier){
|
||||
|
||||
},
|
||||
initMouseEvent: function(type, bubbles, cancelable, windowObject,
|
||||
keyIdentifier, keyLocation, modifiersList, repeat){
|
||||
this.initUIEvent(type, bubbles, cancelable, windowObject, 0);
|
||||
this._keyIdentifier = keyIdentifier;
|
||||
this._keyLocation = keyLocation;
|
||||
this._modifiersList = modifiersList;
|
||||
this._repeat = repeat;
|
||||
}
|
||||
});
|
||||
|
||||
KeyboardEvent.DOM_KEY_LOCATION_STANDARD = 0;
|
||||
KeyboardEvent.DOM_KEY_LOCATION_LEFT = 1;
|
||||
KeyboardEvent.DOM_KEY_LOCATION_RIGHT = 2;
|
||||
KeyboardEvent.DOM_KEY_LOCATION_NUMPAD = 3;
|
||||
KeyboardEvent.DOM_KEY_LOCATION_MOBILE = 4;
|
||||
KeyboardEvent.DOM_KEY_LOCATION_JOYSTICK = 5;
|
||||
|
||||
}(/*Envjs.DOM3.KeyboardEvent*/));
|
||||
|
||||
|
||||
//We dont fire mutation events until someone has registered for them
|
||||
var __supportedMutations__ = /DOMSubtreeModified|DOMNodeInserted|DOMNodeRemoved|DOMAttrModified|DOMCharacterDataModified/;
|
||||
|
||||
var __fireMutationEvents__ = Aspect.before({
|
||||
target: EventTarget,
|
||||
method: 'addEventListener'
|
||||
}, function(target, type){
|
||||
if(type && type.match(__supportedMutations__)){
|
||||
//unweaving removes the __addEventListener__ aspect
|
||||
__fireMutationEvents__.unweave();
|
||||
// These two methods are enough to cover all dom 2 manipulations
|
||||
Aspect.around({
|
||||
target: Node,
|
||||
method:"removeChild"
|
||||
}, function(invocation){
|
||||
var event,
|
||||
node = invocation['arguments'][0];
|
||||
event = node.ownerDocument.createEvent('MutationEvents');
|
||||
event.initEvent('DOMNodeRemoved', true, false, node.parentNode, null, null, null, null);
|
||||
node.dispatchEvent(event, false);
|
||||
return invocation.proceed();
|
||||
|
||||
});
|
||||
Aspect.around({
|
||||
target: Node,
|
||||
method:"appendChild"
|
||||
}, function(invocation) {
|
||||
var event,
|
||||
node = invocation.proceed();
|
||||
event = node.ownerDocument.createEvent('MutationEvents');
|
||||
event.initEvent('DOMNodeInserted', true, false, node.parentNode, null, null, null, null);
|
||||
node.dispatchEvent(event, false);
|
||||
return node;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.DOM.MutationEvent').debug('available');
|
||||
});
|
||||
|
||||
/**
|
||||
* @name MutationEvent
|
||||
* @param {Object} options
|
||||
*/
|
||||
exports.MutationEvent = MutationEvent = function(options) {
|
||||
this._cancelable = false;
|
||||
this._timeStamp = 0;
|
||||
};
|
||||
|
||||
MutationEvent.prototype = new Event();
|
||||
__extend__(MutationEvent.prototype,{
|
||||
get relatedNode(){
|
||||
return this._relatedNode;
|
||||
},
|
||||
get prevValue(){
|
||||
return this._prevValue;
|
||||
},
|
||||
get newValue(){
|
||||
return this._newValue;
|
||||
},
|
||||
get attrName(){
|
||||
return this._attrName;
|
||||
},
|
||||
get attrChange(){
|
||||
return this._attrChange;
|
||||
},
|
||||
initMutationEvent: function( type, bubbles, cancelable,
|
||||
relatedNode, prevValue, newValue, attrName, attrChange ){
|
||||
this._relatedNode = relatedNode;
|
||||
this._prevValue = prevValue;
|
||||
this._newValue = newValue;
|
||||
this._attrName = attrName;
|
||||
this._attrChange = attrChange;
|
||||
switch(type){
|
||||
case "DOMSubtreeModified":
|
||||
this.initEvent(type, true, false);
|
||||
break;
|
||||
case "DOMNodeInserted":
|
||||
this.initEvent(type, true, false);
|
||||
break;
|
||||
case "DOMNodeRemoved":
|
||||
this.initEvent(type, true, false);
|
||||
break;
|
||||
case "DOMNodeRemovedFromDocument":
|
||||
this.initEvent(type, false, false);
|
||||
break;
|
||||
case "DOMNodeInsertedIntoDocument":
|
||||
this.initEvent(type, false, false);
|
||||
break;
|
||||
case "DOMAttrModified":
|
||||
this.initEvent(type, true, false);
|
||||
break;
|
||||
case "DOMCharacterDataModified":
|
||||
this.initEvent(type, true, false);
|
||||
break;
|
||||
default:
|
||||
this.initEvent(type, bubbles, cancelable);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// constants
|
||||
MutationEvent.ADDITION = 0;
|
||||
MutationEvent.MODIFICATION = 1;
|
||||
MutationEvent.REMOVAL = 2;
|
||||
|
||||
}(/*Envjs.DOM.MutationEvent*/));
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.DOM.EventException').debug('available');
|
||||
});
|
||||
|
||||
/**
|
||||
* @name EventException
|
||||
*/
|
||||
exports.EventException = EventException = function(code) {
|
||||
this.code = code;
|
||||
};
|
||||
EventException.UNSPECIFIED_EVENT_TYPE_ERR = 0;
|
||||
|
||||
}(/*Envjs.DOM2.EventException*/));
|
||||
/**
|
||||
*
|
||||
* DOM Level 2: http://www.w3.org/TR/DOM-Level-2-Events/events.html
|
||||
* DOM Level 3: http://www.w3.org/TR/DOM-Level-3-Events/
|
||||
*
|
||||
* interface DocumentEvent {
|
||||
* Event createEvent (in DOMString eventType)
|
||||
* raises (DOMException);
|
||||
* };
|
||||
*
|
||||
* Firefox (3.6) exposes DocumentEvent
|
||||
* Safari (4) does NOT.
|
||||
*/
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.DOM.DocumentEvent').debug('available');
|
||||
});
|
||||
|
||||
/**
|
||||
* TODO: Not sure we need a full prototype. We not just an regular object?
|
||||
*/
|
||||
exports.DocumentEvent = DocumentEvent = function(){};
|
||||
DocumentEvent.prototype.__EventMap__ = {
|
||||
// Safari4: singular and plural forms accepted
|
||||
// Firefox3.6: singular and plural forms accepted
|
||||
'Event' : Event,
|
||||
'Events' : Event,
|
||||
'UIEvent' : UIEvent,
|
||||
'UIEvents' : UIEvent,
|
||||
'MouseEvent' : MouseEvent,
|
||||
'MouseEvents' : MouseEvent,
|
||||
'MutationEvent' : MutationEvent,
|
||||
'MutationEvents' : MutationEvent,
|
||||
|
||||
// Safari4: accepts HTMLEvents, but not HTMLEvent
|
||||
// Firefox3.6: accepts HTMLEvents, but not HTMLEvent
|
||||
'HTMLEvent' : Event,
|
||||
'HTMLEvents' : Event,
|
||||
|
||||
// Safari4: both not accepted
|
||||
// Firefox3.6, only KeyEvents is accepted
|
||||
'KeyEvent' : KeyboardEvent,
|
||||
'KeyEvents' : KeyboardEvent,
|
||||
|
||||
// Safari4: both accepted
|
||||
// Firefox3.6: none accepted
|
||||
'KeyboardEvent' : KeyboardEvent,
|
||||
'KeyboardEvents' : KeyboardEvent
|
||||
};
|
||||
|
||||
DocumentEvent.prototype.createEvent = function(eventType) {
|
||||
var Clazz = this.__EventMap__[eventType];
|
||||
if (Clazz) {
|
||||
return new Clazz();
|
||||
}
|
||||
throw(new DOMException(DOMException.NOT_SUPPORTED_ERR));
|
||||
};
|
||||
|
||||
__extend__(Document.prototype, DocumentEvent.prototype);
|
||||
|
||||
|
||||
}(/*Envjs.DOM.DocumentEvent*/));
|
||||
|
||||
/**
|
||||
* @author john resig & the envjs team
|
||||
* @uri http://www.envjs.com/
|
||||
* @copyright 2008-2010
|
||||
* @license MIT
|
||||
*/
|
||||
//CLOSURE_END
|
||||
}());
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,66 @@
|
|||
// This file must be executed automatically on startup for ruby/v8 rubyracer support.
|
||||
var __this__ = this;
|
||||
|
||||
var require = (function() {
|
||||
var cached = {};
|
||||
var currentPath = Ruby.ENV['PWD'];
|
||||
var paths = [currentPath];
|
||||
|
||||
function normalize(id) {
|
||||
var file;
|
||||
id = id + '.js';
|
||||
if (/^\.\.?/.test(id)) {
|
||||
// relative path
|
||||
try{ return Ruby.File.open(id, 'r') }catch(e){}
|
||||
} else {
|
||||
for (var i = 0, len = paths.length; i < len; ++i) {
|
||||
try{ return Ruby.File.open(paths[i]+'/'+id, 'r') }catch(e){}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
|
||||
function require(id) {
|
||||
//print('require :'+ id);
|
||||
var file = normalize(id);
|
||||
if (!file) {
|
||||
throw new Error("couldn't find module \"" + id + "\"");
|
||||
}
|
||||
if (!cached.hasOwnProperty(id)) {
|
||||
//print('loading '+id);
|
||||
var source = file.read();
|
||||
source = source.replace(/^\#\!.*/, '');
|
||||
source = "(function (require, exports, module) { "+source+"\n});";
|
||||
cached[id] = {
|
||||
exports: {},
|
||||
module: {
|
||||
id: id,
|
||||
uri: id
|
||||
}
|
||||
};
|
||||
var previousPath = currentPath;
|
||||
try {
|
||||
currentPath = id.substr(0, id.lastIndexOf('/')) || '.';
|
||||
var func = global.evaluate( source, id );
|
||||
func(require, cached[id].exports, cached[id].module);
|
||||
} finally {
|
||||
currentPath = previousPath;
|
||||
}
|
||||
}
|
||||
/*
|
||||
print('returning exports for id: '+id+' '+cached[id].exports);
|
||||
for(var prop in cached[id].exports){
|
||||
print('export: '+prop);
|
||||
}
|
||||
*/
|
||||
return cached[id].exports;
|
||||
};
|
||||
|
||||
require.paths = paths;
|
||||
|
||||
return require;
|
||||
})();
|
||||
|
||||
require('./platform/johnson');
|
||||
require('./window');
|
|
@ -0,0 +1,31 @@
|
|||
require 'johnson'
|
||||
require 'net/http'
|
||||
require 'uri'
|
||||
require 'thread'
|
||||
|
||||
include Config
|
||||
|
||||
def configure_context(context)
|
||||
context['global'] = context
|
||||
context['HTTPConnection'] = HTTPConnection.new
|
||||
end
|
||||
|
||||
class HTTPConnection
|
||||
def go(connection, request, headers, data)
|
||||
headers.each{|key,value| request.add_field(key,value)}
|
||||
response, body = connection.request(request, data)
|
||||
respheaders = Hash.new
|
||||
response.each_header do |name, value|
|
||||
respheaders.store(name, value)
|
||||
end
|
||||
response['body'] = body
|
||||
[response, respheaders]
|
||||
end
|
||||
end
|
||||
|
||||
global = Johnson::Runtime.new
|
||||
configure_context(global)
|
||||
envjs = ARGV[0]
|
||||
global.load(envjs)
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
require('./platform/node');
|
||||
Envjs.eventLoop = function() {}; // disabled for clean shutdown
|
||||
|
||||
require('./window');
|
||||
new Window(__this__); // initialize a blank window
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,363 @@
|
|||
var __context__ = __this__;
|
||||
|
||||
var Envjs = Envjs ||
|
||||
require('./core').Envjs;
|
||||
require('local_settings');
|
||||
|
||||
Envjs.platform = "Johnson SpiderMonkey";
|
||||
Envjs.revision = Ruby.CONFIG.ruby_version;
|
||||
|
||||
Ruby.ARGV.shift();
|
||||
Envjs.argv = Ruby.ARGV;
|
||||
|
||||
Envjs.exit = function(){ Ruby['exit!'](); };
|
||||
|
||||
/*
|
||||
* Envjs johnson-env.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
//CLOSURE_START
|
||||
(function(){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author john resig
|
||||
*/
|
||||
// Helper method for extending one object with another.
|
||||
function __extend__(a,b) {
|
||||
for ( var i in b ) {
|
||||
if(b.hasOwnProperty(i)){
|
||||
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||
if ( g || s ) {
|
||||
if ( g ) { a.__defineGetter__(i, g); }
|
||||
if ( s ) { a.__defineSetter__(i, s); }
|
||||
} else {
|
||||
a[i] = b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
Envjs.log = function(msg){
|
||||
Ruby.puts(msg);
|
||||
}
|
||||
|
||||
Envjs.lineSource = function(e){
|
||||
return "(line ?)";
|
||||
};
|
||||
|
||||
Envjs.readConsole = function(){
|
||||
return Ruby.$stdin.gets();
|
||||
};
|
||||
|
||||
Envjs.prompt = function(){
|
||||
Ruby.$stdout.write(Envjs.CURSOR+' ');
|
||||
Ruby.$stdout.flush;
|
||||
};
|
||||
|
||||
//No REPL for
|
||||
Envjs.repl = function(){
|
||||
console.log('Envjs REPL Not Available');
|
||||
};
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger('Envjs.Platform.Johnson');
|
||||
|
||||
Envjs.eval = function(context, source, name){
|
||||
if(context == __this__){
|
||||
return global.evaluate( source, name );
|
||||
}else{
|
||||
var abc = new Ruby.Johnson.Runtime()
|
||||
log.debug('evaluating in framed context %s %s', context, abc);
|
||||
return context.evaluate( source, name );
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
/**
|
||||
* synchronizes thread modifications
|
||||
* @param {Function} fn
|
||||
*/
|
||||
var lock = new Ruby.Mutex();
|
||||
|
||||
//NOTES:
|
||||
//context['sync'] = lambda{|wrapper|
|
||||
// Proc.new{|*args|lock.synchronize {wrapper['fn'].call(*args)}}
|
||||
//}
|
||||
//context['sync'] = lambda{|fn| Proc.new{|*args| fn.call(*args) }}
|
||||
Envjs.sync = function(fn){
|
||||
//console.log('syncing js fn %s', fn);
|
||||
var wrapper = {fn:fn};
|
||||
//return lock.synchronize(fn)
|
||||
return fn;
|
||||
};
|
||||
|
||||
//NOTES:
|
||||
//context['spawn'] = lambda{|wrapper| Thread.new {wrapper['fn'].call} }
|
||||
//context['spawn'] = lambda{|wrapper| wrapper['fn'].call }
|
||||
Envjs.spawn = function(fn){
|
||||
//console.log('spawning js fn %s', fn);
|
||||
var wrapper = {fn:fn};
|
||||
return fn();
|
||||
};
|
||||
|
||||
/**
|
||||
* sleep thread for specified duration
|
||||
* @param {Object} milliseconds
|
||||
*/
|
||||
Envjs.sleep = function(milliseconds){
|
||||
return Ruby.sleep(1.0*milliseconds/1000.0);
|
||||
};
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger('Envjs.Platform.Johnson');
|
||||
|
||||
//Since we're running in spydermonkey I guess we can safely assume
|
||||
//java is not 'enabled'. I'm sure this requires more thought
|
||||
//than I've given it here
|
||||
Envjs.javaEnabled = false;
|
||||
|
||||
Envjs.homedir = Ruby.ENV.HOME
|
||||
Envjs.tmpdir = Ruby.ENV.TMPDIR;
|
||||
Envjs.os_name = Ruby.CONFIG.host_os;
|
||||
Envjs.os_arch = Ruby.CONFIG.host_cpu;
|
||||
Envjs.os_version = "";//part of os_arch
|
||||
Envjs.lang = Ruby.ENV.LANG;
|
||||
|
||||
Envjs.gc = function(){ Ruby.Johnson.Runtime.gc(); };
|
||||
|
||||
/**
|
||||
* Makes an object window-like by proxying object accessors
|
||||
* @param {Object} scope
|
||||
* @param {Object} parent
|
||||
*/
|
||||
Envjs.proxy = function(scope, parent) {
|
||||
try{
|
||||
if(scope == __this__){
|
||||
return scope;
|
||||
}else{
|
||||
return new Ruby.Johnson.Runtime();
|
||||
}
|
||||
}catch(e){
|
||||
console.log('failed to init standard objects %s %s \n%s', scope, parent, e);
|
||||
}
|
||||
};
|
||||
|
||||
})();(function(){
|
||||
|
||||
var log = Envjs.logger('Envjs.XMLHttpRequest.Johnson');
|
||||
|
||||
/**
|
||||
* Get 'Current Working Directory'
|
||||
*/
|
||||
Envjs.getcwd = function() {
|
||||
return Ruby.ENV['PWD'];
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to read the contents of a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.readFromFile = function( url ){
|
||||
if(/^file\:\/\//.test(url))
|
||||
url = url.substring(7,url.length);
|
||||
log.debug('reading file %s', url);
|
||||
var file = Ruby.File.open(url, 'r'),
|
||||
data = file.read();
|
||||
return data;
|
||||
};
|
||||
|
||||
Envjs.writeToFile = function(text, url){
|
||||
var file = Ruby.File.open(url, 'w');
|
||||
log.debug('writing to file %s', url);
|
||||
file.write(text);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to write to a local file
|
||||
* @param {Object} text
|
||||
* @param {Object} suffix
|
||||
*/
|
||||
Envjs.writeToTempFile = function(text, suffix){
|
||||
// Create temp file.
|
||||
var temp = Envjs.tmpdir+"."+(new Date().getTime())+(suffix||'.js');
|
||||
log.debug("writing text to temp url : %s ", temp);
|
||||
Envjs.writeToFile(text, temp);
|
||||
return temp;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to read the contents of a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.readFromFile = function( url ){
|
||||
if(/^file\:\/\//.test(url))
|
||||
url = url.substring(7,url.length);
|
||||
log.debug('reading file %s', url);
|
||||
var file = Ruby.File.open(url, 'r'),
|
||||
data = file.read();
|
||||
return data;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to delete a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.deleteFile = function(url){
|
||||
return ;//TODO
|
||||
};
|
||||
|
||||
/**
|
||||
* establishes connection and calls responsehandler
|
||||
* @param {Object} xhr
|
||||
* @param {Object} responseHandler
|
||||
* @param {Object} data
|
||||
*/
|
||||
Envjs.connection = function(xhr, responseHandler, data){
|
||||
var url = xhr.url,
|
||||
urlparts = Envjs.urlsplit(xhr.url),
|
||||
connection,
|
||||
request,
|
||||
headers,
|
||||
header,
|
||||
length,
|
||||
binary = false,
|
||||
name, value,
|
||||
contentEncoding,
|
||||
responseXML,
|
||||
i;
|
||||
|
||||
if ( /^file\:/.test(url) ) {
|
||||
//console.log('establishing file connection');
|
||||
Envjs.localXHR(url, xhr, connection, data);
|
||||
} else {
|
||||
log.debug('establishing http connection %s', xhr.url);
|
||||
try{
|
||||
|
||||
connection = Ruby.Net.HTTP.start(
|
||||
urlparts.hostname,
|
||||
Number(urlparts.port||80)
|
||||
);
|
||||
log.debug('connection established %s', connection);
|
||||
|
||||
path = urlparts.path+(urlparts.query?'?'+urlparts.query:'');
|
||||
switch( xhr.method.toUpperCase() ){
|
||||
case "GET":
|
||||
request = new Ruby.Net.HTTP.Get(path);break;
|
||||
case "PUT":
|
||||
request = new Ruby.Net.HTTP.Put(path);break;
|
||||
case "POST" :
|
||||
request = new Ruby.Net.HTTP.Post(path);break;
|
||||
case "HEAD":
|
||||
request = new Ruby.Net.HTTP.Head(path);break;
|
||||
case "DELETE":
|
||||
request = new Ruby.Net.HTTP.Delete(path);break;
|
||||
default:
|
||||
request = null;
|
||||
}
|
||||
log.debug('request query string %s', urlparts.query);
|
||||
log.debug('formulated %s request %s %s', xhr.method, urlparts.path, request);
|
||||
//TODO: add gzip support
|
||||
//connection.putheader("Accept-Encoding", 'gzip');
|
||||
//connection.endheaders();
|
||||
|
||||
//write data to output stream if required
|
||||
//TODO: if they have set the request header for a chunked
|
||||
//request body, implement a chunked output stream
|
||||
if(data){
|
||||
if(data instanceof Document){
|
||||
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||
connection.send((new XMLSerializer()).serializeToString(data));
|
||||
}
|
||||
}else if(data.length&&data.length>0){
|
||||
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||
connection.send(data+'');
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
log.error("connection failed %s",e);
|
||||
if (connection)
|
||||
connection.finish();
|
||||
connection = null;
|
||||
}
|
||||
}
|
||||
|
||||
if(connection){
|
||||
[response, headers] = HTTPConnection.go(connection, request, xhr.headers, null);
|
||||
|
||||
try{
|
||||
// Stick the response headers into responseHeaders
|
||||
var keys = headers.keys();
|
||||
for (var i = 0;i<keys.length;i++) {
|
||||
header = keys[i];
|
||||
log.debug('response header [%s] = %s', header, headers[header]);
|
||||
xhr.responseHeaders[header] = headers[header];
|
||||
}
|
||||
}catch(e){
|
||||
log.error('failed to load response headers \n%s',e);
|
||||
}
|
||||
|
||||
xhr.readyState = 4;
|
||||
xhr.status = parseInt(response.code,10) || undefined;
|
||||
xhr.statusText = response.message || "";
|
||||
log.info('%s %s %s %s', xhr.method, xhr.status, xhr.url, xhr.statusText);
|
||||
contentEncoding = xhr.getResponseHeader('content-encoding') || "utf-8";
|
||||
responseXML = null;
|
||||
|
||||
try{
|
||||
//console.log('contentEncoding %s', contentEncoding);
|
||||
if( contentEncoding.toLowerCase() == "gzip" ||
|
||||
contentEncoding.toLowerCase() == "decompress"){
|
||||
//zipped content
|
||||
binary = true;
|
||||
//TODO
|
||||
log.debug('TODO: handle gzip compression');
|
||||
xhr.responseText = response.body;
|
||||
}else{
|
||||
//this is a text file
|
||||
xhr.responseText = response.body+'';
|
||||
}
|
||||
}catch(e){
|
||||
log.warn('failed to open connection stream \n%s, %s %s %s',
|
||||
xhr.status, xhr.url, e.toString(), e
|
||||
);
|
||||
}finally{
|
||||
if(connection)
|
||||
connection.finish();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(responseHandler){
|
||||
log.debug('calling ajax response handler');
|
||||
if(!xhr.async){
|
||||
log.debug('calling sync response handler directly');
|
||||
responseHandler();
|
||||
}else{
|
||||
log.debug('using setTimeout for async response handler');
|
||||
setTimeout(responseHandler, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(/*Envjs.XMLHttpRequest.Johnson*/);
|
||||
/**
|
||||
* @author john resig & the envjs team
|
||||
* @uri http://www.envjs.com/
|
||||
* @copyright 2008-2010
|
||||
* @license MIT
|
||||
*/
|
||||
//CLOSURE_END
|
||||
}());
|
|
@ -0,0 +1,343 @@
|
|||
var __context__ = __this__ = global;
|
||||
|
||||
var Envjs = Envjs ||
|
||||
require('./core').Envjs;
|
||||
require('./../../local_settings');
|
||||
|
||||
Envjs.platform = "Node";
|
||||
Envjs.revision = process.version;
|
||||
|
||||
/*process.on('uncaughtException', function (err) {
|
||||
console.log('Envjs Caught exception: %s \n %s', err);
|
||||
});*/
|
||||
|
||||
Envjs.argv = process.argv;
|
||||
Envjs.argv.shift();
|
||||
Envjs.argv.shift();//node is argv[0] but we want to start at argv[1]
|
||||
|
||||
Envjs.exit = function(){
|
||||
/*setTimeout(function () {
|
||||
if(!Envjs.timers.length){
|
||||
//console.log('no timers remaining %s', Envjs.timers.length);
|
||||
process.exit();
|
||||
}else{
|
||||
Envjs.exit();
|
||||
}
|
||||
}, 13);*/
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Envjs node-env.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
//CLOSURE_START
|
||||
(function(){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author john resig
|
||||
*/
|
||||
// Helper method for extending one object with another.
|
||||
function __extend__(a,b) {
|
||||
for ( var i in b ) {
|
||||
if(b.hasOwnProperty(i)){
|
||||
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||
if ( g || s ) {
|
||||
if ( g ) { a.__defineGetter__(i, g); }
|
||||
if ( s ) { a.__defineSetter__(i, s); }
|
||||
} else {
|
||||
a[i] = b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
var $print = require('sys').print;
|
||||
|
||||
Envjs.log = function(msg){
|
||||
console.log(msg+'\n\n');
|
||||
};
|
||||
|
||||
Envjs.lineSource = function(e){
|
||||
return "(line ?)";
|
||||
};
|
||||
|
||||
Envjs.readConsole = function(){
|
||||
return $stdin.gets();
|
||||
};
|
||||
|
||||
Envjs.prompt = function(){
|
||||
$stdout.write(Envjs.CURSOR+' ');
|
||||
$stdout.flush;
|
||||
};
|
||||
|
||||
//No REPL for
|
||||
Envjs.repl = function(){
|
||||
//require('repl').start(Envjs.CURSOR+' ');
|
||||
console.log('Envjs REPL Not Available');
|
||||
};
|
||||
var Script = process.binding('evals').Script;
|
||||
|
||||
Envjs.eval = function(context, source, name, warming){
|
||||
if(context === global){
|
||||
return warming ?
|
||||
eval(source) :
|
||||
Script.runInThisContext(source, name);
|
||||
}else{
|
||||
return Script.runInNewContext(source, context, name);
|
||||
}
|
||||
};
|
||||
Envjs.wait = function(){ return; }
|
||||
|
||||
var $tick = function(){
|
||||
process.nextTick(function () {
|
||||
//console.log('node tick');
|
||||
Envjs.tick();
|
||||
$tick();
|
||||
});
|
||||
};
|
||||
|
||||
Envjs.eventLoop = function(){
|
||||
//console.log('event loop');
|
||||
$tick();
|
||||
};
|
||||
/**
|
||||
* provides callback hook for when the system exits
|
||||
*/
|
||||
Envjs.onExit = function(callback){
|
||||
process.on('exit', callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* synchronizes thread modifications
|
||||
* @param {Function} fn
|
||||
*/
|
||||
Envjs.sync = function(fn){
|
||||
//console.log('syncing js fn %s', fn);
|
||||
return fn;
|
||||
};
|
||||
|
||||
Envjs.spawn = function(fn){
|
||||
return fn();
|
||||
};
|
||||
|
||||
/**
|
||||
* sleep thread for specified duration
|
||||
* @param {Object} milliseconds
|
||||
*/
|
||||
Envjs.sleep = function(milliseconds){
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
//Since we're running in v8 I guess we can safely assume
|
||||
//java is not 'enabled'. I'm sure this requires more thought
|
||||
//than I've given it here
|
||||
Envjs.javaEnabled = false;
|
||||
|
||||
Envjs.homedir = process.env["HOME"];
|
||||
Envjs.tmpdir = process.env["TMPDIR"];
|
||||
Envjs.os_name = process.platform;
|
||||
Envjs.os_arch = "os arch";
|
||||
Envjs.os_version = "os version";
|
||||
Envjs.lang = process.env["LANG"];
|
||||
|
||||
|
||||
Envjs.gc = function(){ return; };
|
||||
|
||||
/**
|
||||
* Makes an object window-like by proxying object accessors
|
||||
* @param {Object} scope
|
||||
* @param {Object} parent
|
||||
*/
|
||||
Envjs.proxy = function(scope, parent) {
|
||||
try{
|
||||
if(scope.toString() == global){
|
||||
return __this__;
|
||||
}else{
|
||||
return scope;
|
||||
}
|
||||
}catch(e){
|
||||
console.log('failed to init standard objects %s %s \n%s', scope, parent, e);
|
||||
}
|
||||
|
||||
};var filesystem = require('fs');
|
||||
/**
|
||||
* Get 'Current Working Directory'
|
||||
*/
|
||||
Envjs.getcwd = function() {
|
||||
return process.cwd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to write to a local file
|
||||
* @param {Object} text
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.writeToFile = function(text, url){
|
||||
if(/^file\:\/\//.test(url))
|
||||
url = url.substring(7,url.length);
|
||||
filesystem.writeFileSync(url, text, 'utf8');
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to write to a local file
|
||||
* @param {Object} text
|
||||
* @param {Object} suffix
|
||||
*/
|
||||
Envjs.writeToTempFile = function(text, suffix){
|
||||
var url = Envjs.tmpdir+'envjs-'+(new Date().getTime())+'.'+suffix;
|
||||
if(/^file\:\/\//.test(url))
|
||||
url = url.substring(7,url.length);
|
||||
filesystem.writeFileSync(tmpfile, text, 'utf8');
|
||||
return tmpfile;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to read the contents of a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.readFromFile = function( url ){
|
||||
if(/^file\:\/\//.test(url))
|
||||
url = url.substring(7,url.length);
|
||||
return filesystem.readFileSync(url, 'utf8');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to delete a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.deleteFile = function(url){
|
||||
if(/^file\:\/\//.test(url))
|
||||
url = url.substring(7,url.length);
|
||||
filesystem.unlink(url);
|
||||
};
|
||||
|
||||
/**
|
||||
* establishes connection and calls responsehandler
|
||||
* @param {Object} xhr
|
||||
* @param {Object} responseHandler
|
||||
* @param {Object} data
|
||||
*/
|
||||
Envjs.connection = function(xhr, responseHandler, data){
|
||||
var url = xhr.url,
|
||||
connection,
|
||||
request,
|
||||
binary = false,
|
||||
contentEncoding,
|
||||
responseXML = null,
|
||||
http = require('http'),
|
||||
urlparts = Envjs.urlsplit(url),
|
||||
i;
|
||||
|
||||
|
||||
if ( /^file\:/.test(url) ) {
|
||||
Envjs.localXHR(url, xhr, connection, data);
|
||||
} else {
|
||||
//console.log('connecting to %s \n\t port(%s) host(%s) path(%s) query(%s)',
|
||||
// url, urlparts.port, urlparts.hostname, urlparts.path, urlparts.query);
|
||||
connection = http.createClient(urlparts.port||'80', urlparts.hostname);
|
||||
request = connection.request(
|
||||
xhr.method,
|
||||
urlparts.path+(urlparts.query?"?"+urlparts.query:''),
|
||||
__extend__(xhr.headers,{
|
||||
"Host": urlparts.hostname,
|
||||
//"Connection":"Keep-Alive"
|
||||
//"Accept-Encoding", 'gzip'
|
||||
})
|
||||
);
|
||||
xhr.statusText = "";
|
||||
|
||||
if(connection&&request){
|
||||
request.on('response', function (response) {
|
||||
//console.log('response begin');
|
||||
xhr.readyState = 3;
|
||||
response.on('end', function (chunk) {
|
||||
//console.log('connection complete');
|
||||
xhr.readyState = 4;
|
||||
if(responseHandler){
|
||||
//console.log('calling ajax response handler');
|
||||
if(!xhr.async){
|
||||
responseHandler();
|
||||
}else{
|
||||
setTimeout(responseHandler, 1);
|
||||
}
|
||||
}
|
||||
if(xhr.onreadystatechange){
|
||||
xhr.onreadystatechange();
|
||||
}
|
||||
});
|
||||
|
||||
xhr.responseHeaders = __extend__({},response.headers);
|
||||
xhr.statusText = "OK";
|
||||
xhr.status = response.statusCode;
|
||||
//console.log('response headers : %s', JSON.stringify(xhr.responseHeaders));
|
||||
contentEncoding = xhr.getResponseHeader('Content-Encoding') || "utf-8";
|
||||
response.setEncoding(contentEncoding);
|
||||
//console.log('contentEncoding %s', contentEncoding);
|
||||
|
||||
response.on('data', function (chunk) {
|
||||
//console.log('\nBODY: %s', chunk);
|
||||
if( contentEncoding.match("gzip") ||
|
||||
contentEncoding.match("decompress")){
|
||||
//zipped content
|
||||
binary = true;
|
||||
//Not supported yet
|
||||
xhr.responseText += (chunk+'');
|
||||
}else{
|
||||
//this is a text file
|
||||
xhr.responseText += (chunk+'');
|
||||
}
|
||||
if(xhr.onreadystatechange){
|
||||
xhr.onreadystatechange();
|
||||
}
|
||||
});
|
||||
if(xhr.onreadystatechange){
|
||||
xhr.onreadystatechange();
|
||||
}
|
||||
});
|
||||
}
|
||||
//write data to output stream if required
|
||||
//TODO: if they have set the request header for a chunked
|
||||
//request body, implement a chunked output stream
|
||||
|
||||
//console.log('sending request %s\n', xhr.url);
|
||||
if(data){
|
||||
if(data instanceof Document){
|
||||
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||
xml = (new XMLSerializer()).serializeToString(data);
|
||||
request.write(xml);
|
||||
}
|
||||
}else if(data.length&&data.length>0){
|
||||
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||
request.write(data);
|
||||
}
|
||||
}
|
||||
request.end();
|
||||
}else{
|
||||
request.end();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @author john resig & the envjs team
|
||||
* @uri http://www.envjs.com/
|
||||
* @copyright 2008-2010
|
||||
* @license MIT
|
||||
*/
|
||||
//CLOSURE_END
|
||||
}());
|
|
@ -0,0 +1,461 @@
|
|||
/*
|
||||
* Envjs rhino-env.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
var Envjs = Envjs ||
|
||||
require('./core').Envjs;
|
||||
require('local_settings');
|
||||
|
||||
var __context__ = Packages.org.mozilla.javascript.Context.getCurrentContext();
|
||||
|
||||
Envjs.platform = "Rhino";
|
||||
Envjs.revision = "1.7.0.rc2";
|
||||
Envjs.argv = [];
|
||||
if(__argv__ && __argv__.length){
|
||||
for(var i = 0; i < __argv__.length; i++){
|
||||
Envjs.argv[i] = __argv__[i];
|
||||
}
|
||||
}
|
||||
|
||||
Envjs.exit = function(){
|
||||
java.lang.System.exit(0);
|
||||
};
|
||||
|
||||
/*
|
||||
* Envjs rhino-env.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
//CLOSURE_START
|
||||
(function(){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author john resig
|
||||
*/
|
||||
// Helper method for extending one object with another.
|
||||
function __extend__(a,b) {
|
||||
for ( var i in b ) {
|
||||
if(b.hasOwnProperty(i)){
|
||||
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||
if ( g || s ) {
|
||||
if ( g ) { a.__defineGetter__(i, g); }
|
||||
if ( s ) { a.__defineSetter__(i, s); }
|
||||
} else {
|
||||
a[i] = b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes message to system out.
|
||||
*
|
||||
* @param {Object} message
|
||||
*/
|
||||
(function(){
|
||||
|
||||
Envjs.log = print;
|
||||
|
||||
Envjs.lineSource = function(e){
|
||||
return e&&e.rhinoException?e.rhinoException.lineSource():"(line ?)";
|
||||
};
|
||||
|
||||
var $in, log;
|
||||
Envjs.readConsole = function(){
|
||||
log = log||Envjs.logger('Envjs.Rhino');
|
||||
$in = $in||new java.io.BufferedReader(
|
||||
new java.io.InputStreamReader(java.lang.System['in'])
|
||||
);
|
||||
return $in.readLine()+'';
|
||||
};
|
||||
Envjs.prompt = function(){
|
||||
java.lang.System.out.print(Envjs.CURSOR+' ');
|
||||
java.lang.System.out.flush();
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger('Envjs.HTML.Rhino');
|
||||
|
||||
Envjs.eval = function(context, source, name){
|
||||
//console.log('evaluating javascript source %s', source.substring(0,64));
|
||||
return __context__.evaluateString(
|
||||
context,
|
||||
source,
|
||||
name,
|
||||
0,
|
||||
null
|
||||
);
|
||||
};
|
||||
|
||||
}());Envjs.renderSVG = function(svgstring, url){
|
||||
//console.log("svg template url %s", templateSVG);
|
||||
// Create a JPEG transcoder
|
||||
var t = new Packages.org.apache.batik.transcoder.image.JPEGTranscoder();
|
||||
|
||||
// Set the transcoding hints.
|
||||
t.addTranscodingHint(
|
||||
Packages.org.apache.batik.transcoder.image.JPEGTranscoder.KEY_QUALITY,
|
||||
new java.lang.Float(1.0));
|
||||
// Create the transcoder input.
|
||||
var input = new Packages.org.apache.batik.transcoder.TranscoderInput(
|
||||
new java.io.StringReader(svgstring));
|
||||
|
||||
// Create the transcoder output.
|
||||
var ostream = new java.io.ByteArrayOutputStream();
|
||||
var output = new Packages.org.apache.batik.transcoder.TranscoderOutput(ostream);
|
||||
|
||||
// Save the image.
|
||||
t.transcode(input, output);
|
||||
|
||||
// Flush and close the stream.
|
||||
ostream.flush();
|
||||
ostream.close();
|
||||
|
||||
var out = new java.io.FileOutputStream(new java.io.File(new java.net.URI(url.toString())));
|
||||
try{
|
||||
out.write( ostream.toByteArray() );
|
||||
}catch(e){
|
||||
|
||||
}finally{
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
};
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger('Envjs.Timer.Rhino');
|
||||
/**
|
||||
* Rhino provides a very succinct 'sync'
|
||||
* @param {Function} fn
|
||||
*/
|
||||
try{
|
||||
Envjs.sync = sync;
|
||||
Envjs.spawn = spawn;
|
||||
//print('sync and spawn are available');
|
||||
} catch(e){
|
||||
//print('sync and spawn are not available : ' + e);
|
||||
//sync unavailable on AppEngine
|
||||
Envjs.sync = function(fn){
|
||||
console.log('Threadless platform, sync is safe');
|
||||
return fn;
|
||||
};
|
||||
|
||||
Envjs.spawn = function(fn){
|
||||
console.log('Threadless platform, spawn shares main thread.');
|
||||
return fn();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* sleep thread for specified duration
|
||||
* @param {Object} milliseconds
|
||||
*/
|
||||
Envjs.sleep = function(milliseconds){
|
||||
try{
|
||||
return java.lang.Thread.currentThread().sleep(milliseconds);
|
||||
}catch(e){
|
||||
console.log('Threadless platform, cannot sleep.');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* provides callback hook for when the system exits
|
||||
*/
|
||||
Envjs.onExit = function(callback){
|
||||
var rhino = Packages.org.mozilla.javascript,
|
||||
contextFactory = __context__.getFactory(),
|
||||
listener = new rhino.ContextFactory.Listener({
|
||||
contextReleased: function(context){
|
||||
if(context === __context__)
|
||||
console.log('context released', context);
|
||||
contextFactory.removeListener(this);
|
||||
if(callback)
|
||||
callback();
|
||||
}
|
||||
});
|
||||
contextFactory.addListener(listener);
|
||||
};
|
||||
|
||||
}());
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger('Envjs.XMLHttpRequest.Rhino');
|
||||
|
||||
/**
|
||||
* Get 'Current Working Directory'
|
||||
*/
|
||||
Envjs.getcwd = function() {
|
||||
return java.lang.System.getProperty('user.dir');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to write to a local file
|
||||
* @param {Object} text
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.writeToFile = function(text, url){
|
||||
//Envjs.debug("writing text to url : " + url);
|
||||
var out = new java.io.FileWriter(
|
||||
new java.io.File(
|
||||
new java.net.URI(url.toString())));
|
||||
out.write( text, 0, text.length );
|
||||
out.flush();
|
||||
out.close();
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to write to a local file
|
||||
* @param {Object} text
|
||||
* @param {Object} suffix
|
||||
*/
|
||||
Envjs.writeToTempFile = function(text, suffix){
|
||||
//console.log("writing text to temp url : %s");
|
||||
// Create temp file.
|
||||
var temp = java.io.File.createTempFile("envjs-tmp", suffix);
|
||||
|
||||
// Delete temp file when program exits.
|
||||
temp.deleteOnExit();
|
||||
|
||||
// Write to temp file
|
||||
var out = new java.io.FileWriter(temp);
|
||||
out.write(text, 0, text.length);
|
||||
out.close();
|
||||
return temp.getAbsolutePath().toString()+'';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to read the contents of a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.readFromFile = function( url ){
|
||||
if(typeof url == 'string')
|
||||
url = Envjs.uri(url);
|
||||
//console.log("reading from url : %s", url);
|
||||
var fileReader = new java.io.FileReader(
|
||||
new java.io.File(
|
||||
new java.net.URI( url )));
|
||||
|
||||
var stringwriter = new java.io.StringWriter(),
|
||||
buffer = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 1024),
|
||||
length;
|
||||
|
||||
while ((length = fileReader.read(buffer, 0, 1024)) != -1) {
|
||||
stringwriter.write(buffer, 0, length);
|
||||
}
|
||||
|
||||
stringwriter.close();
|
||||
return stringwriter.toString()+"";
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to delete a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.deleteFile = function(url){
|
||||
var file = new java.io.File( new java.net.URI( url ) );
|
||||
file["delete"]();
|
||||
};
|
||||
|
||||
/**
|
||||
* establishes connection and calls responsehandler
|
||||
* @param {Object} xhr
|
||||
* @param {Object} responseHandler
|
||||
* @param {Object} data
|
||||
*/
|
||||
Envjs.connection = function(xhr, responseHandler, data){
|
||||
var url = java.net.URL(xhr.url),
|
||||
connection,
|
||||
header,
|
||||
outstream,
|
||||
buffer,
|
||||
length,
|
||||
binary = false,
|
||||
name, value,
|
||||
contentEncoding,
|
||||
instream,
|
||||
responseXML,
|
||||
i;
|
||||
|
||||
|
||||
if ( /^file\:/.test(url) ) {
|
||||
Envjs.localXHR(url, xhr, connection, data);
|
||||
} else {
|
||||
connection = url.openConnection();
|
||||
//handle redirects manually since cookie support sucks out of the box
|
||||
connection.setFollowRedirects(false);
|
||||
connection.setRequestMethod( xhr.method );
|
||||
|
||||
// Add headers to Java connection
|
||||
for (header in xhr.headers){
|
||||
connection.addRequestProperty(header+'', xhr.headers[header]+'');
|
||||
}
|
||||
connection.addRequestProperty("Accept-Encoding", 'gzip');
|
||||
|
||||
//write data to output stream if required
|
||||
//TODO: if they have set the request header for a chunked
|
||||
//request body, implement a chunked output stream
|
||||
if(data){
|
||||
if(data instanceof Document){
|
||||
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||
connection.setDoOutput(true);
|
||||
outstream = connection.getOutputStream(),
|
||||
xml = (new XMLSerializer()).serializeToString(data);
|
||||
buffer = new java.lang.String(xml).getBytes('UTF-8');
|
||||
outstream.write(buffer, 0, buffer.length);
|
||||
outstream.close();
|
||||
}
|
||||
}else if(data.length&&data.length>0){
|
||||
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||
connection.setDoOutput(true);
|
||||
outstream = connection.getOutputStream();
|
||||
buffer = new java.lang.String(data).getBytes('UTF-8');
|
||||
outstream.write(buffer, 0, buffer.length);
|
||||
outstream.close();
|
||||
}
|
||||
}
|
||||
connection.connect();
|
||||
}else{
|
||||
connection.connect();
|
||||
}
|
||||
}
|
||||
|
||||
if(connection){
|
||||
try{
|
||||
length = connection.getHeaderFields().size();
|
||||
// Stick the response headers into responseHeaders
|
||||
for (i = 0; i < length; i++) {
|
||||
name = connection.getHeaderFieldKey(i);
|
||||
value = connection.getHeaderField(i);
|
||||
if (name)
|
||||
xhr.responseHeaders[name+''] = value+'';
|
||||
}
|
||||
}catch(e){
|
||||
console.log('failed to load response headers \n%s',e);
|
||||
}
|
||||
|
||||
xhr.readyState = 4;
|
||||
xhr.status = parseInt(connection.responseCode,10) || undefined;
|
||||
xhr.statusText = connection.responseMessage || "";
|
||||
|
||||
contentEncoding = connection.getContentEncoding() || "utf-8";
|
||||
instream = null;
|
||||
responseXML = null;
|
||||
|
||||
try{
|
||||
//console.log('contentEncoding %s', contentEncoding);
|
||||
if( contentEncoding.equalsIgnoreCase("gzip") ||
|
||||
contentEncoding.equalsIgnoreCase("decompress")){
|
||||
//zipped content
|
||||
binary = true;
|
||||
outstream = new java.io.ByteArrayOutputStream();
|
||||
buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024);
|
||||
instream = new java.util.zip.GZIPInputStream(connection.getInputStream())
|
||||
}else{
|
||||
//this is a text file
|
||||
outstream = new java.io.StringWriter();
|
||||
buffer = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 1024);
|
||||
instream = new java.io.InputStreamReader(connection.getInputStream());
|
||||
}
|
||||
}catch(e){
|
||||
if (connection.getResponseCode() == 404){
|
||||
console.log('failed to open connection stream \n %s %s',
|
||||
e.toString(), e);
|
||||
}else{
|
||||
console.log('failed to open connection stream \n %s %s',
|
||||
e.toString(), e);
|
||||
}
|
||||
instream = connection.getErrorStream();
|
||||
}
|
||||
|
||||
while ((length = instream.read(buffer, 0, 1024)) != -1) {
|
||||
outstream.write(buffer, 0, length);
|
||||
}
|
||||
|
||||
outstream.close();
|
||||
instream.close();
|
||||
|
||||
if(binary){
|
||||
xhr.responseText = new java.lang.String(outstream.toByteArray(), 'UTF-8')+'';
|
||||
}else{
|
||||
xhr.responseText = outstream.toString()+'';
|
||||
}
|
||||
|
||||
}
|
||||
if(responseHandler){
|
||||
//console.log('calling ajax response handler');
|
||||
if(!xhr.async){
|
||||
responseHandler();
|
||||
}else{
|
||||
//console.log('synchronizing ajax response handler via setTimeout');
|
||||
setTimeout(responseHandler, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger('Envjs.Window.Rhino');
|
||||
|
||||
//Since we're running in rhino I guess we can safely assume
|
||||
//java is 'enabled'. I'm sure this requires more thought
|
||||
//than I've given it here
|
||||
Envjs.javaEnabled = true;
|
||||
|
||||
Envjs.homedir = java.lang.System.getProperty("user.home");
|
||||
Envjs.tmpdir = java.lang.System.getProperty("java.io.tmpdir");
|
||||
Envjs.os_name = java.lang.System.getProperty("os.name");
|
||||
Envjs.os_arch = java.lang.System.getProperty("os.arch");
|
||||
Envjs.os_version = java.lang.System.getProperty("os.version");
|
||||
Envjs.lang = java.lang.System.getProperty("user.lang");
|
||||
|
||||
|
||||
Envjs.gc = function(){ gc(); };
|
||||
|
||||
/**
|
||||
* Makes an object window-like by proxying object accessors
|
||||
* @param {Object} scope
|
||||
* @param {Object} parent
|
||||
*/
|
||||
Envjs.proxy = function(scope, parent) {
|
||||
try{
|
||||
if(scope+'' == '[object global]'){
|
||||
return scope;
|
||||
}else{
|
||||
return __context__.initStandardObjects();
|
||||
}
|
||||
}catch(e){
|
||||
console.log('failed to init standard objects %s %s \n%s', scope, parent, e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}());
|
||||
/**
|
||||
* @author john resig & the envjs team
|
||||
* @uri http://www.envjs.com/
|
||||
* @copyright 2008-2010
|
||||
* @license MIT
|
||||
*/
|
||||
//CLOSURE_END
|
||||
}());
|
|
@ -0,0 +1,340 @@
|
|||
var __context__ = __this__;
|
||||
|
||||
var Envjs = Envjs ||
|
||||
require('./core').Envjs;
|
||||
require('local_settings');
|
||||
|
||||
Envjs.platform = "V8 RubyRacer";
|
||||
Envjs.revision = Ruby.CONFIG.ruby_version;
|
||||
|
||||
Ruby.ARGV.shift();
|
||||
Envjs.argv = Ruby.ARGV;
|
||||
|
||||
Envjs.exit = function(){ Ruby.Process['exit!'](); };
|
||||
|
||||
/*
|
||||
* Envjs rubyracer-env.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
//CLOSURE_START
|
||||
(function(){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author john resig
|
||||
*/
|
||||
// Helper method for extending one object with another.
|
||||
function __extend__(a,b) {
|
||||
for ( var i in b ) {
|
||||
if(b.hasOwnProperty(i)){
|
||||
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||
if ( g || s ) {
|
||||
if ( g ) { a.__defineGetter__(i, g); }
|
||||
if ( s ) { a.__defineSetter__(i, s); }
|
||||
} else {
|
||||
a[i] = b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
Envjs.log = function(msg){
|
||||
Ruby.puts(msg);
|
||||
};
|
||||
|
||||
Envjs.lineSource = function(e){
|
||||
return "(line ?)";
|
||||
};
|
||||
|
||||
var line = "";
|
||||
Envjs.readConsole = function(){
|
||||
try{
|
||||
line = Ruby.$stdin.gets();
|
||||
}catch(e){
|
||||
console.log('ERROR : %s', e);
|
||||
}
|
||||
return line;
|
||||
};
|
||||
|
||||
Envjs.prompt = function(){
|
||||
Ruby.$stdout.write(Envjs.CURSOR+' ');
|
||||
Ruby.$stdout.flush;
|
||||
};
|
||||
|
||||
//No REPL for
|
||||
Envjs.repl = function(){
|
||||
console.log('Envjs REPL Not Available');
|
||||
};
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger('Envjs.Platform.RubyRacer');
|
||||
|
||||
Envjs.eval = function(context, source, name){
|
||||
if(context == __this__){
|
||||
return __this__.eval( source );
|
||||
}else{
|
||||
log.debug('evaluating in proxy scope %s', context);
|
||||
return context.eval( source );
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
/**
|
||||
* synchronizes thread modifications
|
||||
* @param {Function} fn
|
||||
*/
|
||||
Envjs.sync = function(fn){
|
||||
//console.log('Threadless platform, sync is safe');
|
||||
return sync(fn);
|
||||
};
|
||||
|
||||
Envjs.spawn = function(fn){
|
||||
return spawn(fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* sleep thread for specified duration
|
||||
* @param {Object} milliseconds
|
||||
*/
|
||||
Envjs.sleep = function(milliseconds){
|
||||
return Ruby.sleep(1.0*milliseconds/1000.0);
|
||||
};
|
||||
//Since we're running in spydermonkey I guess we can safely assume
|
||||
//java is not 'enabled'. I'm sure this requires more thought
|
||||
//than I've given it here
|
||||
Envjs.javaEnabled = false;
|
||||
|
||||
Envjs.homedir = Ruby.ENV.HOME
|
||||
Envjs.tmpdir = Ruby.ENV.TMPDIR;
|
||||
Envjs.os_name = Ruby.CONFIG.host_os;
|
||||
Envjs.os_arch = Ruby.CONFIG.host_cpu;
|
||||
Envjs.os_version = "";//part of os_arch
|
||||
Envjs.lang = Ruby.ENV.LANG;
|
||||
|
||||
Envjs.gc = function(){ Ruby.gc(); };
|
||||
|
||||
/**
|
||||
* Makes an object window-like by proxying object accessors
|
||||
* @param {Object} scope
|
||||
* @param {Object} parent
|
||||
*/
|
||||
Envjs.proxy = function(scope, parent) {
|
||||
try{
|
||||
if(scope == __this__){
|
||||
return scope;
|
||||
}else{
|
||||
return new_context();
|
||||
}
|
||||
}catch(e){
|
||||
console.log('failed to init standard objects %s %s \n%s', scope, parent, e);
|
||||
}
|
||||
|
||||
};
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger('Envjs.XMLHttpRequest.RubyRacer');
|
||||
|
||||
/**
|
||||
* Get 'Current Working Directory'
|
||||
*/
|
||||
Envjs.getcwd = function() {
|
||||
return Ruby.ENV.PWD;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to read the contents of a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.readFromFile = function( url ){
|
||||
if(/^file\:\/\//.test(url))
|
||||
url = url.substring(7,url.length);
|
||||
log.debug('reading file %s', url);
|
||||
var file = fopen(url, 'r'),
|
||||
data = file.read();
|
||||
return data;
|
||||
};
|
||||
|
||||
Envjs.writeToFile = function(text, url){
|
||||
var file = fopen(url, 'w');
|
||||
log.debug('writing to file %s', url);
|
||||
file.write(text);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to write to a local file
|
||||
* @param {Object} text
|
||||
* @param {Object} suffix
|
||||
*/
|
||||
Envjs.writeToTempFile = function(text, suffix){
|
||||
// Create temp file.
|
||||
var temp = Envjs.tmpdir+"."+(new Date().getTime())+(suffix||'.js');
|
||||
log.debug("writing text to temp url : %s ", temp);
|
||||
Envjs.writeToFile(text, temp);
|
||||
return temp;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to read the contents of a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.readFromFile = function( url ){
|
||||
if(/^file\:\/\//.test(url))
|
||||
url = url.substring(7,url.length);
|
||||
log.debug('reading file %s', url);
|
||||
var file = fopen(url, 'r'),
|
||||
data = file.read();
|
||||
return data;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to delete a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.deleteFile = function(url){
|
||||
return ;//TODO
|
||||
};
|
||||
|
||||
/**
|
||||
* establishes connection and calls responsehandler
|
||||
* @param {Object} xhr
|
||||
* @param {Object} responseHandler
|
||||
* @param {Object} data
|
||||
*/
|
||||
Envjs.connection = function(xhr, responseHandler, data){
|
||||
var url = xhr.url,
|
||||
urlparts = Envjs.urlsplit(xhr.url),
|
||||
connection,
|
||||
request,
|
||||
headers,
|
||||
header,
|
||||
length,
|
||||
binary = false,
|
||||
name, value,
|
||||
contentEncoding,
|
||||
responseXML,
|
||||
i;
|
||||
|
||||
if ( /^file\:/.test(url) ) {
|
||||
log.debug('establishing file connection');
|
||||
Envjs.localXHR(url, xhr, connection, data);
|
||||
} else {
|
||||
log.debug('establishing http native ruby connection %s', xhr.url);
|
||||
try{
|
||||
|
||||
connection = HTTPConnection.connect(
|
||||
urlparts.hostname,
|
||||
Number(urlparts.port||80)
|
||||
);
|
||||
log.debug('native ruby connection established %s', connection);
|
||||
|
||||
path = urlparts.path+(urlparts.query?'?'+urlparts.query:'');
|
||||
request = HTTPConnection.request(xhr.method.toUpperCase(), path);
|
||||
log.debug('request query string %s', urlparts.query);
|
||||
log.debug('formulated %s request %s %s', xhr.method, urlparts.path, request);
|
||||
//TODO: add gzip support
|
||||
//connection.putheader("Accept-Encoding", 'gzip');
|
||||
//connection.endheaders();
|
||||
|
||||
//write data to output stream if required
|
||||
//TODO: if they have set the request header for a chunked
|
||||
//request body, implement a chunked output stream
|
||||
if(data){
|
||||
if(data instanceof Document){
|
||||
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||
connection.send((new XMLSerializer()).serializeToString(data));
|
||||
}
|
||||
}else if(data.length&&data.length>0){
|
||||
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||
connection.send(data+'');
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
log.error("connection failed %s",e);
|
||||
if (connection){
|
||||
HTTPConnection.finish(connection);
|
||||
}
|
||||
connection = null;
|
||||
}
|
||||
}
|
||||
|
||||
if(connection){
|
||||
log.debug('loading response from native ruby connection');
|
||||
response = HTTPConnection.go(connection, request, xhr.headers, null);
|
||||
log.debug('got response from native ruby connection');
|
||||
headers = response[1];
|
||||
response = response[0];
|
||||
try{
|
||||
// Stick the response headers into responseHeaders
|
||||
for (var header in headers) {
|
||||
log.debug('response header [%s] = %s', header, headers[header]);
|
||||
xhr.responseHeaders[header] = headers[header];
|
||||
}
|
||||
}catch(e){
|
||||
log.error('failed to load response headers \n%s',e);
|
||||
}
|
||||
|
||||
xhr.readyState = 4;
|
||||
xhr.status = parseInt(response.code,10) || undefined;
|
||||
xhr.statusText = response.message || "";
|
||||
log.info('%s %s %s %s', xhr.method, xhr.status, xhr.url, xhr.statusText);
|
||||
contentEncoding = xhr.getResponseHeader('content-encoding') || "utf-8";
|
||||
responseXML = null;
|
||||
|
||||
try{
|
||||
//console.log('contentEncoding %s', contentEncoding);
|
||||
if( contentEncoding.toLowerCase() == "gzip" ||
|
||||
contentEncoding.toLowerCase() == "decompress"){
|
||||
//zipped content
|
||||
binary = true;
|
||||
//TODO
|
||||
log.debug('TODO: handle gzip compression');
|
||||
xhr.responseText = response.body;
|
||||
}else{
|
||||
//this is a text file
|
||||
xhr.responseText = response.body+'';
|
||||
}
|
||||
}catch(e){
|
||||
log.warn('failed to open connection stream \n%s, %s %s %s',
|
||||
xhr.status, xhr.url, e.toString(), e
|
||||
);
|
||||
}finally{
|
||||
if(connection){
|
||||
HTTPConnection.finish(connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(responseHandler){
|
||||
log.debug('calling ajax response handler');
|
||||
if(!xhr.async){
|
||||
log.debug('calling sync response handler directly');
|
||||
responseHandler();
|
||||
}else{
|
||||
log.debug('using setTimeout for async response handler');
|
||||
setTimeout(responseHandler, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(/*Envjs.XMLHttpRequest.Johnson*/);
|
||||
/**
|
||||
* @author john resig & the envjs team
|
||||
* @uri http://www.envjs.com/
|
||||
* @copyright 2008-2010
|
||||
* @license MIT
|
||||
*/
|
||||
//CLOSURE_END
|
||||
}());
|
|
@ -0,0 +1,352 @@
|
|||
var __context__ = __this__;
|
||||
|
||||
var Envjs = Envjs ||
|
||||
require('./core').Envjs;
|
||||
require('local_settings');
|
||||
|
||||
Envjs.platform = "SpyderMonkey";
|
||||
Envjs.revision = sys.version.substring(0,5);
|
||||
|
||||
Envjs.argv = []
|
||||
for(var i in sys.argv){
|
||||
Envjs.argv.push(sys.argv[i]);
|
||||
}
|
||||
Envjs.argv.shift();
|
||||
Envjs.argv.shift();
|
||||
|
||||
Envjs.exit = function(){
|
||||
exit();
|
||||
};
|
||||
|
||||
/*
|
||||
* Envjs node-env.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
//CLOSURE_START
|
||||
(function(){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author john resig
|
||||
*/
|
||||
// Helper method for extending one object with another.
|
||||
function __extend__(a,b) {
|
||||
for ( var i in b ) {
|
||||
if(b.hasOwnProperty(i)){
|
||||
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||
if ( g || s ) {
|
||||
if ( g ) { a.__defineGetter__(i, g); }
|
||||
if ( s ) { a.__defineSetter__(i, s); }
|
||||
} else {
|
||||
a[i] = b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
Envjs.log = print;
|
||||
|
||||
Envjs.lineSource = function(e){
|
||||
return "(line ?)";
|
||||
};
|
||||
|
||||
Envjs.readConsole = function(){
|
||||
return sys.stdin.readline();
|
||||
};
|
||||
|
||||
Envjs.prompt = function(){
|
||||
sys.stdout.write(Envjs.CURSOR+' ');
|
||||
sys.stdout.flush();
|
||||
};
|
||||
|
||||
//No REPL for
|
||||
Envjs.repl = function(){
|
||||
console.log('Envjs REPL Not Available');
|
||||
};
|
||||
|
||||
Envjs.eval = function(context, source, name){
|
||||
if(context == __this__){
|
||||
return global.execute( source );
|
||||
}else{
|
||||
return context.execute( source );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* synchronizes thread modifications
|
||||
* @param {Function} fn
|
||||
*/
|
||||
Envjs.sync = function(fn){
|
||||
/*return function(){
|
||||
try{
|
||||
//console.log('locking');
|
||||
$lock.acquire();
|
||||
fn.apply(fn, arguments);
|
||||
}catch(e){
|
||||
console.log('error in sync: %s',e);
|
||||
}finally{
|
||||
//console.log('unlocking');
|
||||
$lock.release();
|
||||
}
|
||||
}*/
|
||||
return fn;
|
||||
};
|
||||
|
||||
Envjs.spawn = function(fn){
|
||||
/*var t = threading.Thread();
|
||||
t.run = function(){
|
||||
try{
|
||||
console.log('spawned');
|
||||
fn.apply(fn, arguments);
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
return t.start();*/
|
||||
fn();
|
||||
};
|
||||
|
||||
/**
|
||||
* sleep thread for specified duration
|
||||
* @param {Number} milliseconds
|
||||
*/
|
||||
Envjs.sleep = function(milliseconds){
|
||||
return time.sleep(1.0*milliseconds/1000.0);
|
||||
};
|
||||
|
||||
//Since we're running in spydermonkey I guess we can safely assume
|
||||
//java is not 'enabled'. I'm sure this requires more thought
|
||||
//than I've given it here
|
||||
Envjs.javaEnabled = false;
|
||||
|
||||
Envjs.homedir = os.environ['HOME']
|
||||
Envjs.tmpdir = os.environ['TMPDIR'];
|
||||
Envjs.os_name = platform.system();
|
||||
Envjs.os_arch = platform.processor();
|
||||
Envjs.os_version = platform.release();
|
||||
Envjs.lang = os.environ['LANG'];
|
||||
|
||||
|
||||
Envjs.gc = function(){ global.gc(); };
|
||||
|
||||
/**
|
||||
* Makes an object window-like by proxying object accessors
|
||||
* @param {Object} scope
|
||||
* @param {Object} parent
|
||||
*/
|
||||
Envjs.proxy = function(scope, parent) {
|
||||
try{
|
||||
if(scope == __this__){
|
||||
return scope;
|
||||
}else{
|
||||
return new_global();
|
||||
}
|
||||
}catch(e){
|
||||
console.log('failed to init standard objects %s %s \n%s', scope, parent, e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger('Envjs.XMLHttpRequest.SpyderMonkey');
|
||||
|
||||
/**
|
||||
* Get 'Current Working Directory'
|
||||
*/
|
||||
Envjs.getcwd = function() {
|
||||
return os.getcwd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to write to a local file
|
||||
* @param {Object} text
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.writeToFile = function(text, url){
|
||||
var file = fopen(url, 'w');
|
||||
file.write(text);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to write to a local file
|
||||
* @param {Object} text
|
||||
* @param {Object} suffix
|
||||
*/
|
||||
Envjs.writeToTempFile = function(text, suffix){
|
||||
// Create temp file.
|
||||
var temp = Envjs.tmpdir+"."+(new Date().getTime())+(suffix||'.js');
|
||||
log.debug("writing text to temp url : %s ", temp);
|
||||
Envjs.writeToFile(text, temp);
|
||||
return temp;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to read the contents of a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.readFromFile = function( url ){
|
||||
if(/^file\:\/\//.test(url))
|
||||
url = url.substring(7,url.length);
|
||||
log.debug('reading file %s', url);
|
||||
var file = fopen(url, 'r'),
|
||||
data = file.read();
|
||||
return data;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to delete a local file
|
||||
* @param {Object} url
|
||||
*/
|
||||
Envjs.deleteFile = function(url){
|
||||
if(/^file\:\/\//.test(url))
|
||||
url = url.substring(7,url.length);
|
||||
log.debug('deleting file %s', url);
|
||||
return os.delete(url);
|
||||
};
|
||||
|
||||
/**
|
||||
* establishes connection and calls responsehandler
|
||||
* @param {Object} xhr
|
||||
* @param {Object} responseHandler
|
||||
* @param {Object} data
|
||||
*/
|
||||
Envjs.connection = function(xhr, responseHandler, data){
|
||||
var url = xhr.url,
|
||||
urlparts = Envjs.urlsplit(xhr.url),
|
||||
connection,
|
||||
request,
|
||||
header,
|
||||
length,
|
||||
binary = false,
|
||||
name, value,
|
||||
contentEncoding,
|
||||
responseXML,
|
||||
i;
|
||||
|
||||
if ( /^file\:/.test(url) ) {
|
||||
log.debug('establishing platform file connection');
|
||||
Envjs.localXHR(url, xhr, connection, data);
|
||||
} else {
|
||||
log.debug('establishing python platform network connection');
|
||||
try{
|
||||
log.debug('connecting to %s \n\t port(%s) hostname(%s) path(%s) query(%s)',
|
||||
url, urlparts.port, urlparts.hostname, urlparts.path, urlparts.query);
|
||||
connection = httplib.HTTPConnection(urlparts.hostname, urlparts.port || 80);
|
||||
connection.connect();
|
||||
request = connection.putrequest(
|
||||
xhr.method,
|
||||
urlparts.path+(urlparts.query?'?'+urlparts.query:'')
|
||||
);
|
||||
|
||||
// Add headers to connection
|
||||
for (header in xhr.headers){
|
||||
log.debug('adding request header %s %s',header+'', xhr.headers[header]+'')
|
||||
connection.putheader(header+'', xhr.headers[header]+'');
|
||||
}
|
||||
//TODO: add gzip support
|
||||
//connection.putheader("Accept-Encoding", 'gzip');
|
||||
connection.endheaders();
|
||||
|
||||
//write data to output stream if required
|
||||
//TODO: if they have set the request header for a chunked
|
||||
//request body, implement a chunked output stream
|
||||
if(data){
|
||||
if(data instanceof Document){
|
||||
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||
connection.send((new XMLSerializer()).serializeToString(data));
|
||||
}
|
||||
}else if(data.length&&data.length>0){
|
||||
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||
connection.send(data+'');
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
log.error('error making python native connection %s', e);
|
||||
connection.close();
|
||||
connection = null;
|
||||
}
|
||||
}
|
||||
|
||||
if(connection){
|
||||
try{
|
||||
response = connection.getresponse();
|
||||
log.debug('got native platform connection response');
|
||||
length = response.getheaders().length;
|
||||
// Stick the response headers into responseHeaders
|
||||
for (i = 0; i < length; i++) {
|
||||
header = response.getheaders()[i];
|
||||
name = header[0];
|
||||
value = header[1];
|
||||
if (name){
|
||||
log.debug('response header %s %s', name, value);
|
||||
xhr.responseHeaders[name+''] = value+'';
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
console.log('failed to load response headers \n%s',e);
|
||||
}
|
||||
|
||||
xhr.readyState = 4;
|
||||
xhr.status = parseInt(response.status,10) || undefined;
|
||||
xhr.statusText = response.reason || "";
|
||||
log.info('%s %s %s %s', xhr.method, xhr.status, xhr.url, xhr.statusText);
|
||||
contentEncoding = xhr.getResponseHeader('content-encoding') || "utf-8";
|
||||
responseXML = null;
|
||||
|
||||
try{
|
||||
//console.log('contentEncoding %s', contentEncoding);
|
||||
if( contentEncoding.toLowerCase() == "gzip" ||
|
||||
contentEncoding.toLowerCase() == "decompress"){
|
||||
//zipped content
|
||||
binary = true;
|
||||
//TODO
|
||||
console.log('TODO: handle gzip compression');
|
||||
xhr.responseText = response.read();
|
||||
}else{
|
||||
//this is a text file
|
||||
xhr.responseText = response.read();
|
||||
}
|
||||
}catch(e){
|
||||
if (xhr.status == 404){
|
||||
console.log('failed to open connection stream \n %s %s',
|
||||
e.toString(), e);
|
||||
}else{
|
||||
console.log('failed to open connection stream \n %s %s',
|
||||
e.toString(), e);
|
||||
}
|
||||
}finally{
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
if(responseHandler){
|
||||
log.debug('calling ajax response handler');
|
||||
if(!xhr.async){
|
||||
responseHandler();
|
||||
}else{
|
||||
setTimeout(responseHandler, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(/*Envjs.Platform.SpyderMonkey*/);
|
||||
/**
|
||||
* @author john resig & the envjs team
|
||||
* @uri http://www.envjs.com/
|
||||
* @copyright 2008-2010
|
||||
* @license MIT
|
||||
*/
|
||||
//CLOSURE_END
|
||||
}());
|
|
@ -0,0 +1,91 @@
|
|||
// This file is compiled into the jar and executed automatically on startup.
|
||||
var __this__ = this;
|
||||
var require = (function() {
|
||||
var cached = {};
|
||||
var currentPath = java.lang.System.getProperty('user.dir');
|
||||
var paths = [currentPath];
|
||||
|
||||
function normalize(id) {
|
||||
var file;
|
||||
id = id + '.js';
|
||||
if (/^\.\.?/.test(id)) {
|
||||
// relative path
|
||||
file = new java.io.File(currentPath, id);
|
||||
if (file.isFile()) {
|
||||
return file.toURL();
|
||||
}
|
||||
} else {
|
||||
for (var i = 0, len = paths.length; i < len; ++i) {
|
||||
file = new java.io.File(paths[i], id);
|
||||
if (file.isFile()) {
|
||||
return file.toURL();
|
||||
}
|
||||
}
|
||||
// try to get it from the jar as a last resort
|
||||
/*var url = rhoop.getClass().getResource('/' + id);
|
||||
if (url !== null) {
|
||||
return url;
|
||||
}*/
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
function read(connection) {
|
||||
var stream = connection.getInputStream();
|
||||
var bytes = java.lang.reflect.Array.newInstance(
|
||||
java.lang.Byte.TYPE, 4096);
|
||||
var bytesStream = new java.io.ByteArrayOutputStream();
|
||||
var bytesRead;
|
||||
while ((bytesRead = stream.read(bytes)) >= 0) {
|
||||
if (bytesRead > 0) {
|
||||
bytesStream.write(bytes, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
return String(bytesStream.toString());
|
||||
};
|
||||
|
||||
function require(id) {
|
||||
//print('require :'+ id);
|
||||
var url = normalize(id);
|
||||
if (!url) {
|
||||
throw new Error("couldn't find module \"" + id + "\"");
|
||||
}
|
||||
id = String(url.toString());
|
||||
if (!cached.hasOwnProperty(id)) {
|
||||
var source = read(url.openConnection());
|
||||
source = source.replace(/^\#\!.*/, '');
|
||||
source = (
|
||||
"(function (require, exports, module) { " + source + "\n});");
|
||||
cached[id] = {
|
||||
exports: {},
|
||||
module: {
|
||||
id: id,
|
||||
uri: id
|
||||
}
|
||||
};
|
||||
var previousPath = currentPath;
|
||||
try {
|
||||
currentPath = id.substr(0, id.lastIndexOf('/')) || '.';
|
||||
var ctx = org.mozilla.javascript.Context.getCurrentContext();
|
||||
var func = ctx.evaluateString({}, source, id, 1, null);
|
||||
func(require, cached[id].exports, cached[id].module);
|
||||
} finally {
|
||||
currentPath = previousPath;
|
||||
}
|
||||
}
|
||||
/*
|
||||
print('returning exports for id: '+id+' '+cached[id].exports);
|
||||
for(var prop in cached[id].exports){
|
||||
print('export: '+prop);
|
||||
}
|
||||
*/
|
||||
return cached[id].exports;
|
||||
};
|
||||
|
||||
require.paths = paths;
|
||||
|
||||
return require;
|
||||
}());
|
||||
var __argv__ = arguments;
|
||||
require('./platform/rhino');
|
||||
require('./window');
|
|
@ -0,0 +1,72 @@
|
|||
// This file must be executed automatically on startup for ruby/v8 rubyracer support.
|
||||
var __this__ = this;
|
||||
var require = (function() {
|
||||
var cached = {};
|
||||
var currentPath = Ruby.ENV.PWD;
|
||||
var paths = [currentPath];
|
||||
|
||||
/*Ruby.puts("$PROGRAM_NAME " + Ruby.$PROGRAM_NAME)
|
||||
Ruby.puts("Ruby.Config.ruby_version " + Ruby.Config.ruby_version)
|
||||
Ruby.puts("Ruby.File " + Ruby.File)
|
||||
Ruby.puts("Ruby.File.open " + Ruby.File.open)
|
||||
Ruby.puts("Ruby.File equality " + (File === Ruby.File))
|
||||
Ruby.puts("Ruby.File.open() " + Ruby.File.open('/tmp/t.tmp','r').read())*/
|
||||
|
||||
function normalize(id) {
|
||||
var file;
|
||||
id = id + '.js';
|
||||
if (/^\.\.?/.test(id)) {
|
||||
// relative path
|
||||
try{ return fopen(id, 'r') }catch(e){}
|
||||
} else {
|
||||
for (var i = 0, len = paths.length; i < len; ++i) {
|
||||
try{ return fopen(paths[i]+'/'+id, 'r') }catch(e){}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
|
||||
function require(id) {
|
||||
//print('require :'+ id);
|
||||
var file = normalize(id);
|
||||
if (!file) {
|
||||
throw new Error("couldn't find module \"" + id + "\"");
|
||||
}
|
||||
if (!cached.hasOwnProperty(id)) {
|
||||
//print('loading '+id);
|
||||
var source = file.read();
|
||||
source = source.replace(/^\#\!.*/, '');
|
||||
source = "(function (require, exports, module) { "+source+"\n});";
|
||||
cached[id] = {
|
||||
exports: {},
|
||||
module: {
|
||||
id: id,
|
||||
uri: id
|
||||
}
|
||||
};
|
||||
var previousPath = currentPath;
|
||||
try {
|
||||
currentPath = id.substr(0, id.lastIndexOf('/')) || '.';
|
||||
var func = __this__.eval(source);
|
||||
func(require, cached[id].exports, cached[id].module);
|
||||
} finally {
|
||||
currentPath = previousPath;
|
||||
}
|
||||
}
|
||||
/*
|
||||
print('returning exports for id: '+id+' '+cached[id].exports);
|
||||
for(var prop in cached[id].exports){
|
||||
print('export: '+prop);
|
||||
}
|
||||
*/
|
||||
return cached[id].exports;
|
||||
};
|
||||
|
||||
require.paths = paths;
|
||||
|
||||
return require;
|
||||
})();
|
||||
var __argv__ = Ruby.ARGV;
|
||||
require('./platform/rubyracer');
|
||||
require('./window');
|
|
@ -0,0 +1,90 @@
|
|||
require 'v8'
|
||||
require 'net/http'
|
||||
require 'uri'
|
||||
require 'thread'
|
||||
|
||||
include Config
|
||||
|
||||
lock = Mutex.new
|
||||
class Runtime
|
||||
def new_context()
|
||||
V8::Context.new
|
||||
end
|
||||
def configure_context(runtime, context)
|
||||
ruby = {}
|
||||
Module.included_modules.each{|m|
|
||||
#puts "adding module #{m}"
|
||||
ruby[m.to_s] = m
|
||||
}
|
||||
Module.constants.each{|c|
|
||||
#puts "adding constant #{c}"
|
||||
ruby[c.to_s] = Kernel.eval(c)
|
||||
}
|
||||
Kernel.global_variables.each{|g|
|
||||
#puts "adding global variable #{g}"
|
||||
ruby[g.to_s] = Kernel.eval(g)
|
||||
}
|
||||
Kernel.methods.each{|m|
|
||||
#puts "adding global method #{m}"
|
||||
ruby[m.to_s] = Kernel.method(m)
|
||||
}
|
||||
ruby['CONFIG'] = CONFIG
|
||||
ruby['gc'] = lambda{ GC.start() }
|
||||
context['Ruby'] = ruby
|
||||
|
||||
context['__this__'] = context
|
||||
context['File'] = File
|
||||
#context['sync'] = lambda{|fn| Proc.new{|*args|lock.synchronize {fn.call(*args)}} }
|
||||
context['sync'] = lambda{|fn| Proc.new{|*args| fn.call(*args) }}
|
||||
#context['spawn'] = lambda{|fn| Thread.new {fn.call}}
|
||||
context['spawn'] = lambda{|fn| fn.call}
|
||||
context['print'] = lambda{|msg| puts msg}
|
||||
context['fopen'] = lambda{|name, mode| File.open(name, mode)}
|
||||
context['runtime'] = runtime
|
||||
context['new_context'] = lambda{
|
||||
rt = Runtime.new
|
||||
ct = rt.new_context()
|
||||
rt.configure_context(rt, ct)
|
||||
ct['_eval'] = lambda{|script| ct.eval(script)}
|
||||
ct.eval('var t = new Function(); t._eval = __this__._eval;t;')
|
||||
}
|
||||
context['HTTPConnection'] = HTTPConnection.new
|
||||
end
|
||||
end
|
||||
|
||||
class HTTPConnection
|
||||
def connect(host, port)
|
||||
Net::HTTP.start(host, port)
|
||||
end
|
||||
def request(httpMethod, path)
|
||||
case httpMethod
|
||||
when "GET" then return Net::HTTP::Get.new(path)
|
||||
when "PUT" then return Net::HTTP::Put.new(path)
|
||||
when "POST" then return Net::HTTP::Post.new(path)
|
||||
when "HEAD" then return Net::HTTP::Head.new(path)
|
||||
when "DELETE" then return Net::HTTP::Delete.new(path)
|
||||
else return nil
|
||||
end
|
||||
end
|
||||
def go(connection, request, headers, data)
|
||||
headers.each{|key,value| request.add_field(key,value)}
|
||||
response, body = connection.request(request, data)
|
||||
respheaders = Hash.new
|
||||
response.each_header do |name, value|
|
||||
respheaders.store(name, value)
|
||||
end
|
||||
response['body'] = body
|
||||
[response, respheaders]
|
||||
end
|
||||
def finish(connection)
|
||||
connection.finish if connection.started?
|
||||
end
|
||||
end
|
||||
|
||||
runtime = Runtime.new
|
||||
global = runtime.new_context()
|
||||
runtime.configure_context(runtime, global)
|
||||
envjs = ARGV[0]
|
||||
global.load(envjs)
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// This file must be executed automatically on startup for ruby/v8 rubyracer support.
|
||||
var __this__ = this;
|
||||
var require = (function() {
|
||||
var cached = {};
|
||||
var currentPath = os.getcwd();
|
||||
var paths = [currentPath];
|
||||
|
||||
function normalize(id) {
|
||||
var file;
|
||||
id = id + '.js';
|
||||
if (/^\.\.?/.test(id)) {
|
||||
// relative path
|
||||
try{ return fopen(id, 'r') }catch(e){}
|
||||
} else {
|
||||
for (var i = 0, len = paths.length; i < len; ++i) {
|
||||
try{ return fopen(paths[i]+'/'+id, 'r') }catch(e){}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
|
||||
function require(id) {
|
||||
//print('require :'+ id);
|
||||
var file = normalize(id);
|
||||
if (!file) {
|
||||
throw new Error("couldn't find module \"" + id + "\"");
|
||||
}
|
||||
if (!cached.hasOwnProperty(id)) {
|
||||
//print('loading '+id);
|
||||
var source = file.read();
|
||||
source = source.replace(/^\#\!.*/, '');
|
||||
source = "(function (require, exports, module) { "+source+"\n});";
|
||||
cached[id] = {
|
||||
exports: {},
|
||||
module: {
|
||||
id: id,
|
||||
uri: id
|
||||
}
|
||||
};
|
||||
var previousPath = currentPath;
|
||||
try {
|
||||
currentPath = id.substr(0, id.lastIndexOf('/')) || '.';
|
||||
var func = global.execute( source );
|
||||
func(require, cached[id].exports, cached[id].module);
|
||||
} finally {
|
||||
currentPath = previousPath;
|
||||
}
|
||||
}
|
||||
/*
|
||||
print('returning exports for id: '+id+' '+cached[id].exports);
|
||||
for(var prop in cached[id].exports){
|
||||
print('export: '+prop);
|
||||
}
|
||||
*/
|
||||
return cached[id].exports;
|
||||
};
|
||||
|
||||
require.paths = paths;
|
||||
|
||||
return require;
|
||||
})();
|
||||
require('./platform/spydermonkey');
|
||||
require('./window');
|
|
@ -0,0 +1,56 @@
|
|||
import spidermonkey
|
||||
import threading
|
||||
import platform
|
||||
import httplib
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
|
||||
runtime = spidermonkey.Runtime()
|
||||
context = runtime.new_context()
|
||||
lock = threading.Lock()
|
||||
|
||||
def load(filename):
|
||||
script = ''
|
||||
f = open(filename, 'r')
|
||||
script = f.read()
|
||||
context.execute(script)
|
||||
|
||||
def _print(string):
|
||||
print string
|
||||
|
||||
def _open(url, mode):
|
||||
return open(url, mode)
|
||||
|
||||
def _exit():
|
||||
return os._exit(1)
|
||||
|
||||
def new_global():
|
||||
nc = runtime.new_context()
|
||||
configure_context(nc)
|
||||
return nc.execute('''
|
||||
this.execute = global.execute;
|
||||
this;
|
||||
''')
|
||||
|
||||
def configure_context(context):
|
||||
context.add_global('os', os)
|
||||
context.add_global('sys', sys)
|
||||
context.add_global('time', time)
|
||||
context.add_global('$lock', lock);
|
||||
context.add_global('exit', _exit)
|
||||
context.add_global('fopen', _open)
|
||||
context.add_global('print', _print)
|
||||
context.add_global('httplib', httplib)
|
||||
context.add_global('platform', platform)
|
||||
context.add_global('threading', threading)
|
||||
context.add_global('global', context)
|
||||
context.add_global('runtime', runtime)
|
||||
context.add_global('new_global', new_global)
|
||||
|
||||
configure_context(context)
|
||||
|
||||
if __name__=='__main__':
|
||||
argv = sys.argv
|
||||
if os.path.isfile( argv[1] ):
|
||||
load(argv[1])
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
/*
|
||||
* Envjs timer.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
//CLOSURE_START
|
||||
(function(){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Envjs timer.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*
|
||||
* Parts of the implementation were originally written by:\
|
||||
* Steven Parkes
|
||||
*
|
||||
* requires Envjs.wait, Envjs.sleep, Envjs.WAIT_INTERVAL
|
||||
|
||||
This module leaks the following global definitions.
|
||||
|
||||
var setTimeout,
|
||||
clearTimeout,
|
||||
setInterval,
|
||||
clearInterval;
|
||||
|
||||
*/
|
||||
|
||||
var Envjs = require('./platform/core').Envjs;
|
||||
/*
|
||||
* - timer.js
|
||||
*/
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.Timer').
|
||||
debug('timer logger available');
|
||||
});
|
||||
|
||||
/**
|
||||
* @function setTimeout
|
||||
* @param {Object} fn
|
||||
* @param {Object} time
|
||||
*/
|
||||
exports.setTimeout = setTimeout = function(fn, time){
|
||||
log.debug('setTimeout %s', time);
|
||||
return Envjs.timers.addTimerOrInterval(fn, time, 'timeout');
|
||||
};
|
||||
|
||||
/**
|
||||
* clearTimeout
|
||||
* @param {Object} id
|
||||
*/
|
||||
exports.clearTimeout = clearTimeout = function(id){
|
||||
log.debug('clearTimeout %s', id);
|
||||
return Envjs.timers.removeTimerOrInterval(id, 'timeout');
|
||||
};
|
||||
|
||||
/**
|
||||
* @function setInterval
|
||||
* @param {Object} fn
|
||||
* @param {Object} time
|
||||
*/
|
||||
exports.setInterval = setInterval = function(fn, time){
|
||||
log.debug('setInterval %s', time);
|
||||
return Envjs.timers.addTimerOrInterval(fn, time, 'interval');
|
||||
};
|
||||
|
||||
/**
|
||||
* clearInterval
|
||||
* @param {Object} id
|
||||
*/
|
||||
exports.clearInterval = clearInterval = function(id){
|
||||
log.debug('clearInterval %s', id);
|
||||
return Envjs.timers.removeTimerOrInterval(id, 'interval');
|
||||
};
|
||||
|
||||
}(/*Timer*/));
|
||||
/**
|
||||
* @author john resig & the envjs team
|
||||
* @uri http://www.envjs.com/
|
||||
* @copyright 2008-2010
|
||||
* @license MIT
|
||||
*/
|
||||
//CLOSURE_END
|
||||
}());
|
|
@ -0,0 +1,864 @@
|
|||
/*
|
||||
* Envjs window.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
|
||||
This module leaks the following global definitions.
|
||||
|
||||
var Window,
|
||||
Screen,
|
||||
History,
|
||||
Navigator;
|
||||
|
||||
*/
|
||||
|
||||
var Envjs = Envjs || require('./platform/core').Envjs,
|
||||
DOMImplementation = DOMImplementation || require('./dom').DOMImplementation,
|
||||
HTMLDocument = HTMLDocument || require('./html').HTMLDocument,
|
||||
HTMLFrameElement = HTMLFrameElement || require('./html').HTMLFrameElement,
|
||||
HTMLIFrameElement = HTMLIFrameElement || require('./html').HTMLIFrameElement,
|
||||
HTMLParser = HTMLParser || require('./parser').HTMLParser,
|
||||
Location = Location || require('./xhr').Location,
|
||||
CSSRule = CSSRule || require('./css').CSSRule;
|
||||
|
||||
|
||||
/*
|
||||
* Envjs window.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
//CLOSURE_START
|
||||
(function(){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author john resig
|
||||
*/
|
||||
// Helper method for extending one object with another.
|
||||
function __extend__(a,b) {
|
||||
for ( var i in b ) {
|
||||
if(b.hasOwnProperty(i)){
|
||||
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||
if ( g || s ) {
|
||||
if ( g ) { a.__defineGetter__(i, g); }
|
||||
if ( s ) { a.__defineSetter__(i, s); }
|
||||
} else {
|
||||
a[i] = b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frame/Window Mixin
|
||||
*/
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.HTML.Frame').
|
||||
debug('html frame logger available');
|
||||
});
|
||||
|
||||
__extend__(HTMLFrameElement.prototype,{
|
||||
|
||||
set src(value){
|
||||
var event;
|
||||
this.setAttribute('src', value);
|
||||
//only load if we are already appended to the dom
|
||||
if (this.parentNode && value && value.length > 0){
|
||||
log.debug('loading frame via set src %s', value);
|
||||
Envjs.loadFrame(this, Envjs.uri(value, this.ownerDocument?this.ownerDocument.location+'':null));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
__extend__(HTMLIFrameElement.prototype, HTMLFrameElement.prototype);
|
||||
|
||||
}(/*Frame/Window Mixin*/));
|
||||
|
||||
/*
|
||||
* TODO: Document the History object via HTML5 spec
|
||||
*
|
||||
*/
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.Window.History').
|
||||
debug('history logger available');
|
||||
});
|
||||
|
||||
exports.History = History = function(owner) {
|
||||
var $current = 0,
|
||||
$history = [null],
|
||||
$owner = owner;
|
||||
|
||||
return {
|
||||
go : function(target) {
|
||||
if (typeof target === "number") {
|
||||
target = $current + target;
|
||||
if (target > -1 && target < $history.length){
|
||||
if ($history[target].type === "hash") {
|
||||
if ($owner.location) {
|
||||
$owner.location.hash = $history[target].value;
|
||||
}
|
||||
} else {
|
||||
if ($owner.location) {
|
||||
$owner.location = $history[target].value;
|
||||
}
|
||||
}
|
||||
$current = target;
|
||||
}
|
||||
} else {
|
||||
//TODO: walk through the history and find the 'best match'?
|
||||
}
|
||||
},
|
||||
|
||||
get length() {
|
||||
return $history.length;
|
||||
},
|
||||
|
||||
back : function(count) {
|
||||
if (count) {
|
||||
this.go(-count);
|
||||
} else {
|
||||
this.go(-1);
|
||||
}
|
||||
},
|
||||
|
||||
get current() {
|
||||
return this.item($current);
|
||||
},
|
||||
|
||||
get previous() {
|
||||
return this.item($current-1);
|
||||
},
|
||||
|
||||
forward : function(count) {
|
||||
if (count) {
|
||||
this.go(count);
|
||||
} else {
|
||||
this.go(1);
|
||||
}
|
||||
},
|
||||
|
||||
item: function(idx) {
|
||||
if (idx >= 0 && idx < $history.length) {
|
||||
return $history[idx];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
add: function(newLocation, type) {
|
||||
//not a standard interface, we expose it to simplify
|
||||
//history state modifications
|
||||
if (newLocation !== $history[$current]) {
|
||||
$history.slice(0, $current);
|
||||
$history.push({
|
||||
type: type || 'href',
|
||||
value: newLocation
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}(/*History*/));
|
||||
|
||||
|
||||
/*
|
||||
* navigator.js
|
||||
* Browser Navigator
|
||||
*/
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.Window.Navigator').
|
||||
debug('window navigator logger available');
|
||||
});
|
||||
|
||||
exports.Navigator = Navigator = function(){
|
||||
var $userAgent;
|
||||
return {
|
||||
get appCodeName(){
|
||||
return Envjs.appCodeName;
|
||||
},
|
||||
get appName(){
|
||||
return Envjs.appName;
|
||||
},
|
||||
get appVersion(){
|
||||
return Envjs.version +" ("+
|
||||
this.platform +"; "+
|
||||
"U; "+//?
|
||||
Envjs.os_name+" "+Envjs.os_arch+" "+Envjs.os_version+"; "+
|
||||
(Envjs.lang?Envjs.lang:"en-US")+"; "+
|
||||
"rv:"+Envjs.revision+
|
||||
")";
|
||||
},
|
||||
get cookieEnabled(){
|
||||
return true;
|
||||
},
|
||||
get mimeTypes(){
|
||||
return [];
|
||||
},
|
||||
get platform(){
|
||||
return Envjs.platform;
|
||||
},
|
||||
get plugins(){
|
||||
return [];
|
||||
},
|
||||
get userAgent(){
|
||||
return $userAgent||(this.appCodeName + "/" + this.appVersion + " Resig/20070309 PilotFish/1.3.pre03");
|
||||
},
|
||||
set userAgent(agent){
|
||||
if(agent){
|
||||
$userAgent = agent;
|
||||
}
|
||||
},
|
||||
javaEnabled : function(){
|
||||
return Envjs.javaEnabled;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}());
|
||||
/**
|
||||
* Screen
|
||||
* @param {Object} __window__
|
||||
*/
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.Window.Screen').
|
||||
debug('window screen logger available');
|
||||
});
|
||||
|
||||
exports.Screen = Screen = function(__window__){
|
||||
|
||||
var $availHeight = 600,
|
||||
$availWidth = 800,
|
||||
$colorDepth = 16,
|
||||
$pixelDepth = 24,
|
||||
$height = 600,
|
||||
$width = 800,
|
||||
$top = 0,
|
||||
$left = 0,
|
||||
$availTop = 0,
|
||||
$availLeft = 0;
|
||||
|
||||
log.debug('extending window with screen properties');
|
||||
__extend__( __window__, {
|
||||
moveBy : function(dx,dy){
|
||||
//TODO - modify $locals to reflect change
|
||||
},
|
||||
moveTo : function(x,y) {
|
||||
//TODO - modify $locals to reflect change
|
||||
},
|
||||
/*print : function(){
|
||||
//TODO - good global to modify to ensure print is not misused
|
||||
};*/
|
||||
resizeBy : function(dw, dh){
|
||||
__window__.resizeTo($width + dw, $height + dh);
|
||||
},
|
||||
resizeTo : function(width, height){
|
||||
$width = (width <= $availWidth) ? width : $availWidth;
|
||||
$height = (height <= $availHeight) ? height : $availHeight;
|
||||
},
|
||||
scroll : function(x,y){
|
||||
//TODO - modify $locals to reflect change
|
||||
},
|
||||
scrollBy : function(dx, dy){
|
||||
//TODO - modify $locals to reflect change
|
||||
},
|
||||
scrollTo : function(x,y){
|
||||
//TODO - modify $locals to reflect change
|
||||
}
|
||||
});
|
||||
|
||||
log.debug('creating screen');
|
||||
return {
|
||||
get top(){
|
||||
return $top;
|
||||
},
|
||||
get left(){
|
||||
return $left;
|
||||
},
|
||||
get availTop(){
|
||||
return $availTop;
|
||||
},
|
||||
get availLeft(){
|
||||
return $availLeft;
|
||||
},
|
||||
get availHeight(){
|
||||
return $availHeight;
|
||||
},
|
||||
get availWidth(){
|
||||
return $availWidth;
|
||||
},
|
||||
get colorDepth(){
|
||||
return $colorDepth;
|
||||
},
|
||||
get pixelDepth(){
|
||||
return $pixelDepth;
|
||||
},
|
||||
get height(){
|
||||
return $height;
|
||||
},
|
||||
get width(){
|
||||
return $width;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}(/*Screen*/));
|
||||
/*
|
||||
* Copyright (c) 2010 Nick Galbreath
|
||||
* http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* base64 encode/decode compatible with window.btoa/atob
|
||||
*
|
||||
* window.atob/btoa is a Firefox extension to convert binary data (the "b")
|
||||
* to base64 (ascii, the "a").
|
||||
*
|
||||
* It is also found in Safari and Chrome. It is not available in IE.
|
||||
*
|
||||
* if (!window.btoa) window.btoa = base64.encode
|
||||
* if (!window.atob) window.atob = base64.decode
|
||||
*
|
||||
* The original spec's for atob/btoa are a bit lacking
|
||||
* https://developer.mozilla.org/en/DOM/window.atob
|
||||
* https://developer.mozilla.org/en/DOM/window.btoa
|
||||
*
|
||||
* window.btoa and base64.encode takes a string where charCodeAt is [0,255]
|
||||
* If any character is not [0,255], then an DOMException(5) is thrown.
|
||||
*
|
||||
* window.atob and base64.decode take a base64-encoded string
|
||||
* If the input length is not a multiple of 4, or contains invalid characters
|
||||
* then an DOMException(5) is thrown.
|
||||
*/
|
||||
var base64 = {};
|
||||
base64.PADCHAR = '=';
|
||||
base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
|
||||
base64.makeDOMException = function() {
|
||||
// sadly in FF,Safari,Chrome you can't make a DOMException
|
||||
var e;
|
||||
|
||||
try {
|
||||
return new DOMException(DOMException.INVALID_CHARACTER_ERR);
|
||||
} catch (tmp) {
|
||||
// not available, just passback a duck-typed equiv
|
||||
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error
|
||||
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error/prototype
|
||||
var ex = new Error("DOM Exception 5");
|
||||
|
||||
// ex.number and ex.description is IE-specific.
|
||||
ex.code = ex.number = 5;
|
||||
ex.name = ex.description = "INVALID_CHARACTER_ERR";
|
||||
|
||||
// Safari/Chrome output format
|
||||
ex.toString = function() { return 'Error: ' + ex.name + ': ' + ex.message; };
|
||||
return ex;
|
||||
}
|
||||
};
|
||||
|
||||
base64.getbyte64 = function(s,i) {
|
||||
// This is oddly fast, except on Chrome/V8.
|
||||
// Minimal or no improvement in performance by using a
|
||||
// object with properties mapping chars to value (eg. 'A': 0)
|
||||
var idx = base64.ALPHA.indexOf(s.charAt(i));
|
||||
if (idx === -1) {
|
||||
throw base64.makeDOMException();
|
||||
}
|
||||
return idx;
|
||||
};
|
||||
|
||||
base64.decode = function(s) {
|
||||
// convert to string
|
||||
s = '' + s;
|
||||
var getbyte64 = base64.getbyte64;
|
||||
var pads, i, b10;
|
||||
var imax = s.length;
|
||||
if (imax === 0) {
|
||||
return s;
|
||||
}
|
||||
|
||||
if (imax % 4 !== 0) {
|
||||
throw base64.makeDOMException();
|
||||
}
|
||||
|
||||
pads = 0;
|
||||
if (s.charAt(imax - 1) === base64.PADCHAR) {
|
||||
pads = 1;
|
||||
if (s.charAt(imax - 2) === base64.PADCHAR) {
|
||||
pads = 2;
|
||||
}
|
||||
// either way, we want to ignore this last block
|
||||
imax -= 4;
|
||||
}
|
||||
|
||||
var x = [];
|
||||
for (i = 0; i < imax; i += 4) {
|
||||
b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) |
|
||||
(getbyte64(s,i+2) << 6) | getbyte64(s,i+3);
|
||||
x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff, b10 & 0xff));
|
||||
}
|
||||
|
||||
switch (pads) {
|
||||
case 1:
|
||||
b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | (getbyte64(s,i+2) << 6);
|
||||
x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff));
|
||||
break;
|
||||
case 2:
|
||||
b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12);
|
||||
x.push(String.fromCharCode(b10 >> 16));
|
||||
break;
|
||||
}
|
||||
return x.join('');
|
||||
};
|
||||
|
||||
base64.getbyte = function(s,i) {
|
||||
var x = s.charCodeAt(i);
|
||||
if (x > 255) {
|
||||
throw base64.makeDOMException();
|
||||
}
|
||||
return x;
|
||||
};
|
||||
|
||||
base64.encode = function(s) {
|
||||
if (arguments.length !== 1) {
|
||||
throw new SyntaxError("Not enough arguments");
|
||||
}
|
||||
var padchar = base64.PADCHAR;
|
||||
var alpha = base64.ALPHA;
|
||||
var getbyte = base64.getbyte;
|
||||
|
||||
var i, b10;
|
||||
var x = [];
|
||||
|
||||
// convert to string
|
||||
s = '' + s;
|
||||
|
||||
var imax = s.length - s.length % 3;
|
||||
|
||||
if (s.length === 0) {
|
||||
return s;
|
||||
}
|
||||
for (i = 0; i < imax; i += 3) {
|
||||
b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8) | getbyte(s,i+2);
|
||||
x.push(alpha.charAt(b10 >> 18));
|
||||
x.push(alpha.charAt((b10 >> 12) & 0x3F));
|
||||
x.push(alpha.charAt((b10 >> 6) & 0x3f));
|
||||
x.push(alpha.charAt(b10 & 0x3f));
|
||||
}
|
||||
switch (s.length - imax) {
|
||||
case 1:
|
||||
b10 = getbyte(s,i) << 16;
|
||||
x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
|
||||
padchar + padchar);
|
||||
break;
|
||||
case 2:
|
||||
b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8);
|
||||
x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
|
||||
alpha.charAt((b10 >> 6) & 0x3f) + padchar);
|
||||
break;
|
||||
}
|
||||
return x.join('');
|
||||
};
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger('Envjs.Window');
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.Window').
|
||||
debug('window logger available');
|
||||
});
|
||||
|
||||
//These descriptions of window properties are taken loosely David Flanagan's
|
||||
//'JavaScript - The Definitive Guide' (O'Reilly)
|
||||
|
||||
var __top__ = function(_scope){
|
||||
var _parent = _scope.parent;
|
||||
while (_scope && _parent && _scope !== _parent) {
|
||||
if (_parent === _parent.parent) {
|
||||
break;
|
||||
}
|
||||
_parent = _parent.parent;
|
||||
//console.log('scope %s _parent %s', scope, _parent);
|
||||
}
|
||||
return _parent || null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Window
|
||||
* @param {Object} scope
|
||||
* @param {Object} parent
|
||||
* @param {Object} opener
|
||||
*/
|
||||
exports.Window = Window = function(scope, parent, opener){
|
||||
|
||||
if(!scope){
|
||||
scope = __this__;
|
||||
}
|
||||
if(!parent){
|
||||
parent = scope;
|
||||
}
|
||||
// the window property is identical to the self property and to this obj
|
||||
scope.__defineGetter__('window', function(){
|
||||
return scope;
|
||||
});
|
||||
|
||||
var $uuid = new Date().getTime()+'-'+Math.floor(Math.random()*1000000000000000);
|
||||
Envjs.windows($uuid, scope);
|
||||
//log.debug('opening window %s', $uuid);
|
||||
|
||||
// every window has one-and-only-one .document property which is always
|
||||
// an [object HTMLDocument]. also, only window.document objects are
|
||||
// html documents, all other documents created by the window.document are
|
||||
// [object XMLDocument]
|
||||
var $htmlImplementation = new DOMImplementation();
|
||||
$htmlImplementation.namespaceAware = true;
|
||||
$htmlImplementation.errorChecking = false;
|
||||
|
||||
// read only reference to the Document object
|
||||
var $document = new HTMLDocument($htmlImplementation, scope);
|
||||
|
||||
// A read-only reference to the Window object that contains this window
|
||||
// or frame. If the window is a top-level window, parent refers to
|
||||
// the window itself. If this window is a frame, this property refers
|
||||
// to the window or frame that contains it.
|
||||
var $parent = parent;
|
||||
|
||||
/**> $cookies - see cookie.js <*/
|
||||
// read only boolean specifies whether the window has been closed
|
||||
var $closed = false;
|
||||
|
||||
// a read/write string that specifies the default message that
|
||||
// appears in the status line
|
||||
var $defaultStatus = "Done";
|
||||
|
||||
// IE only, refers to the most recent event object - this maybe be
|
||||
// removed after review
|
||||
var $event = null;
|
||||
|
||||
// a read-only reference to the History object
|
||||
var $history = new History();
|
||||
|
||||
// a read-only reference to the Location object. the location object does
|
||||
// expose read/write properties
|
||||
var $location = new Location('about:blank', $document, $history);
|
||||
|
||||
// The name of window/frame. Set directly, when using open(), or in frameset.
|
||||
// May be used when specifying the target attribute of links
|
||||
var $name = null;
|
||||
|
||||
// a read-only reference to the Navigator object
|
||||
var $navigator = new Navigator();
|
||||
|
||||
// a read/write reference to the Window object that contained the script
|
||||
// that called open() to open this browser window. This property is valid
|
||||
// only for top-level window objects.
|
||||
var $opener = opener?opener:null;
|
||||
|
||||
// read-only properties that specify the height and width, in pixels
|
||||
var $innerHeight = 600, $innerWidth = 800;
|
||||
|
||||
// Read-only properties that specify the total height and width, in pixels,
|
||||
// of the browser window. These dimensions include the height and width of
|
||||
// the menu bar, toolbars, scrollbars, window borders and so on. These
|
||||
// properties are not supported by IE and IE offers no alternative
|
||||
// properties;
|
||||
var $outerHeight = $innerHeight,
|
||||
$outerWidth = $innerWidth;
|
||||
|
||||
// Read-only properties that specify the number of pixels that the current
|
||||
// document has been scrolled to the right and down. These are not
|
||||
// supported by IE.
|
||||
var $pageXOffset = 0, $pageYOffset = 0;
|
||||
|
||||
// a read-only reference to the Screen object that specifies information
|
||||
// about the screen: the number of available pixels and the number of
|
||||
// available colors.
|
||||
var $screen = new Screen(scope);
|
||||
|
||||
// read only properties that specify the coordinates of the upper-left
|
||||
// corner of the screen.
|
||||
var $screenX = 1,
|
||||
$screenY = 1;
|
||||
var $screenLeft = $screenX,
|
||||
$screenTop = $screenY;
|
||||
|
||||
// a read/write string that specifies the current status line.
|
||||
var $status = '';
|
||||
__extend__(scope, EventTarget.prototype);
|
||||
|
||||
return __extend__( scope, {
|
||||
get closed(){
|
||||
return $closed;
|
||||
},
|
||||
get defaultStatus(){
|
||||
return $defaultStatus;
|
||||
},
|
||||
set defaultStatus(defaultStatus){
|
||||
$defaultStatus = defaultStatus;
|
||||
},
|
||||
get document(){
|
||||
return $document;
|
||||
},
|
||||
set document(doc){
|
||||
$document = doc;
|
||||
},
|
||||
/*
|
||||
deprecated ie specific property probably not good to support
|
||||
get event(){
|
||||
return $event;
|
||||
},
|
||||
*/
|
||||
get frames(){
|
||||
return $document.getElementsByTagName('frame');
|
||||
},
|
||||
get length(){
|
||||
// should be frames.length,
|
||||
return this.frames.length;
|
||||
},
|
||||
get history(){
|
||||
return $history;
|
||||
},
|
||||
get innerHeight(){
|
||||
return $innerHeight;
|
||||
},
|
||||
get innerWidth(){
|
||||
return $innerWidth;
|
||||
},
|
||||
get clientHeight(){
|
||||
return $innerHeight;
|
||||
},
|
||||
get clientWidth(){
|
||||
return $innerWidth;
|
||||
},
|
||||
get location(){
|
||||
return $location;
|
||||
},
|
||||
set location(url){
|
||||
//very important or you will go into an infinite
|
||||
//loop when creating a xml document
|
||||
log.debug('setting window location %s', url);
|
||||
if(url) {
|
||||
$location.assign(Envjs.uri(url, $location+''));
|
||||
}
|
||||
},
|
||||
get name(){
|
||||
return $name;
|
||||
},
|
||||
set name(newName){
|
||||
$name = newName;
|
||||
},
|
||||
get navigator(){
|
||||
return $navigator;
|
||||
},
|
||||
get opener(){
|
||||
return $opener;
|
||||
},
|
||||
get outerHeight(){
|
||||
return $outerHeight;
|
||||
},
|
||||
get outerWidth(){
|
||||
return $outerWidth;
|
||||
},
|
||||
get pageXOffest(){
|
||||
return $pageXOffset;
|
||||
},
|
||||
get pageYOffset(){
|
||||
return $pageYOffset;
|
||||
},
|
||||
get parent(){
|
||||
return $parent;
|
||||
},
|
||||
get screen(){
|
||||
return $screen;
|
||||
},
|
||||
get screenLeft(){
|
||||
return $screenLeft;
|
||||
},
|
||||
get screenTop(){
|
||||
return $screenTop;
|
||||
},
|
||||
get screenX(){
|
||||
return $screenX;
|
||||
},
|
||||
get screenY(){
|
||||
return $screenY;
|
||||
},
|
||||
get self(){
|
||||
return scope;
|
||||
},
|
||||
get status(){
|
||||
return $status;
|
||||
},
|
||||
set status(status){
|
||||
$status = status;
|
||||
},
|
||||
// a read-only reference to the top-level window that contains this window.
|
||||
// If this window is a top-level window it is simply a reference to itself.
|
||||
// If this window is a frame, the top property refers to the top-level
|
||||
// window that contains the frame.
|
||||
get top(){
|
||||
return __top__(scope);
|
||||
},
|
||||
get window(){
|
||||
return this;
|
||||
},
|
||||
toString : function(){
|
||||
return '[Window]';
|
||||
},
|
||||
|
||||
/**
|
||||
* getComputedStyle
|
||||
*
|
||||
* Firefox 3.6:
|
||||
* - Requires both elements to be present else an
|
||||
* exception is thrown.
|
||||
* - Returns a 'ComputedCSSStyleDeclaration' object.
|
||||
* while a raw element.style returns a 'CSSStyleDeclaration' object.
|
||||
* - Bogus input also throws exception
|
||||
*
|
||||
* Safari 4:
|
||||
* - Requires one argument (second can be MIA)
|
||||
* - Returns a CSSStyleDeclaration object
|
||||
* - if bad imput, returns null
|
||||
*
|
||||
* getComputedStyle should really be an "add on" from the css
|
||||
* modules. Unfortunately, 'window' comes way after the 'css'
|
||||
* so css can't add it.
|
||||
*/
|
||||
getComputedStyle: function(element, pseudoElement) {
|
||||
return element.style;
|
||||
},
|
||||
|
||||
open: function(url, name, features, replace){
|
||||
if (features) {
|
||||
console.log("'features argument not yet implemented");
|
||||
}
|
||||
var _window = Envjs.proxy({}),
|
||||
open;
|
||||
if(replace && name){
|
||||
for(open in Envjs.windows()){
|
||||
if(open.name === name) {
|
||||
_window = open;
|
||||
}
|
||||
}
|
||||
}
|
||||
var w = new Window(_window, _window, this);
|
||||
if(name) {
|
||||
_window.name = name;
|
||||
}
|
||||
_window.document.async = false;
|
||||
_window.document.location.assign(Envjs.uri(url));
|
||||
return _window;
|
||||
},
|
||||
close: function(){
|
||||
log.debug('closing window %s', $uuid);
|
||||
var frames = $document.getElementsByTagName('frame'),
|
||||
iframes = $document.getElementsByTagName('iframe'),
|
||||
i;
|
||||
for(i=0;i<frames.length;i++){
|
||||
Envjs.unloadFrame(frames[i]);
|
||||
}
|
||||
for(i=0;i<iframes.length;i++){
|
||||
Envjs.unloadFrame(iframes[i]);
|
||||
}
|
||||
try{
|
||||
Envjs.windows($uuid, null);
|
||||
}catch(e){
|
||||
log.error('%s',e);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
alert : function(message){
|
||||
Envjs.alert(message);
|
||||
},
|
||||
confirm : function(question){
|
||||
Envjs.confirm(question);
|
||||
},
|
||||
prompt : function(message, defaultMsg){
|
||||
Envjs.prompt(message, defaultMsg);
|
||||
},
|
||||
btoa: function(binary){
|
||||
return base64.encode(binary);
|
||||
},
|
||||
atob: function(ascii){
|
||||
return base64.decode(ascii);
|
||||
},
|
||||
//these should be undefined on instantiation
|
||||
//onload: function(){},
|
||||
//onunload: function(){},
|
||||
focus: function(){},
|
||||
blur: function(){},
|
||||
get guid(){
|
||||
return $uuid;
|
||||
},
|
||||
set guid(_guid){
|
||||
$uuid = _guid;
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
//console.log('scheduling default window creation');
|
||||
setTimeout(function(){
|
||||
var w = new Window(__this__);
|
||||
log.info('[ %s ]', window.navigator.userAgent);
|
||||
},1);
|
||||
|
||||
}(/*Window*/));
|
||||
|
||||
|
||||
//console.log('starting Envjs.eventLoop');
|
||||
Envjs.eventLoop();
|
||||
|
||||
/**
|
||||
* @author john resig & the envjs team
|
||||
* @uri http://www.envjs.com/
|
||||
* @copyright 2008-2010
|
||||
* @license MIT
|
||||
*/
|
||||
//CLOSURE_END
|
||||
}());
|
|
@ -0,0 +1,566 @@
|
|||
|
||||
/*
|
||||
* Envjs xhr.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
//CLOSURE_START
|
||||
(function(){
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Envjs xhr.1.3.pre03
|
||||
* Pure JavaScript Browser Environment
|
||||
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||
* Copyright 2008-2010 John Resig, under the MIT License
|
||||
*
|
||||
* Parts of the implementation originally written by Yehuda Katz.
|
||||
*
|
||||
* This file simply provides the global definitions we need to
|
||||
* be able to correctly implement to core browser (XML)HTTPRequest
|
||||
* interfaces.
|
||||
|
||||
This module leaks the following global definitions.
|
||||
|
||||
var Location,
|
||||
XMLHttpRequest;
|
||||
|
||||
*/
|
||||
|
||||
var Envjs = Envjs || require('./platform/core').Envjs,
|
||||
Document = Document || require('./dom').Document;
|
||||
|
||||
/**
|
||||
* @author john resig
|
||||
*/
|
||||
// Helper method for extending one object with another.
|
||||
function __extend__(a,b) {
|
||||
for ( var i in b ) {
|
||||
if(b.hasOwnProperty(i)){
|
||||
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||
if ( g || s ) {
|
||||
if ( g ) { a.__defineGetter__(i, g); }
|
||||
if ( s ) { a.__defineSetter__(i, s); }
|
||||
} else {
|
||||
a[i] = b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* These functions require network IO provided by XMLHttpRequest
|
||||
*/
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.DOM.Document').
|
||||
info('doc logger available');
|
||||
});
|
||||
|
||||
__extend__(Document.prototype,{
|
||||
load: function(url){
|
||||
if(this.documentURI == 'about:html'){
|
||||
this.location.assign(url);
|
||||
}else if(this.documentURI == url){
|
||||
this.location.reload(false);
|
||||
}else{
|
||||
this.location.replace(url);
|
||||
}
|
||||
},
|
||||
get location(){
|
||||
return this.ownerWindow.location;
|
||||
},
|
||||
set location(url){
|
||||
//very important or you will go into an infinite
|
||||
//loop when creating a xml document
|
||||
this.ownerWindow.location = url;
|
||||
}
|
||||
});
|
||||
|
||||
}(/*Document/Location Mixin*/));
|
||||
/**
|
||||
* Location
|
||||
*
|
||||
* Mozilla MDC:
|
||||
* https://developer.mozilla.org/En/DOM/Window.location
|
||||
* https://developer.mozilla.org/en/DOM/document.location
|
||||
*
|
||||
* HTML5: 6.10.4 The Location interface
|
||||
* http://dev.w3.org/html5/spec/Overview.html#location
|
||||
*
|
||||
* HTML5: 2.5.3 Interfaces for URL manipulation
|
||||
* http://dev.w3.org/html5/spec/Overview.html#url-decomposition-idl-attributes
|
||||
* All of section 2.5 is worth reading, but 2.5.3 contains very
|
||||
* detailed information on how getters/setter should work
|
||||
*
|
||||
* NOT IMPLEMENTED:
|
||||
* HTML5: Section 6.10.4.1 Security -- prevents scripts from another domain
|
||||
* from accessing most of the 'Location'
|
||||
* Not sure if anyone implements this in HTML4
|
||||
*/
|
||||
(function(){
|
||||
|
||||
var log = Envjs.logger();
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.Location').
|
||||
debug('location logger available');
|
||||
});
|
||||
|
||||
exports.Location = Location = function(url, doc, history) {
|
||||
log = log||Envjs.logger('Envjs.Location');
|
||||
log.debug('Location url %s', url);
|
||||
var $url = url,
|
||||
$document = doc ? doc : null,
|
||||
$history = history ? history : null;
|
||||
|
||||
var parts = Envjs.urlsplit($url);
|
||||
|
||||
return {
|
||||
get hash() {
|
||||
return parts.fragment ? '#' + parts.fragment : parts.fragment;
|
||||
},
|
||||
set hash(s) {
|
||||
if (s[0] === '#') {
|
||||
parts.fragment = s.substr(1);
|
||||
} else {
|
||||
parts.fragment = s;
|
||||
}
|
||||
$url = Envjs.urlunsplit(parts);
|
||||
if ($history) {
|
||||
$history.add($url, 'hash');
|
||||
}
|
||||
},
|
||||
|
||||
get host() {
|
||||
return parts.netloc;
|
||||
},
|
||||
set host(s) {
|
||||
if (!s || s === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
parts.netloc = s;
|
||||
$url = Envjs.urlunsplit(parts);
|
||||
|
||||
// this regenerates hostname & port
|
||||
parts = Envjs.urlsplit($url);
|
||||
|
||||
if ($history) {
|
||||
$history.add( $url, 'host');
|
||||
}
|
||||
this.assign($url);
|
||||
},
|
||||
|
||||
get hostname() {
|
||||
return parts.hostname;
|
||||
},
|
||||
set hostname(s) {
|
||||
if (!s || s === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
parts.netloc = s;
|
||||
if (parts.port != '') {
|
||||
parts.netloc += ':' + parts.port;
|
||||
}
|
||||
parts.hostname = s;
|
||||
$url = Envjs.urlunsplit(parts);
|
||||
if ($history) {
|
||||
$history.add( $url, 'hostname');
|
||||
}
|
||||
this.assign($url);
|
||||
},
|
||||
|
||||
get href() {
|
||||
return $url;
|
||||
},
|
||||
set href(url) {
|
||||
$url = url;
|
||||
if ($history) {
|
||||
$history.add($url, 'href');
|
||||
}
|
||||
this.assign($url);
|
||||
},
|
||||
|
||||
get pathname() {
|
||||
return parts.path;
|
||||
},
|
||||
set pathname(s) {
|
||||
if (s[0] === '/') {
|
||||
parts.path = s;
|
||||
} else {
|
||||
parts.path = '/' + s;
|
||||
}
|
||||
$url = Envjs.urlunsplit(parts);
|
||||
|
||||
if ($history) {
|
||||
$history.add($url, 'pathname');
|
||||
}
|
||||
this.assign($url);
|
||||
},
|
||||
|
||||
get port() {
|
||||
// make sure it's a string
|
||||
return '' + parts.port;
|
||||
},
|
||||
set port(p) {
|
||||
// make a string
|
||||
var s = '' + p;
|
||||
parts.port = s;
|
||||
parts.netloc = parts.hostname + ':' + parts.port;
|
||||
$url = Envjs.urlunsplit(parts);
|
||||
if ($history) {
|
||||
$history.add( $url, 'port');
|
||||
}
|
||||
this.assign($url);
|
||||
},
|
||||
|
||||
get protocol() {
|
||||
return parts.scheme + ':';
|
||||
},
|
||||
set protocol(s) {
|
||||
var i = s.indexOf(':');
|
||||
if (i != -1) {
|
||||
s = s.substr(0,i);
|
||||
}
|
||||
parts.scheme = s;
|
||||
$url = Envjs.urlunsplit(parts);
|
||||
if ($history) {
|
||||
$history.add($url, 'protocol');
|
||||
}
|
||||
this.assign($url);
|
||||
},
|
||||
|
||||
get search() {
|
||||
return (parts.query) ? '?' + parts.query : parts.query;
|
||||
},
|
||||
set search(s) {
|
||||
if (s[0] == '?') {
|
||||
s = s.substr(1);
|
||||
}
|
||||
parts.query = s;
|
||||
$url = Envjs.urlunsplit(parts);
|
||||
if ($history) {
|
||||
$history.add($url, 'search');
|
||||
}
|
||||
this.assign($url);
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
return $url;
|
||||
},
|
||||
|
||||
assign: function(url, /*non-standard*/ method, data) {
|
||||
var _this = this,
|
||||
xhr,
|
||||
event;
|
||||
method = method||"GET";
|
||||
data = data||null;
|
||||
log.debug('assigning %s',url);
|
||||
|
||||
//we can only assign if this Location is associated with a document
|
||||
if ($document) {
|
||||
log.debug('fetching %s (async? %s)', url, $document.async);
|
||||
xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.setRequestHeader('Referer', $document.location);
|
||||
log.debug("REFERER: %s", $document.location);
|
||||
// TODO: make async flag a Envjs paramter
|
||||
xhr.open(method, url, false);//$document.async);
|
||||
|
||||
// TODO: is there a better way to test if a node is an HTMLDocument?
|
||||
if ($document.toString() === '[object HTMLDocument]') {
|
||||
//tell the xhr to not parse the document as XML
|
||||
log.debug('loading html document');
|
||||
xhr.onreadystatechange = function() {
|
||||
log.debug('readyState %s', xhr.readyState);
|
||||
if (xhr.readyState === 4) {
|
||||
switch(xhr.status){
|
||||
case 301:
|
||||
case 302:
|
||||
case 303:
|
||||
case 305:
|
||||
case 307:
|
||||
log.debug('status is not good for assignment %s', xhr.status);
|
||||
break;
|
||||
default:
|
||||
log.debug('status is good for assignment %s', xhr.status);
|
||||
$url = xhr.url;
|
||||
parts = Envjs.urlsplit($url);
|
||||
log.debug('new document location %s', xhr.url);
|
||||
Envjs.exchangeHTMLDocument($document, xhr.responseText, xhr.url);
|
||||
}
|
||||
}
|
||||
};
|
||||
try{
|
||||
xhr.send(data, false);//dont parse html
|
||||
}catch(e){
|
||||
log.debug('failed to load content %s', e);
|
||||
Envjs.exchangeHTMLDocument(
|
||||
$document,
|
||||
"<html><head><title>Error Loading</title></head><body>"+e+"</body></html>",
|
||||
xhr.url
|
||||
);
|
||||
}
|
||||
} else {
|
||||
//Treat as an XMLDocument
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === 4) {
|
||||
log.debug('exchanging xml content %s', e);
|
||||
$document = xhr.responseXML;
|
||||
$document.baseURI = xhr.url;
|
||||
if ($document.createEvent) {
|
||||
event = $document.createEvent('Event');
|
||||
event.initEvent('DOMContentLoaded');
|
||||
$document.dispatchEvent( event, false );
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
}//end if($document)
|
||||
},
|
||||
reload: function(forceget) {
|
||||
//for now we have no caching so just proxy to assign
|
||||
log.debug('reloading %s',$url);
|
||||
this.assign($url);
|
||||
},
|
||||
replace: function(url, /*non-standard*/ method, data) {
|
||||
this.assign(url, method, data);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}(/*Location*/));
|
||||
/**
|
||||
*
|
||||
* @class XMLHttpRequest
|
||||
* @author Originally implemented by Yehuda Katz
|
||||
*
|
||||
*/
|
||||
|
||||
(function(){
|
||||
|
||||
// this implementation can be used without requiring a DOMParser
|
||||
// assuming you dont try to use it to get xml/html documents
|
||||
var domparser,
|
||||
log = Envjs.logger();
|
||||
|
||||
Envjs.once('tick', function(){
|
||||
log = Envjs.logger('Envjs.XMLHttpRequest').
|
||||
debug('xhr logger available');
|
||||
});
|
||||
|
||||
exports.XMLHttpRequest = XMLHttpRequest = function(){
|
||||
this.headers = {};
|
||||
this.responseHeaders = {};
|
||||
this.aborted = false;//non-standard
|
||||
};
|
||||
|
||||
// defined by the standard: http://www.w3.org/TR/XMLHttpRequest/#xmlhttprequest
|
||||
// but not provided by Firefox. Safari and others do define it.
|
||||
XMLHttpRequest.UNSENT = 0;
|
||||
XMLHttpRequest.OPEN = 1;
|
||||
XMLHttpRequest.HEADERS_RECEIVED = 2;
|
||||
XMLHttpRequest.LOADING = 3;
|
||||
XMLHttpRequest.DONE = 4;
|
||||
|
||||
XMLHttpRequest.prototype = {
|
||||
open: function(method, url, async, user, password){
|
||||
log.debug('opening xhr %s %s %s', method, url, async);
|
||||
this.readyState = 1;
|
||||
this.async = (async === false)?false:true;
|
||||
this.method = method || "GET";
|
||||
this.url = Envjs.uri(url);
|
||||
this.onreadystatechange();
|
||||
},
|
||||
setRequestHeader: function(header, value){
|
||||
this.headers[header] = value;
|
||||
},
|
||||
send: function(data, parsedoc/*non-standard*/, redirect_count){
|
||||
var _this = this;
|
||||
log.debug('sending request for url %s', this.url);
|
||||
parsedoc = (parsedoc === undefined)?true:!!parsedoc;
|
||||
redirect_count = (redirect_count === undefined) ? 0 : redirect_count;
|
||||
function makeRequest(){
|
||||
var cookie = Envjs.getCookies(_this.url),
|
||||
redirecting = false;
|
||||
if(cookie){
|
||||
_this.setRequestHeader('COOKIE', cookie);
|
||||
}
|
||||
if(window&&window.navigator&&window.navigator.userAgent){
|
||||
_this.setRequestHeader('User-Agent', window.navigator.userAgent);
|
||||
}
|
||||
|
||||
log.debug('establishing platform native connection %s', _this.url);
|
||||
Envjs.connection(_this, function(){
|
||||
log.debug('callback remove xhr from network queue');
|
||||
Envjs.connections.removeConnection(_this);
|
||||
if (!_this.aborted){
|
||||
var doc = null,
|
||||
domparser,
|
||||
cookie,
|
||||
contentType,
|
||||
location;
|
||||
|
||||
try{
|
||||
cookie = _this.getResponseHeader('SET-COOKIE');
|
||||
if(cookie){
|
||||
Envjs.setCookie(_this.url, cookie);
|
||||
}
|
||||
}catch(e){
|
||||
log.warn("Failed to set cookie");
|
||||
}
|
||||
//console.log('status : %s', _this.status);
|
||||
switch(_this.status){
|
||||
case 301:
|
||||
case 302:
|
||||
case 303:
|
||||
case 305:
|
||||
case 307:
|
||||
if(_this.getResponseHeader('Location') && redirect_count < 20){
|
||||
//follow redirect and copy headers
|
||||
redirecting = true;
|
||||
location = _this.getResponseHeader('Location');
|
||||
log.debug('following %s redirect %s from %s url %s',
|
||||
redirect_count,
|
||||
_this.status,
|
||||
_this.url,
|
||||
location);
|
||||
_this.url = Envjs.uri(location);
|
||||
//remove current cookie headers to allow the redirect to determine
|
||||
//the currect cookie based on the new location
|
||||
if('Cookie' in _this.headers ){
|
||||
delete _this.headers.Cookie;
|
||||
}
|
||||
if('Cookie2' in _this.headers ){
|
||||
delete _this.headers.Cookie2;
|
||||
}
|
||||
redirect_count++;
|
||||
if (_this.async){
|
||||
//TODO: see TODO notes below
|
||||
Envjs.runAsync(makeRequest);
|
||||
}else{
|
||||
makeRequest();
|
||||
}
|
||||
return;
|
||||
}break;
|
||||
default:
|
||||
// try to parse the document if we havent explicitly set a
|
||||
// flag saying not to and if we can assure the text at least
|
||||
// starts with valid xml
|
||||
contentType = _this.getResponseHeader('Content-Type');
|
||||
log.debug("response content-type : %s", contentType);
|
||||
if ( parsedoc &&
|
||||
contentType &&
|
||||
contentType.indexOf('xml') > -1 &&
|
||||
_this.responseText.match(/^\s*</) ) {
|
||||
|
||||
domparser = domparser||new DOMParser();
|
||||
try {
|
||||
log.debug("parsing response text into xml document");
|
||||
doc = domparser.parseFromString(_this.responseText+"", 'text/xml');
|
||||
} catch(ee) {
|
||||
//Envjs.error('response XML does not appear to be well formed xml', e);
|
||||
log.error('parseerror \n%s', ee);
|
||||
doc = document.implementation.createDocument('','error',null);
|
||||
doc.appendChild(doc.createTextNode(ee+''));
|
||||
}
|
||||
|
||||
}else{
|
||||
log.debug('response XML does not appear to be xml');
|
||||
}
|
||||
|
||||
_this.__defineGetter__("responseXML", function(){
|
||||
return doc;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}, data);
|
||||
|
||||
if (!_this.aborted && !redirecting){
|
||||
log.debug('did not abort and not redirecting so calling onreadystatechange');
|
||||
_this.onreadystatechange();
|
||||
}
|
||||
|
||||
}//end makeRequest
|
||||
|
||||
log.debug('requesting async: %s', this.url);
|
||||
Envjs.connections.addConnection(this);
|
||||
if (this.async){
|
||||
//DONE: what we really need to do here is rejoin the
|
||||
// current thread and call onreadystatechange via
|
||||
// setTimeout so the callback is essentially applied
|
||||
// at the end of the current callstack
|
||||
Envjs.runAsync(makeRequest);
|
||||
}else{
|
||||
log.debug('requesting sync: %s', this.url);
|
||||
makeRequest();
|
||||
}
|
||||
},
|
||||
abort: function(){
|
||||
this.aborted = true;
|
||||
},
|
||||
onreadystatechange: function(){
|
||||
//Instance specific
|
||||
},
|
||||
getResponseHeader: function(header){
|
||||
log.debug('getting response header %s', header);
|
||||
var rHeader, returnedHeaders;
|
||||
if (this.readyState < 3){
|
||||
throw new Error("INVALID_STATE_ERR");
|
||||
} else {
|
||||
returnedHeaders = [];
|
||||
log.debug('searching response headers for %s ', header);
|
||||
for (rHeader in this.responseHeaders) {
|
||||
if ((rHeader+'').match(new RegExp(header, "i"))) {
|
||||
log.debug('found response header, %s is %s', rHeader, header);
|
||||
returnedHeaders.push(this.responseHeaders[rHeader]);
|
||||
}
|
||||
}
|
||||
|
||||
if (returnedHeaders.length){
|
||||
returnedHeaders = returnedHeaders.join(", ");
|
||||
log.debug('got response header %s', returnedHeaders);
|
||||
return returnedHeaders;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getAllResponseHeaders: function(){
|
||||
var header, returnedHeaders = [];
|
||||
if (this.readyState < 3){
|
||||
throw new Error("INVALID_STATE_ERR");
|
||||
} else {
|
||||
for (header in this.responseHeaders) {
|
||||
if(this.responseHeader.hasOwnProperty(header)){
|
||||
returnedHeaders.push( header + ": " + this.responseHeaders[header] );
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnedHeaders.join("\r\n");
|
||||
},
|
||||
async: true,
|
||||
readyState: 0,
|
||||
responseText: "",
|
||||
status: 0,
|
||||
statusText: ""
|
||||
};
|
||||
|
||||
}(/*XMLHttpREquest*/));
|
||||
/**
|
||||
* @author john resig & the envjs team
|
||||
* @uri http://www.envjs.com/
|
||||
* @copyright 2008-2010
|
||||
* @license MIT
|
||||
*/
|
||||
//CLOSURE_END
|
||||
}());
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
/**
|
||||
* This file provides local settings you'll need to modify to make sure
|
||||
* envjs platform tests can function properly. Dont modify this
|
||||
* file directly, copy it to local_settings.js and then modify it so
|
||||
* as not to commit your local settings back to the repo.
|
||||
*/
|
||||
|
||||
var SETTINGS = {
|
||||
BASE_URI : 'file:///mnt/repos/thatcher/env-js/',
|
||||
AJAX_BASE: 'http://github.com/thatcher/env-js/raw/master/',
|
||||
LOCAL_PORT: '8080',
|
||||
APP_CONTEXT: '/env-js/'
|
||||
};
|
||||
|
||||
|
||||
Envjs.config('logging',[
|
||||
{category:'Envjs.Core', level:'WARN'},
|
||||
{category:'Envjs.Core.REPL', level:'WARN'},
|
||||
{category:'Envjs.DOM', level:'WARN'},
|
||||
{category:'Envjs.DOM.Node', level:'WARN'},
|
||||
{category:'Envjs.DOM.NodeList', level:'WARN'},
|
||||
{category:'Envjs.DOM.NamedNodeMap', level:'WARN'},
|
||||
{category:'Envjs.DOM.NamespacedNodeMap',level:'WARN'},
|
||||
{category:'Envjs.DOM.Element', level:'WARN'},
|
||||
{category:'Envjs.DOM.Document', level:'WARN'},
|
||||
{category:'Envjs.DOM.EventTarget', level:'WARN'},
|
||||
{category:'Envjs.Timer', level:'WARN'},
|
||||
{category:'Envjs.Location', level:'WARN'},
|
||||
{category:'Envjs.XMLHttpRequest', level:'INFO'},
|
||||
{category:'Envjs.Parser', level:'WARN'},
|
||||
{category:'Envjs.Parser.HTMLParser', level:'WARN'},
|
||||
{category:'Envjs.Parser.XMLParser', level:'WARN'},
|
||||
{category:'Envjs.HTML.Frame', level:'WARN'},
|
||||
{category:'Envjs.Window', level:'WARN'},
|
||||
{category:'Envjs.Platform', level:'WARN'},
|
||||
{category:'Envjs.Platform.Johnson', level:'WARN'},
|
||||
{category:'root', level:'WARN'}
|
||||
]);
|
|
@ -1 +1 @@
|
|||
d3 = {version: "1.4.0"}; // semver
|
||||
d3 = {version: "1.5.1"}; // semver
|
||||
|
|
|
@ -2,30 +2,45 @@
|
|||
d3.format = function(specifier) {
|
||||
var match = d3_format_re.exec(specifier),
|
||||
fill = match[1] || " ",
|
||||
sign = d3_format_signs[match[3]] || d3_format_signs["-"],
|
||||
sign = match[3] || "",
|
||||
zfill = match[5],
|
||||
width = +match[6],
|
||||
comma = match[7],
|
||||
precision = match[8],
|
||||
type = match[9];
|
||||
if (precision) precision = precision.substring(1);
|
||||
if (zfill) fill = "0"; // TODO align = "=";
|
||||
if (zfill) {
|
||||
fill = "0"; // TODO align = "=";
|
||||
if (comma) width -= Math.floor((width - 1) / 4);
|
||||
}
|
||||
if (type == "d") precision = "0";
|
||||
return function(value) {
|
||||
var number = +value,
|
||||
negative = (number < 0) && (number = -number);
|
||||
negative = (number < 0) && (number = -number) ? "\u2212" : sign;
|
||||
|
||||
// Return the empty string for floats formatted as ints.
|
||||
if ((type == "d") && (number % 1)) return "";
|
||||
|
||||
// Convert the input value to the desired precision.
|
||||
if (precision) value = number.toFixed(precision);
|
||||
else value = "" + number;
|
||||
if (comma) {
|
||||
var i = value.lastIndexOf("."),
|
||||
f = i >= 0 ? value.substring(i) : (i = value.length, ""),
|
||||
t = [];
|
||||
while (i > 0) t.push(value.substring(i -= 3, i + 3));
|
||||
value = t.reverse().join(",") + f;
|
||||
}
|
||||
var length = (value = sign(negative, value)).length;
|
||||
|
||||
// If the fill character is 0, the sign and group is applied after the fill.
|
||||
if (zfill) {
|
||||
var length = value.length + negative.length;
|
||||
if (length < width) value = new Array(width - length + 1).join(fill) + value;
|
||||
if (comma) value = d3_format_group(value);
|
||||
value = negative + value;
|
||||
}
|
||||
|
||||
// Otherwise (e.g., space-filling), the sign and group is applied before.
|
||||
else {
|
||||
if (comma) value = d3_format_group(value);
|
||||
value = negative + value;
|
||||
var length = value.length;
|
||||
if (length < width) value = new Array(width - length + 1).join(fill) + value;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
};
|
||||
|
@ -33,8 +48,11 @@ d3.format = function(specifier) {
|
|||
// [[fill]align][sign][#][0][width][,][.precision][type]
|
||||
var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
|
||||
|
||||
var d3_format_signs = {
|
||||
"+": function(negative, value) { return (negative ? "\u2212" : "+") + value; },
|
||||
" ": function(negative, value) { return (negative ? "\u2212" : " ") + value; },
|
||||
"-": function(negative, value) { return negative ? "\u2212" + value : value; }
|
||||
};
|
||||
// Apply comma grouping for thousands.
|
||||
function d3_format_group(value) {
|
||||
var i = value.lastIndexOf("."),
|
||||
f = i >= 0 ? value.substring(i) : (i = value.length, ""),
|
||||
t = [];
|
||||
while (i > 0) t.push(value.substring(i -= 3, i + 3));
|
||||
return t.reverse().join(",") + f;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// A rudimentary force layout using Gauss-Seidel.
|
||||
function layout_force() {
|
||||
d3.layout.force = function() {
|
||||
var force = {},
|
||||
event = d3.dispatch("tick"),
|
||||
size = {x: 1, y: 1},
|
||||
size = [1, 1],
|
||||
alpha = .5,
|
||||
distance = 30,
|
||||
interval,
|
||||
|
@ -88,8 +88,8 @@ function layout_force() {
|
|||
k,
|
||||
n = nodes.length,
|
||||
m = links.length,
|
||||
w = size.x,
|
||||
h = size.y,
|
||||
w = size[0],
|
||||
h = size[1],
|
||||
o;
|
||||
|
||||
var paths = [];
|
||||
|
@ -183,6 +183,7 @@ function layout_force() {
|
|||
function mouseup() {
|
||||
if (!node) return;
|
||||
mousemove();
|
||||
node.fixed = false;
|
||||
node = element = null;
|
||||
}
|
||||
|
||||
|
@ -190,4 +191,4 @@ function layout_force() {
|
|||
};
|
||||
|
||||
return force;
|
||||
}
|
||||
};
|
|
@ -1,7 +1,8 @@
|
|||
// Squarified Treemaps by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
|
||||
function layout_treemap() {
|
||||
var children = layout_treemapChildren,
|
||||
value = layout_treemapValue,
|
||||
d3.layout.treemap = function() {
|
||||
var children = d3_layout_treemapChildren,
|
||||
value = d3_layout_treemapValue,
|
||||
round = Math.round,
|
||||
size = [1, 1]; // width, height
|
||||
|
||||
// Recursively compute the node depth and value.
|
||||
|
@ -43,17 +44,17 @@ function layout_treemap() {
|
|||
}
|
||||
}
|
||||
|
||||
// Arranges the specified children into squarified rows.
|
||||
function squarify(children, node) {
|
||||
// Recursively arranges the specified node's children into squarified rows.
|
||||
function squarify(node) {
|
||||
if (!node.children) return;
|
||||
var rect = {x: node.x, y: node.y, dx: node.dx, dy: node.dy},
|
||||
row = [],
|
||||
children = node.children.slice().sort(d3_layout_treemapSort),
|
||||
child,
|
||||
best = Infinity, // the best row score so far
|
||||
score, // the current row score
|
||||
u = Math.min(rect.dx, rect.dy), // initial orientation
|
||||
n;
|
||||
children = children.slice(); // copy-on-write
|
||||
children.sort(function(a, b) { return b.area - a.area; });
|
||||
row.area = 0;
|
||||
while ((n = children.length) > 0) {
|
||||
row.push(child = children[n - 1]);
|
||||
|
@ -63,16 +64,17 @@ function layout_treemap() {
|
|||
best = score;
|
||||
} else { // abort, and try a different orientation
|
||||
row.area -= row.pop().area;
|
||||
position(row, u, rect);
|
||||
position(row, u, rect, false);
|
||||
u = Math.min(rect.dx, rect.dy);
|
||||
row.length = row.area = 0;
|
||||
best = Infinity;
|
||||
}
|
||||
}
|
||||
if (row.length) {
|
||||
position(row, u, rect);
|
||||
position(row, u, rect, true);
|
||||
row.length = row.area = 0;
|
||||
}
|
||||
node.children.forEach(squarify);
|
||||
}
|
||||
|
||||
// Computes the score for the specified row, as the worst aspect ratio.
|
||||
|
@ -94,45 +96,40 @@ function layout_treemap() {
|
|||
}
|
||||
|
||||
// Positions the specified row of nodes. Modifies `rect`.
|
||||
function position(row, u, rect) {
|
||||
function position(row, u, rect, flush) {
|
||||
var i = -1,
|
||||
n = row.length,
|
||||
x = rect.x,
|
||||
y = rect.y,
|
||||
v = u ? row.area / u : 0,
|
||||
v = u ? round(row.area / u) : 0,
|
||||
o;
|
||||
if (u == rect.dx) { // horizontal subdivision
|
||||
if (flush || v > rect.dy) v = rect.dy; // over+underflow
|
||||
while (++i < n) {
|
||||
o = row[i];
|
||||
o.x = x;
|
||||
o.y = y;
|
||||
o.dy = v;
|
||||
x += o.dx = o.area / v;
|
||||
x += o.dx = round(o.area / v);
|
||||
}
|
||||
o.dx += rect.x + rect.dx - x; // rounding error
|
||||
rect.y += v;
|
||||
rect.dy -= v;
|
||||
} else { // vertical subdivision
|
||||
if (flush || v > rect.dx) v = rect.dx; // over+underflow
|
||||
while (++i < n) {
|
||||
o = row[i];
|
||||
o.x = x;
|
||||
o.y = y;
|
||||
o.dx = v;
|
||||
y += o.dy = o.area / v;
|
||||
y += o.dy = round(o.area / v);
|
||||
}
|
||||
o.dy += rect.y + rect.dy - y; // rounding error
|
||||
rect.x += v;
|
||||
rect.dx -= v;
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively computes the treemap layout for the node and its children.
|
||||
function layout(node) {
|
||||
var children = node.children;
|
||||
if (children) {
|
||||
squarify(children, node);
|
||||
children.forEach(layout);
|
||||
}
|
||||
}
|
||||
|
||||
function treemap(d) {
|
||||
var nodes = [],
|
||||
root = sum(d, 0, nodes);
|
||||
|
@ -140,7 +137,7 @@ function layout_treemap() {
|
|||
root.y = 0;
|
||||
root.dx = size[0];
|
||||
root.dy = size[1];
|
||||
layout(root);
|
||||
squarify(root);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
|
@ -162,13 +159,23 @@ function layout_treemap() {
|
|||
return treemap;
|
||||
};
|
||||
|
||||
treemap.round = function(x) {
|
||||
if (!arguments.length) return round != Number;
|
||||
round = x ? Math.round : Number;
|
||||
return treemap;
|
||||
}
|
||||
};
|
||||
|
||||
function layout_treemapChildren(d) {
|
||||
return treemap;
|
||||
};
|
||||
|
||||
function d3_layout_treemapChildren(d) {
|
||||
return d.children;
|
||||
}
|
||||
|
||||
function layout_treemapValue(d) {
|
||||
function d3_layout_treemapValue(d) {
|
||||
return d.value;
|
||||
}
|
||||
|
||||
function d3_layout_treemapSort(a, b) {
|
||||
return b.area - a.area;
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
require("./../lib/env-js/envjs/node");
|
||||
require("./../d3");
|
||||
|
||||
console.log("zero fill:");
|
||||
console.log(" ", d3.format("08d")(0));
|
||||
console.log(" ", d3.format("08d")(42));
|
||||
console.log(" ", d3.format("08d")(42000000));
|
||||
console.log(" ", d3.format("08d")(420000000));
|
||||
console.log(" ", d3.format("08d")(-4));
|
||||
console.log(" ", d3.format("08d")(-42));
|
||||
console.log(" ", d3.format("08d")(-4200000));
|
||||
console.log(" ", d3.format("08d")(-42000000));
|
||||
console.log("");
|
||||
|
||||
console.log("space fill:");
|
||||
console.log(" ", d3.format("8d")(0));
|
||||
console.log(" ", d3.format("8d")(42));
|
||||
console.log(" ", d3.format("8d")(42000000));
|
||||
console.log(" ", d3.format("8d")(420000000));
|
||||
console.log(" ", d3.format("8d")(-4));
|
||||
console.log(" ", d3.format("8d")(-42));
|
||||
console.log(" ", d3.format("8d")(-4200000));
|
||||
console.log(" ", d3.format("8d")(-42000000));
|
||||
console.log("");
|
||||
|
||||
// TODO fill with other characters (requires align support)
|
||||
|
||||
console.log("grouping:");
|
||||
console.log(" ", d3.format(",d")(0));
|
||||
console.log(" ", d3.format(",d")(42));
|
||||
console.log(" ", d3.format(",d")(42000000));
|
||||
console.log(" ", d3.format(",d")(420000000));
|
||||
console.log(" ", d3.format(",d")(-4));
|
||||
console.log(" ", d3.format(",d")(-42));
|
||||
console.log(" ", d3.format(",d")(-4200000));
|
||||
console.log(" ", d3.format(",d")(-42000000));
|
||||
console.log("");
|
||||
|
||||
console.log("grouping with zero fill:");
|
||||
console.log(" ", d3.format("01,d")(0));
|
||||
console.log(" ", d3.format("01,d")(0));
|
||||
console.log(" ", d3.format("02,d")(0));
|
||||
console.log(" ", d3.format("03,d")(0));
|
||||
console.log(" ", d3.format("05,d")(0));
|
||||
console.log(" ", d3.format("08,d")(0));
|
||||
console.log(" ", d3.format("013,d")(0));
|
||||
console.log(" ", d3.format("021,d")(0));
|
||||
console.log("");
|
||||
|
||||
console.log("grouping with zero fill (overflow):");
|
||||
console.log(" ", d3.format("01,d")(1));
|
||||
console.log(" ", d3.format("01,d")(1));
|
||||
console.log(" ", d3.format("02,d")(12));
|
||||
console.log(" ", d3.format("03,d")(123));
|
||||
console.log(" ", d3.format("05,d")(12345));
|
||||
console.log(" ", d3.format("08,d")(12345678));
|
||||
console.log(" ", d3.format("013,d")(1234567890123));
|
||||
console.log("");
|
||||
|
||||
console.log("grouping with space fill:");
|
||||
console.log(" ", d3.format("1,d")(0));
|
||||
console.log(" ", d3.format("1,d")(0));
|
||||
console.log(" ", d3.format("2,d")(0));
|
||||
console.log(" ", d3.format("3,d")(0));
|
||||
console.log(" ", d3.format("5,d")(0));
|
||||
console.log(" ", d3.format("8,d")(0));
|
||||
console.log(" ", d3.format("13,d")(0));
|
||||
console.log(" ", d3.format("21,d")(0));
|
||||
console.log("");
|
||||
|
||||
console.log("grouping with space fill (overflow):");
|
||||
console.log(" ", d3.format("1,d")(1));
|
||||
console.log(" ", d3.format("1,d")(1));
|
||||
console.log(" ", d3.format("2,d")(12));
|
||||
console.log(" ", d3.format("3,d")(123));
|
||||
console.log(" ", d3.format("5,d")(12345));
|
||||
console.log(" ", d3.format("8,d")(12345678));
|
||||
console.log(" ", d3.format("13,d")(1234567890123));
|
||||
console.log("");
|
||||
|
||||
console.log("precision:");
|
||||
console.log(" ", d3.format(".1f")(0.49));
|
||||
console.log(" ", d3.format(".2f")(0.449));
|
||||
console.log(" ", d3.format(".3f")(0.4449));
|
||||
console.log(" ", d3.format(".5f")(0.444449));
|
||||
console.log(" ", d3.format(".1f")(100));
|
||||
console.log(" ", d3.format(".2f")(100));
|
||||
console.log(" ", d3.format(".3f")(100));
|
||||
console.log(" ", d3.format(".5f")(100));
|
||||
console.log("");
|
||||
|
||||
console.log("precision and grouping with space fill:");
|
||||
console.log(" ", d3.format("10,.1f")(123456.49));
|
||||
console.log(" ", d3.format("10,.2f")(1234567.449));
|
||||
console.log(" ", d3.format("10,.3f")(12345678.4449));
|
||||
console.log(" ", d3.format("10,.5f")(123456789.444449));
|
||||
console.log(" ", d3.format("10,.1f")(123456));
|
||||
console.log(" ", d3.format("10,.2f")(1234567));
|
||||
console.log(" ", d3.format("10,.3f")(12345678));
|
||||
console.log(" ", d3.format("10,.5f")(123456789));
|
||||
console.log("");
|
||||
|
||||
console.log("float type passed int:");
|
||||
console.log(" ", d3.format("f")(42));
|
||||
console.log("");
|
||||
|
||||
console.log("int type passed float:");
|
||||
console.log(" ", d3.format("d")(4.2));
|
||||
console.log("");
|
|
@ -0,0 +1,94 @@
|
|||
zero fill:
|
||||
00000000
|
||||
00000042
|
||||
42000000
|
||||
420000000
|
||||
−0000004
|
||||
−0000042
|
||||
−4200000
|
||||
−42000000
|
||||
|
||||
space fill:
|
||||
0
|
||||
42
|
||||
42000000
|
||||
420000000
|
||||
−4
|
||||
−42
|
||||
−4200000
|
||||
−42000000
|
||||
|
||||
grouping:
|
||||
0
|
||||
42
|
||||
42,000,000
|
||||
420,000,000
|
||||
−4
|
||||
−42
|
||||
−4,200,000
|
||||
−42,000,000
|
||||
|
||||
grouping with zero fill:
|
||||
0
|
||||
0
|
||||
00
|
||||
000
|
||||
0,000
|
||||
0,000,000
|
||||
0,000,000,000
|
||||
0,000,000,000,000,000
|
||||
|
||||
grouping with zero fill (overflow):
|
||||
1
|
||||
1
|
||||
12
|
||||
123
|
||||
12,345
|
||||
12,345,678
|
||||
1,234,567,890,123
|
||||
|
||||
grouping with space fill:
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
|
||||
grouping with space fill (overflow):
|
||||
1
|
||||
1
|
||||
12
|
||||
123
|
||||
12,345
|
||||
12,345,678
|
||||
1,234,567,890,123
|
||||
|
||||
precision:
|
||||
0.5
|
||||
0.45
|
||||
0.445
|
||||
0.44445
|
||||
100.0
|
||||
100.00
|
||||
100.000
|
||||
100.00000
|
||||
|
||||
precision and grouping with space fill:
|
||||
123,456.5
|
||||
1,234,567.45
|
||||
12,345,678.445
|
||||
123,456,789.44445
|
||||
123,456.0
|
||||
1,234,567.00
|
||||
12,345,678.000
|
||||
123,456,789.00000
|
||||
|
||||
float type passed int:
|
||||
42
|
||||
|
||||
int type passed float:
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче