From 773fd5c1a60468096792f540f53f0207686ecec8 Mon Sep 17 00:00:00 2001 From: Jeff Avallone Date: Sat, 13 Dec 2014 09:09:58 -0500 Subject: [PATCH] Refactoring how _position is called to be promise-based The render method now returns a promise. Once this promise is resolved, the _position method for that node will be called (if applicable). This promise must be resolved only after all subordinate nodes have completed their render phase (the promise returned by subordinate node's render method has resolved). Node that do not have subordinates can return the result of calling terminalRender, and proxied renders only need to return the result of calling proxy. With this change, it is no longer necessary to explicitly position subordinate nodes. They will already be positioned once their render promise is resolved. --- src/js/parser/javascript/any_character.js | 1 + src/js/parser/javascript/base.js | 35 +++++++++++++--------- src/js/parser/javascript/charset.js | 9 +++--- src/js/parser/javascript/charset_range.js | 12 ++++---- src/js/parser/javascript/escape.js | 2 ++ src/js/parser/javascript/literal.js | 2 ++ src/js/parser/javascript/match.js | 14 ++++----- src/js/parser/javascript/match_fragment.js | 5 ++-- src/js/parser/javascript/regexp.js | 11 ++++--- src/js/parser/javascript/root.js | 10 +++---- src/js/parser/javascript/subexp.js | 6 ++-- src/js/regexper.js | 30 ++++++------------- 12 files changed, 64 insertions(+), 73 deletions(-) diff --git a/src/js/parser/javascript/any_character.js b/src/js/parser/javascript/any_character.js index 88eca9e..4bfe969 100644 --- a/src/js/parser/javascript/any_character.js +++ b/src/js/parser/javascript/any_character.js @@ -6,5 +6,6 @@ export default _.extend({}, Base, { _render() { this.renderLabel('any character'); + return this.terminalRender(); } }); diff --git a/src/js/parser/javascript/base.js b/src/js/parser/javascript/base.js index d26feda..cb7f887 100644 --- a/src/js/parser/javascript/base.js +++ b/src/js/parser/javascript/base.js @@ -1,4 +1,5 @@ import _ from 'lodash'; +import Q from 'q'; export default { setContainer(container) { @@ -50,37 +51,43 @@ export default { } this._labelGroups = []; - this._render(); - }, + return this._render().then((function() { + if (!this._proxy) { + _.each(this._labelGroups, this.positionLabel.bind(this)); + this._position(); + } - position() { - if (this._proxy) { - this._proxy.position(); - } else { - _.each(this._labelGroups, this.positionLabel.bind(this)); - this._position(); - } + return this; + }).bind(this)); }, proxy(node) { this._proxy = node; - this._proxy.render(this.container); + return this._proxy.render(this.container); + }, + + terminalRender() { + var deferred = Q.defer(); + + setTimeout(() => { deferred.resolve() }); + return deferred.promise; }, _render() { - console.log(this); + console.log(this.type, this); this.container.addClass('placeholder'); - this.renderLabel(this.textValue) + this.renderLabel(this.type + ': ' + this.textValue) .select('rect').attr({ rx: 10, ry: 10 }); + + return this.terminalRender(); }, - _position() { - }, + _position() {}, spaceHorizontally(items, options) { var verticalCenter = 0; diff --git a/src/js/parser/javascript/charset.js b/src/js/parser/javascript/charset.js index 6e15f61..cc8b802 100644 --- a/src/js/parser/javascript/charset.js +++ b/src/js/parser/javascript/charset.js @@ -1,4 +1,5 @@ import _ from 'lodash'; +import Q from 'q'; import Base from './base.js'; export default _.extend({}, Base, { @@ -9,14 +10,12 @@ export default _.extend({}, Base, { this.partContainer = this.container.group(); - _.each(this.parts.elements, (part => { - part.render(this.partContainer.group()); - }).bind(this)); + return Q.all(_.map(this.parts.elements, (part => { + return part.render(this.partContainer.group()); + }).bind(this))); }, _position() { - _.invoke(this.parts.elements, 'position'); - this.spaceVertically(this.parts.elements, { padding: 5 }); diff --git a/src/js/parser/javascript/charset_range.js b/src/js/parser/javascript/charset_range.js index d943338..358b950 100644 --- a/src/js/parser/javascript/charset_range.js +++ b/src/js/parser/javascript/charset_range.js @@ -1,23 +1,23 @@ import _ from 'lodash'; +import Q from 'q'; import Base from './base.js'; export default _.extend({}, Base, { type: 'charset-range', _render() { - this.first.render(this.container.group()); - this.last.render(this.container.group()); - this.hyphen = this.container.text() .attr({ text: '-' }); + + return Q.all([ + this.first.render(this.container.group()), + this.last.render(this.container.group()) + ]); }, _position() { - this.first.position(); - this.last.position(); - this.spaceHorizontally([this.first, this.hyphen, this.last], { padding: 5 }); diff --git a/src/js/parser/javascript/escape.js b/src/js/parser/javascript/escape.js index f086754..069c3f8 100644 --- a/src/js/parser/javascript/escape.js +++ b/src/js/parser/javascript/escape.js @@ -18,6 +18,8 @@ export default _.extend({}, Base, { rx: 3, ry: 3 }); + + return this.terminalRender(); }, // Escape code mappings diff --git a/src/js/parser/javascript/literal.js b/src/js/parser/javascript/literal.js index 7f41b17..e663a00 100644 --- a/src/js/parser/javascript/literal.js +++ b/src/js/parser/javascript/literal.js @@ -10,5 +10,7 @@ export default _.extend({}, Base, { rx: 3, ry: 3 }); + + return this.terminalRender(); } }); diff --git a/src/js/parser/javascript/match.js b/src/js/parser/javascript/match.js index f3f8925..64b91bd 100644 --- a/src/js/parser/javascript/match.js +++ b/src/js/parser/javascript/match.js @@ -1,4 +1,5 @@ import _ from 'lodash'; +import Q from 'q'; import Base from './base.js'; export default _.extend({}, Base, { @@ -18,20 +19,17 @@ export default _.extend({}, Base, { } if (this.contents.anchor_start || this.contents.anchor_end || this.contents.parts.length !== 1) { - _.each(this.contents.parts, (function(part) { - part.render(this.container.group()); - }).bind(this)); + return Q.all(_.map(this.contents.parts, (function(part) { + return part.render(this.container.group()); + }).bind(this))); } else { - this.proxy(this.contents.parts[0]); + return this.proxy(this.contents.parts[0]); } }, _position() { - var items; + var items = _(this.contents).at('anchor_start', 'parts', 'anchor_end').flatten().compact().value(); - _.invoke(this.contents.parts, 'position'); - - items = _(this.contents).at('anchor_start', 'parts', 'anchor_end').flatten().compact().value(); this.spaceHorizontally(items, { padding: 10 }); diff --git a/src/js/parser/javascript/match_fragment.js b/src/js/parser/javascript/match_fragment.js index a56e334..fc42862 100644 --- a/src/js/parser/javascript/match_fragment.js +++ b/src/js/parser/javascript/match_fragment.js @@ -6,16 +6,15 @@ export default _.extend({}, Base, { _render() { if (this._repeat.textValue === '') { - this.proxy(this._content); + return this.proxy(this._content); } else { - this._content.render(this.container.group()); + return this._content.render(this.container.group()); } }, _position() { var box, paths = []; - this._content.position(); this._content.transform(this._repeat.contentPosition()); box = this._content.getBBox(); diff --git a/src/js/parser/javascript/regexp.js b/src/js/parser/javascript/regexp.js index 4e22b81..9211899 100644 --- a/src/js/parser/javascript/regexp.js +++ b/src/js/parser/javascript/regexp.js @@ -1,4 +1,5 @@ import _ from 'lodash'; +import Q from 'q'; import Base from './base.js'; export default _.extend({}, Base, { @@ -8,14 +9,14 @@ export default _.extend({}, Base, { var matches = this.matches(); if (matches.length === 1) { - this.proxy(matches[0]); + return this.proxy(matches[0]); } else { this.matchContainer = this.container.group() .addClass('regexp-matches'); - _.each(matches, (match => { - match.render(this.matchContainer.group()); - }).bind(this)); + return Q.all(_.map(matches, (match => { + return match.render(this.matchContainer.group()); + }).bind(this))); } }, @@ -24,8 +25,6 @@ export default _.extend({}, Base, { containerBox, paths; - _.invoke(matches, 'position'); - this.spaceVertically(matches, { padding: 5 }); diff --git a/src/js/parser/javascript/root.js b/src/js/parser/javascript/root.js index 8beb210..d305d48 100644 --- a/src/js/parser/javascript/root.js +++ b/src/js/parser/javascript/root.js @@ -5,7 +5,7 @@ export default _.extend({}, Base, { type: 'root', _render() { - this.regexp.render(this.container.group()); + var promise = this.regexp.render(this.container.group()); this.regexp.transform(Snap.matrix() .translate(10, 0)); @@ -15,14 +15,12 @@ export default _.extend({}, Base, { this.end = this.container.circle() .addClass('pin') .attr({ r: 5 }); + + return promise; }, _position() { - var contentBox; - - this.regexp.position(); - - contentBox = this.regexp.getBBox(); + var contentBox = this.regexp.getBBox(); this.start.transform(Snap.matrix() .translate(0, contentBox.cy)); diff --git a/src/js/parser/javascript/subexp.js b/src/js/parser/javascript/subexp.js index 2d669f3..0dee3d7 100644 --- a/src/js/parser/javascript/subexp.js +++ b/src/js/parser/javascript/subexp.js @@ -18,15 +18,13 @@ export default _.extend({}, Base, { if (label) { this.renderLabeledBox(label); - this.regexp.render(this.container.group()); + return this.regexp.render(this.container.group()); } else { - this.proxy(this.regexp); + return this.proxy(this.regexp); } }, _position() { - this.regexp.position(); - this.positionLabeledBox(this.regexp, { padding: 10 }); diff --git a/src/js/regexper.js b/src/js/regexper.js index 513513f..9a9e80b 100644 --- a/src/js/regexper.js +++ b/src/js/regexper.js @@ -88,30 +88,18 @@ export default class Regexper { parser.resetGroupCounter(); return Q.fcall(parser.parse.bind(parser), expression) + .then(null, this.showError.bind(this)) + .invoke('render', snap.group()) .then((result) => { - result.render(snap.group()); - return result; - }, this.showError.bind(this)) - .then((result) => { - var deferred = Q.defer(); + var box; - setTimeout(() => { - var box; - - result.position(); - - box = result.getBBox(); - result.container.transform(Snap.matrix() - .translate(padding - box.x, padding - box.y)); - snap.attr({ - width: box.width + padding * 2, - height: box.height + padding * 2 - }); - - deferred.resolve(); + box = result.getBBox(); + result.container.transform(Snap.matrix() + .translate(padding - box.x, padding - box.y)); + snap.attr({ + width: box.width + padding * 2, + height: box.height + padding * 2 }); - - return deferred.promise; }); } }