You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
1.6 KiB
JavaScript
81 lines
1.6 KiB
JavaScript
'use strict';
|
|
|
|
const dedupe = require("dedupe");
|
|
const queryParser = require("./query");
|
|
const flatten = require("./flatten-query");
|
|
const tagQueries = require("./tag-queries");
|
|
|
|
function ensureArray(item) {
|
|
if (Array.isArray(item)) {
|
|
return item;
|
|
} else if (item == null) {
|
|
return [];
|
|
} else {
|
|
return [item];
|
|
}
|
|
}
|
|
|
|
function recurseTags(tag) {
|
|
let allTags = [tag];
|
|
|
|
Object.keys(tag.tags).forEach((tagType) => {
|
|
ensureArray(tag.tags[tagType]).forEach((subTag) => {
|
|
allTags = allTags.concat(recurseTags(subTag));
|
|
});
|
|
});
|
|
|
|
return allTags;
|
|
}
|
|
|
|
function createQuery(query) {
|
|
let {riotQuery, domQuery} = queryParser.parse(query);
|
|
let flattenedQueries = flatten(riotQuery);
|
|
tagQueries(flattenedQueries);
|
|
|
|
return function traverse(tag) {
|
|
let results = [];
|
|
|
|
flattenedQueries.forEach((subQuery) => {
|
|
let lastFound = [tag];
|
|
|
|
subQuery.forEach((segment) => {
|
|
let nextLastFound = [];
|
|
|
|
lastFound.forEach((subTag) => {
|
|
//console.log("subtag", subQuery, segment, subTag);
|
|
let found;
|
|
|
|
if (segment.type === "identifier") {
|
|
found = ensureArray(subTag.tags[segment.value]);
|
|
} else if (segment.type === "wildcard") {
|
|
found = recurseTags(subTag);
|
|
}
|
|
|
|
if (found.length > 0) {
|
|
nextLastFound = nextLastFound.concat(found)
|
|
}
|
|
});
|
|
|
|
lastFound = nextLastFound;
|
|
});
|
|
|
|
results = results.concat(lastFound);
|
|
});
|
|
|
|
return dedupe(results, result => result._riot_id);
|
|
}
|
|
}
|
|
|
|
let queryCache = {};
|
|
|
|
module.exports = function(tag, query) {
|
|
if (queryCache[query] == null) {
|
|
queryCache[query] = createQuery(query);
|
|
}
|
|
|
|
// TODO: DOM traversal
|
|
|
|
return queryCache[query](tag);
|
|
}
|
|
|