diff --git a/package.json b/package.json
index f078f74f983..905f7f29d3a 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,7 @@
"citest-jasmine": "karma start test/jasmine/karma.ciconf.js",
"test-image": "./tasks/test_image.sh",
"test-syntax": "node test/syntax_test.js",
- "test": "npm run test-jasmine && npm test-image",
+ "test": "npm run test-jasmine && npm test-image && npm test-syntax",
"start-test_dashboard": "node devtools/test_dashboard/server.js",
"start-image_viewer": "node devtools/image_viewer/server.js",
"baseline": "./tasks/baseline.sh",
@@ -44,7 +44,7 @@
"alpha-shape": "^1.0.0",
"arraytools": "^1.0.0",
"convex-hull": "^1.0.3",
- "d3": "3.5.6",
+ "d3": "^3.5.12",
"delaunay-triangulate": "^1.1.6",
"es6-promise": "^3.0.2",
"fast-isnumeric": "^1.1.1",
@@ -73,17 +73,17 @@
"robust-orientation": "^1.1.3",
"sane-topojson": "^1.2.0",
"superscript-text": "^1.0.0",
- "tinycolor2": "1.1.2",
- "topojson": "^1.6.19"
+ "tinycolor2": "^1.3.0",
+ "topojson": "^1.6.20"
},
"devDependencies": {
- "brfs": "^1.4.1",
- "browserify": "^12.0.1",
- "browserify-transform-tools": "^1.5.0",
+ "brfs": "^1.4.3",
+ "browserify": "^13.0.0",
+ "browserify-transform-tools": "^1.5.1",
"ecstatic": "^1.2.0",
"eslint": "^1.10.3",
"falafel": "^1.2.0",
- "glob": "^6.0.1",
+ "glob": "^6.0.4",
"jasmine-core": "^2.3.4",
"karma": "^0.13.15",
"karma-browserify": "^4.4.1",
@@ -97,7 +97,7 @@
"prettysize": "0.0.3",
"through2": "^2.0.0",
"uglify-js": "^2.5.0",
- "watchify": "^3.6.0",
- "xml2js": "^0.4.15"
+ "watchify": "^3.7.0",
+ "xml2js": "^0.4.16"
}
}
diff --git a/src/components/drawing/index.js b/src/components/drawing/index.js
index 6f2a025ae73..8e0f48fcbfe 100644
--- a/src/components/drawing/index.js
+++ b/src/components/drawing/index.js
@@ -13,6 +13,7 @@ var Plotly = require('../../plotly');
var d3 = require('d3');
var isNumeric = require('fast-isnumeric');
+var xmlnsNamespaces = require('../../constants/xmlns_namespaces');
var subTypes = require('../../traces/scatter/subtypes');
var makeBubbleSizeFn = require('../../traces/scatter/make_bubble_size_func');
@@ -449,12 +450,8 @@ drawing.makeTester = function(gd) {
.data([0]);
tester.enter().append('svg')
- .attr({
- id: 'js-plotly-tester',
- xmlns: 'http://www.w3.org/2000/svg',
- // odd d3 quirk - need namespace twice??
- 'xmlns:xmlns:xlink': 'http://www.w3.org/1999/xlink'
- })
+ .attr('id', 'js-plotly-tester')
+ .attr(xmlnsNamespaces.svgAttrs)
.style({
position: 'absolute',
left: '-10000px',
diff --git a/src/constants/xmlns_namespaces.js b/src/constants/xmlns_namespaces.js
new file mode 100644
index 00000000000..a2da63d921e
--- /dev/null
+++ b/src/constants/xmlns_namespaces.js
@@ -0,0 +1,22 @@
+/**
+* Copyright 2012-2016, Plotly, Inc.
+* All rights reserved.
+*
+* This source code is licensed under the MIT license found in the
+* LICENSE file in the root directory of this source tree.
+*/
+
+
+'use strict';
+
+
+exports.xmlns = 'http://www.w3.org/2000/xmlns/';
+exports.svg = 'http://www.w3.org/2000/svg';
+exports.xlink = 'http://www.w3.org/1999/xlink';
+
+// the 'old' d3 quirk got fix in v3.5.7
+// https://github.com/mbostock/d3/commit/a6f66e9dd37f764403fc7c1f26be09ab4af24fed
+exports.svgAttrs = {
+ xmlns: exports.svg,
+ 'xmlns:xlink': exports.xlink
+};
diff --git a/src/lib/svg_text_utils.js b/src/lib/svg_text_utils.js
index ae5c151bc99..032b01fee14 100644
--- a/src/lib/svg_text_utils.js
+++ b/src/lib/svg_text_utils.js
@@ -14,16 +14,23 @@
var Plotly = require('../plotly');
var d3 = require('d3');
+var xmlnsNamespaces = require('../constants/xmlns_namespaces');
+
var util = module.exports = {};
// Append SVG
d3.selection.prototype.appendSVG = function(_svgString) {
- var skeleton = '',
- dom = new DOMParser().parseFromString(skeleton, 'application/xml'),
+ var skeleton = [
+ ''
+ ].join('');
+
+ var dom = new DOMParser().parseFromString(skeleton, 'application/xml'),
childNode = dom.documentElement.firstChild;
+
while(childNode) {
this.node().appendChild(this.node().ownerDocument.importNode(childNode, true));
childNode = childNode.nextSibling;
diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js
index 86d92cdfea4..094f803597e 100644
--- a/src/plot_api/plot_api.js
+++ b/src/plot_api/plot_api.js
@@ -28,6 +28,7 @@ var Legend = require('../components/legend');
var Shapes = require('../components/shapes');
var Titles = require('../components/titles');
var manageModeBar = require('../components/modebar/manage');
+var xmlnsNamespaces = require('../constants/xmlns_namespaces');
/**
@@ -2567,11 +2568,7 @@ function makePlotFramework(gd) {
}
fullLayout._paperdiv.selectAll('.main-svg')
- .attr({
- xmlns: 'http://www.w3.org/2000/svg',
- // odd d3 quirk - need namespace twice??
- 'xmlns:xmlns:xlink': 'http://www.w3.org/1999/xlink'
- });
+ .attr(xmlnsNamespaces.svgAttrs);
fullLayout._defs = fullLayout._paper.append('defs')
.attr('id', 'defs-' + fullLayout._uid);
diff --git a/src/plots/geo/geo.js b/src/plots/geo/geo.js
index 022162258e2..2f08fafcbfb 100644
--- a/src/plots/geo/geo.js
+++ b/src/plots/geo/geo.js
@@ -24,6 +24,7 @@ var createGeoScale = require('./set_scale');
var createGeoZoom = require('./zoom');
var createGeoZoomReset = require('./zoom_reset');
+var xmlnsNamespaces = require('../../constants/xmlns_namespaces');
var constants = require('../../constants/geo_constants');
var topojsonUtils = require('../../lib/topojson_utils');
var topojsonFeature = require('topojson').feature;
@@ -217,10 +218,7 @@ proto.makeFramework = function() {
var hoverContainer = this.hoverContainer = geoDiv.append('svg');
hoverContainer
- .attr({
- xmlns:'http://www.w3.org/2000/svg',
- 'xmlns:xmlns:xlink': 'http://www.w3.org/1999/xlink'
- })
+ .attr(xmlnsNamespaces.svgAttrs)
.style({
'position': 'absolute',
'z-index': 20,
@@ -229,9 +227,8 @@ proto.makeFramework = function() {
var framework = this.framework = geoDiv.append('svg');
framework
+ .attr(xmlnsNamespaces.svgAttrs)
.attr({
- 'xmlns':'http://www.w3.org/2000/svg',
- 'xmlns:xmlns:xlink': 'http://www.w3.org/1999/xlink',
'position': 'absolute',
'preserveAspectRatio': 'none'
});
diff --git a/src/plots/polar/micropolar.js b/src/plots/polar/micropolar.js
index f28af079454..a17a0cf3995 100644
--- a/src/plots/polar/micropolar.js
+++ b/src/plots/polar/micropolar.js
@@ -1071,7 +1071,7 @@ var extendDeepAll = Plotly.Lib.extendDeepAll;
width: 300,
height: height + lineHeight,
xmlns: 'http://www.w3.org/2000/svg',
- 'xmlns:xmlns:xlink': 'http://www.w3.org/1999/xlink',
+ 'xmlns:xlink': 'http://www.w3.org/1999/xlink',
version: '1.1'
});
svgEnter.append('g').classed('legend-axis', true);
diff --git a/src/snapshot/tosvg.js b/src/snapshot/tosvg.js
index bea6334e528..0ebc68e44e4 100644
--- a/src/snapshot/tosvg.js
+++ b/src/snapshot/tosvg.js
@@ -9,8 +9,11 @@
'use strict';
-var Plotly = require('../plotly'),
- d3 = require('d3');
+var Plotly = require('../plotly');
+var d3 = require('d3');
+
+var xmlnsNamespaces = require('../constants/xmlns_namespaces');
+
module.exports = function toSVG(gd, format) {
@@ -139,8 +142,8 @@ module.exports = function toSVG(gd, format) {
// fix for IE namespacing quirk?
// http://stackoverflow.com/questions/19610089/unwanted-namespaces-on-svg-markup-when-using-xmlserializer-in-javascript-with-ie
- svg.node().setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'http://www.w3.org/2000/svg');
- svg.node().setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', 'http://www.w3.org/1999/xlink');
+ svg.node().setAttributeNS(xmlnsNamespaces.xmlns, 'xmlns', xmlnsNamespaces.svg);
+ svg.node().setAttributeNS(xmlnsNamespaces.xmlns, 'xmlns:xlink', xmlnsNamespaces.xlink);
var s = new window.XMLSerializer().serializeToString(svg.node());
s = Plotly.util.html_entity_decode(s);
@@ -154,8 +157,8 @@ function insertGlImage(fullLayout, scene, opts) {
fullLayout._glimages.append('svg:image')
.attr({
- xmlns:'http://www.w3.org/2000/svg',
- 'xlink:xlink:href': imageData, // odd d3 quirk, need namespace twice
+ xmlns: xmlnsNamespaces.svg,
+ 'xlink:href': imageData,
x: opts.x,
y: opts.y,
width: opts.width,
diff --git a/src/traces/heatmap/plot.js b/src/traces/heatmap/plot.js
index e087f306e18..3f0f87d0597 100644
--- a/src/traces/heatmap/plot.js
+++ b/src/traces/heatmap/plot.js
@@ -15,6 +15,7 @@ var tinycolor = require('tinycolor2');
var Plotly = require('../../plotly');
var Lib = require('../../lib');
var getColorscale = require('../../components/colorscale/get_scale');
+var xmlnsNamespaces = require('../../constants/xmlns_namespaces');
var maxRowLength = require('./max_row_length');
@@ -372,8 +373,8 @@ function plotOne(gd, plotinfo, cd) {
.classed(id, true)
.datum(cd[0])
.attr({
- xmlns: 'http://www.w3.org/2000/svg',
- 'xlink:xlink:href': canvas.toDataURL('image/png'), // odd d3 quirk, need namespace twice
+ xmlns: xmlnsNamespaces.svg,
+ 'xlink:href': canvas.toDataURL('image/png'),
height: imageHeight,
width: imageWidth,
x: left,
diff --git a/test/jasmine/tests/plot_interact_test.js b/test/jasmine/tests/plot_interact_test.js
index bdf46fafbd7..89d1970be64 100644
--- a/test/jasmine/tests/plot_interact_test.js
+++ b/test/jasmine/tests/plot_interact_test.js
@@ -9,6 +9,13 @@ var destroyGraphDiv = require('../assets/destroy_graph_div');
describe('Test plot structure', function() {
'use strict';
+ function assertNamespaces(node) {
+ expect(node.getAttribute('xmlns'))
+ .toEqual('http://www.w3.org/2000/svg');
+ expect(node.getAttribute('xmlns:xlink'))
+ .toEqual('http://www.w3.org/1999/xlink');
+ }
+
afterEach(destroyGraphDiv);
describe('cartesian plots', function() {
@@ -21,17 +28,17 @@ describe('Test plot structure', function() {
it('has one *subplot xy* node', function() {
var nodes = d3.selectAll('g.subplot.xy');
- expect(nodes[0].length).toEqual(1);
+ expect(nodes.size()).toEqual(1);
});
it('has one *scatterlayer* node', function() {
var nodes = d3.selectAll('g.scatterlayer');
- expect(nodes[0].length).toEqual(1);
+ expect(nodes.size()).toEqual(1);
});
it('has as many *trace scatter* nodes as there are traces', function() {
var nodes = d3.selectAll('g.trace.scatter');
- expect(nodes[0].length).toEqual(mock.data.length);
+ expect(nodes.size()).toEqual(mock.data.length);
});
it('has as many *point* nodes as there are traces', function() {
@@ -42,7 +49,16 @@ describe('Test plot structure', function() {
Npts += trace.x.length;
});
- expect(nodes[0].length).toEqual(Npts);
+ expect(nodes.size()).toEqual(Npts);
+ });
+
+ it('has the correct name spaces', function() {
+ var mainSVGs = d3.selectAll('.main-svg');
+
+ mainSVGs.each(function() {
+ var node = this;
+ assertNamespaces(node);
+ });
});
});
@@ -61,7 +77,19 @@ describe('Test plot structure', function() {
Npts += trace.values.length;
});
- expect(nodes[0].length).toEqual(Npts);
+ expect(nodes.size()).toEqual(Npts);
+ });
+
+ it('has the correct name spaces', function() {
+ var mainSVGs = d3.selectAll('.main-svg');
+
+ mainSVGs.each(function() {
+ var node = this;
+ assertNamespaces(node);
+ });
+
+ var testerSVG = d3.selectAll('#js-plotly-tester');
+ assertNamespaces(testerSVG.node());
});
});
});
@@ -82,7 +110,7 @@ describe('Test plot structure', function() {
if(items) Npts += items.length;
});
- expect(nodes[0].length).toEqual(Npts);
+ expect(nodes.size()).toEqual(Npts);
});
it('has as many *point* nodes as there are marker points', function() {
@@ -94,7 +122,23 @@ describe('Test plot structure', function() {
if(items) Npts += items.length;
});
- expect(nodes[0].length).toEqual(Npts);
+ expect(nodes.size()).toEqual(Npts);
+ });
+
+ it('has the correct name spaces', function() {
+ var mainSVGs = d3.selectAll('.main-svg');
+
+ mainSVGs.each(function() {
+ var node = this;
+ assertNamespaces(node);
+ });
+
+ var geoSVGs = d3.select('#geo').selectAll('svg');
+
+ geoSVGs.each(function() {
+ var node = this;
+ assertNamespaces(node);
+ });
});
});
@@ -113,7 +157,7 @@ describe('Test plot structure', function() {
Npts += trace.r.length;
});
- expect(nodes[0].length).toEqual(Npts);
+ expect(nodes.size()).toEqual(Npts);
});
});
});
diff --git a/test/syntax_test.js b/test/syntax_test.js
index 9f982601c60..cb4dc383340 100644
--- a/test/syntax_test.js
+++ b/test/syntax_test.js
@@ -6,7 +6,7 @@ var glob = require('glob');
var constants = require('../tasks/util/constants');
-var focusGlobals = ['fdescribe', 'fit'];
+var focusGlobals = ['fdescribe', 'fit', 'xdescribe', 'xit'];
var logs = [];
@@ -19,12 +19,13 @@ glob(path.join(constants.pathToJasmineTests, '**/*.js'), function(err, files) {
logs.push([
path.basename(file),
'[line ' + node.loc.start.line + '] :',
- 'contains either a *fdescribe* or a *fit* block.'
+ 'contains either a *fdescribe*, *fit*,',
+ '*xdescribe* or *xit* block.'
].join(' '));
}
});
});
- if(logs.length) throw new Error(logs.join('\n'));
+ if(logs.length) throw new Error('\n' + logs.join('\n') + '\n');
});