1(function (global, factory) { 2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 typeof define === 'function' && define.amd ? define(factory) : 4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.autoComplete = factory()); 5})(this, (function () { 'use strict'; 6 7 function ownKeys(object, enumerableOnly) { 8 var keys = Object.keys(object); 9 10 if (Object.getOwnPropertySymbols) { 11 var symbols = Object.getOwnPropertySymbols(object); 12 enumerableOnly && (symbols = symbols.filter(function (sym) { 13 return Object.getOwnPropertyDescriptor(object, sym).enumerable; 14 })), keys.push.apply(keys, symbols); 15 } 16 17 return keys; 18 } 19 20 function _objectSpread2(target) { 21 for (var i = 1; i < arguments.length; i++) { 22 var source = null != arguments[i] ? arguments[i] : {}; 23 i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { 24 _defineProperty(target, key, source[key]); 25 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { 26 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); 27 }); 28 } 29 30 return target; 31 } 32 33 function _typeof(obj) { 34 "@babel/helpers - typeof"; 35 36 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { 37 return typeof obj; 38 } : function (obj) { 39 return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 40 }, _typeof(obj); 41 } 42 43 function _defineProperty(obj, key, value) { 44 if (key in obj) { 45 Object.defineProperty(obj, key, { 46 value: value, 47 enumerable: true, 48 configurable: true, 49 writable: true 50 }); 51 } else { 52 obj[key] = value; 53 } 54 55 return obj; 56 } 57 58 function _toConsumableArray(arr) { 59 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); 60 } 61 62 function _arrayWithoutHoles(arr) { 63 if (Array.isArray(arr)) return _arrayLikeToArray(arr); 64 } 65 66 function _iterableToArray(iter) { 67 if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); 68 } 69 70 function _unsupportedIterableToArray(o, minLen) { 71 if (!o) return; 72 if (typeof o === "string") return _arrayLikeToArray(o, minLen); 73 var n = Object.prototype.toString.call(o).slice(8, -1); 74 if (n === "Object" && o.constructor) n = o.constructor.name; 75 if (n === "Map" || n === "Set") return Array.from(o); 76 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); 77 } 78 79 function _arrayLikeToArray(arr, len) { 80 if (len == null || len > arr.length) len = arr.length; 81 82 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; 83 84 return arr2; 85 } 86 87 function _nonIterableSpread() { 88 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 89 } 90 91 function _createForOfIteratorHelper(o, allowArrayLike) { 92 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; 93 94 if (!it) { 95 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { 96 if (it) o = it; 97 var i = 0; 98 99 var F = function () {}; 100 101 return { 102 s: F, 103 n: function () { 104 if (i >= o.length) return { 105 done: true 106 }; 107 return { 108 done: false, 109 value: o[i++] 110 }; 111 }, 112 e: function (e) { 113 throw e; 114 }, 115 f: F 116 }; 117 } 118 119 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 120 } 121 122 var normalCompletion = true, 123 didErr = false, 124 err; 125 return { 126 s: function () { 127 it = it.call(o); 128 }, 129 n: function () { 130 var step = it.next(); 131 normalCompletion = step.done; 132 return step; 133 }, 134 e: function (e) { 135 didErr = true; 136 err = e; 137 }, 138 f: function () { 139 try { 140 if (!normalCompletion && it.return != null) it.return(); 141 } finally { 142 if (didErr) throw err; 143 } 144 } 145 }; 146 } 147 148 var select$1 = function select(element) { 149 return typeof element === "string" ? document.querySelector(element) : element(); 150 }; 151 var create = function create(tag, options) { 152 var el = typeof tag === "string" ? document.createElement(tag) : tag; 153 for (var key in options) { 154 var val = options[key]; 155 if (key === "inside") { 156 val.append(el); 157 } else if (key === "dest") { 158 select$1(val[0]).insertAdjacentElement(val[1], el); 159 } else if (key === "around") { 160 var ref = val; 161 ref.parentNode.insertBefore(el, ref); 162 el.append(ref); 163 if (ref.getAttribute("autofocus") != null) ref.focus(); 164 } else if (key in el) { 165 el[key] = val; 166 } else { 167 el.setAttribute(key, val); 168 } 169 } 170 return el; 171 }; 172 var getQuery = function getQuery(field) { 173 return field instanceof HTMLInputElement || field instanceof HTMLTextAreaElement ? field.value : field.innerHTML; 174 }; 175 var format = function format(value, diacritics) {
vendor: 8,986 bytes, lines 176-445
176 value = String(value).toLowerCase(); 177 return diacritics ? value.normalize("NFD").replace(/[\u0300-\u036f]/g, "").normalize("NFC") : value; 178 }; 179 var debounce = function debounce(callback, duration) { 180 var timer; 181 return function () { 182 clearTimeout(timer); 183 timer = setTimeout(function () { 184 return callback(); 185 }, duration); 186 }; 187 }; 188 var checkTrigger = function checkTrigger(query, condition, threshold) { 189 return condition ? condition(query) : query.length >= threshold; 190 }; 191 var mark = function mark(value, cls) { 192 return create("mark", _objectSpread2({ 193 innerHTML: value 194 }, typeof cls === "string" && { 195 "class": cls 196 })).outerHTML; 197 }; 198 199 var configure = (function (ctx) { 200 var name = ctx.name, 201 options = ctx.options, 202 resultsList = ctx.resultsList, 203 resultItem = ctx.resultItem; 204 for (var option in options) { 205 if (_typeof(options[option]) === "object") { 206 if (!ctx[option]) ctx[option] = {}; 207 for (var subOption in options[option]) { 208 ctx[option][subOption] = options[option][subOption]; 209 } 210 } else { 211 ctx[option] = options[option]; 212 } 213 } 214 ctx.selector = ctx.selector || "#" + name; 215 resultsList.destination = resultsList.destination || ctx.selector; 216 resultsList.id = resultsList.id || name + "_list_" + ctx.id; 217 resultItem.id = resultItem.id || name + "_result"; 218 ctx.input = select$1(ctx.selector); 219 }); 220 221 var eventEmitter = (function (name, ctx) { 222 ctx.input.dispatchEvent(new CustomEvent(name, { 223 bubbles: true, 224 detail: ctx.feedback, 225 cancelable: true 226 })); 227 }); 228 229 var search = (function (query, record, options) { 230 var _ref = options || {}, 231 mode = _ref.mode, 232 diacritics = _ref.diacritics, 233 highlight = _ref.highlight; 234 var nRecord = format(record, diacritics); 235 record = String(record); 236 query = format(query, diacritics); 237 if (mode === "loose") { 238 query = query.replace(/ /g, ""); 239 var qLength = query.length; 240 var cursor = 0; 241 var match = Array.from(record).map(function (character, index) { 242 if (cursor < qLength && nRecord[index] === query[cursor]) { 243 character = highlight ? mark(character, highlight) : character; 244 cursor++; 245 } 246 return character; 247 }).join(""); 248 if (cursor === qLength) return match; 249 } else { 250 var _match = nRecord.indexOf(query); 251 if (~_match) { 252 query = record.substring(_match, _match + query.length); 253 _match = highlight ? record.replace(query, mark(query, highlight)) : record; 254 return _match; 255 } 256 } 257 }); 258 259 var getData = function getData(ctx, query) { 260 return new Promise(function ($return, $error) { 261 var data; 262 data = ctx.data; 263 if (data.cache && data.store) return $return(); 264 return new Promise(function ($return, $error) { 265 if (typeof data.src === "function") { 266 return new Promise(function ($return, $error) { 267 if (data.src.constructor.name === "AsyncFunction") { 268 return data.src(query).then($return, $error); 269 } 270 return $return(data.src(query)); 271 }).then($return, $error); 272 } 273 return $return(data.src); 274 }).then(function ($await_7) { 275 try { 276 ctx.feedback = data.store = $await_7; 277 eventEmitter("response", ctx); 278 return $return(); 279 } catch ($boundEx) { 280 return $error($boundEx); 281 } 282 }, $error); 283 }); 284 }; 285 var findMatches = function findMatches(query, ctx) { 286 var data = ctx.data, 287 searchEngine = ctx.searchEngine; 288 var matches = []; 289 data.store.forEach(function (value, index) { 290 var find = function find(key) { 291 var record = key ? value[key] : value; 292 var match = typeof searchEngine === "function" ? searchEngine(query, record) : search(query, record, { 293 mode: searchEngine, 294 diacritics: ctx.diacritics, 295 highlight: ctx.resultItem.highlight 296 }); 297 if (!match) return; 298 var result = { 299 match: match, 300 value: value 301 }; 302 if (key) result.key = key; 303 matches.push(result); 304 }; 305 if (data.keys) { 306 var _iterator = _createForOfIteratorHelper(data.keys), 307 _step; 308 try { 309 for (_iterator.s(); !(_step = _iterator.n()).done;) { 310 var key = _step.value; 311 find(key); 312 } 313 } catch (err) { 314 _iterator.e(err); 315 } finally { 316 _iterator.f(); 317 } 318 } else { 319 find(); 320 } 321 }); 322 if (data.filter) matches = data.filter(matches); 323 var results = matches.slice(0, ctx.resultsList.maxResults); 324 ctx.feedback = { 325 query: query, 326 matches: matches, 327 results: results 328 }; 329 eventEmitter("results", ctx); 330 }; 331 332 var Expand = "aria-expanded"; 333 var Active = "aria-activedescendant"; 334 var Selected = "aria-selected"; 335 var feedback = function feedback(ctx, index) { 336 ctx.feedback.selection = _objectSpread2({ 337 index: index 338 }, ctx.feedback.results[index]); 339 }; 340 var render = function render(ctx) { 341 var resultsList = ctx.resultsList, 342 list = ctx.list, 343 resultItem = ctx.resultItem, 344 feedback = ctx.feedback; 345 var matches = feedback.matches, 346 results = feedback.results; 347 ctx.cursor = -1; 348 list.innerHTML = ""; 349 if (matches.length || resultsList.noResults) { 350 var fragment = new DocumentFragment(); 351 results.forEach(function (result, index) { 352 var element = create(resultItem.tag, _objectSpread2({ 353 id: "".concat(resultItem.id, "_").concat(index), 354 role: "option", 355 innerHTML: result.match, 356 inside: fragment 357 }, resultItem["class"] && { 358 "class": resultItem["class"] 359 })); 360 if (resultItem.element) resultItem.element(element, result); 361 }); 362 list.append(fragment); 363 if (resultsList.element) resultsList.element(list, feedback); 364 open(ctx); 365 } else { 366 close(ctx); 367 } 368 }; 369 var open = function open(ctx) { 370 if (ctx.isOpen) return; 371 (ctx.wrapper || ctx.input).setAttribute(Expand, true); 372 ctx.list.removeAttribute("hidden"); 373 ctx.isOpen = true; 374 eventEmitter("open", ctx); 375 }; 376 var close = function close(ctx) { 377 if (!ctx.isOpen) return; 378 (ctx.wrapper || ctx.input).setAttribute(Expand, false); 379 ctx.input.setAttribute(Active, ""); 380 ctx.list.setAttribute("hidden", ""); 381 ctx.isOpen = false; 382 eventEmitter("close", ctx); 383 }; 384 var goTo = function goTo(index, ctx) { 385 var resultItem = ctx.resultItem; 386 var results = ctx.list.getElementsByTagName(resultItem.tag); 387 var cls = resultItem.selected ? resultItem.selected.split(" ") : false; 388 if (ctx.isOpen && results.length) { 389 var _results$index$classL; 390 var state = ctx.cursor; 391 if (index >= results.length) index = 0; 392 if (index < 0) index = results.length - 1; 393 ctx.cursor = index; 394 if (state > -1) { 395 var _results$state$classL; 396 results[state].removeAttribute(Selected); 397 if (cls) (_results$state$classL = results[state].classList).remove.apply(_results$state$classL, _toConsumableArray(cls)); 398 } 399 results[index].setAttribute(Selected, true); 400 if (cls) (_results$index$classL = results[index].classList).add.apply(_results$index$classL, _toConsumableArray(cls)); 401 ctx.input.setAttribute(Active, results[ctx.cursor].id); 402 ctx.list.scrollTop = results[index].offsetTop - ctx.list.clientHeight + results[index].clientHeight + 5; 403 ctx.feedback.cursor = ctx.cursor; 404 feedback(ctx, index); 405 eventEmitter("navigate", ctx); 406 } 407 }; 408 var next = function next(ctx) { 409 goTo(ctx.cursor + 1, ctx); 410 }; 411 var previous = function previous(ctx) { 412 goTo(ctx.cursor - 1, ctx); 413 }; 414 var select = function select(ctx, event, index) { 415 index = index >= 0 ? index : ctx.cursor; 416 if (index < 0) return; 417 ctx.feedback.event = event; 418 feedback(ctx, index); 419 eventEmitter("selection", ctx); 420 close(ctx); 421 }; 422 var click = function click(event, ctx) { 423 var itemTag = ctx.resultItem.tag.toUpperCase(); 424 var items = Array.from(ctx.list.querySelectorAll(itemTag)); 425 var item = event.target.closest(itemTag); 426 if (item && item.nodeName === itemTag) { 427 select(ctx, event, items.indexOf(item)); 428 } 429 }; 430 var navigate = function navigate(event, ctx) { 431 switch (event.keyCode) { 432 case 40: 433 case 38: 434 event.preventDefault(); 435 event.keyCode === 40 ? next(ctx) : previous(ctx); 436 break; 437 case 13: 438 if (!ctx.submit) event.preventDefault(); 439 if (ctx.cursor >= 0) select(ctx, event); 440 break; 441 case 9: 442 if (ctx.resultsList.tabSelect && ctx.cursor >= 0) select(ctx, event); 443 break; 444 case 27: 445 ctx.input.value = ""
vendor: 5,476 bytes, lines 445-641
445; 446 close(ctx); 447 break; 448 } 449 }; 450 451 function start (ctx, q) { 452 var _this = this; 453 return new Promise(function ($return, $error) { 454 var queryVal, condition; 455 queryVal = q || getQuery(ctx.input); 456 queryVal = ctx.query ? ctx.query(queryVal) : queryVal; 457 condition = checkTrigger(queryVal, ctx.trigger, ctx.threshold); 458 if (condition) { 459 return getData(ctx, queryVal).then(function ($await_2) { 460 try { 461 if (ctx.feedback instanceof Error) return $return(); 462 findMatches(queryVal, ctx); 463 if (ctx.resultsList) render(ctx); 464 return $If_1.call(_this); 465 } catch ($boundEx) { 466 return $error($boundEx); 467 } 468 }, $error); 469 } else { 470 close(ctx); 471 return $If_1.call(_this); 472 } 473 function $If_1() { 474 return $return(); 475 } 476 }); 477 } 478 479 var eventsManager = function eventsManager(events, callback) { 480 for (var element in events) { 481 for (var event in events[element]) { 482 callback(element, event); 483 } 484 } 485 }; 486 var addEvents = function addEvents(ctx) { 487 var events = ctx.events; 488 var run = debounce(function () { 489 return start(ctx); 490 }, ctx.debounce); 491 var publicEvents = ctx.events = _objectSpread2({ 492 input: _objectSpread2({}, events && events.input) 493 }, ctx.resultsList && { 494 list: events ? _objectSpread2({}, events.list) : {} 495 }); 496 var privateEvents = { 497 input: { 498 input: function input() { 499 run(); 500 }, 501 keydown: function keydown(event) { 502 navigate(event, ctx); 503 }, 504 blur: function blur() { 505 close(ctx); 506 } 507 }, 508 list: { 509 mousedown: function mousedown(event) { 510 event.preventDefault(); 511 }, 512 click: function click$1(event) { 513 click(event, ctx); 514 } 515 } 516 }; 517 eventsManager(privateEvents, function (element, event) { 518 if (!ctx.resultsList && event !== "input") return; 519 if (publicEvents[element][event]) return; 520 publicEvents[element][event] = privateEvents[element][event]; 521 }); 522 eventsManager(publicEvents, function (element, event) { 523 ctx[element].addEventListener(event, publicEvents[element][event]); 524 }); 525 }; 526 var removeEvents = function removeEvents(ctx) { 527 eventsManager(ctx.events, function (element, event) { 528 ctx[element].removeEventListener(event, ctx.events[element][event]); 529 }); 530 }; 531 532 function init (ctx) { 533 var _this = this; 534 return new Promise(function ($return, $error) { 535 var placeHolder, resultsList, parentAttrs; 536 placeHolder = ctx.placeHolder; 537 resultsList = ctx.resultsList; 538 parentAttrs = { 539 role: "combobox", 540 "aria-owns": resultsList.id, 541 "aria-haspopup": true, 542 "aria-expanded": false 543 }; 544 create(ctx.input, _objectSpread2(_objectSpread2({ 545 "aria-controls": resultsList.id, 546 "aria-autocomplete": "both" 547 }, placeHolder && { 548 placeholder: placeHolder 549 }), !ctx.wrapper && _objectSpread2({}, parentAttrs))); 550 if (ctx.wrapper) ctx.wrapper = create("div", _objectSpread2({ 551 around: ctx.input, 552 "class": ctx.name + "_wrapper" 553 }, parentAttrs)); 554 if (resultsList) ctx.list = create(resultsList.tag, _objectSpread2({ 555 dest: [resultsList.destination, resultsList.position], 556 id: resultsList.id, 557 role: "listbox", 558 hidden: "hidden" 559 }, resultsList["class"] && { 560 "class": resultsList["class"] 561 })); 562 addEvents(ctx); 563 if (ctx.data.cache) { 564 return getData(ctx).then(function ($await_2) { 565 try { 566 return $If_1.call(_this); 567 } catch ($boundEx) { 568 return $error($boundEx); 569 } 570 }, $error); 571 } 572 function $If_1() { 573 eventEmitter("init", ctx); 574 return $return(); 575 } 576 return $If_1.call(_this); 577 }); 578 } 579 580 function extend (autoComplete) { 581 var prototype = autoComplete.prototype; 582 prototype.init = function () { 583 init(this); 584 }; 585 prototype.start = function (query) { 586 start(this, query); 587 }; 588 prototype.unInit = function () { 589 if (this.wrapper) { 590 var parentNode = this.wrapper.parentNode; 591 parentNode.insertBefore(this.input, this.wrapper); 592 parentNode.removeChild(this.wrapper); 593 } 594 removeEvents(this); 595 }; 596 prototype.open = function () { 597 open(this); 598 }; 599 prototype.close = function () { 600 close(this); 601 }; 602 prototype.goTo = function (index) { 603 goTo(index, this); 604 }; 605 prototype.next = function () { 606 next(this); 607 }; 608 prototype.previous = function () { 609 previous(this); 610 }; 611 prototype.select = function (index) { 612 select(this, null, index); 613 }; 614 prototype.search = function (query, record, options) { 615 return search(query, record, options); 616 }; 617 } 618 619 function autoComplete(config) { 620 this.options = config; 621 this.id = autoComplete.instances = (autoComplete.instances || 0) + 1; 622 this.name = "autoComplete"; 623 this.wrapper = 1; 624 this.threshold = 1; 625 this.debounce = 0; 626 this.resultsList = { 627 position: "afterend", 628 tag: "ul", 629 maxResults: 5 630 }; 631 this.resultItem = { 632 tag: "li" 633 }; 634 configure(this); 635 extend.call(this, autoComplete); 636 init(this); 637 } 638 639 return autoComplete; 640 641}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.