diff --git a/src/editor/view/EditorView.js b/src/editor/view/EditorView.js index 9b23c353ce..1076198ddf 100644 --- a/src/editor/view/EditorView.js +++ b/src/editor/view/EditorView.js @@ -9,6 +9,7 @@ module.exports = Backbone.View.extend({ this.pn = model.get('Panels'); model.on('loaded', () => { this.pn.active(); + this.pn.disableButtons(); model.runDefault(); setTimeout(() => model.trigger('load'), 0); }); diff --git a/src/panels/index.js b/src/panels/index.js index 2fed77a457..74400356b7 100644 --- a/src/panels/index.js +++ b/src/panels/index.js @@ -200,6 +200,19 @@ module.exports = () => { }); }); }, + + /** + * Disable buttons flagged as disabled + * @private + */ + disableButtons() { + this.getPanels().each(p => { + p.get('buttons').each(btn => { + if(btn.get('disable')) + btn.trigger('change:disable'); + }); + }); + }, Panel, diff --git a/src/panels/model/Button.js b/src/panels/model/Button.js index e66951678a..559fcd55d6 100644 --- a/src/panels/model/Button.js +++ b/src/panels/model/Button.js @@ -14,6 +14,7 @@ module.exports = Backbone.Model.extend({ dragDrop: false, runDefaultCommand: true, stopDefaultCommand: false, + disable: false, }, initialize(options) { diff --git a/src/panels/model/Buttons.js b/src/panels/model/Buttons.js index cf09589f15..74901156ba 100644 --- a/src/panels/model/Buttons.js +++ b/src/panels/model/Buttons.js @@ -38,5 +38,39 @@ module.exports = Backbone.Collection.extend({ } }); }, + + /** + * Disables all buttons + * @param {String} ctx Context string + * + * @return void + * */ + disableAllButtons(ctx) { + var context = ctx || ''; + this.forEach((model, index) => { + if( model.get('context') == context ){ + model.set('disable', true); + if(model.get('buttons').length) + model.get('buttons').disableAllButtons(context); + } + }); + }, + + /** + * Disables all buttons, except one passed + * @param {Object} except Model to ignore + * @param {Boolean} r Recursive flag + * + * @return void + * */ + disableAllButtonsExceptOne(except, r) { + this.forEach((model, index) => { + if(model !== except){ + model.set('disable', true); + if(r && model.get('buttons').length) + model.get('buttons').disableAllButtonsExceptOne(except,r); + } + }); + }, }); diff --git a/src/panels/view/ButtonView.js b/src/panels/view/ButtonView.js index f61f4f390a..abfc322d2a 100644 --- a/src/panels/view/ButtonView.js +++ b/src/panels/view/ButtonView.js @@ -13,6 +13,7 @@ module.exports = Backbone.View.extend({ this.ppfx = this.config.pStylePrefix || ''; this.id = this.pfx + this.model.get('id'); this.activeCls = this.pfx + 'active'; + this.disableCls = this.pfx + 'active'; this.btnsVisCls = this.pfx + 'visible'; this.parentM = o.parentM || null; this.className = this.pfx + 'btn' + (cls ? ' ' + cls : ''); @@ -21,6 +22,7 @@ module.exports = Backbone.View.extend({ this.listenTo(this.model, 'change:bntsVis', this.updateBtnsVis); this.listenTo(this.model, 'change:attributes', this.updateAttributes); this.listenTo(this.model, 'change:className', this.updateClassName); + this.listenTo(this.model, 'change:disable', this.updateDisable); if(this.model.get('buttons').length){ this.$el.on('mousedown', this.startTimer); @@ -234,6 +236,15 @@ module.exports = Backbone.View.extend({ } }, + updateDisable() { + if(this.model.get('disable')) { + this.$el.addClass(this.disableCls); + } else { + this.$el.removeClass(this.disableCls); + } + + }, + /** * Update active style status * @@ -255,9 +266,18 @@ module.exports = Backbone.View.extend({ clicked(e) { if(this.model.get('bntsVis') ) return; + + if(this.model.get('disable') ) + return; + + this.toogleActive(); + }, + + toogleActive() { if(this.parentM) this.swapParent(); + var active = this.model.get('active'); this.model.set('active', !active); diff --git a/test/specs/panels/index.js b/test/specs/panels/index.js index 5a6c79bd1d..96d24eaf6b 100644 --- a/test/specs/panels/index.js +++ b/test/specs/panels/index.js @@ -93,6 +93,15 @@ describe('Panels', () => { expect(spy.called).toEqual(true); }); + it("Disable correctly buttons flagged as disabled", () => { + var spy = sinon.spy(); + var panel = obj.addPanel({id: 'test'}); + var btn = obj.addButton('test', {id:'btn', disable: true}); + btn.on('change:disable', spy); + obj.disableButtons(); + expect(spy.called).toEqual(true); + }); + }); Models.run(); diff --git a/test/specs/panels/model/PanelModels.js b/test/specs/panels/model/PanelModels.js index c4f4f3099b..5bf63722c6 100644 --- a/test/specs/panels/model/PanelModels.js +++ b/test/specs/panels/model/PanelModels.js @@ -33,6 +33,10 @@ module.exports = { expect(obj.get('buttons').length).toEqual(1); }); + it('Has a disable attribute with default value as false', () => { + expect(obj.get('disable')).toEqual(false); + }); + }); describe('Buttons', () => { @@ -69,6 +73,24 @@ module.exports = { obj.deactivateAllExceptOne(btn); expect(obj.at(0).get('active')).toEqual(true); }); + + it('Disable all buttons', () => { + obj.add({ disable: false }); + obj.disableAllButtons(); + expect(obj.at(0).get('disable')).toEqual(true); + }); + + it('Disables buttons with context', () => { + obj.add({ disable: false, context: 'someContext' }); + obj.disableAllButtons('someContext'); + expect(obj.at(0).get('disable')).toEqual(true); + }); + + it('Disables except one', () => { + var btn = obj.add({ disable: false }); + obj.disableAllButtonsExceptOne(btn); + expect(obj.at(0).get('disable')).toEqual(false); + }); }); diff --git a/test/specs/panels/view/ButtonView.js b/test/specs/panels/view/ButtonView.js index f988181e5c..dbdb5020cf 100644 --- a/test/specs/panels/view/ButtonView.js +++ b/test/specs/panels/view/ButtonView.js @@ -14,7 +14,7 @@ module.exports = { beforeEach(() => { model = new Button(); view = new ButtonView({ - model + model: model }); document.body.innerHTML = '
'; fixtures = document.body.querySelector('#fixtures'); @@ -55,6 +55,35 @@ module.exports = { expect(view.el.getAttribute('class')).toEqual(btnClass); }); + it('Disable the button', () => { + model.set('disable', true, {silent: true}); + view.updateDisable(); + expect(view.el.getAttribute('class')).toEqual(btnClass + ' active'); + }); + + it('Enable the disabled button', () => { + model.set('disable', true, {silent: true}); + view.updateDisable(); + expect(view.el.getAttribute('class')).toEqual(btnClass + ' active'); + model.set('disable', false, {silent: true}); + view.updateDisable(); + expect(view.el.getAttribute('class')).toEqual(btnClass); + }); + + it('Cancels the click action when button is disabled', () => { + const stub = sinon.stub(view, 'toogleActive'); + model.set('disable', true, {silent: true}); + view.clicked(); + expect(stub.called).toEqual(false); + }); + + it('Enable the click action when button is enable', () => { + const stub = sinon.stub(view, 'toogleActive'); + model.set('disable', false, {silent: true}); + view.clicked(); + expect(stub.called).toEqual(true); + }); + it('Renders correctly', () => { expect(view.render()).toExist(); });