Commit e15ac86c authored by Mike Bostock's avatar Mike Bostock
Browse files

Merge branch '3.1.10'

parents eb384180 fcbf4f2f
......@@ -31,7 +31,7 @@ d3.js: $(shell node_modules/.bin/smash --list src/d3.js) package.json
d3.min.js: d3.js
@rm -f $@
node_modules/.bin/uglifyjs $< -c -m -o $@
bin/uglify $< > $@
component.json: bin/component d3.js package.json
@rm -f $@
......
#!/usr/bin/env node
var fs = require("fs"),
uglify = require("uglify-js");
var filename = process.argv[2],
toplevel = uglify.parse(fs.readFileSync(filename, "utf8"), {filename: filename}),
output = uglify.OutputStream(),
compressor = uglify.Compressor(true),
warn = uglify.AST_Node.warn;
uglify.AST_Node.warn = function(s, o) {
if (o.msg === "Accidental global?" && o.name === "d3" && o.line === 1 && !o.col) return;
warn.apply(this, arguments);
};
toplevel.figure_out_scope();
toplevel.scope_warnings({
undeclared: false,
unreferenced: false,
assign_to_global: true,
func_arguments: false,
nested_defuns: false,
eval: false
});
toplevel = toplevel.transform(compressor);
toplevel.figure_out_scope();
toplevel.compute_char_frequency(true);
toplevel.mangle_names(true);
toplevel.print(output);
require("util").print(output.get());
{
"name": "d3",
"version": "3.1.9",
"version": "3.1.10",
"main": "index-browserify.js",
"scripts": [
"index-browserify.js",
......
d3 = function() {
var d3 = {
version: "3.1.9"
version: "3.1.10"
};
if (!Date.now) Date.now = function() {
return +new Date();
......@@ -1628,14 +1628,32 @@ d3 = function() {
function d3_identity(d) {
return d;
}
d3.xhr = function(url, mimeType, callback) {
var xhr = {}, dispatch = d3.dispatch("progress", "load", "error"), headers = {}, response = d3_identity, request = new (d3_window.XDomainRequest && /^(http(s)?:)?\/\//.test(url) ? XDomainRequest : XMLHttpRequest)();
d3.xhr = d3_xhrType(d3_identity);
function d3_xhrType(response) {
return function(url, mimeType, callback) {
if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType,
mimeType = null;
return d3_xhr(url, mimeType, response, callback);
};
}
function d3_xhr(url, mimeType, response, callback) {
var xhr = {}, dispatch = d3.dispatch("progress", "load", "error"), headers = {}, request = new (d3_window.XDomainRequest && /^(http(s)?:)?\/\//.test(url) ? XDomainRequest : XMLHttpRequest)();
"onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() {
request.readyState > 3 && respond();
};
function respond() {
var s = request.status;
!s && request.responseText || s >= 200 && s < 300 || s === 304 ? dispatch.load.call(xhr, response.call(xhr, request)) : dispatch.error.call(xhr, request);
var status = request.status, result;
if (!status && request.responseText || status >= 200 && status < 300 || status === 304) {
try {
result = response.call(xhr, request);
} catch (e) {
dispatch.error.call(xhr, e);
return;
}
dispatch.load.call(xhr, result);
} else {
dispatch.error.call(xhr, request);
}
}
request.onprogress = function(event) {
var o = d3.event;
......@@ -1683,10 +1701,8 @@ d3 = function() {
return xhr;
};
d3.rebind(xhr, dispatch, "on");
if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType,
mimeType = null;
return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback));
};
}
function d3_xhr_fixCallback(callback) {
return callback.length === 1 ? function(error, request) {
callback(error == null ? request : null);
......@@ -1796,22 +1812,20 @@ d3 = function() {
}
d3.csv = d3_dsv(",", "text/csv");
d3.tsv = d3_dsv(" ", "text/tab-separated-values");
var d3_timer_id = 0, d3_timer_byId = {}, d3_timer_queue = null, d3_timer_interval, d3_timer_timeout;
var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout;
d3.timer = function(callback, delay, then) {
if (arguments.length < 3) {
if (arguments.length < 2) delay = 0; else if (!isFinite(delay)) return;
then = Date.now();
}
var timer = d3_timer_byId[callback.id];
if (timer && timer.callback === callback) {
timer.then = then;
timer.delay = delay;
} else d3_timer_byId[callback.id = ++d3_timer_id] = d3_timer_queue = {
var time = then + delay;
var timer = {
callback: callback,
then: then,
delay: delay,
next: d3_timer_queue
time: time,
next: null
};
if (d3_timer_queueTail) d3_timer_queueTail.next = timer; else d3_timer_queueHead = timer;
d3_timer_queueTail = timer;
if (!d3_timer_interval) {
d3_timer_timeout = clearTimeout(d3_timer_timeout);
d3_timer_interval = 1;
......@@ -1819,13 +1833,7 @@ d3 = function() {
}
};
function d3_timer_step() {
var elapsed, now = Date.now(), t1 = d3_timer_queue;
while (t1) {
elapsed = now - t1.then;
if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed);
t1 = t1.next;
}
var delay = d3_timer_flush() - now;
var now = d3_timer_mark(), delay = d3_timer_sweep() - now;
if (delay > 24) {
if (isFinite(delay)) {
clearTimeout(d3_timer_timeout);
......@@ -1838,26 +1846,29 @@ d3 = function() {
}
}
d3.timer.flush = function() {
var elapsed, now = Date.now(), t1 = d3_timer_queue;
while (t1) {
elapsed = now - t1.then;
if (!t1.delay) t1.flush = t1.callback(elapsed);
t1 = t1.next;
}
d3_timer_flush();
d3_timer_mark();
d3_timer_sweep();
};
function d3_timer_flush() {
var t0 = null, t1 = d3_timer_queue, then = Infinity;
function d3_timer_mark() {
var now = Date.now(), timer = d3_timer_queueHead;
while (timer) {
if (now >= timer.time) timer.flush = timer.callback(now - timer.time);
timer = timer.next;
}
return now;
}
function d3_timer_sweep() {
var t0, t1 = d3_timer_queueHead, time = Infinity;
while (t1) {
if (t1.flush) {
delete d3_timer_byId[t1.callback.id];
t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next;
t1 = t0 ? t0.next = t1.next : d3_timer_queueHead = t1.next;
} else {
then = Math.min(then, t1.then + t1.delay);
if (t1.time < time) time = t1.time;
t1 = (t0 = t1).next;
}
}
return then;
d3_timer_queueTail = t0;
return time;
}
var d3_timer_frame = d3_window.requestAnimationFrame || d3_window.webkitRequestAnimationFrame || d3_window.mozRequestAnimationFrame || d3_window.oRequestAnimationFrame || d3_window.msRequestAnimationFrame || function(callback) {
setTimeout(callback, 17);
......@@ -2777,7 +2788,7 @@ d3 = function() {
function insidePolygon(p) {
var wn = 0, n = polygon.length, y = p[1];
for (var i = 0; i < n; ++i) {
for (var j = 1, v = polygon[i], m = v.length, a = v[0]; j < m; ++j) {
for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) {
b = v[j];
if (a[1] <= y) {
if (b[1] > y && isLeft(a, b, p) > 0) ++wn;
......@@ -8550,31 +8561,25 @@ d3 = function() {
d3.time.scale.utc = function() {
return d3_time_scale(d3.scale.linear(), d3_time_scaleUTCMethods, d3_time_scaleUTCFormat);
};
d3.text = function() {
return d3.xhr.apply(d3, arguments).response(d3_text);
};
function d3_text(request) {
d3.text = d3_xhrType(function(request) {
return request.responseText;
}
});
d3.json = function(url, callback) {
return d3.xhr(url, "application/json", callback).response(d3_json);
return d3_xhr(url, "application/json", d3_json, callback);
};
function d3_json(request) {
return JSON.parse(request.responseText);
}
d3.html = function(url, callback) {
return d3.xhr(url, "text/html", callback).response(d3_html);
return d3_xhr(url, "text/html", d3_html, callback);
};
function d3_html(request) {
var range = d3_document.createRange();
range.selectNode(d3_document.body);
return range.createContextualFragment(request.responseText);
}
d3.xml = function() {
return d3.xhr.apply(d3, arguments).response(d3_xml);
};
function d3_xml(request) {
d3.xml = d3_xhrType(function(request) {
return request.responseXML;
}
});
return d3;
}();
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "d3",
"version": "3.1.9",
"version": "3.1.10",
"description": "A small, free JavaScript library for manipulating documents based on data.",
"keywords": [
"dom",
......
import "../core/document";
var d3_timer_id = 0,
d3_timer_byId = {},
d3_timer_queue = null,
var d3_timer_queueHead,
d3_timer_queueTail,
d3_timer_interval, // is an interval (or frame) active?
d3_timer_timeout; // is a timeout active?
......@@ -14,20 +13,13 @@ d3.timer = function(callback, delay, then) {
then = Date.now();
}
// If the callback's already in the queue, update it.
var timer = d3_timer_byId[callback.id];
if (timer && timer.callback === callback) {
timer.then = then;
timer.delay = delay;
}
var time = then + delay;
// Otherwise, add the callback to the queue.
else d3_timer_byId[callback.id = ++d3_timer_id] = d3_timer_queue = {
callback: callback,
then: then,
delay: delay,
next: d3_timer_queue
};
// Add the callback to the tail of the queue.
var timer = {callback: callback, time: time, next: null};
if (d3_timer_queueTail) d3_timer_queueTail.next = timer;
else d3_timer_queueHead = timer;
d3_timer_queueTail = timer;
// Start animatin'!
if (!d3_timer_interval) {
......@@ -38,17 +30,8 @@ d3.timer = function(callback, delay, then) {
};
function d3_timer_step() {
var elapsed,
now = Date.now(),
t1 = d3_timer_queue;
while (t1) {
elapsed = now - t1.then;
if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed);
t1 = t1.next;
}
var delay = d3_timer_flush() - now;
var now = d3_timer_mark(),
delay = d3_timer_sweep() - now;
if (delay > 24) {
if (isFinite(delay)) {
clearTimeout(d3_timer_timeout);
......@@ -62,34 +45,36 @@ function d3_timer_step() {
}
d3.timer.flush = function() {
var elapsed,
now = Date.now(),
t1 = d3_timer_queue;
d3_timer_mark();
d3_timer_sweep();
};
while (t1) {
elapsed = now - t1.then;
if (!t1.delay) t1.flush = t1.callback(elapsed);
t1 = t1.next;
function d3_timer_mark() {
var now = Date.now(),
timer = d3_timer_queueHead;
while (timer) {
if (now >= timer.time) timer.flush = timer.callback(now - timer.time);
timer = timer.next;
}
d3_timer_flush();
};
return now;
}
// Flush after callbacks to avoid concurrent queue modification.
function d3_timer_flush() {
var t0 = null,
t1 = d3_timer_queue,
then = Infinity;
// Returns the time of the earliest active timer, post-sweep.
function d3_timer_sweep() {
var t0,
t1 = d3_timer_queueHead,
time = Infinity;
while (t1) {
if (t1.flush) {
delete d3_timer_byId[t1.callback.id];
t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next;
t1 = t0 ? t0.next = t1.next : d3_timer_queueHead = t1.next;
} else {
then = Math.min(then, t1.then + t1.delay);
if (t1.time < time) time = t1.time;
t1 = (t0 = t1).next;
}
}
return then;
d3_timer_queueTail = t0;
return time;
}
var d3_timer_frame = d3_window.requestAnimationFrame
......
......@@ -49,7 +49,7 @@ function d3_geo_clipView(x0, y0, x1, y1) {
y = p[1];
for (var i = 0; i < n; ++i) {
for (var j = 1, v = polygon[i], m = v.length, a = v[0]; j < m; ++j) {
for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) {
b = v[j];
if (a[1] <= y) {
if (b[1] > y && isLeft(a, b, p) > 0) ++wn;
......
d3 = (function(){
var d3 = {version: "3.1.9"}; // semver
var d3 = {version: "3.1.10"}; // semver
......@@ -2,7 +2,7 @@ import "../core/document";
import "xhr";
d3.html = function(url, callback) {
return d3.xhr(url, "text/html", callback).response(d3_html);
return d3_xhr(url, "text/html", d3_html, callback);
};
function d3_html(request) {
......
import "xhr";
d3.json = function(url, callback) {
return d3.xhr(url, "application/json", callback).response(d3_json);
return d3_xhr(url, "application/json", d3_json, callback);
};
function d3_json(request) {
......
import "xhr";
d3.text = function() {
return d3.xhr.apply(d3, arguments).response(d3_text);
};
function d3_text(request) {
d3.text = d3_xhrType(function(request) {
return request.responseText;
}
});
......@@ -4,11 +4,19 @@ import "../core/identity";
import "../core/rebind";
import "../event/dispatch";
d3.xhr = function(url, mimeType, callback) {
d3.xhr = d3_xhrType(d3_identity);
function d3_xhrType(response) {
return function(url, mimeType, callback) {
if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, mimeType = null;
return d3_xhr(url, mimeType, response, callback);
};
}
function d3_xhr(url, mimeType, response, callback) {
var xhr = {},
dispatch = d3.dispatch("progress", "load", "error"),
headers = {},
response = d3_identity,
request = new (d3_window.XDomainRequest && /^(http(s)?:)?\/\//.test(url) ? XDomainRequest : XMLHttpRequest);
"onload" in request
......@@ -16,10 +24,18 @@ d3.xhr = function(url, mimeType, callback) {
: request.onreadystatechange = function() { request.readyState > 3 && respond(); };
function respond() {
var s = request.status;
!s && request.responseText || s >= 200 && s < 300 || s === 304
? dispatch.load.call(xhr, response.call(xhr, request))
: dispatch.error.call(xhr, request);
var status = request.status, result;
if (!status && request.responseText || status >= 200 && status < 300 || status === 304) {
try {
result = response.call(xhr, request);
} catch (e) {
dispatch.error.call(xhr, e);
return;
}
dispatch.load.call(xhr, result);
} else {
dispatch.error.call(xhr, request);
}
}
request.onprogress = function(event) {
......@@ -77,7 +93,6 @@ d3.xhr = function(url, mimeType, callback) {
d3.rebind(xhr, dispatch, "on");
if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, mimeType = null;
return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback));
};
......
import "xhr";
d3.xml = function() {
return d3.xhr.apply(d3, arguments).response(d3_xml);
};
function d3_xml(request) {
d3.xml = d3_xhrType(function(request) {
return request.responseXML;
}
});
......@@ -32,6 +32,20 @@ suite.addBatch({
"calls every 17 ms": function(info) {
assert.inDelta(info.stop - info.start, 17 * 3, 20);
}
},
"with multiple registered tasks": {
topic: function(timer) {
var callback = this.callback,
results = [];
timer(function() { results.push("A"); return true; });
timer(function() { results.push("B"); return true; });
timer(function() { results.push("C"); return true; });
timer(function() { callback(null, results); return true; })
},
"invokes tasks in the order they were registered": function(results) {
assert.deepEqual(results, ["A", "B", "C"]);
}
}
}
});
......
......@@ -33,21 +33,15 @@ module.exports = {
}
},
// The order here is a bit brittle: because the transition has zero delay,
// it's invoking the start event immediately for all nodes, rather than
// pushing each node onto the timer queue (which would reverse the order of
// callbacks). The order in which tweens are invoked is undefined, so perhaps
// we should sort the expected and actual values before comparing.
"defines the corresponding attr tween": function(result) {
assert.typeOf(result.transition.tween("attr.color"), "function");
},
"invokes the tween function": function(result) {
assert.deepEqual(result.data, ["green", "red"], "expected data, got {actual}");
assert.deepEqual(result.index, [1, 0], "expected data, got {actual}");
assert.deepEqual(result.value, ["#008000", "#ff0000"], "expected value, got {actual}");
assert.domEqual(result.context[0], result.selection[0][1], "expected this, got {actual}");
assert.domEqual(result.context[1], result.selection[0][0], "expected this, got {actual}");
assert.deepEqual(result.data, ["red", "green"], "expected data, got {actual}");
assert.deepEqual(result.index, [0, 1], "expected data, got {actual}");
assert.deepEqual(result.value, ["#ff0000", "#008000"], "expected value, got {actual}");
assert.domEqual(result.context[0], result.selection[0][0], "expected this, got {actual}");
assert.domEqual(result.context[1], result.selection[0][1], "expected this, got {actual}");
},
"end": {
......
......@@ -36,12 +36,6 @@ module.exports = {
}
},
// The order here is a bit brittle: because the transition has zero delay,
// it's invoking the start event immediately for all nodes, rather than
// pushing each node onto the timer queue (which would reverse the order of
// callbacks). The order in which tweens are invoked is undefined, so perhaps
// we should sort the expected and actual values before comparing.
"defines the corresponding style tween": function(result) {
assert.typeOf(result.transition.tween("style.background-color"), "function");
},
......@@ -49,11 +43,11 @@ module.exports = {
assert.equal(result.fails, 0);
},
"invokes the tween function": function(result) {
assert.deepEqual(result.data, ["green", "red"], "expected data, got {actual}");
assert.deepEqual(result.index, [1, 0], "expected index, got {actual}");
assert.deepEqual(result.value, ["#008000", "#ff0000"], "expected value, got {actual}");
assert.domEqual(result.context[0], result.selection[0][1], "expected this, got {actual}");
assert.domEqual(result.context[1], result.selection[0][0], "expected this, got {actual}");
assert.deepEqual(result.data, ["red", "green"], "expected data, got {actual}");
assert.deepEqual(result.index, [0, 1], "expected index, got {actual}");
assert.deepEqual(result.value, ["#ff0000", "#008000"], "expected value, got {actual}");
assert.domEqual(result.context[0], result.selection[0][0], "expected this, got {actual}");
assert.domEqual(result.context[1], result.selection[0][1], "expected this, got {actual}");
},
"end": {
......
......@@ -34,12 +34,6 @@ module.exports = {
}
},
// The order here is a bit brittle: because the transition has zero delay,
// it's invoking the start event immediately for all nodes, rather than
// pushing each node onto the timer queue (which would reverse the order of
// callbacks). The order in which tweens are invoked is undefined, so perhaps
// we should sort the expected and actual values before comparing.
"defines the corresponding tween": function(result) {
assert.typeOf(result.transition.tween("text"), "function");
},
......@@ -47,10 +41,10 @@ module.exports = {
assert.equal(result.fails, 0);
},
"invokes the tween function": function(result) {
assert.deepEqual(result.data, ["green", "red"], "expected data, got {actual}");
assert.deepEqual(result.index, [1, 0], "expected data, got {actual}");
assert.domEqual(result.context[0], result.selection[0][1], "expected this, got {actual}");
assert.domEqual(result.context[1], result.selection[0][0], "expected this, got {actual}");
assert.deepEqual(result.data, ["red", "green"], "expected data, got {actual}");
assert.deepEqual(result.index, [0, 1], "expected data, got {actual}");
assert.domEqual(result.context[0], result.selection[0][0], "expected this, got {actual}");
assert.domEqual(result.context[1], result.selection[0][1], "expected this, got {actual}");
},
"end": {
......
......@@ -24,11 +24,25 @@ suite.addBatch({
topic: function(json) {
var callback = this.callback;
json("//does/not/exist.json", function(error, json) {
callback(null, json);
callback(null, {error: error, value: json});
});
},