Skip to content

Commit a5dad2a

Browse files
committed
PR feedback: moved crawler and its constituent parts into coerce
1 parent 59b741d commit a5dad2a

File tree

6 files changed

+68
-76
lines changed

6 files changed

+68
-76
lines changed

src/lib/coerce.js

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@
1212
var isNumeric = require('fast-isnumeric');
1313
var tinycolor = require('tinycolor2');
1414
var nestedProperty = require('./nested_property');
15+
var isPlainObject = require('./is_plain_object');
1516

1617
var getColorscale = require('../components/colorscale/get_scale');
1718
var colorscaleNames = Object.keys(require('../components/colorscale/scales'));
1819

1920
var idRegex = /^([2-9]|[1-9][0-9]+)$/;
2021

22+
function isValObject(obj) {
23+
return obj && obj.valType !== undefined;
24+
}
25+
2126
exports.valObjects = {
2227
data_array: {
2328
// You can use *dflt=[] to force said array to exist though.
@@ -359,6 +364,48 @@ exports.validate = function(value, opts) {
359364
/*
360365
* returns true for a valid value object and false for tree nodes in the attribute hierarchy
361366
*/
362-
exports.isValObject = function(obj) {
363-
return obj && obj.valType !== undefined;
367+
exports.isValObject = isValObject;
368+
369+
exports.IS_SUBPLOT_OBJ = '_isSubplotObj';
370+
exports.IS_LINKED_TO_ARRAY = '_isLinkedToArray';
371+
exports.DEPRECATED = '_deprecated';
372+
373+
// list of underscore attributes to keep in schema as is
374+
exports.UNDERSCORE_ATTRS = [exports.IS_SUBPLOT_OBJ, exports.IS_LINKED_TO_ARRAY, exports.DEPRECATED];
375+
376+
/**
377+
* Crawl the attribute tree, recursively calling a callback function
378+
*
379+
* @param {object} attrs
380+
* The node of the attribute tree (e.g. the root) from which recursion originates
381+
* @param {Function} callback
382+
* A callback function with the signature:
383+
* @callback callback
384+
* @param {object} attr an attribute
385+
* @param {String} attrName name string
386+
* @param {object[]} attrs all the attributes
387+
* @param {Number} level the recursion level, 0 at the root
388+
* @param {Number} [specifiedLevel]
389+
* The level in the tree, in order to let the callback function detect descend or backtrack,
390+
* typically unsupplied (implied 0), just used by the self-recursive call.
391+
* The necessity arises because the tree traversal is not controlled by callback return values.
392+
* The decision to not use callback return values for controlling tree pruning arose from
393+
* the goal of keeping the crawler backwards compatible. Observe that one of the pruning conditions
394+
* precedes the callback call.
395+
*
396+
* @return {object} transformOut
397+
* copy of transformIn that contains attribute defaults
398+
*/
399+
exports.crawl = function(attrs, callback, specifiedLevel) {
400+
var level = specifiedLevel || 0;
401+
Object.keys(attrs).forEach(function(attrName) {
402+
var attr = attrs[attrName];
403+
404+
if(exports.UNDERSCORE_ATTRS.indexOf(attrName) !== -1) return;
405+
406+
callback(attr, attrName, attrs, level);
407+
408+
if(isValObject(attr)) return;
409+
if(isPlainObject(attr)) exports.crawl(attr, callback, level + 1);
410+
});
364411
};

src/lib/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ lib.coerce2 = coerceModule.coerce2;
2424
lib.coerceFont = coerceModule.coerceFont;
2525
lib.validate = coerceModule.validate;
2626
lib.isValObject = coerceModule.isValObject;
27+
lib.crawl = coerceModule.crawl;
28+
lib.IS_SUBPLOT_OBJ = coerceModule.IS_SUBPLOT_OBJ;
29+
lib.IS_LINKED_TO_ARRAY = coerceModule.IS_LINKED_TO_ARRAY;
30+
lib.DEPRECATED = coerceModule.DEPRECATED;
31+
lib.UNDERSCORE_ATTRS = coerceModule.UNDERSCORE_ATTRS;
2732

2833
var datesModule = require('./dates');
2934
lib.dateTime2ms = datesModule.dateTime2ms;

src/plot_api/crawler.js

Lines changed: 0 additions & 58 deletions
This file was deleted.

src/plot_api/plot_schema.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ var Plotly = require('../plotly');
1313
var Registry = require('../registry');
1414
var Plots = require('../plots/plots');
1515
var Lib = require('../lib');
16-
var crawler = require('./crawler');
1716

1817
// FIXME polar attribute are not part of Plotly yet
1918
var polarAreaAttrs = require('../plots/polar/area_attributes');
@@ -51,7 +50,7 @@ PlotSchema.get = function() {
5150
return plotSchema;
5251
};
5352

54-
PlotSchema.crawl = crawler.crawl;
53+
PlotSchema.crawl = Lib.crawl;
5554

5655
PlotSchema.isValObject = Lib.isValObject;
5756

@@ -140,7 +139,7 @@ function getTransformAttributes(name) {
140139
function getDefs() {
141140
plotSchema.defs = {
142141
valObjects: Lib.valObjects,
143-
metaKeys: crawler.UNDERSCORE_ATTRS.concat(['description', 'role'])
142+
metaKeys: Lib.UNDERSCORE_ATTRS.concat(['description', 'role'])
144143
};
145144
}
146145

@@ -223,7 +222,7 @@ function mergeValTypeAndRole(attrs) {
223222
}
224223
}
225224

226-
crawler.crawl(attrs, callback);
225+
Lib.crawl(attrs, callback);
227226
}
228227

229228
// helper methods
@@ -249,7 +248,7 @@ function getModule(arg) {
249248
function removeUnderscoreAttrs(attributes) {
250249
Object.keys(attributes).forEach(function(k) {
251250
if(k.charAt(0) === '_' &&
252-
crawler.UNDERSCORE_ATTRS.indexOf(k) === -1) delete attributes[k];
251+
Lib.UNDERSCORE_ATTRS.indexOf(k) === -1) delete attributes[k];
253252
});
254253
return attributes;
255254
}
@@ -303,7 +302,7 @@ function handleSubplotObjs(layoutAttributes) {
303302
isSubplotObj = subplotRegistry.attrRegex.test(k);
304303
}
305304

306-
if(isSubplotObj) layoutAttributes[k][crawler.IS_SUBPLOT_OBJ] = true;
305+
if(isSubplotObj) layoutAttributes[k][Lib.IS_SUBPLOT_OBJ] = true;
307306
});
308307
});
309308

@@ -313,17 +312,17 @@ function handleSubplotObjs(layoutAttributes) {
313312
function handleLinkedToArray(layoutAttributes) {
314313

315314
function callback(attr, attrName, attrs) {
316-
if(attr[crawler.IS_LINKED_TO_ARRAY] !== true) return;
315+
if(attr[Lib.IS_LINKED_TO_ARRAY] !== true) return;
317316

318317
// TODO more robust logic
319318
var itemName = attrName.substr(0, attrName.length - 1);
320319

321-
delete attr[crawler.IS_LINKED_TO_ARRAY];
320+
delete attr[Lib.IS_LINKED_TO_ARRAY];
322321

323322
attrs[attrName] = { items: {} };
324323
attrs[attrName].items[itemName] = attr;
325324
attrs[attrName].role = 'object';
326325
}
327326

328-
crawler.crawl(layoutAttributes, callback);
327+
Lib.crawl(layoutAttributes, callback);
329328
}

src/plots/plots.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
'use strict';
1111

12-
var crawler = require('./../plot_api/crawler');
1312
var d3 = require('d3');
1413
var isNumeric = require('fast-isnumeric');
1514

@@ -815,7 +814,7 @@ function applyTransforms(fullTrace, fullData, layout) {
815814
}
816815
}
817816

818-
crawler.crawl(trace._module.attributes, callback);
817+
Lib.crawl(trace._module.attributes, callback);
819818

820819
return arraySplitAttributes;
821820
});

test/jasmine/tests/transform_groupby_test.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Plotly.register([
1010
require('@src/transforms/groupby')
1111
]);
1212

13-
fdescribe('groupby', function() {
13+
describe('groupby', function() {
1414

1515
describe('one-to-many transforms:', function() {
1616
'use strict';
@@ -511,15 +511,15 @@ fdescribe('groupby', function() {
511511
it('passes with lots of attributes and heterogenous attrib presence', test(mockData2));
512512

513513
it('passes with group styles partially overriding top level aesthetics', test(mockData3));
514-
it('passes extended tests with group styles partially overriding top level aesthetics', function (done) {
514+
it('passes extended tests with group styles partially overriding top level aesthetics', function(done) {
515515
var data = Lib.extendDeep([], mockData3);
516516
var gd = createGraphDiv();
517517
Plotly.plot(gd, data).then(function() {
518518
expect(gd._fullData[0].marker.line.color).toEqual(['orange', 'red', 'cyan', 'pink']);
519519
expect(gd._fullData[1].marker.line.color).toEqual('yellow');
520520
done();
521521
});
522-
} );
522+
});
523523

524524
it('passes with no explicit styling for the individual group', test(mockData4));
525525

@@ -542,12 +542,12 @@ fdescribe('groupby', function() {
542542
marker: {size: 20, line: {width: [4, 2, 4, 2, 2, 3, 3]}},
543543
transforms: [{
544544
type: 'groupby',
545-
//groups: ['a', 'a', 'b', 'a', 'b', 'b', 'a'],
545+
// groups: ['a', 'a', 'b', 'a', 'b', 'b', 'a'],
546546
style: { a: {marker: {color: 'red'}}, b: {marker: {color: 'blue'}} }
547547
}]
548548
}];
549549

550-
it("passes", function(done) {
550+
it('passes', function(done) {
551551
var data = Lib.extendDeep([], mockData);
552552

553553
var gd = createGraphDiv();

0 commit comments

Comments
 (0)