Skip to content

Commit 9c3df31

Browse files
committed
Demote JSDOM to development dependency; fix d3#2190.
Code that previously assumed a global document or window now uses the related node’s ownerDocument or ownerDocument.defaultView as appropriate. If no related node is available, the corresponding code will crash; however, the rest of D3 will work just fine. For example, you can’t use d3.select(string) unless a global document is available; it just doesn’t make sense. Use d3.select(node) instead, followed by selection.select(string). Code that previously checked for a global on the window (e.g., XDomainRequest) now uses the global context (`this`) rather than the window.
1 parent ca0b7cb commit 9c3df31

File tree

22 files changed

+261
-201
lines changed

22 files changed

+261
-201
lines changed

d3.js

Lines changed: 114 additions & 82 deletions
Large diffs are not rendered by default.

d3.min.js

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

index.js

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,9 @@
1-
var document = require("jsdom").jsdom(),
2-
globals = {};
1+
var globals = {};
32

4-
// Stash old globals.
3+
// Stash old global.
54
if ("d3" in global) globals.d3 = global.d3;
6-
if ("window" in global) globals.window = global.window;
7-
if ("document" in global) globals.document = global.document;
8-
9-
// Set temporary globals to pretend we’re in a browser.
10-
global.window = document.parentWindow;
11-
global.document = document;
125

136
module.exports = require("./d3");
147

15-
// Restore old globals.
8+
// Restore old global.
169
if ("d3" in globals) global.d3 = globals.d3; else delete global.d3;
17-
if ("window" in globals) global.window = globals.window; else delete global.window;
18-
if ("document" in globals) global.document = globals.document; else delete global.document;

package.json

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,12 @@
5050
"spm": {
5151
"main": "d3.js"
5252
},
53-
"dependencies": {
54-
"jsdom": "1.0.0"
55-
},
5653
"devDependencies": {
57-
"smash": "~0.0.12",
58-
"uglify-js": "2.4.0",
59-
"vows": "0.7.0",
60-
"seedrandom": "2.3.1"
54+
"jsdom": "3",
55+
"seedrandom": "2",
56+
"smash": "0.0",
57+
"uglify-js": "2.4",
58+
"vows": "0.8"
6159
},
6260
"scripts": {
6361
"test": "vows; echo"

src/behavior/drag.js

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import "../core/document";
2+
import "../core/identity";
23
import "../core/rebind";
34
import "../event/drag";
45
import "../event/event";
@@ -9,8 +10,8 @@ import "behavior";
910
d3.behavior.drag = function() {
1011
var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"),
1112
origin = null,
12-
mousedown = dragstart(d3_noop, d3.mouse, d3_behavior_dragMouseSubject, "mousemove", "mouseup"),
13-
touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_behavior_dragTouchSubject, "touchmove", "touchend");
13+
mousedown = dragstart(d3_noop, d3.mouse, d3_window, "mousemove", "mouseup"),
14+
touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_identity, "touchmove", "touchend");
1415

1516
function drag() {
1617
this.on("mousedown.drag", mousedown)
@@ -27,8 +28,8 @@ d3.behavior.drag = function() {
2728
dragId = id(),
2829
dragName = ".drag" + (dragId == null ? "" : "-" + dragId),
2930
dragOffset,
30-
dragSubject = d3.select(subject()).on(move + dragName, moved).on(end + dragName, ended),
31-
dragRestore = d3_event_dragSuppress(),
31+
dragSubject = d3.select(subject(target)).on(move + dragName, moved).on(end + dragName, ended),
32+
dragRestore = d3_event_dragSuppress(target),
3233
position0 = position(parent, dragId);
3334

3435
if (origin) {
@@ -85,11 +86,3 @@ d3.behavior.drag = function() {
8586
function d3_behavior_dragTouchId() {
8687
return d3.event.changedTouches[0].identifier;
8788
}
88-
89-
function d3_behavior_dragTouchSubject() {
90-
return d3.event.target;
91-
}
92-
93-
function d3_behavior_dragMouseSubject() {
94-
return d3_window;
95-
}

src/behavior/zoom.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ d3.behavior.zoom = function() {
2929
y0,
3030
y1;
3131

32+
// Lazily determine the DOM’s support for Wheel events.
33+
// https://developer.mozilla.org/en-US/docs/Mozilla_event_reference/wheel
34+
if (!d3_behavior_zoomWheel) {
35+
d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); }, "wheel")
36+
: "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { return d3.event.wheelDelta; }, "mousewheel")
37+
: (d3_behavior_zoomDelta = function() { return -d3.event.detail; }, "MozMousePixelScroll");
38+
}
39+
3240
function zoom(g) {
3341
g .on(mousedown, mousedowned)
3442
.on(d3_behavior_zoomWheel + ".zoom", mousewheeled)
@@ -183,9 +191,9 @@ d3.behavior.zoom = function() {
183191
target = d3.event.target,
184192
dispatch = event.of(that, arguments),
185193
dragged = 0,
186-
subject = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended),
194+
subject = d3.select(d3_window(that)).on(mousemove, moved).on(mouseup, ended),
187195
location0 = location(d3.mouse(that)),
188-
dragRestore = d3_event_dragSuppress();
196+
dragRestore = d3_event_dragSuppress(that);
189197

190198
d3_selection_interrupt.call(that);
191199
zoomstarted(dispatch);
@@ -215,7 +223,7 @@ d3.behavior.zoom = function() {
215223
touchend = "touchend" + zoomName,
216224
targets = [],
217225
subject = d3.select(that),
218-
dragRestore = d3_event_dragSuppress();
226+
dragRestore = d3_event_dragSuppress(that);
219227

220228
started();
221229
zoomstarted(dispatch);
@@ -336,10 +344,6 @@ d3.behavior.zoom = function() {
336344
return d3.rebind(zoom, event, "on");
337345
};
338346

339-
var d3_behavior_zoomInfinity = [0, Infinity]; // default scale extent
340-
341-
// https://developer.mozilla.org/en-US/docs/Mozilla_event_reference/wheel
342-
var d3_behavior_zoomDelta, d3_behavior_zoomWheel
343-
= "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); }, "wheel")
344-
: "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { return d3.event.wheelDelta; }, "mousewheel")
345-
: (d3_behavior_zoomDelta = function() { return -d3.event.detail; }, "MozMousePixelScroll");
347+
var d3_behavior_zoomInfinity = [0, Infinity], // default scale extent
348+
d3_behavior_zoomDelta, // initialized lazily
349+
d3_behavior_zoomWheel;

src/compat/array.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import "../core/array";
2+
import "../core/document";
3+
4+
// Redefine d3_array if the browser doesn’t support slice-based conversion.
5+
if (d3_document) {
6+
try {
7+
d3_array(d3_document.documentElement.childNodes)[0].nodeType;
8+
} catch (e) {
9+
d3_array = function(list) {
10+
var i = list.length, array = new Array(i);
11+
while (i--) array[i] = list[i];
12+
return array;
13+
};
14+
}
15+
}

src/compat/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
import "array";
12
import "date";
23
import "style";

src/compat/style.js

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import "../core/document";
22

3-
try {
4-
d3_document.createElement("div").style.setProperty("opacity", 0, "");
5-
} catch (error) {
6-
var d3_element_prototype = d3_window.Element.prototype,
7-
d3_element_setAttribute = d3_element_prototype.setAttribute,
8-
d3_element_setAttributeNS = d3_element_prototype.setAttributeNS,
9-
d3_style_prototype = d3_window.CSSStyleDeclaration.prototype,
10-
d3_style_setProperty = d3_style_prototype.setProperty;
11-
d3_element_prototype.setAttribute = function(name, value) {
12-
d3_element_setAttribute.call(this, name, value + "");
13-
};
14-
d3_element_prototype.setAttributeNS = function(space, local, value) {
15-
d3_element_setAttributeNS.call(this, space, local, value + "");
16-
};
17-
d3_style_prototype.setProperty = function(name, value, priority) {
18-
d3_style_setProperty.call(this, name, value + "", priority);
19-
};
3+
// Redefine style.setProperty et al. if the browser doesn’t coerce arguments.
4+
if (d3_document) {
5+
try {
6+
d3_document.createElement("DIV").style.setProperty("opacity", 0, "");
7+
} catch (error) {
8+
var d3_element_prototype = this.Element.prototype,
9+
d3_element_setAttribute = d3_element_prototype.setAttribute,
10+
d3_element_setAttributeNS = d3_element_prototype.setAttributeNS,
11+
d3_style_prototype = this.CSSStyleDeclaration.prototype,
12+
d3_style_setProperty = d3_style_prototype.setProperty;
13+
d3_element_prototype.setAttribute = function(name, value) {
14+
d3_element_setAttribute.call(this, name, value + "");
15+
};
16+
d3_element_prototype.setAttributeNS = function(space, local, value) {
17+
d3_element_setAttributeNS.call(this, space, local, value + "");
18+
};
19+
d3_style_prototype.setProperty = function(name, value, priority) {
20+
d3_style_setProperty.call(this, name, value + "", priority);
21+
};
22+
}
2023
}

src/core/document.js

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
1-
import "array";
1+
var d3_document = this.document;
22

3-
var d3_document = document,
4-
d3_documentElement = d3_document.documentElement,
5-
d3_window = window;
3+
function d3_documentElement(node) {
4+
return node && node.ownerDocument.documentElement;
5+
}
66

7-
// Redefine d3_array if the browser doesn’t support slice-based conversion.
8-
try {
9-
d3_array(d3_documentElement.childNodes)[0].nodeType;
10-
} catch(e) {
11-
d3_array = function(list) {
12-
var i = list.length, array = new Array(i);
13-
while (i--) array[i] = list[i];
14-
return array;
15-
};
7+
function d3_window(node) {
8+
return node && node.ownerDocument.defaultView;
169
}

0 commit comments

Comments
 (0)