UNPKG

6.61 kBJavaScriptView Raw
1"use strict";
2/*-----------------------------------------------------------------------------
3| Copyright (c) 2014-2017, PhosphorJS Contributors
4|
5| Distributed under the terms of the BSD 3-Clause License.
6|
7| The full license is in the file LICENSE, distributed with this software.
8|----------------------------------------------------------------------------*/
9Object.defineProperty(exports, "__esModule", { value: true });
10/**
11 * The namespace for string-specific algorithms.
12 */
13var StringExt;
14(function (StringExt) {
15 /**
16 * Find the indices of characters in a source text.
17 *
18 * @param source - The source text which should be searched.
19 *
20 * @param query - The characters to locate in the source text.
21 *
22 * @param start - The index to start the search.
23 *
24 * @returns The matched indices, or `null` if there is no match.
25 *
26 * #### Complexity
27 * Linear on `sourceText`.
28 *
29 * #### Notes
30 * In order for there to be a match, all of the characters in `query`
31 * **must** appear in `source` in the order given by `query`.
32 *
33 * Characters are matched using strict `===` equality.
34 */
35 function findIndices(source, query, start) {
36 if (start === void 0) { start = 0; }
37 var indices = new Array(query.length);
38 for (var i = 0, j = start, n = query.length; i < n; ++i, ++j) {
39 j = source.indexOf(query[i], j);
40 if (j === -1) {
41 return null;
42 }
43 indices[i] = j;
44 }
45 return indices;
46 }
47 StringExt.findIndices = findIndices;
48 /**
49 * A string matcher which uses a sum-of-squares algorithm.
50 *
51 * @param source - The source text which should be searched.
52 *
53 * @param query - The characters to locate in the source text.
54 *
55 * @param start - The index to start the search.
56 *
57 * @returns The match result, or `null` if there is no match.
58 * A lower `score` represents a stronger match.
59 *
60 * #### Complexity
61 * Linear on `sourceText`.
62 *
63 * #### Notes
64 * This scoring algorithm uses a sum-of-squares approach to determine
65 * the score. In order for there to be a match, all of the characters
66 * in `query` **must** appear in `source` in order. The index of each
67 * matching character is squared and added to the score. This means
68 * that early and consecutive character matches are preferred, while
69 * late matches are heavily penalized.
70 */
71 function matchSumOfSquares(source, query, start) {
72 if (start === void 0) { start = 0; }
73 var indices = findIndices(source, query, start);
74 if (!indices) {
75 return null;
76 }
77 var score = 0;
78 for (var i = 0, n = indices.length; i < n; ++i) {
79 var j = indices[i] - start;
80 score += j * j;
81 }
82 return { score: score, indices: indices };
83 }
84 StringExt.matchSumOfSquares = matchSumOfSquares;
85 /**
86 * A string matcher which uses a sum-of-deltas algorithm.
87 *
88 * @param source - The source text which should be searched.
89 *
90 * @param query - The characters to locate in the source text.
91 *
92 * @param start - The index to start the search.
93 *
94 * @returns The match result, or `null` if there is no match.
95 * A lower `score` represents a stronger match.
96 *
97 * #### Complexity
98 * Linear on `sourceText`.
99 *
100 * #### Notes
101 * This scoring algorithm uses a sum-of-deltas approach to determine
102 * the score. In order for there to be a match, all of the characters
103 * in `query` **must** appear in `source` in order. The delta between
104 * the indices are summed to create the score. This means that groups
105 * of matched characters are preferred, while fragmented matches are
106 * penalized.
107 */
108 function matchSumOfDeltas(source, query, start) {
109 if (start === void 0) { start = 0; }
110 var indices = findIndices(source, query, start);
111 if (!indices) {
112 return null;
113 }
114 var score = 0;
115 var last = start - 1;
116 for (var i = 0, n = indices.length; i < n; ++i) {
117 var j = indices[i];
118 score += j - last - 1;
119 last = j;
120 }
121 return { score: score, indices: indices };
122 }
123 StringExt.matchSumOfDeltas = matchSumOfDeltas;
124 /**
125 * Highlight the matched characters of a source text.
126 *
127 * @param source - The text which should be highlighted.
128 *
129 * @param indices - The indices of the matched characters. They must
130 * appear in increasing order and must be in bounds of the source.
131 *
132 * @param fn - The function to apply to the matched chunks.
133 *
134 * @returns An array of unmatched and highlighted chunks.
135 */
136 function highlight(source, indices, fn) {
137 // Set up the result array.
138 var result = [];
139 // Set up the counter variables.
140 var k = 0;
141 var last = 0;
142 var n = indices.length;
143 // Iterator over each index.
144 while (k < n) {
145 // Set up the chunk indices.
146 var i = indices[k];
147 var j = indices[k];
148 // Advance the right chunk index until it's non-contiguous.
149 while (++k < n && indices[k] === j + 1) {
150 j++;
151 }
152 // Extract the unmatched text.
153 if (last < i) {
154 result.push(source.slice(last, i));
155 }
156 // Extract and highlight the matched text.
157 if (i < j + 1) {
158 result.push(fn(source.slice(i, j + 1)));
159 }
160 // Update the last visited index.
161 last = j + 1;
162 }
163 // Extract any remaining unmatched text.
164 if (last < source.length) {
165 result.push(source.slice(last));
166 }
167 // Return the highlighted result.
168 return result;
169 }
170 StringExt.highlight = highlight;
171 /**
172 * A 3-way string comparison function.
173 *
174 * @param a - The first string of interest.
175 *
176 * @param b - The second string of interest.
177 *
178 * @returns `-1` if `a < b`, else `1` if `a > b`, else `0`.
179 */
180 function cmp(a, b) {
181 return a < b ? -1 : a > b ? 1 : 0;
182 }
183 StringExt.cmp = cmp;
184})(StringExt = exports.StringExt || (exports.StringExt = {}));