Adding documentation to match.js

This commit is contained in:
Jeff Avallone 2015-04-21 20:23:55 -04:00
parent ce41796f8b
commit 1b03663473

View File

@ -1,3 +1,8 @@
// Match nodes are used for the parts of a regular expression between `|`
// symbols. They consist of a series of [MatchFragment](./match_fragment.html)
// nodes. Optional `^` and `$` symbols are also allowed at the beginning and
// end of the Match.
import util from '../../util.js'; import util from '../../util.js';
import _ from 'lodash'; import _ from 'lodash';
@ -5,6 +10,8 @@ export default {
type: 'match', type: 'match',
definedProperties: { definedProperties: {
// Default anchor is overridden to attach the left point of the anchor to
// the first element, and the right point to the last element.
_anchor: { _anchor: {
get: function() { get: function() {
var start = util.normalizeBBox(this.start.getBBox()), var start = util.normalizeBBox(this.start.getBBox()),
@ -20,11 +27,14 @@ export default {
} }
}, },
// Renders the match into the currently set container.
_render() { _render() {
var start, end, var start, end,
partPromises, partPromises,
items; items;
// A `^` at the beginning of the match leads to the "Start of line"
// indicator being rendered.
if (this.anchorStart) { if (this.anchorStart) {
start = this.renderLabel('Start of line') start = this.renderLabel('Start of line')
.then(label => { .then(label => {
@ -32,6 +42,8 @@ export default {
}); });
} }
// A `$` at the end of the match leads to the "End of line" indicator
// being rendered.
if (this.anchorEnd) { if (this.anchorEnd) {
end = this.renderLabel('End of line') end = this.renderLabel('End of line')
.then(label => { .then(label => {
@ -39,18 +51,24 @@ export default {
}); });
} }
// Render each of the match fragments.
partPromises = _.map(this.parts, part => { partPromises = _.map(this.parts, part => {
return part.render(this.container.group()); return part.render(this.container.group());
}); });
items = _([start, partPromises, end]).flatten().compact().value(); items = _([start, partPromises, end]).flatten().compact().value();
// Handle the situation where a regular expression of `()` is rendered.
// This leads to a Match node with no fragments, no start indicator, and
// no end indicator. Something must be rendered so that the anchor can be
// calculated based on it.
if (items.length === 0) { if (items.length === 0) {
items = [this.container.group()]; items = [this.container.group()];
} }
return Promise.all(items) return Promise.all(items)
.then(items => { .then(items => {
// Find SVG elements to be used when calculating the anchor.
this.start = _.first(items); this.start = _.first(items);
this.end = _.last(items); this.end = _.last(items);
@ -58,11 +76,14 @@ export default {
padding: 10 padding: 10
}); });
// Add lines between each item.
this.container.prepend( this.container.prepend(
this.container.path(this.connectorPaths(items).join(''))); this.container.path(this.connectorPaths(items).join('')));
}); });
}, },
// Returns an array of SVG path strings between each item.
// - __items__ - Array of SVG elements or nodes.
connectorPaths(items) { connectorPaths(items) {
var prev, next; var prev, next;
@ -79,21 +100,29 @@ export default {
}, },
setup() { setup() {
// Merged list of MatchFragments to be rendered.
this.parts = _.reduce(this.properties.parts.elements, function(result, node) { this.parts = _.reduce(this.properties.parts.elements, function(result, node) {
var last = _.last(result); var last = _.last(result);
if (last && node.canMerge && last.canMerge) { if (last && node.canMerge && last.canMerge) {
// Merged the content of `node` into `last` when possible. This also
// discards `node` in the process since `result` has not been changed.
last.content.merge(node.content); last.content.merge(node.content);
} else { } else {
// `node` cannot be merged with the previous node, so it is added to
// the list of parts.
result.push(node); result.push(node);
} }
return result; return result;
}, []); }, []);
// Indicates if the expression starts with a `^`.
this.anchorStart = (this.properties.anchor_start.textValue !== ''); this.anchorStart = (this.properties.anchor_start.textValue !== '');
// Indicates if the expression ends with a `$`.
this.anchorEnd = (this.properties.anchor_end.textValue !== ''); this.anchorEnd = (this.properties.anchor_end.textValue !== '');
// When there are no anchors and only one part, then proxy to the part.
if (!this.anchorStart && !this.anchorEnd && this.parts.length === 1) { if (!this.anchorStart && !this.anchorEnd && this.parts.length === 1) {
this.proxy = this.parts[0]; this.proxy = this.parts[0];
} }