forked from rmm5t/jquery-flexselect
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathliquidmetal.js
88 lines (76 loc) · 2.42 KB
/
liquidmetal.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
* LiquidMetal, version: 0.1 (2009-02-05)
*
* A mimetic poly-alloy of Quicksilver's scoring algorithm, essentially
* LiquidMetal.
*
* For usage and examples, visit:
* http://github.com/rmm5t/liquidmetal
*
* Licensed under the MIT:
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright (c) 2009, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org)
*/
var LiquidMetal = function() {
var SCORE_NO_MATCH = 0.0;
var SCORE_MATCH = 1.0;
var SCORE_TRAILING = 0.8;
var SCORE_TRAILING_BUT_STARTED = 0.9;
var SCORE_BUFFER = 0.85;
return {
score: function(string, abbreviation) {
// Short circuits
if (abbreviation.length == 0) return SCORE_TRAILING;
if (abbreviation.length > string.length) return SCORE_NO_MATCH;
var scores = this.buildScoreArray(string, abbreviation);
var sum = 0.0;
for (var i in scores) {
sum += scores[i];
}
return (sum / scores.length);
},
buildScoreArray: function(string, abbreviation) {
var scores = new Array(string.length);
var lower = string.toLowerCase();
var chars = abbreviation.toLowerCase().split("");
var lastIndex = -1;
var started = false;
for (var i in chars) {
var c = chars[i];
var index = lower.indexOf(c, lastIndex+1);
if (index < 0) return fillArray(scores, SCORE_NO_MATCH);
if (index == 0) started = true;
if (isNewWord(string, index)) {
scores[index-1] = 1;
fillArray(scores, SCORE_BUFFER, lastIndex+1, index-1);
}
else if (isUpperCase(string, index)) {
fillArray(scores, SCORE_BUFFER, lastIndex+1, index);
}
else {
fillArray(scores, SCORE_NO_MATCH, lastIndex+1, index);
}
scores[index] = SCORE_MATCH;
lastIndex = index;
}
var trailingScore = started ? SCORE_TRAILING_BUT_STARTED : SCORE_TRAILING;
fillArray(scores, trailingScore, lastIndex+1);
return scores;
}
};
function isUpperCase(string, index) {
var c = string.charAt(index);
return ("A" <= c && c <= "Z");
}
function isNewWord(string, index) {
var c = string.charAt(index-1);
return (c == " " || c == "\t");
}
function fillArray(array, value, from, to) {
from = Math.max(from || 0, 0);
to = Math.min(to || array.length, array.length);
for (var i = from; i < to; i++) { array[i] = value; }
return array;
}
}();