From 365f53a10c933759fe25e2274b1761e0acd3f86e Mon Sep 17 00:00:00 2001 From: Robert Monfera Date: Fri, 19 Aug 2016 18:56:50 +0200 Subject: [PATCH 1/3] nestedProperty to handle regular and typed arrays alike (cherry picked from commit 31d66fe) --- src/lib/is_array.js | 17 +++++++++++++++++ src/lib/nested_property.js | 13 +++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 src/lib/is_array.js diff --git a/src/lib/is_array.js b/src/lib/is_array.js new file mode 100644 index 00000000000..0b371023053 --- /dev/null +++ b/src/lib/is_array.js @@ -0,0 +1,17 @@ +/** +* 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'; + +/** + * Truncate a Float32Array to some length. A wrapper to support environments + * (e.g. node-webkit) that do not implement Float32Array.prototype.slice + */ +module.exports = function isArray(a) { + return Array.isArray(a) || ArrayBuffer.isView(a); +} diff --git a/src/lib/nested_property.js b/src/lib/nested_property.js index ac51e2ab4bd..a3e004c2caa 100644 --- a/src/lib/nested_property.js +++ b/src/lib/nested_property.js @@ -10,6 +10,7 @@ 'use strict'; var isNumeric = require('fast-isnumeric'); +var isArray = require('./is_array'); /** * convert a string s (such as 'xaxis.range[0]') @@ -93,7 +94,7 @@ function npGet(cont, parts) { } return allSame ? out[0] : out; } - if(typeof curPart === 'number' && !Array.isArray(curCont)) { + if(typeof curPart === 'number' && !isArray(curCont)) { return undefined; } curCont = curCont[curPart]; @@ -122,7 +123,7 @@ function isDataArray(val, key) { var containers = ['annotations', 'shapes', 'range', 'domain', 'buttons'], isNotAContainer = containers.indexOf(key) === -1; - return Array.isArray(val) && isNotAContainer; + return isArray(val) && isNotAContainer; } function npSet(cont, parts) { @@ -136,7 +137,7 @@ function npSet(cont, parts) { for(i = 0; i < parts.length - 1; i++) { curPart = parts[i]; - if(typeof curPart === 'number' && !Array.isArray(curCont)) { + if(typeof curPart === 'number' && !isArray(curCont)) { throw 'array index but container is not an array'; } @@ -170,7 +171,7 @@ function npSet(cont, parts) { // handle special -1 array index function setArrayAll(containerArray, innerParts, val) { - var arrayVal = Array.isArray(val), + var arrayVal = isArray(val), allSet = true, thisVal = val, deleteThis = arrayVal ? false : emptyObj(val), @@ -215,7 +216,7 @@ function pruneContainers(containerLevels) { for(i = containerLevels.length - 1; i >= 0; i--) { curCont = containerLevels[i]; remainingKeys = false; - if(Array.isArray(curCont)) { + if(isArray(curCont)) { for(j = curCont.length - 1; j >= 0; j--) { if(emptyObj(curCont[j])) { if(remainingKeys) curCont[j] = undefined; @@ -239,7 +240,7 @@ function pruneContainers(containerLevels) { function emptyObj(obj) { if(obj === undefined || obj === null) return true; if(typeof obj !== 'object') return false; // any plain value - if(Array.isArray(obj)) return !obj.length; // [] + if(isArray(obj)) return !obj.length; // [] return !Object.keys(obj).length; // {} } From 6324fff2a7e318d68608ecb7413b6c8dbd64542c Mon Sep 17 00:00:00 2001 From: Robert Monfera Date: Fri, 19 Aug 2016 19:03:49 +0200 Subject: [PATCH 2/3] adding ArrayBuffer to global permitted by eslint --- src/.eslintrc | 3 ++- src/lib/is_array.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/.eslintrc b/src/.eslintrc index 98bd042585b..428c1ee3b53 100644 --- a/src/.eslintrc +++ b/src/.eslintrc @@ -6,7 +6,8 @@ "globals": { "Promise": true, "Float32Array": true, - "Uint8Array": true + "Uint8Array": true, + "ArrayBuffer": true }, "rules": { "strict": [2, "global"], diff --git a/src/lib/is_array.js b/src/lib/is_array.js index 0b371023053..cd45b77a9e6 100644 --- a/src/lib/is_array.js +++ b/src/lib/is_array.js @@ -14,4 +14,4 @@ */ module.exports = function isArray(a) { return Array.isArray(a) || ArrayBuffer.isView(a); -} +}; From 3a5a5eb7d077b11e90f6130bfdb4449aea4202e3 Mon Sep 17 00:00:00 2001 From: Robert Monfera Date: Fri, 19 Aug 2016 19:12:53 +0200 Subject: [PATCH 3/3] adding test cases --- src/lib/index.js | 1 + src/lib/is_array.js | 3 +- test/jasmine/tests/is_array_test.js | 47 ++++++++++++++++++++++ test/jasmine/tests/is_plain_object_test.js | 1 + 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 test/jasmine/tests/is_array_test.js diff --git a/src/lib/index.js b/src/lib/index.js index d1ccb36f1a6..6f9a3d57c90 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -15,6 +15,7 @@ var lib = module.exports = {}; lib.nestedProperty = require('./nested_property'); lib.isPlainObject = require('./is_plain_object'); +lib.isArray = require('./is_array'); var coerceModule = require('./coerce'); lib.valObjects = coerceModule.valObjects; diff --git a/src/lib/is_array.js b/src/lib/is_array.js index cd45b77a9e6..c01cdac4007 100644 --- a/src/lib/is_array.js +++ b/src/lib/is_array.js @@ -9,8 +9,7 @@ 'use strict'; /** - * Truncate a Float32Array to some length. A wrapper to support environments - * (e.g. node-webkit) that do not implement Float32Array.prototype.slice + * Return true for arrays, whether they're untyped or not. */ module.exports = function isArray(a) { return Array.isArray(a) || ArrayBuffer.isView(a); diff --git a/test/jasmine/tests/is_array_test.js b/test/jasmine/tests/is_array_test.js new file mode 100644 index 00000000000..bea361516db --- /dev/null +++ b/test/jasmine/tests/is_array_test.js @@ -0,0 +1,47 @@ +var Lib = require('@src/lib'); + +describe('isArray', function() { + 'use strict'; + + var isArray = Lib.isArray; + + function A() {} + + var shouldPass = [ + [], + new Array(10), + new Float32Array(1), + new Int32Array([1, 2, 3]) + ]; + + var shouldFail = [ + A, + new A(), + document, + window, + null, + undefined, + 'string', + true, + false, + NaN, + Infinity, + /foo/, + '\n', + new Date(), + new RegExp('foo'), + new String('string') + ]; + + shouldPass.forEach(function(obj) { + it('treats ' + JSON.stringify(obj) + ' as an array', function() { + expect(isArray(obj)).toBe(true); + }); + }); + + shouldFail.forEach(function(obj) { + it('treats ' + JSON.stringify(obj !== window ? obj : 'window') + ' as NOT an array', function() { + expect(isArray(obj)).toBe(false); + }); + }); +}); diff --git a/test/jasmine/tests/is_plain_object_test.js b/test/jasmine/tests/is_plain_object_test.js index 95b199db902..cf2ba311f25 100644 --- a/test/jasmine/tests/is_plain_object_test.js +++ b/test/jasmine/tests/is_plain_object_test.js @@ -20,6 +20,7 @@ describe('isPlainObject', function() { null, undefined, [], + new Float32Array(1), 'string', true, false,