molstar
Version:
A comprehensive macromolecular library.
374 lines • 16 kB
JavaScript
/**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { __spreadArray } from "tslib";
import { StateTree } from '../tree';
import { StateTransform } from '../transform';
var StateSelection;
(function (StateSelection) {
function select(s, state) {
return compile(s)(state);
}
StateSelection.select = select;
function compile(s) {
var selector = s ? s : Generators.root;
var query;
if (isBuilder(selector))
query = selector.compile();
else if (isObj(selector))
query = Generators.byValue(selector).compile();
else if (isQuery(selector))
query = selector;
else
query = Generators.byRef(selector).compile();
return query;
}
StateSelection.compile = compile;
function isObj(arg) {
return arg.transform !== void 0 && arg.status !== void 0;
}
function isBuilder(arg) {
return arg.compile !== void 0;
}
function isQuery(arg) {
return typeof arg === 'function';
}
var BuilderPrototype = {
select: function (state) {
return select(this, state || this.state);
}
};
function registerModifier(name, f) {
BuilderPrototype[name] = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return f.call.apply(f, __spreadArray([void 0, this], args, false));
};
}
function build(compile) {
return Object.create(BuilderPrototype, { compile: { writable: false, configurable: false, value: compile } });
}
var Generators;
(function (Generators) {
Generators.root = build(function () { return function (state) { return [state.cells.get(state.tree.root.ref)]; }; });
function byRef() {
var refs = [];
for (var _i = 0; _i < arguments.length; _i++) {
refs[_i] = arguments[_i];
}
return build(function () { return function (state) {
var ret = [];
for (var _i = 0, refs_1 = refs; _i < refs_1.length; _i++) {
var ref = refs_1[_i];
var n = state.cells.get(ref);
if (!n)
continue;
ret.push(n);
}
return ret;
}; });
}
Generators.byRef = byRef;
function byValue() {
var objects = [];
for (var _i = 0; _i < arguments.length; _i++) {
objects[_i] = arguments[_i];
}
return build(function () { return function (state) { return objects; }; });
}
Generators.byValue = byValue;
function rootsOfType(type, root) {
if (root === void 0) { root = StateTransform.RootRef; }
return build(function () { return function (state) {
var ctx = { roots: [], cells: state.cells, type: type.type };
StateTree.doPreOrder(state.tree, state.tree.transforms.get(root), ctx, _findRootsOfType);
return ctx.roots;
}; });
}
Generators.rootsOfType = rootsOfType;
function ofType(type, root) {
if (root === void 0) { root = StateTransform.RootRef; }
return build(function () { return function (state) {
var ctx = { ret: [], cells: state.cells, type: type.type };
StateTree.doPreOrder(state.tree, state.tree.transforms.get(root), ctx, _findOfType);
return ctx.ret;
}; });
}
Generators.ofType = ofType;
function ofTransformer(t, root) {
if (root === void 0) { root = StateTransform.RootRef; }
return build(function () { return function (state) {
var ctx = { ret: [], cells: state.cells, t: t };
StateTree.doPreOrder(state.tree, state.tree.transforms.get(root), ctx, _findOfTransformer);
return ctx.ret;
}; });
}
Generators.ofTransformer = ofTransformer;
function ofTransformerWithError(t, root) {
if (root === void 0) { root = StateTransform.RootRef; }
return build(function () { return function (state) {
var ctx = { ret: [], cells: state.cells, t: t };
StateTree.doPreOrder(state.tree, state.tree.transforms.get(root), ctx, _findOfTransformerWithError);
return ctx.ret;
}; });
}
Generators.ofTransformerWithError = ofTransformerWithError;
function _findRootsOfType(n, _, s) {
var cell = s.cells.get(n.ref);
if (cell && cell.obj && cell.obj.type === s.type) {
s.roots.push(cell);
return false;
}
return true;
}
function _findOfType(n, _, s) {
var cell = s.cells.get(n.ref);
if (cell && cell.obj && cell.obj.type === s.type) {
s.ret.push(cell);
}
return true;
}
function _findOfTransformer(n, _, s) {
var cell = s.cells.get(n.ref);
if (cell && cell.obj && cell.transform.transformer === s.t) {
s.ret.push(cell);
}
return true;
}
function _findOfTransformerWithError(n, _, s) {
var cell = s.cells.get(n.ref);
if (cell && cell.status === 'error' && cell.transform.transformer === s.t) {
s.ret.push(cell);
}
return true;
}
})(Generators = StateSelection.Generators || (StateSelection.Generators = {}));
registerModifier('flatMap', flatMap);
function flatMap(b, f) {
var q = compile(b);
return build(function () { return function (state) {
var ret = [];
for (var _i = 0, _a = q(state); _i < _a.length; _i++) {
var n = _a[_i];
for (var _b = 0, _c = f(n, state); _b < _c.length; _b++) {
var m = _c[_b];
ret.push(m);
}
}
return ret;
}; });
}
StateSelection.flatMap = flatMap;
registerModifier('mapObject', mapObject);
function mapObject(b, f) {
var q = compile(b);
return build(function () { return function (state) {
var ret = [];
for (var _i = 0, _a = q(state); _i < _a.length; _i++) {
var n = _a[_i];
var x = f(n, state);
if (x)
ret.push(x);
}
return ret;
}; });
}
StateSelection.mapObject = mapObject;
registerModifier('unique', unique);
function unique(b) {
var q = compile(b);
return build(function () { return function (state) {
var set = new Set();
var ret = [];
for (var _i = 0, _a = q(state); _i < _a.length; _i++) {
var n = _a[_i];
if (!n)
continue;
if (!set.has(n.transform.ref)) {
set.add(n.transform.ref);
ret.push(n);
}
}
return ret;
}; });
}
StateSelection.unique = unique;
registerModifier('first', first);
function first(b) {
var q = compile(b);
return build(function () { return function (state) {
var r = q(state);
return r.length ? [r[0]] : [];
}; });
}
StateSelection.first = first;
registerModifier('filter', filter);
function filter(b, p) { return flatMap(b, function (n) { return p(n) ? [n] : []; }); }
StateSelection.filter = filter;
registerModifier('withStatus', withStatus);
function withStatus(b, s) { return filter(b, function (n) { return n.status === s; }); }
StateSelection.withStatus = withStatus;
registerModifier('withTag', withTag);
function withTag(b, tag) { return filter(b, function (n) { return !!n.transform.tags && n.transform.tags.indexOf(tag) >= 0; }); }
StateSelection.withTag = withTag;
registerModifier('subtree', subtree);
function subtree(b) {
return flatMap(b, function (n, s) {
var nodes = [];
StateTree.doPreOrder(s.tree, s.tree.transforms.get(n.transform.ref), nodes, function (x, _, ctx) { ctx.push(x.ref); });
return nodes.map(function (x) { return s.cells.get(x); });
});
}
StateSelection.subtree = subtree;
registerModifier('children', children);
function children(b) {
return flatMap(b, function (n, s) {
var nodes = [];
s.tree.children.get(n.transform.ref).forEach(function (c) { return nodes.push(s.cells.get(c)); });
return nodes;
});
}
StateSelection.children = children;
registerModifier('ofType', ofType);
function ofType(b, t) { return filter(b, function (n) { return n.obj ? n.obj.type === t.type : false; }); }
StateSelection.ofType = ofType;
registerModifier('ancestor', ancestor);
function ancestor(b, test) { return unique(mapObject(b, function (n, s) { return findAncestor(s.tree, s.cells, n.transform.ref, test); })); }
StateSelection.ancestor = ancestor;
registerModifier('ancestorOfType', ancestorOfType);
function ancestorOfType(b, types) { return unique(mapObject(b, function (n, s) { return findAncestorOfType(s.tree, s.cells, n.transform.ref, types); })); }
StateSelection.ancestorOfType = ancestorOfType;
registerModifier('ancestorWithTransformer', ancestorWithTransformer);
function ancestorWithTransformer(b, transfomers) { return unique(mapObject(b, function (n, s) { return findAncestorWithTransformer(s.tree, s.cells, n.transform.ref, transfomers); })); }
StateSelection.ancestorWithTransformer = ancestorWithTransformer;
registerModifier('withTransformer', withTransformer);
function withTransformer(b, t) { return filter(b, function (o) { return o.transform.transformer === t; }); }
StateSelection.withTransformer = withTransformer;
registerModifier('root', root);
function root(b, test) { return unique(mapObject(b, function (n, s) { return findRoot(s.tree, s.cells, n.transform.ref, test); })); }
StateSelection.root = root;
registerModifier('rootOfType', rootOfType);
function rootOfType(b, types) { return unique(mapObject(b, function (n, s) { return findRootOfType(s.tree, s.cells, n.transform.ref, types); })); }
StateSelection.rootOfType = rootOfType;
registerModifier('parent', parent);
function parent(b) { return unique(mapObject(b, function (n, s) { return s.cells.get(s.tree.transforms.get(n.transform.ref).parent); })); }
StateSelection.parent = parent;
function _findAncestor(tree, cells, root, test, findClosest) {
var current = tree.transforms.get(root);
var ret = void 0;
while (true) {
current = tree.transforms.get(current.parent);
var cell = cells.get(current.ref);
if (cell.obj && test(cell)) {
ret = cell;
if (findClosest)
return ret;
}
if (current.ref === StateTransform.RootRef) {
return ret;
}
}
}
// Return first ancestor that satisfies the given test
function findAncestor(tree, cells, root, test) {
return _findAncestor(tree, cells, root, test, true);
}
StateSelection.findAncestor = findAncestor;
// Return last (with lowest depth) ancestor that satisfies the given test
function findRoot(tree, cells, root, test) {
return _findAncestor(tree, cells, root, test, false);
}
StateSelection.findRoot = findRoot;
function findAncestorWithTransformer(tree, cells, root, transfomers) {
return findAncestor(tree, cells, root, Array.isArray(transfomers)
? function (cell) { return transfomers.indexOf(cell.transform.transformer) >= 0; }
: function (cell) { return cell.transform.transformer === transfomers; });
}
StateSelection.findAncestorWithTransformer = findAncestorWithTransformer;
function findAncestorOfType(tree, cells, root, types) {
return findAncestor(tree, cells, root, _testTypes(types));
}
StateSelection.findAncestorOfType = findAncestorOfType;
function findRootOfType(tree, cells, root, types) {
return findRoot(tree, cells, root, _testTypes(types));
}
StateSelection.findRootOfType = findRootOfType;
function _testTypes(types) {
return Array.isArray(types)
? function (cell) {
for (var _i = 0, types_1 = types; _i < types_1.length; _i++) {
var t = types_1[_i];
if (t.type === cell.obj.type)
return true;
}
} : function (cell) { return cell.obj.type === types.type; };
}
function findUniqueTagsInSubtree(tree, root, tags) {
return StateTree.doPreOrder(tree, tree.transforms.get(root), { refs: {}, tags: tags }, _findUniqueTagsInSubtree).refs;
}
StateSelection.findUniqueTagsInSubtree = findUniqueTagsInSubtree;
function _findUniqueTagsInSubtree(n, _, s) {
if (n.tags) {
for (var _i = 0, _a = n.tags; _i < _a.length; _i++) {
var t = _a[_i];
if (!s.tags.has(t))
continue;
s.refs[t] = n.ref;
break;
}
}
return true;
}
function findTagInSubtree(tree, root, tag) {
return StateTree.doPreOrder(tree, tree.transforms.get(root), { ref: void 0, tag: tag }, _findTagInSubtree).ref;
}
StateSelection.findTagInSubtree = findTagInSubtree;
function _findTagInSubtree(n, _, s) {
if (n.tags && n.tags.indexOf(s.tag) >= 0) {
s.ref = n.ref;
return false;
}
return true;
}
function findWithAllTags(tree, root, tags) {
return StateTree.doPreOrder(tree, tree.transforms.get(root), { refs: [], tags: tags }, _findWithAllTags).refs;
}
StateSelection.findWithAllTags = findWithAllTags;
function _findWithAllTags(n, _, s) {
if (n.tags) {
var len = s.tags.size;
var found = 0;
for (var _i = 0, _a = n.tags; _i < _a.length; _i++) {
var t = _a[_i];
if (!s.tags.has(t))
continue;
found++;
if (found === len) {
s.refs.push(n);
break;
}
}
}
else if (s.tags.size === 0) {
s.refs.push(n);
}
}
function tryFindDecorator(state, root, transformer) {
var t = state.transforms.get(root);
if (t.transformer === transformer)
return state.cells.get(root);
var children = state.tree.children.get(root);
if (children.size !== 1)
return;
var first = children.first();
if (state.transforms.get(first).transformer.definition.isDecorator)
return tryFindDecorator(state, first, transformer);
}
StateSelection.tryFindDecorator = tryFindDecorator;
})(StateSelection || (StateSelection = {}));
export { StateSelection };
//# sourceMappingURL=selection.js.map