source: main/trunk/greenstone3/web/interfaces/default/js/List.js@ 38928

Last change on this file since 38928 was 38152, checked in by kjdon, 9 months ago

working on facets. added List.js - a simple list javascript file which adds sorting and searching functionality to any list. I'm using this on the facet lists. some updates to facets - need to update the matchdocs parts, and the next/prev buttons. Also all other facet lists, other than the ones which have been selected, need to be updated.

File size: 56.3 KB
Line 
1/**
2
3The MIT License (MIT)
4
5Copyright (c) 2011-2018 Jonny Strömberg, jonnystromberg.com
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in
15all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23THE SOFTWARE.
24
25list.js downloaded from https://listjs.com/, September 2023.
26version 2.3.1
27
28*/
29var List;List =
30/******/ (function() { // webpackBootstrap
31/******/ var __webpack_modules__ = ({
32
33/***/ "./src/add-async.js":
34/*!**************************!*\
35 !*** ./src/add-async.js ***!
36 \**************************/
37/*! unknown exports (runtime-defined) */
38/*! runtime requirements: module */
39/*! CommonJS bailout: module.exports is used directly at 1:0-14 */
40/***/ (function(module) {
41
42module.exports = function (list) {
43 var addAsync = function addAsync(values, callback, items) {
44 var valuesToAdd = values.splice(0, 50);
45 items = items || [];
46 items = items.concat(list.add(valuesToAdd));
47
48 if (values.length > 0) {
49 setTimeout(function () {
50 addAsync(values, callback, items);
51 }, 1);
52 } else {
53 list.update();
54 callback(items);
55 }
56 };
57
58 return addAsync;
59};
60
61/***/ }),
62
63/***/ "./src/filter.js":
64/*!***********************!*\
65 !*** ./src/filter.js ***!
66 \***********************/
67/*! unknown exports (runtime-defined) */
68/*! runtime requirements: module */
69/*! CommonJS bailout: module.exports is used directly at 1:0-14 */
70/***/ (function(module) {
71
72module.exports = function (list) {
73 // Add handlers
74 list.handlers.filterStart = list.handlers.filterStart || [];
75 list.handlers.filterComplete = list.handlers.filterComplete || [];
76 return function (filterFunction) {
77 list.trigger('filterStart');
78 list.i = 1; // Reset paging
79
80 list.reset.filter();
81
82 if (filterFunction === undefined) {
83 list.filtered = false;
84 } else {
85 list.filtered = true;
86 var is = list.items;
87
88 for (var i = 0, il = is.length; i < il; i++) {
89 var item = is[i];
90
91 if (filterFunction(item)) {
92 item.filtered = true;
93 } else {
94 item.filtered = false;
95 }
96 }
97 }
98
99 list.update();
100 list.trigger('filterComplete');
101 return list.visibleItems;
102 };
103};
104
105/***/ }),
106
107/***/ "./src/fuzzy-search.js":
108/*!*****************************!*\
109 !*** ./src/fuzzy-search.js ***!
110 \*****************************/
111/*! unknown exports (runtime-defined) */
112/*! runtime requirements: module, __webpack_require__ */
113/*! CommonJS bailout: module.exports is used directly at 8:0-14 */
114/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
115
116var classes = __webpack_require__(/*! ./utils/classes */ "./src/utils/classes.js"),
117 events = __webpack_require__(/*! ./utils/events */ "./src/utils/events.js"),
118 extend = __webpack_require__(/*! ./utils/extend */ "./src/utils/extend.js"),
119 toString = __webpack_require__(/*! ./utils/to-string */ "./src/utils/to-string.js"),
120 getByClass = __webpack_require__(/*! ./utils/get-by-class */ "./src/utils/get-by-class.js"),
121 fuzzy = __webpack_require__(/*! ./utils/fuzzy */ "./src/utils/fuzzy.js");
122
123module.exports = function (list, options) {
124 options = options || {};
125 options = extend({
126 location: 0,
127 distance: 100,
128 threshold: 0.4,
129 multiSearch: true,
130 searchClass: 'fuzzy-search'
131 }, options);
132 var fuzzySearch = {
133 search: function search(searchString, columns) {
134 // Substract arguments from the searchString or put searchString as only argument
135 var searchArguments = options.multiSearch ? searchString.replace(/ +$/, '').split(/ +/) : [searchString];
136
137 for (var k = 0, kl = list.items.length; k < kl; k++) {
138 fuzzySearch.item(list.items[k], columns, searchArguments);
139 }
140 },
141 item: function item(_item, columns, searchArguments) {
142 var found = true;
143
144 for (var i = 0; i < searchArguments.length; i++) {
145 var foundArgument = false;
146
147 for (var j = 0, jl = columns.length; j < jl; j++) {
148 if (fuzzySearch.values(_item.values(), columns[j], searchArguments[i])) {
149 foundArgument = true;
150 }
151 }
152
153 if (!foundArgument) {
154 found = false;
155 }
156 }
157
158 _item.found = found;
159 },
160 values: function values(_values, value, searchArgument) {
161 if (_values.hasOwnProperty(value)) {
162 var text = toString(_values[value]).toLowerCase();
163
164 if (fuzzy(text, searchArgument, options)) {
165 return true;
166 }
167 }
168
169 return false;
170 }
171 };
172 events.bind(getByClass(list.listContainer, options.searchClass), 'keyup', list.utils.events.debounce(function (e) {
173 var target = e.target || e.srcElement; // IE have srcElement
174
175 list.search(target.value, fuzzySearch.search);
176 }, list.searchDelay));
177 return function (str, columns) {
178 list.search(str, columns, fuzzySearch.search);
179 };
180};
181
182/***/ }),
183
184/***/ "./src/index.js":
185/*!**********************!*\
186 !*** ./src/index.js ***!
187 \**********************/
188/*! unknown exports (runtime-defined) */
189/*! runtime requirements: module, __webpack_require__ */
190/*! CommonJS bailout: module.exports is used directly at 11:0-14 */
191/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
192
193var naturalSort = __webpack_require__(/*! string-natural-compare */ "./node_modules/string-natural-compare/natural-compare.js"),
194 getByClass = __webpack_require__(/*! ./utils/get-by-class */ "./src/utils/get-by-class.js"),
195 extend = __webpack_require__(/*! ./utils/extend */ "./src/utils/extend.js"),
196 indexOf = __webpack_require__(/*! ./utils/index-of */ "./src/utils/index-of.js"),
197 events = __webpack_require__(/*! ./utils/events */ "./src/utils/events.js"),
198 toString = __webpack_require__(/*! ./utils/to-string */ "./src/utils/to-string.js"),
199 classes = __webpack_require__(/*! ./utils/classes */ "./src/utils/classes.js"),
200 getAttribute = __webpack_require__(/*! ./utils/get-attribute */ "./src/utils/get-attribute.js"),
201 toArray = __webpack_require__(/*! ./utils/to-array */ "./src/utils/to-array.js");
202
203module.exports = function (id, options, values) {
204 var self = this,
205 init,
206 Item = __webpack_require__(/*! ./item */ "./src/item.js")(self),
207 addAsync = __webpack_require__(/*! ./add-async */ "./src/add-async.js")(self),
208 initPagination = __webpack_require__(/*! ./pagination */ "./src/pagination.js")(self);
209
210 init = {
211 start: function start() {
212 self.listClass = 'list';
213 self.searchClass = 'search';
214 self.sortClass = 'sort';
215 self.page = 10000;
216 self.i = 1;
217 self.items = [];
218 self.visibleItems = [];
219 self.matchingItems = [];
220 self.searched = false;
221 self.filtered = false;
222 self.searchColumns = undefined;
223 self.searchDelay = 0;
224 self.handlers = {
225 updated: []
226 };
227 self.valueNames = [];
228 self.utils = {
229 getByClass: getByClass,
230 extend: extend,
231 indexOf: indexOf,
232 events: events,
233 toString: toString,
234 naturalSort: naturalSort,
235 classes: classes,
236 getAttribute: getAttribute,
237 toArray: toArray
238 };
239 self.utils.extend(self, options);
240 self.listContainer = typeof id === 'string' ? document.getElementById(id) : id;
241
242 if (!self.listContainer) {
243 return;
244 }
245
246 self.list = getByClass(self.listContainer, self.listClass, true);
247 self.parse = __webpack_require__(/*! ./parse */ "./src/parse.js")(self);
248 self.templater = __webpack_require__(/*! ./templater */ "./src/templater.js")(self);
249 self.search = __webpack_require__(/*! ./search */ "./src/search.js")(self);
250 self.filter = __webpack_require__(/*! ./filter */ "./src/filter.js")(self);
251 self.sort = __webpack_require__(/*! ./sort */ "./src/sort.js")(self);
252 self.fuzzySearch = __webpack_require__(/*! ./fuzzy-search */ "./src/fuzzy-search.js")(self, options.fuzzySearch);
253 this.handlers();
254 this.items();
255 this.pagination();
256 self.update();
257 },
258 handlers: function handlers() {
259 for (var handler in self.handlers) {
260 if (self[handler] && self.handlers.hasOwnProperty(handler)) {
261 self.on(handler, self[handler]);
262 }
263 }
264 },
265 items: function items() {
266 self.parse(self.list);
267
268 if (values !== undefined) {
269 self.add(values);
270 }
271 },
272 pagination: function pagination() {
273 if (options.pagination !== undefined) {
274 if (options.pagination === true) {
275 options.pagination = [{}];
276 }
277
278 if (options.pagination[0] === undefined) {
279 options.pagination = [options.pagination];
280 }
281
282 for (var i = 0, il = options.pagination.length; i < il; i++) {
283 initPagination(options.pagination[i]);
284 }
285 }
286 }
287 };
288 /*
289 * Re-parse the List, use if html have changed
290 */
291
292 this.reIndex = function () {
293 self.items = [];
294 self.visibleItems = [];
295 self.matchingItems = [];
296 self.searched = false;
297 self.filtered = false;
298 self.parse(self.list);
299 };
300
301 this.toJSON = function () {
302 var json = [];
303
304 for (var i = 0, il = self.items.length; i < il; i++) {
305 json.push(self.items[i].values());
306 }
307
308 return json;
309 };
310 /*
311 * Add object to list
312 */
313
314
315 this.add = function (values, callback) {
316 if (values.length === 0) {
317 return;
318 }
319
320 if (callback) {
321 addAsync(values.slice(0), callback);
322 return;
323 }
324
325 var added = [],
326 notCreate = false;
327
328 if (values[0] === undefined) {
329 values = [values];
330 }
331
332 for (var i = 0, il = values.length; i < il; i++) {
333 var item = null;
334 notCreate = self.items.length > self.page ? true : false;
335 item = new Item(values[i], undefined, notCreate);
336 self.items.push(item);
337 added.push(item);
338 }
339
340 self.update();
341 return added;
342 };
343
344 this.show = function (i, page) {
345 this.i = i;
346 this.page = page;
347 self.update();
348 return self;
349 };
350 /* Removes object from list.
351 * Loops through the list and removes objects where
352 * property "valuename" === value
353 */
354
355
356 this.remove = function (valueName, value, options) {
357 var found = 0;
358
359 for (var i = 0, il = self.items.length; i < il; i++) {
360 if (self.items[i].values()[valueName] == value) {
361 self.templater.remove(self.items[i], options);
362 self.items.splice(i, 1);
363 il--;
364 i--;
365 found++;
366 }
367 }
368
369 self.update();
370 return found;
371 };
372 /* Gets the objects in the list which
373 * property "valueName" === value
374 */
375
376
377 this.get = function (valueName, value) {
378 var matchedItems = [];
379
380 for (var i = 0, il = self.items.length; i < il; i++) {
381 var item = self.items[i];
382
383 if (item.values()[valueName] == value) {
384 matchedItems.push(item);
385 }
386 }
387
388 return matchedItems;
389 };
390 /*
391 * Get size of the list
392 */
393
394
395 this.size = function () {
396 return self.items.length;
397 };
398 /*
399 * Removes all items from the list
400 */
401
402
403 this.clear = function () {
404 self.templater.clear();
405 self.items = [];
406 return self;
407 };
408
409 this.on = function (event, callback) {
410 self.handlers[event].push(callback);
411 return self;
412 };
413
414 this.off = function (event, callback) {
415 var e = self.handlers[event];
416 var index = indexOf(e, callback);
417
418 if (index > -1) {
419 e.splice(index, 1);
420 }
421
422 return self;
423 };
424
425 this.trigger = function (event) {
426 var i = self.handlers[event].length;
427
428 while (i--) {
429 self.handlers[event][i](self);
430 }
431
432 return self;
433 };
434
435 this.reset = {
436 filter: function filter() {
437 var is = self.items,
438 il = is.length;
439
440 while (il--) {
441 is[il].filtered = false;
442 }
443
444 return self;
445 },
446 search: function search() {
447 var is = self.items,
448 il = is.length;
449
450 while (il--) {
451 is[il].found = false;
452 }
453
454 return self;
455 }
456 };
457
458 this.update = function () {
459 var is = self.items,
460 il = is.length;
461 self.visibleItems = [];
462 self.matchingItems = [];
463 self.templater.clear();
464
465 for (var i = 0; i < il; i++) {
466 if (is[i].matching() && self.matchingItems.length + 1 >= self.i && self.visibleItems.length < self.page) {
467 is[i].show();
468 self.visibleItems.push(is[i]);
469 self.matchingItems.push(is[i]);
470 } else if (is[i].matching()) {
471 self.matchingItems.push(is[i]);
472 is[i].hide();
473 } else {
474 is[i].hide();
475 }
476 }
477
478 self.trigger('updated');
479 return self;
480 };
481
482 init.start();
483};
484
485/***/ }),
486
487/***/ "./src/item.js":
488/*!*********************!*\
489 !*** ./src/item.js ***!
490 \*********************/
491/*! unknown exports (runtime-defined) */
492/*! runtime requirements: module */
493/*! CommonJS bailout: module.exports is used directly at 1:0-14 */
494/***/ (function(module) {
495
496module.exports = function (list) {
497 return function (initValues, element, notCreate) {
498 var item = this;
499 this._values = {};
500 this.found = false; // Show if list.searched == true and this.found == true
501
502 this.filtered = false; // Show if list.filtered == true and this.filtered == true
503
504 var init = function init(initValues, element, notCreate) {
505 if (element === undefined) {
506 if (notCreate) {
507 item.values(initValues, notCreate);
508 } else {
509 item.values(initValues);
510 }
511 } else {
512 item.elm = element;
513 var values = list.templater.get(item, initValues);
514 item.values(values);
515 }
516 };
517
518 this.values = function (newValues, notCreate) {
519 if (newValues !== undefined) {
520 for (var name in newValues) {
521 item._values[name] = newValues[name];
522 }
523
524 if (notCreate !== true) {
525 list.templater.set(item, item.values());
526 }
527 } else {
528 return item._values;
529 }
530 };
531
532 this.show = function () {
533 list.templater.show(item);
534 };
535
536 this.hide = function () {
537 list.templater.hide(item);
538 };
539
540 this.matching = function () {
541 return list.filtered && list.searched && item.found && item.filtered || list.filtered && !list.searched && item.filtered || !list.filtered && list.searched && item.found || !list.filtered && !list.searched;
542 };
543
544 this.visible = function () {
545 return item.elm && item.elm.parentNode == list.list ? true : false;
546 };
547
548 init(initValues, element, notCreate);
549 };
550};
551
552/***/ }),
553
554/***/ "./src/pagination.js":
555/*!***************************!*\
556 !*** ./src/pagination.js ***!
557 \***************************/
558/*! unknown exports (runtime-defined) */
559/*! runtime requirements: module, __webpack_require__ */
560/*! CommonJS bailout: module.exports is used directly at 5:0-14 */
561/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
562
563var classes = __webpack_require__(/*! ./utils/classes */ "./src/utils/classes.js"),
564 events = __webpack_require__(/*! ./utils/events */ "./src/utils/events.js"),
565 List = __webpack_require__(/*! ./index */ "./src/index.js");
566
567module.exports = function (list) {
568 var isHidden = false;
569
570 var refresh = function refresh(pagingList, options) {
571 if (list.page < 1) {
572 list.listContainer.style.display = 'none';
573 isHidden = true;
574 return;
575 } else if (isHidden) {
576 list.listContainer.style.display = 'block';
577 }
578
579 var item,
580 l = list.matchingItems.length,
581 index = list.i,
582 page = list.page,
583 pages = Math.ceil(l / page),
584 currentPage = Math.ceil(index / page),
585 innerWindow = options.innerWindow || 2,
586 left = options.left || options.outerWindow || 0,
587 right = options.right || options.outerWindow || 0;
588 right = pages - right;
589 pagingList.clear();
590
591 for (var i = 1; i <= pages; i++) {
592 var className = currentPage === i ? 'active' : ''; //console.log(i, left, right, currentPage, (currentPage - innerWindow), (currentPage + innerWindow), className);
593
594 if (is.number(i, left, right, currentPage, innerWindow)) {
595 item = pagingList.add({
596 page: i,
597 dotted: false
598 })[0];
599
600 if (className) {
601 classes(item.elm).add(className);
602 }
603
604 item.elm.firstChild.setAttribute('data-i', i);
605 item.elm.firstChild.setAttribute('data-page', page);
606 } else if (is.dotted(pagingList, i, left, right, currentPage, innerWindow, pagingList.size())) {
607 item = pagingList.add({
608 page: '...',
609 dotted: true
610 })[0];
611 classes(item.elm).add('disabled');
612 }
613 }
614 };
615
616 var is = {
617 number: function number(i, left, right, currentPage, innerWindow) {
618 return this.left(i, left) || this.right(i, right) || this.innerWindow(i, currentPage, innerWindow);
619 },
620 left: function left(i, _left) {
621 return i <= _left;
622 },
623 right: function right(i, _right) {
624 return i > _right;
625 },
626 innerWindow: function innerWindow(i, currentPage, _innerWindow) {
627 return i >= currentPage - _innerWindow && i <= currentPage + _innerWindow;
628 },
629 dotted: function dotted(pagingList, i, left, right, currentPage, innerWindow, currentPageItem) {
630 return this.dottedLeft(pagingList, i, left, right, currentPage, innerWindow) || this.dottedRight(pagingList, i, left, right, currentPage, innerWindow, currentPageItem);
631 },
632 dottedLeft: function dottedLeft(pagingList, i, left, right, currentPage, innerWindow) {
633 return i == left + 1 && !this.innerWindow(i, currentPage, innerWindow) && !this.right(i, right);
634 },
635 dottedRight: function dottedRight(pagingList, i, left, right, currentPage, innerWindow, currentPageItem) {
636 if (pagingList.items[currentPageItem - 1].values().dotted) {
637 return false;
638 } else {
639 return i == right && !this.innerWindow(i, currentPage, innerWindow) && !this.right(i, right);
640 }
641 }
642 };
643 return function (options) {
644 var pagingList = new List(list.listContainer.id, {
645 listClass: options.paginationClass || 'pagination',
646 item: options.item || "<li><a class='page' href='#'></a></li>",
647 valueNames: ['page', 'dotted'],
648 searchClass: 'pagination-search-that-is-not-supposed-to-exist',
649 sortClass: 'pagination-sort-that-is-not-supposed-to-exist'
650 });
651 events.bind(pagingList.listContainer, 'click', function (e) {
652 var target = e.target || e.srcElement,
653 page = list.utils.getAttribute(target, 'data-page'),
654 i = list.utils.getAttribute(target, 'data-i');
655
656 if (i) {
657 list.show((i - 1) * page + 1, page);
658 }
659 });
660 list.on('updated', function () {
661 refresh(pagingList, options);
662 });
663 refresh(pagingList, options);
664 };
665};
666
667/***/ }),
668
669/***/ "./src/parse.js":
670/*!**********************!*\
671 !*** ./src/parse.js ***!
672 \**********************/
673/*! unknown exports (runtime-defined) */
674/*! runtime requirements: module, __webpack_require__ */
675/*! CommonJS bailout: module.exports is used directly at 1:0-14 */
676/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
677
678module.exports = function (list) {
679 var Item = __webpack_require__(/*! ./item */ "./src/item.js")(list);
680
681 var getChildren = function getChildren(parent) {
682 var nodes = parent.childNodes,
683 items = [];
684
685 for (var i = 0, il = nodes.length; i < il; i++) {
686 // Only textnodes have a data attribute
687 if (nodes[i].data === undefined) {
688 items.push(nodes[i]);
689 }
690 }
691
692 return items;
693 };
694
695 var parse = function parse(itemElements, valueNames) {
696 for (var i = 0, il = itemElements.length; i < il; i++) {
697 list.items.push(new Item(valueNames, itemElements[i]));
698 }
699 };
700
701 var parseAsync = function parseAsync(itemElements, valueNames) {
702 var itemsToIndex = itemElements.splice(0, 50); // TODO: If < 100 items, what happens in IE etc?
703
704 parse(itemsToIndex, valueNames);
705
706 if (itemElements.length > 0) {
707 setTimeout(function () {
708 parseAsync(itemElements, valueNames);
709 }, 1);
710 } else {
711 list.update();
712 list.trigger('parseComplete');
713 }
714 };
715
716 list.handlers.parseComplete = list.handlers.parseComplete || [];
717 return function () {
718 var itemsToIndex = getChildren(list.list),
719 valueNames = list.valueNames;
720
721 if (list.indexAsync) {
722 parseAsync(itemsToIndex, valueNames);
723 } else {
724 parse(itemsToIndex, valueNames);
725 }
726 };
727};
728
729/***/ }),
730
731/***/ "./src/search.js":
732/*!***********************!*\
733 !*** ./src/search.js ***!
734 \***********************/
735/*! unknown exports (runtime-defined) */
736/*! runtime requirements: module */
737/*! CommonJS bailout: module.exports is used directly at 1:0-14 */
738/***/ (function(module) {
739
740module.exports = function (_list) {
741 var item, text, columns, searchString, customSearch;
742 var prepare = {
743 resetList: function resetList() {
744 _list.i = 1;
745
746 _list.templater.clear();
747
748 customSearch = undefined;
749 },
750 setOptions: function setOptions(args) {
751 if (args.length == 2 && args[1] instanceof Array) {
752 columns = args[1];
753 } else if (args.length == 2 && typeof args[1] == 'function') {
754 columns = undefined;
755 customSearch = args[1];
756 } else if (args.length == 3) {
757 columns = args[1];
758 customSearch = args[2];
759 } else {
760 columns = undefined;
761 }
762 },
763 setColumns: function setColumns() {
764 if (_list.items.length === 0) return;
765
766 if (columns === undefined) {
767 columns = _list.searchColumns === undefined ? prepare.toArray(_list.items[0].values()) : _list.searchColumns;
768 }
769 },
770 setSearchString: function setSearchString(s) {
771 s = _list.utils.toString(s).toLowerCase();
772 s = s.replace(/[-[\]{}()*+?.,\\^$|#]/g, '\\$&'); // Escape regular expression characters
773
774 searchString = s;
775 },
776 toArray: function toArray(values) {
777 var tmpColumn = [];
778
779 for (var name in values) {
780 tmpColumn.push(name);
781 }
782
783 return tmpColumn;
784 }
785 };
786 var search = {
787 list: function list() {
788 // Extract quoted phrases "word1 word2" from original searchString
789 // searchString is converted to lowercase by List.js
790 var words = [],
791 phrase,
792 ss = searchString;
793
794 while ((phrase = ss.match(/"([^"]+)"/)) !== null) {
795 words.push(phrase[1]);
796 ss = ss.substring(0, phrase.index) + ss.substring(phrase.index + phrase[0].length);
797 } // Get remaining space-separated words (if any)
798
799
800 ss = ss.trim();
801 if (ss.length) words = words.concat(ss.split(/\s+/));
802
803 for (var k = 0, kl = _list.items.length; k < kl; k++) {
804 var item = _list.items[k];
805 item.found = false;
806 if (!words.length) continue;
807
808 for (var i = 0, il = words.length; i < il; i++) {
809 var word_found = false;
810
811 for (var j = 0, jl = columns.length; j < jl; j++) {
812 var values = item.values(),
813 column = columns[j];
814
815 if (values.hasOwnProperty(column) && values[column] !== undefined && values[column] !== null) {
816 var text = typeof values[column] !== 'string' ? values[column].toString() : values[column];
817
818 if (text.toLowerCase().indexOf(words[i]) !== -1) {
819 // word found, so no need to check it against any other columns
820 word_found = true;
821 break;
822 }
823 }
824 } // this word not found? no need to check any other words, the item cannot match
825
826
827 if (!word_found) break;
828 }
829
830 item.found = word_found;
831 }
832 },
833 // Removed search.item() and search.values()
834 reset: function reset() {
835 _list.reset.search();
836
837 _list.searched = false;
838 }
839 };
840
841 var searchMethod = function searchMethod(str) {
842 _list.trigger('searchStart');
843
844 prepare.resetList();
845 prepare.setSearchString(str);
846 prepare.setOptions(arguments); // str, cols|searchFunction, searchFunction
847
848 prepare.setColumns();
849
850 if (searchString === '') {
851 search.reset();
852 } else {
853 _list.searched = true;
854
855 if (customSearch) {
856 customSearch(searchString, columns);
857 } else {
858 search.list();
859 }
860 }
861
862 _list.update();
863
864 _list.trigger('searchComplete');
865
866 return _list.visibleItems;
867 };
868
869 _list.handlers.searchStart = _list.handlers.searchStart || [];
870 _list.handlers.searchComplete = _list.handlers.searchComplete || [];
871
872 _list.utils.events.bind(_list.utils.getByClass(_list.listContainer, _list.searchClass), 'keyup', _list.utils.events.debounce(function (e) {
873 var target = e.target || e.srcElement,
874 // IE have srcElement
875 alreadyCleared = target.value === '' && !_list.searched;
876
877 if (!alreadyCleared) {
878 // If oninput already have resetted the list, do nothing
879 searchMethod(target.value);
880 }
881 }, _list.searchDelay)); // Used to detect click on HTML5 clear button
882
883
884 _list.utils.events.bind(_list.utils.getByClass(_list.listContainer, _list.searchClass), 'input', function (e) {
885 var target = e.target || e.srcElement;
886
887 if (target.value === '') {
888 searchMethod('');
889 }
890 });
891
892 return searchMethod;
893};
894
895/***/ }),
896
897/***/ "./src/sort.js":
898/*!*********************!*\
899 !*** ./src/sort.js ***!
900 \*********************/
901/*! unknown exports (runtime-defined) */
902/*! runtime requirements: module */
903/*! CommonJS bailout: module.exports is used directly at 1:0-14 */
904/***/ (function(module) {
905
906module.exports = function (list) {
907 var buttons = {
908 els: undefined,
909 clear: function clear() {
910 for (var i = 0, il = buttons.els.length; i < il; i++) {
911 list.utils.classes(buttons.els[i]).remove('asc');
912 list.utils.classes(buttons.els[i]).remove('desc');
913 }
914 },
915 getOrder: function getOrder(btn) {
916 var predefinedOrder = list.utils.getAttribute(btn, 'data-order');
917
918 if (predefinedOrder == 'asc' || predefinedOrder == 'desc') {
919 return predefinedOrder;
920 } else if (list.utils.classes(btn).has('desc')) {
921 return 'asc';
922 } else if (list.utils.classes(btn).has('asc')) {
923 return 'desc';
924 } else {
925 return 'asc';
926 }
927 },
928 getInSensitive: function getInSensitive(btn, options) {
929 var insensitive = list.utils.getAttribute(btn, 'data-insensitive');
930
931 if (insensitive === 'false') {
932 options.insensitive = false;
933 } else {
934 options.insensitive = true;
935 }
936 },
937 setOrder: function setOrder(options) {
938 for (var i = 0, il = buttons.els.length; i < il; i++) {
939 var btn = buttons.els[i];
940
941 if (list.utils.getAttribute(btn, 'data-sort') !== options.valueName) {
942 continue;
943 }
944
945 var predefinedOrder = list.utils.getAttribute(btn, 'data-order');
946
947 if (predefinedOrder == 'asc' || predefinedOrder == 'desc') {
948 if (predefinedOrder == options.order) {
949 list.utils.classes(btn).add(options.order);
950 }
951 } else {
952 list.utils.classes(btn).add(options.order);
953 }
954 }
955 }
956 };
957
958 var sort = function sort() {
959 list.trigger('sortStart');
960 var options = {};
961 var target = arguments[0].currentTarget || arguments[0].srcElement || undefined;
962
963 if (target) {
964 options.valueName = list.utils.getAttribute(target, 'data-sort');
965 buttons.getInSensitive(target, options);
966 options.order = buttons.getOrder(target);
967 } else {
968 options = arguments[1] || options;
969 options.valueName = arguments[0];
970 options.order = options.order || 'asc';
971 options.insensitive = typeof options.insensitive == 'undefined' ? true : options.insensitive;
972 }
973
974 buttons.clear();
975 buttons.setOrder(options); // caseInsensitive
976 // alphabet
977
978 var customSortFunction = options.sortFunction || list.sortFunction || null,
979 multi = options.order === 'desc' ? -1 : 1,
980 sortFunction;
981
982 if (customSortFunction) {
983 sortFunction = function sortFunction(itemA, itemB) {
984 return customSortFunction(itemA, itemB, options) * multi;
985 };
986 } else {
987 sortFunction = function sortFunction(itemA, itemB) {
988 var sort = list.utils.naturalSort;
989 sort.alphabet = list.alphabet || options.alphabet || undefined;
990
991 if (!sort.alphabet && options.insensitive) {
992 sort = list.utils.naturalSort.caseInsensitive;
993 }
994
995 return sort(itemA.values()[options.valueName], itemB.values()[options.valueName]) * multi;
996 };
997 }
998
999 list.items.sort(sortFunction);
1000 list.update();
1001 list.trigger('sortComplete');
1002 }; // Add handlers
1003
1004
1005 list.handlers.sortStart = list.handlers.sortStart || [];
1006 list.handlers.sortComplete = list.handlers.sortComplete || [];
1007 buttons.els = list.utils.getByClass(list.listContainer, list.sortClass);
1008 list.utils.events.bind(buttons.els, 'click', sort);
1009 list.on('searchStart', buttons.clear);
1010 list.on('filterStart', buttons.clear);
1011 return sort;
1012};
1013
1014/***/ }),
1015
1016/***/ "./src/templater.js":
1017/*!**************************!*\
1018 !*** ./src/templater.js ***!
1019 \**************************/
1020/*! unknown exports (runtime-defined) */
1021/*! runtime requirements: module */
1022/*! CommonJS bailout: module.exports is used directly at 216:0-14 */
1023/***/ (function(module) {
1024
1025var Templater = function Templater(list) {
1026 var createItem,
1027 templater = this;
1028
1029 var init = function init() {
1030 var itemSource;
1031
1032 if (typeof list.item === 'function') {
1033 createItem = function createItem(values) {
1034 var item = list.item(values);
1035 return getItemSource(item);
1036 };
1037
1038 return;
1039 }
1040
1041 if (typeof list.item === 'string') {
1042 if (list.item.indexOf('<') === -1) {
1043 itemSource = document.getElementById(list.item);
1044 } else {
1045 itemSource = getItemSource(list.item);
1046 }
1047 } else {
1048 /* If item source does not exists, use the first item in list as
1049 source for new items */
1050 itemSource = getFirstListItem();
1051 }
1052
1053 if (!itemSource) {
1054 throw new Error("The list needs to have at least one item on init otherwise you'll have to add a template.");
1055 }
1056
1057 itemSource = createCleanTemplateItem(itemSource, list.valueNames);
1058
1059 createItem = function createItem() {
1060 return itemSource.cloneNode(true);
1061 };
1062 };
1063
1064 var createCleanTemplateItem = function createCleanTemplateItem(templateNode, valueNames) {
1065 var el = templateNode.cloneNode(true);
1066 el.removeAttribute('id');
1067
1068 for (var i = 0, il = valueNames.length; i < il; i++) {
1069 var elm = undefined,
1070 valueName = valueNames[i];
1071
1072 if (valueName.data) {
1073 for (var j = 0, jl = valueName.data.length; j < jl; j++) {
1074 el.setAttribute('data-' + valueName.data[j], '');
1075 }
1076 } else if (valueName.attr && valueName.name) {
1077 elm = list.utils.getByClass(el, valueName.name, true);
1078
1079 if (elm) {
1080 elm.setAttribute(valueName.attr, '');
1081 }
1082 } else {
1083 elm = list.utils.getByClass(el, valueName, true);
1084
1085 if (elm) {
1086 elm.innerHTML = '';
1087 }
1088 }
1089 }
1090
1091 return el;
1092 };
1093
1094 var getFirstListItem = function getFirstListItem() {
1095 var nodes = list.list.childNodes;
1096
1097 for (var i = 0, il = nodes.length; i < il; i++) {
1098 // Only textnodes have a data attribute
1099 if (nodes[i].data === undefined) {
1100 return nodes[i].cloneNode(true);
1101 }
1102 }
1103
1104 return undefined;
1105 };
1106
1107 var getItemSource = function getItemSource(itemHTML) {
1108 if (typeof itemHTML !== 'string') return undefined;
1109
1110 if (/<tr[\s>]/g.exec(itemHTML)) {
1111 var tbody = document.createElement('tbody');
1112 tbody.innerHTML = itemHTML;
1113 return tbody.firstElementChild;
1114 } else if (itemHTML.indexOf('<') !== -1) {
1115 var div = document.createElement('div');
1116 div.innerHTML = itemHTML;
1117 return div.firstElementChild;
1118 }
1119
1120 return undefined;
1121 };
1122
1123 var getValueName = function getValueName(name) {
1124 for (var i = 0, il = list.valueNames.length; i < il; i++) {
1125 var valueName = list.valueNames[i];
1126
1127 if (valueName.data) {
1128 var data = valueName.data;
1129
1130 for (var j = 0, jl = data.length; j < jl; j++) {
1131 if (data[j] === name) {
1132 return {
1133 data: name
1134 };
1135 }
1136 }
1137 } else if (valueName.attr && valueName.name && valueName.name == name) {
1138 return valueName;
1139 } else if (valueName === name) {
1140 return name;
1141 }
1142 }
1143 };
1144
1145 var setValue = function setValue(item, name, value) {
1146 var elm = undefined,
1147 valueName = getValueName(name);
1148 if (!valueName) return;
1149
1150 if (valueName.data) {
1151 item.elm.setAttribute('data-' + valueName.data, value);
1152 } else if (valueName.attr && valueName.name) {
1153 elm = list.utils.getByClass(item.elm, valueName.name, true);
1154
1155 if (elm) {
1156 elm.setAttribute(valueName.attr, value);
1157 }
1158 } else {
1159 elm = list.utils.getByClass(item.elm, valueName, true);
1160
1161 if (elm) {
1162 elm.innerHTML = value;
1163 }
1164 }
1165 };
1166
1167 this.get = function (item, valueNames) {
1168 templater.create(item);
1169 var values = {};
1170
1171 for (var i = 0, il = valueNames.length; i < il; i++) {
1172 var elm = undefined,
1173 valueName = valueNames[i];
1174
1175 if (valueName.data) {
1176 for (var j = 0, jl = valueName.data.length; j < jl; j++) {
1177 values[valueName.data[j]] = list.utils.getAttribute(item.elm, 'data-' + valueName.data[j]);
1178 }
1179 } else if (valueName.attr && valueName.name) {
1180 elm = list.utils.getByClass(item.elm, valueName.name, true);
1181 values[valueName.name] = elm ? list.utils.getAttribute(elm, valueName.attr) : '';
1182 } else {
1183 elm = list.utils.getByClass(item.elm, valueName, true);
1184 values[valueName] = elm ? elm.innerHTML : '';
1185 }
1186 }
1187
1188 return values;
1189 };
1190
1191 this.set = function (item, values) {
1192 if (!templater.create(item)) {
1193 for (var v in values) {
1194 if (values.hasOwnProperty(v)) {
1195 setValue(item, v, values[v]);
1196 }
1197 }
1198 }
1199 };
1200
1201 this.create = function (item) {
1202 if (item.elm !== undefined) {
1203 return false;
1204 }
1205
1206 item.elm = createItem(item.values());
1207 templater.set(item, item.values());
1208 return true;
1209 };
1210
1211 this.remove = function (item) {
1212 if (item.elm.parentNode === list.list) {
1213 list.list.removeChild(item.elm);
1214 }
1215 };
1216
1217 this.show = function (item) {
1218 templater.create(item);
1219 list.list.appendChild(item.elm);
1220 };
1221
1222 this.hide = function (item) {
1223 if (item.elm !== undefined && item.elm.parentNode === list.list) {
1224 list.list.removeChild(item.elm);
1225 }
1226 };
1227
1228 this.clear = function () {
1229 /* .innerHTML = ''; fucks up IE */
1230 if (list.list.hasChildNodes()) {
1231 while (list.list.childNodes.length >= 1) {
1232 list.list.removeChild(list.list.firstChild);
1233 }
1234 }
1235 };
1236
1237 init();
1238};
1239
1240module.exports = function (list) {
1241 return new Templater(list);
1242};
1243
1244/***/ }),
1245
1246/***/ "./src/utils/classes.js":
1247/*!******************************!*\
1248 !*** ./src/utils/classes.js ***!
1249 \******************************/
1250/*! unknown exports (runtime-defined) */
1251/*! runtime requirements: module, __webpack_require__ */
1252/*! CommonJS bailout: module.exports is used directly at 24:0-14 */
1253/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
1254
1255/**
1256 * Module dependencies.
1257 */
1258var index = __webpack_require__(/*! ./index-of */ "./src/utils/index-of.js");
1259/**
1260 * Whitespace regexp.
1261 */
1262
1263
1264var re = /\s+/;
1265/**
1266 * toString reference.
1267 */
1268
1269var toString = Object.prototype.toString;
1270/**
1271 * Wrap `el` in a `ClassList`.
1272 *
1273 * @param {Element} el
1274 * @return {ClassList}
1275 * @api public
1276 */
1277
1278module.exports = function (el) {
1279 return new ClassList(el);
1280};
1281/**
1282 * Initialize a new ClassList for `el`.
1283 *
1284 * @param {Element} el
1285 * @api private
1286 */
1287
1288
1289function ClassList(el) {
1290 if (!el || !el.nodeType) {
1291 throw new Error('A DOM element reference is required');
1292 }
1293
1294 this.el = el;
1295 this.list = el.classList;
1296}
1297/**
1298 * Add class `name` if not already present.
1299 *
1300 * @param {String} name
1301 * @return {ClassList}
1302 * @api public
1303 */
1304
1305
1306ClassList.prototype.add = function (name) {
1307 // classList
1308 if (this.list) {
1309 this.list.add(name);
1310 return this;
1311 } // fallback
1312
1313
1314 var arr = this.array();
1315 var i = index(arr, name);
1316 if (!~i) arr.push(name);
1317 this.el.className = arr.join(' ');
1318 return this;
1319};
1320/**
1321 * Remove class `name` when present, or
1322 * pass a regular expression to remove
1323 * any which match.
1324 *
1325 * @param {String|RegExp} name
1326 * @return {ClassList}
1327 * @api public
1328 */
1329
1330
1331ClassList.prototype.remove = function (name) {
1332 // classList
1333 if (this.list) {
1334 this.list.remove(name);
1335 return this;
1336 } // fallback
1337
1338
1339 var arr = this.array();
1340 var i = index(arr, name);
1341 if (~i) arr.splice(i, 1);
1342 this.el.className = arr.join(' ');
1343 return this;
1344};
1345/**
1346 * Toggle class `name`, can force state via `force`.
1347 *
1348 * For browsers that support classList, but do not support `force` yet,
1349 * the mistake will be detected and corrected.
1350 *
1351 * @param {String} name
1352 * @param {Boolean} force
1353 * @return {ClassList}
1354 * @api public
1355 */
1356
1357
1358ClassList.prototype.toggle = function (name, force) {
1359 // classList
1360 if (this.list) {
1361 if ('undefined' !== typeof force) {
1362 if (force !== this.list.toggle(name, force)) {
1363 this.list.toggle(name); // toggle again to correct
1364 }
1365 } else {
1366 this.list.toggle(name);
1367 }
1368
1369 return this;
1370 } // fallback
1371
1372
1373 if ('undefined' !== typeof force) {
1374 if (!force) {
1375 this.remove(name);
1376 } else {
1377 this.add(name);
1378 }
1379 } else {
1380 if (this.has(name)) {
1381 this.remove(name);
1382 } else {
1383 this.add(name);
1384 }
1385 }
1386
1387 return this;
1388};
1389/**
1390 * Return an array of classes.
1391 *
1392 * @return {Array}
1393 * @api public
1394 */
1395
1396
1397ClassList.prototype.array = function () {
1398 var className = this.el.getAttribute('class') || '';
1399 var str = className.replace(/^\s+|\s+$/g, '');
1400 var arr = str.split(re);
1401 if ('' === arr[0]) arr.shift();
1402 return arr;
1403};
1404/**
1405 * Check if class `name` is present.
1406 *
1407 * @param {String} name
1408 * @return {ClassList}
1409 * @api public
1410 */
1411
1412
1413ClassList.prototype.has = ClassList.prototype.contains = function (name) {
1414 return this.list ? this.list.contains(name) : !!~index(this.array(), name);
1415};
1416
1417/***/ }),
1418
1419/***/ "./src/utils/events.js":
1420/*!*****************************!*\
1421 !*** ./src/utils/events.js ***!
1422 \*****************************/
1423/*! default exports */
1424/*! export bind [provided] [no usage info] [missing usage info prevents renaming] */
1425/*! export debounce [provided] [no usage info] [missing usage info prevents renaming] */
1426/*! export unbind [provided] [no usage info] [missing usage info prevents renaming] */
1427/*! other exports [not provided] [no usage info] */
1428/*! runtime requirements: __webpack_exports__, __webpack_require__ */
1429/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1430
1431var bind = window.addEventListener ? 'addEventListener' : 'attachEvent',
1432 unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent',
1433 prefix = bind !== 'addEventListener' ? 'on' : '',
1434 toArray = __webpack_require__(/*! ./to-array */ "./src/utils/to-array.js");
1435/**
1436 * Bind `el` event `type` to `fn`.
1437 *
1438 * @param {Element} el, NodeList, HTMLCollection or Array
1439 * @param {String} type
1440 * @param {Function} fn
1441 * @param {Boolean} capture
1442 * @api public
1443 */
1444
1445
1446exports.bind = function (el, type, fn, capture) {
1447 el = toArray(el);
1448
1449 for (var i = 0, il = el.length; i < il; i++) {
1450 el[i][bind](prefix + type, fn, capture || false);
1451 }
1452};
1453/**
1454 * Unbind `el` event `type`'s callback `fn`.
1455 *
1456 * @param {Element} el, NodeList, HTMLCollection or Array
1457 * @param {String} type
1458 * @param {Function} fn
1459 * @param {Boolean} capture
1460 * @api public
1461 */
1462
1463
1464exports.unbind = function (el, type, fn, capture) {
1465 el = toArray(el);
1466
1467 for (var i = 0, il = el.length; i < il; i++) {
1468 el[i][unbind](prefix + type, fn, capture || false);
1469 }
1470};
1471/**
1472 * Returns a function, that, as long as it continues to be invoked, will not
1473 * be triggered. The function will be called after it stops being called for
1474 * `wait` milliseconds. If `immediate` is true, trigger the function on the
1475 * leading edge, instead of the trailing.
1476 *
1477 * @param {Function} fn
1478 * @param {Integer} wait
1479 * @param {Boolean} immediate
1480 * @api public
1481 */
1482
1483
1484exports.debounce = function (fn, wait, immediate) {
1485 var timeout;
1486 return wait ? function () {
1487 var context = this,
1488 args = arguments;
1489
1490 var later = function later() {
1491 timeout = null;
1492 if (!immediate) fn.apply(context, args);
1493 };
1494
1495 var callNow = immediate && !timeout;
1496 clearTimeout(timeout);
1497 timeout = setTimeout(later, wait);
1498 if (callNow) fn.apply(context, args);
1499 } : fn;
1500};
1501
1502/***/ }),
1503
1504/***/ "./src/utils/extend.js":
1505/*!*****************************!*\
1506 !*** ./src/utils/extend.js ***!
1507 \*****************************/
1508/*! unknown exports (runtime-defined) */
1509/*! runtime requirements: module */
1510/*! CommonJS bailout: module.exports is used directly at 4:0-14 */
1511/***/ (function(module) {
1512
1513/*
1514 * Source: https://github.com/segmentio/extend
1515 */
1516module.exports = function extend(object) {
1517 // Takes an unlimited number of extenders.
1518 var args = Array.prototype.slice.call(arguments, 1); // For each extender, copy their properties on our object.
1519
1520 for (var i = 0, source; source = args[i]; i++) {
1521 if (!source) continue;
1522
1523 for (var property in source) {
1524 object[property] = source[property];
1525 }
1526 }
1527
1528 return object;
1529};
1530
1531/***/ }),
1532
1533/***/ "./src/utils/fuzzy.js":
1534/*!****************************!*\
1535 !*** ./src/utils/fuzzy.js ***!
1536 \****************************/
1537/*! unknown exports (runtime-defined) */
1538/*! runtime requirements: module */
1539/*! CommonJS bailout: module.exports is used directly at 1:0-14 */
1540/***/ (function(module) {
1541
1542module.exports = function (text, pattern, options) {
1543 // Aproximately where in the text is the pattern expected to be found?
1544 var Match_Location = options.location || 0; //Determines how close the match must be to the fuzzy location (specified above). An exact letter match which is 'distance' characters away from the fuzzy location would score as a complete mismatch. A distance of '0' requires the match be at the exact location specified, a threshold of '1000' would require a perfect match to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.
1545
1546 var Match_Distance = options.distance || 100; // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match (of both letters and location), a threshold of '1.0' would match anything.
1547
1548 var Match_Threshold = options.threshold || 0.4;
1549 if (pattern === text) return true; // Exact match
1550
1551 if (pattern.length > 32) return false; // This algorithm cannot be used
1552 // Set starting location at beginning text and initialise the alphabet.
1553
1554 var loc = Match_Location,
1555 s = function () {
1556 var q = {},
1557 i;
1558
1559 for (i = 0; i < pattern.length; i++) {
1560 q[pattern.charAt(i)] = 0;
1561 }
1562
1563 for (i = 0; i < pattern.length; i++) {
1564 q[pattern.charAt(i)] |= 1 << pattern.length - i - 1;
1565 }
1566
1567 return q;
1568 }(); // Compute and return the score for a match with e errors and x location.
1569 // Accesses loc and pattern through being a closure.
1570
1571
1572 function match_bitapScore_(e, x) {
1573 var accuracy = e / pattern.length,
1574 proximity = Math.abs(loc - x);
1575
1576 if (!Match_Distance) {
1577 // Dodge divide by zero error.
1578 return proximity ? 1.0 : accuracy;
1579 }
1580
1581 return accuracy + proximity / Match_Distance;
1582 }
1583
1584 var score_threshold = Match_Threshold,
1585 // Highest score beyond which we give up.
1586 best_loc = text.indexOf(pattern, loc); // Is there a nearby exact match? (speedup)
1587
1588 if (best_loc != -1) {
1589 score_threshold = Math.min(match_bitapScore_(0, best_loc), score_threshold); // What about in the other direction? (speedup)
1590
1591 best_loc = text.lastIndexOf(pattern, loc + pattern.length);
1592
1593 if (best_loc != -1) {
1594 score_threshold = Math.min(match_bitapScore_(0, best_loc), score_threshold);
1595 }
1596 } // Initialise the bit arrays.
1597
1598
1599 var matchmask = 1 << pattern.length - 1;
1600 best_loc = -1;
1601 var bin_min, bin_mid;
1602 var bin_max = pattern.length + text.length;
1603 var last_rd;
1604
1605 for (var d = 0; d < pattern.length; d++) {
1606 // Scan for the best match; each iteration allows for one more error.
1607 // Run a binary search to determine how far from 'loc' we can stray at this
1608 // error level.
1609 bin_min = 0;
1610 bin_mid = bin_max;
1611
1612 while (bin_min < bin_mid) {
1613 if (match_bitapScore_(d, loc + bin_mid) <= score_threshold) {
1614 bin_min = bin_mid;
1615 } else {
1616 bin_max = bin_mid;
1617 }
1618
1619 bin_mid = Math.floor((bin_max - bin_min) / 2 + bin_min);
1620 } // Use the result from this iteration as the maximum for the next.
1621
1622
1623 bin_max = bin_mid;
1624 var start = Math.max(1, loc - bin_mid + 1);
1625 var finish = Math.min(loc + bin_mid, text.length) + pattern.length;
1626 var rd = Array(finish + 2);
1627 rd[finish + 1] = (1 << d) - 1;
1628
1629 for (var j = finish; j >= start; j--) {
1630 // The alphabet (s) is a sparse hash, so the following line generates
1631 // warnings.
1632 var charMatch = s[text.charAt(j - 1)];
1633
1634 if (d === 0) {
1635 // First pass: exact match.
1636 rd[j] = (rd[j + 1] << 1 | 1) & charMatch;
1637 } else {
1638 // Subsequent passes: fuzzy match.
1639 rd[j] = (rd[j + 1] << 1 | 1) & charMatch | ((last_rd[j + 1] | last_rd[j]) << 1 | 1) | last_rd[j + 1];
1640 }
1641
1642 if (rd[j] & matchmask) {
1643 var score = match_bitapScore_(d, j - 1); // This match will almost certainly be better than any existing match.
1644 // But check anyway.
1645
1646 if (score <= score_threshold) {
1647 // Told you so.
1648 score_threshold = score;
1649 best_loc = j - 1;
1650
1651 if (best_loc > loc) {
1652 // When passing loc, don't exceed our current distance from loc.
1653 start = Math.max(1, 2 * loc - best_loc);
1654 } else {
1655 // Already passed loc, downhill from here on in.
1656 break;
1657 }
1658 }
1659 }
1660 } // No hope for a (better) match at greater error levels.
1661
1662
1663 if (match_bitapScore_(d + 1, loc) > score_threshold) {
1664 break;
1665 }
1666
1667 last_rd = rd;
1668 }
1669
1670 return best_loc < 0 ? false : true;
1671};
1672
1673/***/ }),
1674
1675/***/ "./src/utils/get-attribute.js":
1676/*!************************************!*\
1677 !*** ./src/utils/get-attribute.js ***!
1678 \************************************/
1679/*! unknown exports (runtime-defined) */
1680/*! runtime requirements: module */
1681/*! CommonJS bailout: module.exports is used directly at 11:0-14 */
1682/***/ (function(module) {
1683
1684/**
1685 * A cross-browser implementation of getAttribute.
1686 * Source found here: http://stackoverflow.com/a/3755343/361337 written by Vivin Paliath
1687 *
1688 * Return the value for `attr` at `element`.
1689 *
1690 * @param {Element} el
1691 * @param {String} attr
1692 * @api public
1693 */
1694module.exports = function (el, attr) {
1695 var result = el.getAttribute && el.getAttribute(attr) || null;
1696
1697 if (!result) {
1698 var attrs = el.attributes;
1699 var length = attrs.length;
1700
1701 for (var i = 0; i < length; i++) {
1702 if (attrs[i] !== undefined) {
1703 if (attrs[i].nodeName === attr) {
1704 result = attrs[i].nodeValue;
1705 }
1706 }
1707 }
1708 }
1709
1710 return result;
1711};
1712
1713/***/ }),
1714
1715/***/ "./src/utils/get-by-class.js":
1716/*!***********************************!*\
1717 !*** ./src/utils/get-by-class.js ***!
1718 \***********************************/
1719/*! unknown exports (runtime-defined) */
1720/*! runtime requirements: module */
1721/*! CommonJS bailout: module.exports is used directly at 53:0-14 */
1722/***/ (function(module) {
1723
1724/**
1725 * A cross-browser implementation of getElementsByClass.
1726 * Heavily based on Dustin Diaz's function: http://dustindiaz.com/getelementsbyclass.
1727 *
1728 * Find all elements with class `className` inside `container`.
1729 * Use `single = true` to increase performance in older browsers
1730 * when only one element is needed.
1731 *
1732 * @param {String} className
1733 * @param {Element} container
1734 * @param {Boolean} single
1735 * @api public
1736 */
1737var getElementsByClassName = function getElementsByClassName(container, className, single) {
1738 if (single) {
1739 return container.getElementsByClassName(className)[0];
1740 } else {
1741 return container.getElementsByClassName(className);
1742 }
1743};
1744
1745var querySelector = function querySelector(container, className, single) {
1746 className = '.' + className;
1747
1748 if (single) {
1749 return container.querySelector(className);
1750 } else {
1751 return container.querySelectorAll(className);
1752 }
1753};
1754
1755var polyfill = function polyfill(container, className, single) {
1756 var classElements = [],
1757 tag = '*';
1758 var els = container.getElementsByTagName(tag);
1759 var elsLen = els.length;
1760 var pattern = new RegExp('(^|\\s)' + className + '(\\s|$)');
1761
1762 for (var i = 0, j = 0; i < elsLen; i++) {
1763 if (pattern.test(els[i].className)) {
1764 if (single) {
1765 return els[i];
1766 } else {
1767 classElements[j] = els[i];
1768 j++;
1769 }
1770 }
1771 }
1772
1773 return classElements;
1774};
1775
1776module.exports = function () {
1777 return function (container, className, single, options) {
1778 options = options || {};
1779
1780 if (options.test && options.getElementsByClassName || !options.test && document.getElementsByClassName) {
1781 return getElementsByClassName(container, className, single);
1782 } else if (options.test && options.querySelector || !options.test && document.querySelector) {
1783 return querySelector(container, className, single);
1784 } else {
1785 return polyfill(container, className, single);
1786 }
1787 };
1788}();
1789
1790/***/ }),
1791
1792/***/ "./src/utils/index-of.js":
1793/*!*******************************!*\
1794 !*** ./src/utils/index-of.js ***!
1795 \*******************************/
1796/*! unknown exports (runtime-defined) */
1797/*! runtime requirements: module */
1798/*! CommonJS bailout: module.exports is used directly at 3:0-14 */
1799/***/ (function(module) {
1800
1801var indexOf = [].indexOf;
1802
1803module.exports = function (arr, obj) {
1804 if (indexOf) return arr.indexOf(obj);
1805
1806 for (var i = 0, il = arr.length; i < il; ++i) {
1807 if (arr[i] === obj) return i;
1808 }
1809
1810 return -1;
1811};
1812
1813/***/ }),
1814
1815/***/ "./src/utils/to-array.js":
1816/*!*******************************!*\
1817 !*** ./src/utils/to-array.js ***!
1818 \*******************************/
1819/*! unknown exports (runtime-defined) */
1820/*! runtime requirements: module */
1821/*! CommonJS bailout: module.exports is used directly at 11:0-14 */
1822/***/ (function(module) {
1823
1824/**
1825 * Source: https://github.com/timoxley/to-array
1826 *
1827 * Convert an array-like object into an `Array`.
1828 * If `collection` is already an `Array`, then will return a clone of `collection`.
1829 *
1830 * @param {Array | Mixed} collection An `Array` or array-like object to convert e.g. `arguments` or `NodeList`
1831 * @return {Array} Naive conversion of `collection` to a new `Array`.
1832 * @api public
1833 */
1834module.exports = function toArray(collection) {
1835 if (typeof collection === 'undefined') return [];
1836 if (collection === null) return [null];
1837 if (collection === window) return [window];
1838 if (typeof collection === 'string') return [collection];
1839 if (isArray(collection)) return collection;
1840 if (typeof collection.length != 'number') return [collection];
1841 if (typeof collection === 'function' && collection instanceof Function) return [collection];
1842 var arr = [];
1843
1844 for (var i = 0, il = collection.length; i < il; i++) {
1845 if (Object.prototype.hasOwnProperty.call(collection, i) || i in collection) {
1846 arr.push(collection[i]);
1847 }
1848 }
1849
1850 if (!arr.length) return [];
1851 return arr;
1852};
1853
1854function isArray(arr) {
1855 return Object.prototype.toString.call(arr) === '[object Array]';
1856}
1857
1858/***/ }),
1859
1860/***/ "./src/utils/to-string.js":
1861/*!********************************!*\
1862 !*** ./src/utils/to-string.js ***!
1863 \********************************/
1864/*! unknown exports (runtime-defined) */
1865/*! runtime requirements: module */
1866/*! CommonJS bailout: module.exports is used directly at 1:0-14 */
1867/***/ (function(module) {
1868
1869module.exports = function (s) {
1870 s = s === undefined ? '' : s;
1871 s = s === null ? '' : s;
1872 s = s.toString();
1873 return s;
1874};
1875
1876/***/ }),
1877
1878/***/ "./node_modules/string-natural-compare/natural-compare.js":
1879/*!****************************************************************!*\
1880 !*** ./node_modules/string-natural-compare/natural-compare.js ***!
1881 \****************************************************************/
1882/*! unknown exports (runtime-defined) */
1883/*! runtime requirements: module */
1884/*! CommonJS bailout: module.exports is used directly at 124:0-14 */
1885/***/ (function(module) {
1886
1887"use strict";
1888
1889
1890var alphabet;
1891var alphabetIndexMap;
1892var alphabetIndexMapLength = 0;
1893
1894function isNumberCode(code) {
1895 return code >= 48 && code <= 57;
1896}
1897
1898function naturalCompare(a, b) {
1899 var lengthA = (a += '').length;
1900 var lengthB = (b += '').length;
1901 var aIndex = 0;
1902 var bIndex = 0;
1903
1904 while (aIndex < lengthA && bIndex < lengthB) {
1905 var charCodeA = a.charCodeAt(aIndex);
1906 var charCodeB = b.charCodeAt(bIndex);
1907
1908 if (isNumberCode(charCodeA)) {
1909 if (!isNumberCode(charCodeB)) {
1910 return charCodeA - charCodeB;
1911 }
1912
1913 var numStartA = aIndex;
1914 var numStartB = bIndex;
1915
1916 while (charCodeA === 48 && ++numStartA < lengthA) {
1917 charCodeA = a.charCodeAt(numStartA);
1918 }
1919 while (charCodeB === 48 && ++numStartB < lengthB) {
1920 charCodeB = b.charCodeAt(numStartB);
1921 }
1922
1923 var numEndA = numStartA;
1924 var numEndB = numStartB;
1925
1926 while (numEndA < lengthA && isNumberCode(a.charCodeAt(numEndA))) {
1927 ++numEndA;
1928 }
1929 while (numEndB < lengthB && isNumberCode(b.charCodeAt(numEndB))) {
1930 ++numEndB;
1931 }
1932
1933 var difference = numEndA - numStartA - numEndB + numStartB; // numA length - numB length
1934 if (difference) {
1935 return difference;
1936 }
1937
1938 while (numStartA < numEndA) {
1939 difference = a.charCodeAt(numStartA++) - b.charCodeAt(numStartB++);
1940 if (difference) {
1941 return difference;
1942 }
1943 }
1944
1945 aIndex = numEndA;
1946 bIndex = numEndB;
1947 continue;
1948 }
1949
1950 if (charCodeA !== charCodeB) {
1951 if (
1952 charCodeA < alphabetIndexMapLength &&
1953 charCodeB < alphabetIndexMapLength &&
1954 alphabetIndexMap[charCodeA] !== -1 &&
1955 alphabetIndexMap[charCodeB] !== -1
1956 ) {
1957 return alphabetIndexMap[charCodeA] - alphabetIndexMap[charCodeB];
1958 }
1959
1960 return charCodeA - charCodeB;
1961 }
1962
1963 ++aIndex;
1964 ++bIndex;
1965 }
1966
1967 if (aIndex >= lengthA && bIndex < lengthB && lengthA >= lengthB) {
1968 return -1;
1969 }
1970
1971 if (bIndex >= lengthB && aIndex < lengthA && lengthB >= lengthA) {
1972 return 1;
1973 }
1974
1975 return lengthA - lengthB;
1976}
1977
1978naturalCompare.caseInsensitive = naturalCompare.i = function(a, b) {
1979 return naturalCompare(('' + a).toLowerCase(), ('' + b).toLowerCase());
1980};
1981
1982Object.defineProperties(naturalCompare, {
1983 alphabet: {
1984 get: function() {
1985 return alphabet;
1986 },
1987
1988 set: function(value) {
1989 alphabet = value;
1990 alphabetIndexMap = [];
1991
1992 var i = 0;
1993
1994 if (alphabet) {
1995 for (; i < alphabet.length; i++) {
1996 alphabetIndexMap[alphabet.charCodeAt(i)] = i;
1997 }
1998 }
1999
2000 alphabetIndexMapLength = alphabetIndexMap.length;
2001
2002 for (i = 0; i < alphabetIndexMapLength; i++) {
2003 if (alphabetIndexMap[i] === undefined) {
2004 alphabetIndexMap[i] = -1;
2005 }
2006 }
2007 },
2008 },
2009});
2010
2011module.exports = naturalCompare;
2012
2013
2014/***/ })
2015
2016/******/ });
2017/************************************************************************/
2018/******/ // The module cache
2019/******/ var __webpack_module_cache__ = {};
2020/******/
2021/******/ // The require function
2022/******/ function __webpack_require__(moduleId) {
2023/******/ // Check if module is in cache
2024/******/ if(__webpack_module_cache__[moduleId]) {
2025/******/ return __webpack_module_cache__[moduleId].exports;
2026/******/ }
2027/******/ // Create a new module (and put it into the cache)
2028/******/ var module = __webpack_module_cache__[moduleId] = {
2029/******/ // no module.id needed
2030/******/ // no module.loaded needed
2031/******/ exports: {}
2032/******/ };
2033/******/
2034/******/ // Execute the module function
2035/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
2036/******/
2037/******/ // Return the exports of the module
2038/******/ return module.exports;
2039/******/ }
2040/******/
2041/************************************************************************/
2042/******/ // module exports must be returned from runtime so entry inlining is disabled
2043/******/ // startup
2044/******/ // Load entry module and return exports
2045/******/ return __webpack_require__("./src/index.js");
2046/******/ })()
2047;
2048
Note: See TracBrowser for help on using the repository browser.