mirror of https://github.com/keeweb/keeweb.git
improved ranking search
This commit is contained in:
parent
7c5b76fda3
commit
a69cf5cd85
|
@ -174,7 +174,7 @@
|
|||
"searchOptions": "Options",
|
||||
"searchCase": "Match case",
|
||||
"searchRegex": "RegEx",
|
||||
"searchRank": "Rank",
|
||||
"searchRank": "Auto",
|
||||
|
||||
"openOpen": "Open",
|
||||
"openNew": "New",
|
||||
|
|
|
@ -63,6 +63,12 @@ kdbxweb.ProtectedValue.prototype.forEachChar = function(fn) {
|
|||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(kdbxweb.ProtectedValue.prototype, 'length', {
|
||||
get() {
|
||||
return this.textLength;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(kdbxweb.ProtectedValue.prototype, 'textLength', {
|
||||
get() {
|
||||
let textLength = 0;
|
||||
|
@ -74,12 +80,18 @@ Object.defineProperty(kdbxweb.ProtectedValue.prototype, 'textLength', {
|
|||
});
|
||||
|
||||
kdbxweb.ProtectedValue.prototype.includesLower = function(findLower) {
|
||||
let matches = false;
|
||||
return this.indexOfLower(findLower) !== -1;
|
||||
};
|
||||
|
||||
kdbxweb.ProtectedValue.prototype.indexOfLower = function(findLower) {
|
||||
let index = -1;
|
||||
const foundSeqs = [];
|
||||
const len = findLower.length;
|
||||
let chIndex = -1;
|
||||
this.forEachChar(ch => {
|
||||
chIndex++;
|
||||
ch = String.fromCharCode(ch).toLowerCase();
|
||||
if (matches) {
|
||||
if (index !== -1) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < foundSeqs.length; i++) {
|
||||
|
@ -90,17 +102,45 @@ kdbxweb.ProtectedValue.prototype.includesLower = function(findLower) {
|
|||
continue;
|
||||
}
|
||||
if (seqIx === len - 1) {
|
||||
matches = true;
|
||||
index = chIndex - len + 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (findLower[0] === ch) {
|
||||
foundSeqs.push(0);
|
||||
if (len === 1) {
|
||||
index = chIndex - len + 1;
|
||||
} else {
|
||||
foundSeqs.push(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
return matches;
|
||||
return index;
|
||||
};
|
||||
|
||||
kdbxweb.ProtectedValue.prototype.indexOfSelfInLower = function(targetLower) {
|
||||
let firstCharIndex = -1;
|
||||
let found = false;
|
||||
do {
|
||||
let chIndex = -1;
|
||||
this.forEachChar(ch => {
|
||||
chIndex++;
|
||||
ch = String.fromCharCode(ch).toLowerCase();
|
||||
if (chIndex === 0) {
|
||||
firstCharIndex = targetLower.indexOf(ch, firstCharIndex + 1);
|
||||
found = firstCharIndex !== -1;
|
||||
return;
|
||||
}
|
||||
if (!found) {
|
||||
return;
|
||||
}
|
||||
found = targetLower[firstCharIndex + chIndex] === ch;
|
||||
});
|
||||
} while (!found && firstCharIndex >= 0);
|
||||
return firstCharIndex;
|
||||
};
|
||||
|
||||
window.PV = kdbxweb.ProtectedValue;
|
||||
|
||||
kdbxweb.ProtectedValue.prototype.equals = function(other) {
|
||||
if (!other) {
|
||||
return false;
|
||||
|
|
|
@ -671,53 +671,39 @@ const EntryModel = Backbone.Model.extend({
|
|||
this._fillByEntry();
|
||||
},
|
||||
|
||||
getRank(searchString) {
|
||||
getRank(filter) {
|
||||
const searchString = filter.textLower;
|
||||
|
||||
if (!searchString) {
|
||||
// no search string given, so rank all items the same
|
||||
return 0;
|
||||
}
|
||||
|
||||
let rank = 0;
|
||||
const checkProtectedFields = filter.advanced && filter.advanced.protect;
|
||||
|
||||
const ranking = [
|
||||
{
|
||||
field: 'Title',
|
||||
multiplicator: 10
|
||||
},
|
||||
{
|
||||
field: 'URL',
|
||||
multiplicator: 8
|
||||
},
|
||||
{
|
||||
field: 'UserName',
|
||||
multiplicator: 5
|
||||
},
|
||||
{
|
||||
field: 'Notes',
|
||||
multiplicator: 2
|
||||
const fieldWeights = {
|
||||
'Title': 10,
|
||||
'URL': 8,
|
||||
'UserName': 5,
|
||||
'Notes': 2
|
||||
};
|
||||
|
||||
const defaultFieldWeight = 2;
|
||||
|
||||
const allFields = Object.keys(fieldWeights).concat(Object.keys(this.fields));
|
||||
|
||||
return allFields.reduce((rank, fieldName) => {
|
||||
const val = this.entry.fields[fieldName];
|
||||
if (!val) {
|
||||
return rank;
|
||||
}
|
||||
];
|
||||
|
||||
const fieldNames = Object.keys(this.fields);
|
||||
_.forEach(fieldNames, field => {
|
||||
ranking.push({
|
||||
field,
|
||||
multiplicator: 2
|
||||
});
|
||||
});
|
||||
|
||||
_.forEach(ranking, rankingEntry => {
|
||||
if (this._getFieldString(rankingEntry.field).toLowerCase() !== '') {
|
||||
const calculatedRank =
|
||||
Ranking.getStringRank(
|
||||
searchString,
|
||||
this._getFieldString(rankingEntry.field).toLowerCase()
|
||||
) * rankingEntry.multiplicator;
|
||||
rank += calculatedRank;
|
||||
if (val.isProtected && (!checkProtectedFields || !val.length)) {
|
||||
return rank;
|
||||
}
|
||||
});
|
||||
|
||||
return rank;
|
||||
const stringRank = Ranking.getStringRank(searchString, val);
|
||||
const fieldWeight = fieldWeights[fieldName] || defaultFieldWeight;
|
||||
return rank + stringRank * fieldWeight;
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ const Comparators = {
|
|||
|
||||
rankComparator() {
|
||||
return function(x, y) {
|
||||
return y.getRank(this.filter.textLower) - x.getRank(this.filter.textLower);
|
||||
return y.getRank(this.filter) - x.getRank(this.filter);
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
const Ranking = {
|
||||
getStringRank(s1, s2) {
|
||||
let ix = s1.indexOf(s2);
|
||||
if (!s1 || !s2) {
|
||||
return 0;
|
||||
}
|
||||
let ix = indexOf(s1, s2);
|
||||
if (ix === 0 && s1.length === s2.length) {
|
||||
return 10;
|
||||
} else if (ix === 0) {
|
||||
|
@ -8,7 +11,7 @@ const Ranking = {
|
|||
} else if (ix > 0) {
|
||||
return 3;
|
||||
}
|
||||
ix = s2.indexOf(s1);
|
||||
ix = indexOf(s2, s1);
|
||||
if (ix === 0) {
|
||||
return 5;
|
||||
} else if (ix > 0) {
|
||||
|
@ -18,4 +21,16 @@ const Ranking = {
|
|||
}
|
||||
};
|
||||
|
||||
function indexOf(target, search) {
|
||||
if (target.isProtected) {
|
||||
return target.indexOfLower(search);
|
||||
}
|
||||
if (search.isProtected) {
|
||||
return search.indexOfSelfInLower(target);
|
||||
}
|
||||
return target.indexOf(search);
|
||||
}
|
||||
|
||||
window.Ranking = Ranking;
|
||||
|
||||
module.exports = Ranking;
|
||||
|
|
|
@ -2,6 +2,7 @@ Release notes
|
|||
-------------
|
||||
##### v1.9.1 (TBD)
|
||||
`-` fix #1231: tooltip arrow positioning
|
||||
`+` improved ranking search
|
||||
|
||||
##### v1.9.0 (2019-08-18)
|
||||
`-` fix #1221: added '30 min' lock option
|
||||
|
|
Loading…
Reference in New Issue