elliptical
Version:
Interactive natural-language interfaces
311 lines (247 loc) • 8.96 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _utils = require('../utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _marked = [visit, optionalTraversals, parseChildControl, parseChild].map(_regenerator2.default.mark);
function visit(option, _ref, traverse) {
var _ref$props$unique = _ref.props.unique;
var unique = _ref$props$unique === undefined ? false : _ref$props$unique;
var children = _ref.children;
var mods, trueOption, iterator;
return _regenerator2.default.wrap(function visit$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
mods = { result: {}, score: 1 };
trueOption = _lodash2.default.assign({}, option, mods);
if (!children.length) {
_context.next = 5;
break;
}
iterator = parseChildControl(0, trueOption, unique, children, traverse);
return _context.delegateYield(iterator, 't0', 5);
case 5:
case 'end':
return _context.stop();
}
}
}, _marked[0], this);
}
function shouldDoEllipsis(index, option, children) {
// Don't do ellipsis for the first element,
// or if this element is both optional and ellipsis, and the text is ''
// because that results in duplicate options output
var child = children[index];
return index > 0 && children[index - 1].props.ellipsis && !(child.props.ellipsis && child.props.optional && option.text === '');
}
function optionalTraversals(index, option, unique, children, traverse) {
var child, withChildParse, withoutChildParse;
return _regenerator2.default.wrap(function optionalTraversals$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
child = children[index];
withChildParse = parseChild(index, option, unique, children, traverse);
withoutChildParse = parseChildControl(index + 1, option, unique, children, traverse);
// yield * limitIterator(optionals, child.props.limited ? 1 : undefined)
if (!child.props.preferred) {
_context2.next = 10;
break;
}
_context2.next = 6;
return withChildParse;
case 6:
_context2.next = 8;
return withoutChildParse;
case 8:
_context2.next = 14;
break;
case 10:
_context2.next = 12;
return withoutChildParse;
case 12:
_context2.next = 14;
return withChildParse;
case 14:
case 'end':
return _context2.stop();
}
}
}, _marked[1], this);
}
function parseChildControl(index, option, unique, children, traverse) {
var child, success;
return _regenerator2.default.wrap(function parseChildControl$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
if (!(index >= children.length)) {
_context3.next = 4;
break;
}
_context3.next = 3;
return option;
case 3:
return _context3.abrupt('return');
case 4:
child = children[index];
if (!shouldDoEllipsis(index, option, children)) {
_context3.next = 16;
break;
}
if (!(option.text === '')) {
_context3.next = 11;
break;
}
_context3.next = 9;
return option;
case 9:
_context3.next = 16;
break;
case 11:
success = false;
_context3.next = 14;
return _lodash2.default.assign({}, option, {
callbacks: option.callbacks.concat(function () {
success = true;
})
});
case 14:
if (!success) {
_context3.next = 16;
break;
}
return _context3.abrupt('return');
case 16:
if (!child.props.optional) {
_context3.next = 20;
break;
}
return _context3.delegateYield((0, _utils.limitIterator)(optionalTraversals(index, option, unique, children, traverse), child.props.limited ? 1 : undefined), 't0', 18);
case 18:
_context3.next = 21;
break;
case 20:
return _context3.delegateYield(parseChild(index, option, unique, children, traverse), 't1', 21);
case 21:
case 'end':
return _context3.stop();
}
}
}, _marked[2], this);
}
function hasSomeSameKeys(option, output) {
var sameKeys = _lodash2.default.intersection(_lodash2.default.keys(option.result), _lodash2.default.keys(output.result));
return !_lodash2.default.isEmpty(sameKeys);
}
function parseChild(index, option, unique, children, traverse) {
var child, childOption, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, output, modifications, nextOutput;
return _regenerator2.default.wrap(function parseChild$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
child = children[index];
childOption = _lodash2.default.assign({}, option, {
qualifiers: [],
annotations: [],
categories: [],
arguments: []
});
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context4.prev = 5;
_iterator = traverse(child, childOption)[Symbol.iterator]();
case 7:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
_context4.next = 22;
break;
}
output = _step.value;
if (!(unique && output.result != null)) {
_context4.next = 16;
break;
}
if (!(child.props.id && option.result[child.props.id] != null)) {
_context4.next = 14;
break;
}
return _context4.abrupt('continue', 19);
case 14:
if (!(child.props.merge && hasSomeSameKeys(option, output))) {
_context4.next = 16;
break;
}
return _context4.abrupt('continue', 19);
case 16:
modifications = {
result: getAccumulatedResult(option.result, child, output.result),
score: option.score * output.score,
qualifiers: option.qualifiers.concat(output.qualifiers),
annotations: option.annotations.concat(output.annotations),
categories: option.categories.concat(output.categories),
arguments: option.arguments.concat(output.arguments)
};
nextOutput = _lodash2.default.assign({}, output, modifications);
return _context4.delegateYield(parseChildControl(index + 1, nextOutput, unique, children, traverse), 't0', 19);
case 19:
_iteratorNormalCompletion = true;
_context4.next = 7;
break;
case 22:
_context4.next = 28;
break;
case 24:
_context4.prev = 24;
_context4.t1 = _context4['catch'](5);
_didIteratorError = true;
_iteratorError = _context4.t1;
case 28:
_context4.prev = 28;
_context4.prev = 29;
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
case 31:
_context4.prev = 31;
if (!_didIteratorError) {
_context4.next = 34;
break;
}
throw _iteratorError;
case 34:
return _context4.finish(31);
case 35:
return _context4.finish(28);
case 36:
case 'end':
return _context4.stop();
}
}
}, _marked[3], this, [[5, 24, 28, 36], [29,, 31, 35]]);
}
function getAccumulatedResult(inputResult, child, childResult) {
if (!_lodash2.default.isUndefined(childResult)) {
var childId = child.props.id;
var childMerge = child.props.merge;
if (childId) {
return _lodash2.default.assign({}, inputResult, (0, _defineProperty3.default)({}, childId, childResult));
} else if (childMerge) {
if (!_lodash2.default.isEmpty(inputResult) && _lodash2.default.isPlainObject(childResult)) {
return _lodash2.default.merge({}, inputResult, childResult);
} else {
return childResult;
}
}
}
return inputResult;
}
exports.default = { visit: visit };