From e890fe7d2c4f8602662b74b8b15567ef974dc586 Mon Sep 17 00:00:00 2001 From: Jeff Avallone Date: Mon, 29 Dec 2014 17:34:44 -0500 Subject: [PATCH] Updating progress using the promise notify feature --- spec/parser/javascript/node_spec.js | 51 +++++++++++++---------------- spec/regexper_spec.js | 23 ------------- src/js/parser/javascript/node.js | 29 +++++++++------- src/js/regexper.js | 23 ++++++------- 4 files changed, 51 insertions(+), 75 deletions(-) diff --git a/spec/parser/javascript/node_spec.js b/spec/parser/javascript/node_spec.js index ee62aee..50fd3c5 100644 --- a/spec/parser/javascript/node_spec.js +++ b/spec/parser/javascript/node_spec.js @@ -131,6 +131,18 @@ describe('parser/javascript/node.js', function() { .done(); }); + it('notifies of the progress when the render is not canceled', function(done) { + this.node.state.renderCounter = 116; + this.node.state.maxCounter = 200; + + this.node.deferredStep('result') + .then(null, null, progress => { + expect(Math.round(100 * progress)).toEqual(42); + }) + .finally(done) + .done(); + }); + it('rejects the returned promise when the render is canceled', function(done) { var resolve = jasmine.createSpy('resolve'), reject = jasmine.createSpy('reject'); @@ -231,45 +243,26 @@ describe('parser/javascript/node.js', function() { expect(this.node.state.renderCounter).toEqual(1); }); + it('sets the maxCounter', function() { + this.node.state.renderCounter = 42; + this.node.state.maxCounter = 0; + this.node.startRender(); + expect(this.node.state.maxCounter).toEqual(43); + this.node.state.maxCounter = 50; + this.node.startRender(); + expect(this.node.state.maxCounter).toEqual(50); + }); + }); describe('#doneRender', function() { - it('sets the maxCounter when the maxCounter is initially 0', function() { - this.node.state.renderCounter = 42; - this.node.state.maxCounter = 0; - this.node.doneRender(); - expect(this.node.state.maxCounter).toEqual(42); - this.node.state.renderCounter = 24; - this.node.doneRender(); - expect(this.node.state.maxCounter).toEqual(42); - }); - it('decrements the renderCounter', function() { this.node.state.renderCounter = 42; this.node.doneRender(); expect(this.node.state.renderCounter).toEqual(41); }); - it('triggers an updateStatus event', function() { - var evt; - - this.node.state.renderCounter = 117; - this.node.state.maxCounter = 200; - spyOn(document.body, 'dispatchEvent'); - this.node.doneRender(); - expect(document.body.dispatchEvent).toHaveBeenCalled(); - - evt = document.body.dispatchEvent.calls.mostRecent().args[0]; - expect(evt.type).toEqual('updateStatus'); - expect(evt.detail).toEqual({ percentage: 0.42 }); - }); - - it('returns a deferredStep', function() { - spyOn(this.node, 'deferredStep').and.returnValue('example deferred'); - expect(this.node.doneRender()).toEqual('example deferred'); - }); - }); describe('#render', function() { diff --git a/spec/regexper_spec.js b/spec/regexper_spec.js index fd5e403..f1b540e 100644 --- a/spec/regexper_spec.js +++ b/spec/regexper_spec.js @@ -190,25 +190,11 @@ describe('regexper.js', function() { }); - describe('#updatePercentage', function() { - - beforeEach(function() { - this.event = util.customEvent('updateStatus', { percentage: 0.42 }); - }); - - it('sets the width of the progress bar', function() { - this.regexper.updatePercentage(this.event); - expect(this.regexper.percentage.style.width).toEqual('42%'); - }); - - }); - describe('#bindListeners', function() { beforeEach(function() { spyOn(this.regexper, 'keypressListener'); spyOn(this.regexper, 'submitListener'); - spyOn(this.regexper, 'updatePercentage'); spyOn(this.regexper, 'documentKeypressListener'); spyOn(this.regexper, 'hashchangeListener'); }); @@ -231,15 +217,6 @@ describe('regexper.js', function() { expect(this.regexper.submitListener).toHaveBeenCalled(); }); - it('binds #updatePercentage to updateStatus on the root', function() { - spyOn(this.regexper.root, 'addEventListener'); - this.regexper.bindListeners(); - expect(this.regexper.root.addEventListener).toHaveBeenCalledWith('updateStatus', jasmine.any(Function)); - - this.regexper.root.addEventListener.calls.first().args[1](); - expect(this.regexper.updatePercentage).toHaveBeenCalled(); - }); - it('binds #documentKeypressListener to keyup on the root', function() { spyOn(this.regexper.root, 'addEventListener'); this.regexper.bindListeners(); diff --git a/src/js/parser/javascript/node.js b/src/js/parser/javascript/node.js index 28a2fa6..b88ffa6 100644 --- a/src/js/parser/javascript/node.js +++ b/src/js/parser/javascript/node.js @@ -66,6 +66,7 @@ export default class Node { if (this.state.cancelRender) { deferred.reject('Render cancelled'); } else { + deferred.notify(1 - this.state.renderCounter / this.state.maxCounter); deferred.resolve.apply(this, result); } }, 1); @@ -98,20 +99,12 @@ export default class Node { startRender() { this.state.renderCounter++; + + this.state.maxCounter = Math.max(this.state.maxCounter, this.state.renderCounter); } doneRender() { - if (this.state.maxCounter === 0) { - this.state.maxCounter = this.state.renderCounter; - } - this.state.renderCounter--; - - document.body.dispatchEvent(util.customEvent('updateStatus', { - percentage: (this.state.maxCounter - this.state.renderCounter) / this.state.maxCounter - })); - - return this.deferredStep(); } render(container) { @@ -124,8 +117,20 @@ export default class Node { } else { this.startRender(); return this._render() - .then(this.doneRender.bind(this)) - .then(_.constant(this)); + .then( + () => { + this.doneRender(); + return this; + }, + null, + progress => { + if (typeof progress.value !== 'undefined') { + return progress.value; + } else { + return progress; + } + } + ); } } diff --git a/src/js/regexper.js b/src/js/regexper.js index eb97296..737283d 100644 --- a/src/js/regexper.js +++ b/src/js/regexper.js @@ -56,14 +56,9 @@ export default class Regexper { this.showExpression(this._getHash()); } - updatePercentage(event) { - this.percentage.style.width = event.detail.percentage * 100 + '%'; - } - bindListeners() { this.field.addEventListener('keypress', this.keypressListener.bind(this)); this.form.addEventListener('submit', this.submitListener.bind(this)); - this.root.addEventListener('updateStatus', this.updatePercentage.bind(this)); this.root.addEventListener('keyup', this.documentKeypressListener.bind(this)); window.addEventListener('hashchange', this.hashchangeListener.bind(this)); } @@ -157,12 +152,18 @@ export default class Regexper { throw message; }) .invoke('render', this.svgContainer, this.svgBase) - .then(() => { - this.state = 'has-results'; - this.updateLinks(); - this.displayWarnings(this.runningParser.warnings); - this._trackEvent('visualization', 'complete'); - }) + .then( + () => { + this.state = 'has-results'; + this.updateLinks(); + this.displayWarnings(this.runningParser.warnings); + this._trackEvent('visualization', 'complete'); + }, + null, + percentage => { + this.percentage.style.width = percentage * 100 + '%'; + } + ) .then(null, message => { if (message === 'Render cancelled') { this._trackEvent('visualization', 'cancelled');