Skip to content

Commit 0991f3b

Browse files
committed
Use captured references for document and window.
This avoids an inconsistency (discussed in d3#1044) when using D3 inside Node.js, where D3 internally creates a JSDOM document during initialization, but then subsequently depends on the current global document, which is not exposed. D3 now always refers to the global document at the time of initialization, and does not depend on the current global document or window.
1 parent 183060d commit 0991f3b

22 files changed

Lines changed: 75 additions & 76 deletions

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ all: \
2727
src/end.js
2828

2929
d3.core.js: \
30+
src/core/core.js \
3031
src/core/format-$(LOCALE).js \
3132
src/compat/date.js \
3233
src/compat/style.js \
33-
src/core/core.js \
3434
src/core/class.js \
3535
src/core/array.js \
3636
src/core/map.js \

d3.js

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
(function() {
2+
d3 = {
3+
version: "3.0.5"
4+
};
5+
var π = Math.PI, ε = 1e-6, d3_radians = π / 180, d3_degrees = 180 / π, d3_document = document, d3_window = window;
6+
function d3_target(d) {
7+
return d.target;
8+
}
9+
function d3_source(d) {
10+
return d.source;
11+
}
212
var d3_format_decimalPoint = ".", d3_format_thousandsSeparator = ",", d3_format_grouping = [ 3, 3 ];
313
if (!Date.now) Date.now = function() {
414
return +new Date();
515
};
616
try {
7-
document.createElement("div").style.setProperty("opacity", 0, "");
17+
d3_document.createElement("div").style.setProperty("opacity", 0, "");
818
} catch (error) {
9-
var d3_style_prototype = CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;
19+
var d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;
1020
d3_style_prototype.setProperty = function(name, value, priority) {
1121
d3_style_setProperty.call(this, name, value + "", priority);
1222
};
1323
}
14-
d3 = {
15-
version: "3.0.5"
16-
};
17-
var π = Math.PI, ε = 1e-6, d3_radians = π / 180, d3_degrees = 180 / π;
18-
function d3_target(d) {
19-
return d.target;
20-
}
21-
function d3_source(d) {
22-
return d.source;
23-
}
2424
function d3_class(ctor, properties) {
2525
try {
2626
for (var key in properties) {
@@ -43,7 +43,7 @@
4343
return Array.prototype.slice.call(pseudoarray);
4444
}
4545
try {
46-
d3_array(document.documentElement.childNodes)[0].nodeType;
46+
d3_array(d3_document.documentElement.childNodes)[0].nodeType;
4747
} catch (e) {
4848
d3_array = d3_arrayCopy;
4949
}
@@ -395,7 +395,7 @@
395395
return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x);
396396
};
397397
d3.xhr = function(url, mimeType, callback) {
398-
var xhr = {}, dispatch = d3.dispatch("progress", "load", "error"), headers = {}, response = d3_identity, request = new (window.XDomainRequest && /^(http(s)?:)?\/\//.test(url) ? XDomainRequest : XMLHttpRequest)();
398+
var xhr = {}, dispatch = d3.dispatch("progress", "load", "error"), headers = {}, response = d3_identity, request = new (d3_window.XDomainRequest && /^(http(s)?:)?\/\//.test(url) ? XDomainRequest : XMLHttpRequest)();
399399
"onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() {
400400
request.readyState > 3 && respond();
401401
};
@@ -474,8 +474,8 @@
474474
return d3.xhr(url, "text/html", callback).response(d3_html);
475475
};
476476
function d3_html(request) {
477-
var range = document.createRange();
478-
range.selectNode(document.body);
477+
var range = d3_document.createRange();
478+
range.selectNode(d3_document.body);
479479
return range.createContextualFragment(request.responseText);
480480
}
481481
d3.xml = function() {
@@ -805,7 +805,7 @@
805805
return dispatch;
806806
}
807807
d3.transform = function(string) {
808-
var g = document.createElementNS(d3.ns.prefix.svg, "g");
808+
var g = d3_document.createElementNS(d3.ns.prefix.svg, "g");
809809
return (d3.transform = function(string) {
810810
g.setAttribute("transform", string);
811811
var t = g.transform.baseVal.consolidate();
@@ -1440,7 +1440,7 @@
14401440
return n.querySelector(s);
14411441
}, d3_selectAll = function(s, n) {
14421442
return n.querySelectorAll(s);
1443-
}, d3_selectRoot = document.documentElement, d3_selectMatcher = d3_selectRoot.matchesSelector || d3_selectRoot.webkitMatchesSelector || d3_selectRoot.mozMatchesSelector || d3_selectRoot.msMatchesSelector || d3_selectRoot.oMatchesSelector, d3_selectMatches = function(n, s) {
1443+
}, d3_selectRoot = d3_document.documentElement, d3_selectMatcher = d3_selectRoot.matchesSelector || d3_selectRoot.webkitMatchesSelector || d3_selectRoot.mozMatchesSelector || d3_selectRoot.msMatchesSelector || d3_selectRoot.oMatchesSelector, d3_selectMatches = function(n, s) {
14441444
return d3_selectMatcher.call(n, s);
14451445
};
14461446
if (typeof Sizzle === "function") {
@@ -1592,7 +1592,7 @@
15921592
for (priority in name) this.each(d3_selection_style(priority, name[priority], value));
15931593
return this;
15941594
}
1595-
if (n < 2) return getComputedStyle(this.node(), null).getPropertyValue(name);
1595+
if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name);
15961596
priority = "";
15971597
}
15981598
return this.each(d3_selection_style(name, value, priority));
@@ -1654,20 +1654,20 @@
16541654
d3_selectionPrototype.append = function(name) {
16551655
name = d3.ns.qualify(name);
16561656
function append() {
1657-
return this.appendChild(document.createElementNS(this.namespaceURI, name));
1657+
return this.appendChild(d3_document.createElementNS(this.namespaceURI, name));
16581658
}
16591659
function appendNS() {
1660-
return this.appendChild(document.createElementNS(name.space, name.local));
1660+
return this.appendChild(d3_document.createElementNS(name.space, name.local));
16611661
}
16621662
return this.select(name.local ? appendNS : append);
16631663
};
16641664
d3_selectionPrototype.insert = function(name, before) {
16651665
name = d3.ns.qualify(name);
16661666
function insert() {
1667-
return this.insertBefore(document.createElementNS(this.namespaceURI, name), d3_select(before, this));
1667+
return this.insertBefore(d3_document.createElementNS(this.namespaceURI, name), d3_select(before, this));
16681668
}
16691669
function insertNS() {
1670-
return this.insertBefore(document.createElementNS(name.space, name.local), d3_select(before, this));
1670+
return this.insertBefore(d3_document.createElementNS(name.space, name.local), d3_select(before, this));
16711671
}
16721672
return this.select(name.local ? insertNS : insert);
16731673
};
@@ -1891,7 +1891,7 @@
18911891
}
18921892
return d3_transition(subgroups, id);
18931893
};
1894-
var d3_selectionRoot = d3_selection([ [ document ] ]);
1894+
var d3_selectionRoot = d3_selection([ [ d3_document ] ]);
18951895
d3_selectionRoot[0].parentNode = d3_selectRoot;
18961896
d3.select = function(selector) {
18971897
return typeof selector === "string" ? d3_selectionRoot.select(selector) : d3_selection([ [ selector ] ]);
@@ -2103,7 +2103,7 @@
21032103
}
21042104
return d3_transition_tween(this, "style." + name, value, function(b) {
21052105
function styleString() {
2106-
var a = getComputedStyle(this, null).getPropertyValue(name), i;
2106+
var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i;
21072107
return a !== b && (i = interpolate(a, b), function(t) {
21082108
this.style.setProperty(name, i(t), priority);
21092109
});
@@ -2114,7 +2114,7 @@
21142114
d3_transitionPrototype.styleTween = function(name, tween, priority) {
21152115
if (arguments.length < 3) priority = "";
21162116
return this.tween("style." + name, function(d, i) {
2117-
var f = tween.call(this, d, i, getComputedStyle(this, null).getPropertyValue(name));
2117+
var f = tween.call(this, d, i, d3_window.getComputedStyle(this, null).getPropertyValue(name));
21182118
return f && function(t) {
21192119
this.style.setProperty(name, f(t), priority);
21202120
};
@@ -2272,19 +2272,19 @@
22722272
}
22732273
return then;
22742274
}
2275-
var d3_timer_frame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
2275+
var d3_timer_frame = d3_window.requestAnimationFrame || d3_window.webkitRequestAnimationFrame || d3_window.mozRequestAnimationFrame || d3_window.oRequestAnimationFrame || d3_window.msRequestAnimationFrame || function(callback) {
22762276
setTimeout(callback, 17);
22772277
};
22782278
d3.mouse = function(container) {
22792279
return d3_mousePoint(container, d3_eventSource());
22802280
};
2281-
var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0;
2281+
var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0;
22822282
function d3_mousePoint(container, e) {
22832283
var svg = container.ownerSVGElement || container;
22842284
if (svg.createSVGPoint) {
22852285
var point = svg.createSVGPoint();
2286-
if (d3_mouse_bug44083 < 0 && (window.scrollX || window.scrollY)) {
2287-
svg = d3.select(document.body).append("svg").style("position", "absolute").style("top", 0).style("left", 0);
2286+
if (d3_mouse_bug44083 < 0 && (d3_window.scrollX || d3_window.scrollY)) {
2287+
svg = d3.select(d3_document.body).append("svg").style("position", "absolute").style("top", 0).style("left", 0);
22882288
var ctm = svg[0][0].getScreenCTM();
22892289
d3_mouse_bug44083 = !(ctm.f || ctm.e);
22902290
svg.remove();
@@ -3523,7 +3523,7 @@
35233523
}
35243524
function brushstart() {
35253525
var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), center, origin = mouse(), offset;
3526-
var w = d3.select(window).on("mousemove.brush", brushmove).on("mouseup.brush", brushend).on("touchmove.brush", brushmove).on("touchend.brush", brushend).on("keydown.brush", keydown).on("keyup.brush", keyup);
3526+
var w = d3.select(d3_window).on("mousemove.brush", brushmove).on("mouseup.brush", brushend).on("touchmove.brush", brushmove).on("touchend.brush", brushend).on("keydown.brush", keydown).on("keyup.brush", keyup);
35273527
if (dragging) {
35283528
origin[0] = extent[0][0] - origin[0];
35293529
origin[1] = extent[0][1] - origin[1];
@@ -3710,7 +3710,7 @@
37103710
}
37113711
function mousedown() {
37123712
var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, touchId = d3.event.touches ? d3.event.changedTouches[0].identifier : null, offset, origin_ = point(), moved = 0;
3713-
var w = d3.select(window).on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true);
3713+
var w = d3.select(d3_window).on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true);
37143714
if (origin) {
37153715
offset = origin.apply(target, arguments);
37163716
offset = [ offset.x - origin_[0], offset.y - origin_[1] ];
@@ -3833,8 +3833,8 @@
38333833
});
38343834
}
38353835
function mousedown() {
3836-
var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, moved = 0, w = d3.select(window).on("mousemove.zoom", mousemove).on("mouseup.zoom", mouseup), l = location(d3.mouse(target));
3837-
window.focus();
3836+
var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, moved = 0, w = d3.select(d3_window).on("mousemove.zoom", mousemove).on("mouseup.zoom", mouseup), l = location(d3.mouse(target));
3837+
d3_window.focus();
38383838
d3_eventCancel();
38393839
function mousemove() {
38403840
moved = 1;

d3.min.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

globals.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
var document = global.document = require("jsdom").jsdom("<html><head></head><body></body></html>"),
2-
window = global.window = document.createWindow(),
3-
navigator = global.navigator = window.navigator,
4-
getComputedStyle = global.getComputedStyle = window.getComputedStyle,
5-
CSSStyleDeclaration = global.CSSStyleDeclaration = window.CSSStyleDeclaration;
2+
window = global.window = document.createWindow();
63

74
// https://github.com/chad3814/CSSStyleDeclaration/issues/3
8-
var CSSStyleDeclaration_setProperty = CSSStyleDeclaration.prototype.setProperty;
9-
CSSStyleDeclaration.prototype.setProperty = function(name, value, priority) {
5+
var CSSStyleDeclaration_prototype = window.CSSStyleDeclaration.prototype,
6+
CSSStyleDeclaration_setProperty = CSSStyleDeclaration_prototype.setProperty;
7+
CSSStyleDeclaration_prototype.setProperty = function(name, value, priority) {
108
return CSSStyleDeclaration_setProperty.call(this, name + "", value == null ? null : value + "", priority == null ? null : priority + "");
119
};

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var globals = ["document", "window", "navigator", "CSSStyleDeclaration", "getComputedStyle", "d3"],
1+
var globals = ["document", "window", "d3"],
22
globalValues = {};
33

44
globals.forEach(function(g) {

src/behavior/drag.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ d3.behavior.drag = function() {
1616
origin_ = point(),
1717
moved = 0;
1818

19-
var w = d3.select(window)
19+
var w = d3.select(d3_window)
2020
.on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove)
2121
.on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true);
2222

src/behavior/zoom.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ d3.behavior.zoom = function() {
9595
event_ = event.of(target, arguments),
9696
eventTarget = d3.event.target,
9797
moved = 0,
98-
w = d3.select(window).on("mousemove.zoom", mousemove).on("mouseup.zoom", mouseup),
98+
w = d3.select(d3_window).on("mousemove.zoom", mousemove).on("mouseup.zoom", mouseup),
9999
l = location(d3.mouse(target));
100100

101-
window.focus();
101+
d3_window.focus();
102102
d3_eventCancel();
103103

104104
function mousemove() {

src/compat/style.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
try {
2-
document.createElement("div").style.setProperty("opacity", 0, "");
2+
d3_document.createElement("div").style.setProperty("opacity", 0, "");
33
} catch (error) {
4-
var d3_style_prototype = CSSStyleDeclaration.prototype,
4+
var d3_style_prototype = d3_window.CSSStyleDeclaration.prototype,
55
d3_style_setProperty = d3_style_prototype.setProperty;
66
d3_style_prototype.setProperty = function(name, value, priority) {
77
d3_style_setProperty.call(this, name, value + "", priority);

src/core/array.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function d3_arraySlice(pseudoarray) {
1111
}
1212

1313
try {
14-
d3_array(document.documentElement.childNodes)[0].nodeType;
14+
d3_array(d3_document.documentElement.childNodes)[0].nodeType;
1515
} catch(e) {
1616
d3_array = d3_arrayCopy;
1717
}

src/core/core.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ d3 = {version: "3.0.5"}; // semver
33
var π = Math.PI,
44
ε = 1e-6,
55
d3_radians = π / 180,
6-
d3_degrees = 180 / π;
6+
d3_degrees = 180 / π,
7+
d3_document = document,
8+
d3_window = window;
79

810
function d3_target(d) {
911
return d.target;

0 commit comments

Comments
 (0)