Improved weight function.
++++ Full match from start to end +++ Full match between word boundaries ++ Begin matches at word boundary, multiple matches are better + Matches somewhere Classes with (multiple) members matching at the beginning are weighted higher.
This commit is contained in:
@@ -2,19 +2,7 @@ $(function () {
|
|||||||
|
|
||||||
// Allow user configuration?
|
// Allow user configuration?
|
||||||
const allowRegex = true;
|
const allowRegex = true;
|
||||||
|
const minInputForFullText = 1;
|
||||||
const reNotCache = {};
|
|
||||||
function escapeRegexp(s, not) {
|
|
||||||
if (not) {
|
|
||||||
let re = reNotCache[not];
|
|
||||||
if (!re) {
|
|
||||||
const characters = '-\/\\^$*+?.()|[\]{}'.replace(new RegExp('[' + escapeRegexp(not) + ']', 'g'), '');
|
|
||||||
re = reNotCache[not] = new RegExp('[' + escapeRegexp(characters) + ']', 'g');
|
|
||||||
}
|
|
||||||
return s.replace(re, '\\$&');
|
|
||||||
}
|
|
||||||
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructRegex(searchTerm, makeRe, allowRegex) {
|
function constructRegex(searchTerm, makeRe, allowRegex) {
|
||||||
try {
|
try {
|
||||||
@@ -23,17 +11,47 @@ $(function () {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
return makeRe(escapeRegexp(searchTerm, '.'));
|
// In case of invalid regexp fall back to non-regexp, but still allow . to match /
|
||||||
|
return makeRe(searchTerm.replace(/\./g, '/').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
||||||
}
|
}
|
||||||
|
|
||||||
var getSearchWeight = function (searchTerm, $matchedItem) {
|
function getWeightFunction(searchTerm, allowRegex) {
|
||||||
let weight = 0;
|
function makeRe(searchTerm) {
|
||||||
|
return {
|
||||||
|
begin: new RegExp('(?:[.~]|\\b)' + searchTerm, 'g'), // Also match . and ~ to demote double matches, in weight function
|
||||||
|
name: new RegExp('\\b' + searchTerm + '(?:[~.]|$)'), // Match until module end or name end
|
||||||
|
fullName: new RegExp('^' + searchTerm + '$')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const re = constructRegex(searchTerm, makeRe, allowRegex);
|
||||||
|
return function (matchedItem, beginOnly) {
|
||||||
// We could get smarter on the weight here
|
// We could get smarter on the weight here
|
||||||
if ($matchedItem.data('name') === searchTerm) {
|
let weight = 0;
|
||||||
weight++;
|
const name = matchedItem.data('name');
|
||||||
|
const match = name.match(re.begin);
|
||||||
|
if (match) {
|
||||||
|
// `ol/geom/Geometry` matches twice when searching 'geom', is weighted higher.
|
||||||
|
// but don't boost something like `ol/source/Vector~VectorSource` when searching for 'Vect'.
|
||||||
|
let matches = match.length;
|
||||||
|
if (matches > 1 && /[.~]/.test(match[matches - 1])) {
|
||||||
|
matches -= 1;
|
||||||
|
}
|
||||||
|
weight += matches * 10000;
|
||||||
|
if (!beginOnly) {
|
||||||
|
// Full match of the last part of the path is weighted even higher
|
||||||
|
// Complete match is weighted highest.
|
||||||
|
if (re.fullName.test(name)) {
|
||||||
|
weight += 10000000;
|
||||||
|
} else if (re.name.test(name)) {
|
||||||
|
weight += 1000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If everything else is equal, prefer shorter names.
|
||||||
|
weight -= name.length;
|
||||||
}
|
}
|
||||||
return weight;
|
return weight;
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// sort function callback
|
// sort function callback
|
||||||
var weightSorter = function (a, b) {
|
var weightSorter = function (a, b) {
|
||||||
@@ -63,6 +81,8 @@ $(function () {
|
|||||||
|
|
||||||
if (searchTerm.length > 1) {
|
if (searchTerm.length > 1) {
|
||||||
searchTerm = searchTerm.toLowerCase();
|
searchTerm = searchTerm.toLowerCase();
|
||||||
|
const getSearchWeight = getWeightFunction(searchTerm, allowRegex);
|
||||||
|
const beginOnly = searchTerm.length < minInputForFullText;
|
||||||
const regexp = constructRegex(searchTerm, function (searchTerm) {
|
const regexp = constructRegex(searchTerm, function (searchTerm) {
|
||||||
return new RegExp(searchTerm);
|
return new RegExp(searchTerm);
|
||||||
}, allowRegex);
|
}, allowRegex);
|
||||||
@@ -77,7 +97,7 @@ $(function () {
|
|||||||
const $members = $item.closest('.member-list');
|
const $members = $item.closest('.member-list');
|
||||||
|
|
||||||
// Do the weight thing
|
// Do the weight thing
|
||||||
const weight = getSearchWeight(searchTerm, $classEntry);
|
const weight = getSearchWeight($classEntry, beginOnly);
|
||||||
$classEntry.data('weight', weight);
|
$classEntry.data('weight', weight);
|
||||||
|
|
||||||
$item.show();
|
$item.show();
|
||||||
|
|||||||
Reference in New Issue
Block a user