From 0065c74397b5988e920c7af3575fd3c78d95666a Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Thu, 18 May 2017 06:44:35 -0400 Subject: [PATCH 1/2] Allow the skip api method for sliders and udpatemenus --- src/components/sliders/attributes.js | 2 +- src/components/sliders/defaults.js | 5 +++-- src/components/updatemenus/attributes.js | 2 +- src/components/updatemenus/defaults.js | 5 +++-- src/plots/command.js | 2 ++ test/jasmine/tests/command_test.js | 20 ++++++++++++++++++ test/jasmine/tests/sliders_test.js | 26 ++++++++++++++++++++++++ test/jasmine/tests/updatemenus_test.js | 25 +++++++++++++++++++++++ 8 files changed, 81 insertions(+), 6 deletions(-) diff --git a/src/components/sliders/attributes.js b/src/components/sliders/attributes.js index 8e584a2455f..36df48a86c4 100644 --- a/src/components/sliders/attributes.js +++ b/src/components/sliders/attributes.js @@ -20,7 +20,7 @@ var stepsAttrs = { method: { valType: 'enumerated', - values: ['restyle', 'relayout', 'animate', 'update'], + values: ['restyle', 'relayout', 'animate', 'update', 'skip'], dflt: 'restyle', role: 'info', description: [ diff --git a/src/components/sliders/defaults.js b/src/components/sliders/defaults.js index b2fed316c7b..0647b533245 100644 --- a/src/components/sliders/defaults.js +++ b/src/components/sliders/defaults.js @@ -95,11 +95,12 @@ function stepsDefaults(sliderIn, sliderOut) { valueIn = valuesIn[i]; valueOut = {}; - if(!Lib.isPlainObject(valueIn) || !Array.isArray(valueIn.args)) { + coerce('method'); + + if(!Lib.isPlainObject(valueIn) || (valueOut.method !== 'skip' && !Array.isArray(valueIn.args))) { continue; } - coerce('method'); coerce('args'); coerce('label', 'step-' + i); coerce('value', valueOut.label); diff --git a/src/components/updatemenus/attributes.js b/src/components/updatemenus/attributes.js index 9dd9f9b155d..479a2d37f6d 100644 --- a/src/components/updatemenus/attributes.js +++ b/src/components/updatemenus/attributes.js @@ -18,7 +18,7 @@ var buttonsAttrs = { method: { valType: 'enumerated', - values: ['restyle', 'relayout', 'animate', 'update'], + values: ['restyle', 'relayout', 'animate', 'update', 'skip'], dflt: 'restyle', role: 'info', description: [ diff --git a/src/components/updatemenus/defaults.js b/src/components/updatemenus/defaults.js index 2d4eeae7faa..310fd77882f 100644 --- a/src/components/updatemenus/defaults.js +++ b/src/components/updatemenus/defaults.js @@ -76,11 +76,12 @@ function buttonsDefaults(menuIn, menuOut) { buttonIn = buttonsIn[i]; buttonOut = {}; - if(!Lib.isPlainObject(buttonIn) || !Array.isArray(buttonIn.args)) { + coerce('method'); + + if(!Lib.isPlainObject(buttonIn) || (buttonOut.method !== 'skip' && !Array.isArray(buttonIn.args))) { continue; } - coerce('method'); coerce('args'); coerce('label'); diff --git a/src/plots/command.js b/src/plots/command.js index 830af6db804..8799ee07fad 100644 --- a/src/plots/command.js +++ b/src/plots/command.js @@ -262,6 +262,8 @@ function bindingValueHasChanged(gd, binding, cache) { * A list of arguments passed to the API command */ exports.executeAPICommand = function(gd, method, args) { + if(method === 'skip') return Promise.resolve(); + var apiMethod = Plotly[method]; var allArgs = [gd]; diff --git a/test/jasmine/tests/command_test.js b/test/jasmine/tests/command_test.js index 6d334dbb51c..e3bef641bcf 100644 --- a/test/jasmine/tests/command_test.js +++ b/test/jasmine/tests/command_test.js @@ -58,6 +58,13 @@ describe('Plots.executeAPICommand', function() { }); }); + + describe('with the skip command', function() { + it('resolves immediately', function(done) { + Plots.executeAPICommand(gd, 'skip') + .catch(fail).then(done); + }); + }); }); describe('Plots.hasSimpleAPICommandBindings', function() { @@ -93,6 +100,14 @@ describe('Plots.hasSimpleAPICommandBindings', function() { }); }); + it('the skip method returns false', function() { + var isSimple = Plots.hasSimpleAPICommandBindings(gd, [{ + method: 'skip', + }]); + + expect(isSimple).toEqual(false); + }); + it('return false when properties are not the same', function() { var isSimple = Plots.hasSimpleAPICommandBindings(gd, [{ method: 'restyle', @@ -187,6 +202,11 @@ describe('Plots.computeAPICommandBindings', function() { destroyGraphDiv(gd); }); + it('the skip method returns no bindings', function() { + var result = Plots.computeAPICommandBindings(gd, 'skip', ['marker.size', 7]); + expect(result).toEqual([]); + }); + describe('restyle', function() { describe('with invalid notation', function() { it('with a scalar value', function() { diff --git a/test/jasmine/tests/sliders_test.js b/test/jasmine/tests/sliders_test.js index 377c82d70aa..398c18d8314 100644 --- a/test/jasmine/tests/sliders_test.js +++ b/test/jasmine/tests/sliders_test.js @@ -158,6 +158,32 @@ describe('sliders defaults', function() { }); }); + it('allow the `skip` method', function() { + layoutIn.sliders = [{ + steps: [{ + method: 'skip', + }, { + method: 'skip', + args: ['title', 'Hello World'] + }] + }]; + + supply(layoutIn, layoutOut); + + expect(layoutOut.sliders[0].steps.length).toEqual(2); + expect(layoutOut.sliders[0].steps[0]).toEqual({ + method: 'skip', + label: 'step-0', + value: 'step-0', + }, { + method: 'skip', + args: ['title', 'Hello World'], + label: 'step-1', + value: 'step-1', + }); + }); + + it('should keep ref to input update menu container', function() { layoutIn.sliders = [{ steps: [{ diff --git a/test/jasmine/tests/updatemenus_test.js b/test/jasmine/tests/updatemenus_test.js index 852f456d12f..b51e9eb7520 100644 --- a/test/jasmine/tests/updatemenus_test.js +++ b/test/jasmine/tests/updatemenus_test.js @@ -140,6 +140,31 @@ describe('update menus defaults', function() { }); }); + it('allow the `skip` method', function() { + layoutIn.updatemenus = [{ + buttons: [{ + method: 'skip', + }, { + method: 'skip', + args: ['title', 'Hello World'] + }] + }]; + + supply(layoutIn, layoutOut); + + expect(layoutOut.updatemenus[0].buttons.length).toEqual(2); + expect(layoutOut.updatemenus[0].buttons[0]).toEqual({ + method: 'skip', + label: '', + _index: 0 + }, { + method: 'skip', + args: ['title', 'Hello World'], + label: '', + _index: 1 + }); + }); + it('should keep ref to input update menu container', function() { layoutIn.updatemenus = [{ buttons: [{ From bdf96b832a3f1f33579e53997608d27e9fd6cd29 Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Thu, 18 May 2017 07:29:12 -0400 Subject: [PATCH 2/2] Add updatemenus test for buttonclicked + skip --- test/jasmine/tests/updatemenus_test.js | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/jasmine/tests/updatemenus_test.js b/test/jasmine/tests/updatemenus_test.js index b51e9eb7520..09b411f1bab 100644 --- a/test/jasmine/tests/updatemenus_test.js +++ b/test/jasmine/tests/updatemenus_test.js @@ -469,6 +469,33 @@ describe('update menus interactions', function() { }).catch(fail).then(done); }); + it('should still emit the event if method = skip', function(done) { + var clickCnt = 0; + var data = []; + gd.on('plotly_buttonclicked', function(datum) { + data.push(datum); + clickCnt++; + }); + + Plotly.relayout(gd, { + 'updatemenus[0].buttons[0].method': 'skip', + 'updatemenus[0].buttons[1].method': 'skip', + 'updatemenus[0].buttons[2].method': 'skip', + 'updatemenus[1].buttons[0].method': 'skip', + 'updatemenus[1].buttons[1].method': 'skip', + 'updatemenus[1].buttons[2].method': 'skip', + 'updatemenus[1].buttons[3].method': 'skip', + }).then(function() { + click(selectHeader(0)).then(function() { + expect(clickCnt).toEqual(0); + + return click(selectButton(2)); + }).then(function() { + expect(clickCnt).toEqual(1); + }).catch(fail).then(done); + }); + }); + it('should apply update on button click', function(done) { var header0 = selectHeader(0), header1 = selectHeader(1);