CanvasBlocker/lib/search.js

84 lines
2.0 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
(function(){
"use strict";
let scope;
if ((typeof exports) !== "undefined"){
scope = exports;
}
else {
scope = require.register("./search", {});
}
const extension = require("./extension");
const texts = [];
scope.register = function(text, content){
texts.push({text: text.toLowerCase(), content});
};
scope.search = function(search){
const resultSets = search.split(/\s+/).filter(function(term){
return term.trim();
}).map(function(term){
const matching = new Set();
if (term.match(/^:[a-z]+$/i)){
const tag = term.substring(1);
texts.forEach(function(text){
if (text.content.querySelector(`.${tag}`)){
matching.add(text.content);
}
});
}
else {
term = new RegExp(term.toLowerCase());
texts.forEach(function(text){
if (term.test(text.text)){
matching.add(text.content);
}
});
}
return matching;
});
if (resultSets.length){
return Array.from(
resultSets.reduce(function(previousSet, set){
const andSet = new Set();
set.forEach(function(entry){
if (previousSet.has(entry)){
andSet.add(entry);
}
});
return andSet;
})
);
}
else {
return [];
}
};
const searchListeners = [];
scope.init = function(){
const node = document.createElement("input");
node.id = "search";
node.placeholder = extension.getTranslation("search");
window.setTimeout(() => node.focus(), 1);
let lastResults = [];
node.addEventListener("input", function(){
this.search();
});
node.search = function(){
const search = this.value;
const results = search? scope.search(search): [];
searchListeners.forEach(function(callback){
callback({search, results, lastResults});
});
lastResults = results;
};
return node;
};
scope.on = function(callback){
searchListeners.push(callback);
};
}());