diff --git a/src/lib/is_array.js b/src/lib/is_array.js index 9b7d64e41aa..cda78eeb627 100644 --- a/src/lib/is_array.js +++ b/src/lib/is_array.js @@ -11,6 +11,12 @@ /** * Return true for arrays, whether they're untyped or not. */ + +// IE9 fallback +var ab = (typeof ArrayBuffer === 'undefined' || !ArrayBuffer.isView) ? + {isView: function() { return false; }} : + ArrayBuffer; + module.exports = function isArray(a) { - return Array.isArray(a) || ArrayBuffer.isView(a); + return Array.isArray(a) || ab.isView(a); }; diff --git a/src/traces/heatmap/plot.js b/src/traces/heatmap/plot.js index 1fc5eda33de..02fbf077ee7 100644 --- a/src/traces/heatmap/plot.js +++ b/src/traces/heatmap/plot.js @@ -337,7 +337,14 @@ function plotOne(gd, plotinfo, cd) { if(zsmooth) { // best or fast, works fastest with imageData var pxIndex = 0, + pixels; + + try { pixels = new Uint8Array(imageWidth * imageHeight * 4); + } + catch(e) { + pixels = new Array(imageWidth * imageHeight * 4); + } if(zsmooth === 'best') { var xPixArray = new Array(x.length), @@ -379,7 +386,17 @@ function plotOne(gd, plotinfo, cd) { } var imageData = context.createImageData(imageWidth, imageHeight); - imageData.data.set(pixels); + try { + imageData.data.set(pixels); + } + catch(e) { + var pxArray = imageData.data, + dlen = pxArray.length; + for(j = 0; j < dlen; j ++) { + pxArray[j] = pixels[j]; + } + } + context.putImageData(imageData, 0, 0); } else { // zsmooth = false -> filling potentially large bricks works fastest with fillRect for(j = 0; j < m; j++) { diff --git a/test/jasmine/assets/ie9_mock.js b/test/jasmine/assets/ie9_mock.js new file mode 100644 index 00000000000..0d032173c95 --- /dev/null +++ b/test/jasmine/assets/ie9_mock.js @@ -0,0 +1,8 @@ +delete window.Promise; + +delete window.ArrayBuffer; +delete window.Uint8Array; +delete window.Float32Array; +delete window.Float64Array; +delete window.Int16Array; +delete window.Int32Array; diff --git a/test/jasmine/bundle_tests/ie9_test.js b/test/jasmine/bundle_tests/ie9_test.js new file mode 100644 index 00000000000..d874657245b --- /dev/null +++ b/test/jasmine/bundle_tests/ie9_test.js @@ -0,0 +1,42 @@ +var Plotly = require('@lib/core'); + +Plotly.register([ + require('@lib/bar'), + require('@lib/box'), + require('@lib/heatmap'), + require('@lib/histogram'), + require('@lib/histogram2d'), + require('@lib/histogram2dcontour'), + require('@lib/pie'), + require('@lib/contour'), + require('@lib/scatterternary'), + require('@lib/ohlc'), + require('@lib/candlestick') +]); + +var createGraphDiv = require('../assets/create_graph_div'); +var destroyGraphDiv = require('../assets/destroy_graph_div'); + +describe('Bundle with IE9 supported trace types:', function() { + + afterEach(destroyGraphDiv); + + it(' check that ie9_mock.js did its job', function() { + expect(function() { return ArrayBuffer; }) + .toThrow(new ReferenceError('ArrayBuffer is not defined')); + expect(function() { return Uint8Array; }) + .toThrow(new ReferenceError('Uint8Array is not defined')); + }); + + it('heatmaps with smoothing should work', function(done) { + var gd = createGraphDiv(); + var data = [{ + type: 'heatmap', + z: [[1, 2, 3], [2, 1, 2]], + zsmooth: 'best' + }]; + + Plotly.plot(gd, data).then(done); + }); + +}); diff --git a/test/jasmine/karma.conf.js b/test/jasmine/karma.conf.js index 28f046bc961..bd84e867925 100644 --- a/test/jasmine/karma.conf.js +++ b/test/jasmine/karma.conf.js @@ -20,6 +20,7 @@ var arg = process.argv[4]; var testFileGlob = arg ? arg : 'tests/*_test.js'; var isSingleSuiteRun = (arg && arg.indexOf('bundle_tests/') === -1); var isRequireJSTest = (arg && arg.indexOf('bundle_tests/requirejs') !== -1); +var isIE9Test = (arg && arg.indexOf('bundle_tests/ie9') !== -1); var pathToMain = '../../lib/index.js'; var pathToJQuery = 'assets/jquery-1.8.3.min.js'; @@ -127,6 +128,18 @@ else if(isRequireJSTest) { testFileGlob ]; } +else if(isIE9Test) { + // load ie9_mock.js before plotly.js+test bundle + // to catch reference errors that could occur + // when plotly.js is first loaded. + + func.defaultConfig.files = [ + './assets/ie9_mock.js', + testFileGlob + ]; + + func.defaultConfig.preprocessors[testFileGlob] = ['browserify']; +} else { func.defaultConfig.files = [ pathToJQuery,