@taufik-nurrohman/option-picker
Version:
Accessible custom `<select>` (and `<input list>`) element.
1,393 lines (1,372 loc) • 127 kB
JavaScript
/*!
*
* The MIT License (MIT)
*
* Copyright © 2025 Taufik Nurrohman <https://github.com/taufik-nurrohman>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the “Software”), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
(function (g, f) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = f() : typeof define === 'function' && define.amd ? define(f) : (g = typeof globalThis !== 'undefined' ? globalThis : g || self, g.OptionPicker = f());
})(this, (function () {
'use strict';
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
return n;
}
function _arrayWithHoles(r) {
if (Array.isArray(r)) return r;
}
function _iterableToArrayLimit(r, l) {
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (null != t) {
var e,
n,
i,
u,
a = [],
f = true,
o = false;
try {
if (i = (t = t.call(r)).next, 0 === l) {
if (Object(t) !== t) return;
f = !1;
} else
for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
} catch (r) {
o = true, n = r;
} finally {
try {
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
} finally {
if (o) throw n;
}
}
return a;
}
}
function _maybeArrayLike(r, a, e) {
if (a && !Array.isArray(a) && "number" == typeof a.length) {
var y = a.length;
return _arrayLikeToArray(a, void 0 !== e && e < y ? e : y);
}
return r(a, e);
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _slicedToArray(r, e) {
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) return _arrayLikeToArray(r, a);
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
var isArray = function isArray(x) {
return Array.isArray(x);
};
var isBoolean = function isBoolean(x) {
return false === x || true === x;
};
var isDefined = function isDefined(x) {
return 'undefined' !== typeof x;
};
var isFloat = function isFloat(x) {
return isNumber(x) && 0 !== x % 1;
};
var isFunction = function isFunction(x) {
return 'function' === typeof x;
};
var isInstance = function isInstance(x, of, exact) {
if (!x || 'object' !== typeof x) {
return false;
}
if (exact) {
return isSet(of) && isSet(x.constructor) && of === x.constructor;
}
return isSet(of) && x instanceof of ;
};
var isInteger = function isInteger(x) {
return isNumber(x) && 0 === x % 1;
};
var isNull = function isNull(x) {
return null === x;
};
var isNumber = function isNumber(x) {
return 'number' === typeof x && !Number.isNaN(x);
};
var isNumeric = function isNumeric(x) {
return /^[+-]?(?:\d*\.)?\d+$/.test(x + "");
};
var isObject = function isObject(x, isPlain) {
if (isPlain === void 0) {
isPlain = true;
}
if (!x || 'object' !== typeof x) {
return false;
}
return isPlain ? isInstance(x, Object, 1) : true;
};
var isSet = function isSet(x) {
return isDefined(x) && !isNull(x);
};
var isString = function isString(x) {
return 'string' === typeof x;
};
var hasValue = function hasValue(x, data) {
return -1 !== data.indexOf(x);
};
var fromJSON = function fromJSON(x) {
var value = null;
try {
value = JSON.parse(x);
} catch (e) {}
return value;
};
var _fromStates = function fromStates() {
for (var _len = arguments.length, lot = new Array(_len), _key = 0; _key < _len; _key++) {
lot[_key] = arguments[_key];
}
var out = lot.shift();
for (var i = 0, j = toCount(lot); i < j; ++i) {
for (var k in lot[i]) {
// Assign value
if (!isSet(out[k])) {
out[k] = lot[i][k];
continue;
}
// Merge array
if (isArray(out[k]) && isArray(lot[i][k])) {
out[k] = [ /* Clone! */ ].concat(out[k]);
for (var ii = 0, jj = toCount(lot[i][k]); ii < jj; ++ii) {
if (!hasValue(lot[i][k][ii], out[k])) {
out[k].push(lot[i][k][ii]);
}
}
// Merge object recursive
} else if (isObject(out[k]) && isObject(lot[i][k])) {
out[k] = _fromStates({
/* Clone! */ }, out[k], lot[i][k]);
// Replace value
} else {
out[k] = lot[i][k];
}
}
}
return out;
};
var _fromValue = function fromValue(x) {
if (isArray(x)) {
return x.map(function (v) {
return _fromValue(x);
});
}
if (isObject(x)) {
for (var k in x) {
x[k] = _fromValue(x[k]);
}
return x;
}
if (false === x) {
return 'false';
}
if (null === x) {
return 'null';
}
if (true === x) {
return 'true';
}
return "" + x;
};
var toCaseCamel = function toCaseCamel(x) {
return x.replace(/[-_.](\w)/g, function (m0, m1) {
return toCaseUpper(m1);
});
};
var toCaseLower = function toCaseLower(x) {
return x.toLowerCase();
};
var toCaseUpper = function toCaseUpper(x) {
return x.toUpperCase();
};
var toCount = function toCount(x) {
return x.length;
};
var toJSON = function toJSON(x) {
return JSON.stringify(x);
};
var toMapCount = function toMapCount(x) {
return x.size;
};
var toNumber = function toNumber(x, base) {
if (base === void 0) {
base = 10;
}
return base ? parseInt(x, base) : parseFloat(x);
};
var toSetCount = function toSetCount(x) {
return x.size;
};
var toString = function toString(x, base) {
return isNumber(x) ? x.toString(base) : "" + x;
};
var _toValue = function toValue(x) {
if (isArray(x)) {
return x.map(function (v) {
return _toValue(v);
});
}
if (isObject(x)) {
for (var k in x) {
x[k] = _toValue(x[k]);
}
return x;
}
if (isString(x) && isNumeric(x)) {
if ('0' === x[0] && -1 === x.indexOf('.')) {
return x;
}
return toNumber(x);
}
if ('false' === x) {
return false;
}
if ('null' === x) {
return null;
}
if ('true' === x) {
return true;
}
return x;
};
function _toIterator(v) {
return v[Symbol.iterator]();
}
var forEachArray = function forEachArray(array, at) {
for (var i = 0, j = toCount(array), v; i < j; ++i) {
v = at.call(array, array[i], i);
if (-1 === v) {
array.splice(i, 1);
continue;
}
if (0 === v) {
break;
}
if (1 === v) {
continue;
}
}
return array;
};
var forEachMap = function forEachMap(map, at) {
var items = _toIterator(map),
item = items.next();
while (!item.done) {
var _item$value = _maybeArrayLike(_slicedToArray, item.value, 2),
k = _item$value[0],
v = _item$value[1];
v = at.call(map, v, k);
if (-1 === v) {
letValueInMap(k, map);
} else if (0 === v) {
break;
}
item = items.next();
}
return map;
};
var forEachObject = function forEachObject(object, at) {
var v;
for (var k in object) {
v = at.call(object, object[k], k);
if (-1 === v) {
delete object[k];
continue;
}
if (0 === v) {
break;
}
if (1 === v) {
continue;
}
}
return object;
};
var forEachSet = function forEachSet(set, at) {
var items = _toIterator(set),
item = items.next();
while (!item.done) {
var k = void 0,
v = item.value;
v = at.call(set, v, k = v);
if (-1 === v) {
letValueInMap(k, set);
} else if (0 === v) {
break;
}
item = items.next();
}
return set;
};
var getPrototype = function getPrototype(of) {
return of.prototype;
};
var getReference = function getReference(key) {
return getValueInMap(key, references) || null;
};
var getValueInMap = function getValueInMap(k, map) {
return map.get(k);
};
var hasKeyInMap = function hasKeyInMap(k, map) {
return map.has(k);
};
var letReference = function letReference(k) {
return letValueInMap(k, references);
};
var letValueInMap = function letValueInMap(k, map) {
return map.delete(k);
};
var onAnimationsEnd = function onAnimationsEnd(node, task) {
return isFunction(node.getAnimations) ? Promise.all(node.getAnimations().map(function (v) {
return v.finished;
})).then(task) : task(), node;
};
var setObjectAttributes = function setObjectAttributes(of, attributes, asStaticAttributes) {
if (!asStaticAttributes) {
of = getPrototype(of);
}
return forEachObject(attributes, function (v, k) {
Object.defineProperty(of, k, v);
}), of;
};
var setObjectMethods = function setObjectMethods(of, methods, asStaticMethods) {
{
of = getPrototype(of);
}
return forEachObject(methods, function (v, k) {
of [k] = v;
}), of;
};
var setReference = function setReference(key, value) {
return setValueInMap(key, value, references);
};
var setValueInMap = function setValueInMap(k, v, map) {
return map.set(k, v);
};
var toValueFirstFromMap = function toValueFirstFromMap(map) {
return toValuesFromMap(map).shift();
};
var toValuesFromMap = function toValuesFromMap(map) {
var r = [];
return forEachMap(map, function (v) {
r.push(v);
}), r;
};
var references = new WeakMap();
function _toArray$1(iterable) {
return Array.from(iterable);
}
var D = document;
var W = window;
var B = D.body;
var R = D.documentElement;
var getAria = function getAria(node, aria, parseValue) {
if (parseValue === void 0) {
parseValue = true;
}
return getAttribute(node, 'aria-' + aria, parseValue);
};
var getAttribute = function getAttribute(node, attribute, parseValue) {
if (parseValue === void 0) {
parseValue = true;
}
if (!hasAttribute(node, attribute)) {
return null;
}
var value = node.getAttribute(attribute);
return parseValue ? _toValue(value) : value;
};
var getAttributes = function getAttributes(node, parseValue) {
if (parseValue === void 0) {
parseValue = true;
}
var attributes = node.attributes,
values = {};
forEachArray(attributes, function (v) {
var name = v.name,
value = v.value;
values[name] = parseValue ? _toValue(value) : value;
});
return values;
};
var getChildFirst = function getChildFirst(parent, anyNode) {
return parent['first' + (anyNode ? "" : 'Element') + 'Child'] || null;
};
var getChildLast = function getChildLast(parent, anyNode) {
return parent['last' + (anyNode ? "" : 'Element') + 'Child'] || null;
};
var getChildren = function getChildren(parent, index, anyNode) {
var children = _toArray$1(parent['child' + (anyNode ? 'Nodes' : 'ren')]);
return isNumber(index) ? children[index] || null : children;
};
var getDatum = function getDatum(node, datum, parseValue) {
if (parseValue === void 0) {
parseValue = true;
}
var value = getAttribute(node, 'data-' + datum, parseValue),
v = (value + "").trim();
if (parseValue && v && ('[' === v[0] && ']' === v.slice(-1) || '{' === v[0] && '}' === v.slice(-1)) && null !== (v = fromJSON(value))) {
return v;
}
return value;
};
var getElement = function getElement(query, scope) {
return (scope || D).querySelector(query);
};
var getElementIndex = function getElementIndex(node, anyNode) {
if (!node || !getParent(node)) {
return -1;
}
var index = 0;
while (node = getPrev(node, anyNode)) {
++index;
}
return index;
};
var getHTML = function getHTML(node, trim) {
if (trim === void 0) {
trim = true;
}
var state = 'innerHTML';
if (!hasState(node, state)) {
return false;
}
var content = node[state];
content = trim ? content.trim() : content;
return "" !== content ? content : null;
};
var getID = function getID(node, batch) {
if (batch === void 0) {
batch = 'e:';
}
if (hasID(node)) {
return getAttribute(node, 'id');
}
if (!isSet(theID[batch])) {
theID[batch] = 0;
}
return batch + toString(Date.now() + (theID[batch] += 1), 16);
};
var getName = function getName(node) {
return toCaseLower(node && node.nodeName || "") || null;
};
var getNext = function getNext(node, anyNode) {
return node['next' + (anyNode ? "" : 'Element') + 'Sibling'] || null;
};
var getParent = function getParent(node, query) {
if (query) {
return node.closest(query) || null;
}
return node.parentNode || null;
};
var getParentForm = function getParentForm(node) {
var state = 'form';
if (hasState(node, state) && state === getName(node[state])) {
return node[state];
}
return getParent(node, state);
};
var getPrev = function getPrev(node, anyNode) {
return node['previous' + (anyNode ? "" : 'Element') + 'Sibling'] || null;
};
var getRole = function getRole(node) {
return getAttribute(node, 'role');
};
var getStyle = function getStyle(node, style, parseValue) {
var value = W.getComputedStyle(node).getPropertyValue(style);
return value || "" === value || 0 === value ? value : null;
};
var getState = function getState(node, state) {
return hasState(node, state) && node[state] || null;
};
var getText = function getText(node, trim) {
if (trim === void 0) {
trim = true;
}
var state = 'textContent';
if (!hasState(node, state)) {
return false;
}
var content = node[state];
content = trim ? content.trim() : content;
return "" !== content ? content : null;
};
var getType = function getType(node) {
return node && node.nodeType || null;
};
var getValue = function getValue(node, parseValue) {
var value = (node.value || "").replace(/\r?\n|\r/g, '\n');
value = parseValue ? _toValue(value) : value;
return "" !== value ? value : null;
};
var hasAttribute = function hasAttribute(node, attribute) {
return node.hasAttribute(attribute);
};
var hasID = function hasID(node) {
return hasAttribute(node, 'id');
};
var hasState = function hasState(node, state) {
return state in node;
};
var isDisabled = function isDisabled(node) {
return node.disabled;
};
var isReadOnly = function isReadOnly(node) {
return node.readOnly;
};
var isRequired = function isRequired(node) {
return node.required;
};
var isWindow = function isWindow(node) {
return node === W;
};
var letAria = function letAria(node, aria) {
return letAttribute(node, 'aria-' + aria);
};
var letAttribute = function letAttribute(node, attribute) {
return node.removeAttribute(attribute), node;
};
var letClass = function letClass(node, value) {
return node.classList.remove(value), node;
};
var letDatum = function letDatum(node, datum) {
return letAttribute(node, 'data-' + datum);
};
var letElement = function letElement(node) {
var parent = getParent(node);
return node.remove(), parent;
};
var letHTML = function letHTML(node) {
var state = 'innerHTML';
return hasState(node, state) && (node[state] = ""), node;
};
var letID = function letID(node) {
return letAttribute(node, 'id');
};
var letStyle = function letStyle(node, style) {
return node.style[toCaseCamel(style)] = null, node;
};
var setAria = function setAria(node, aria, value) {
return setAttribute(node, 'aria-' + aria, true === value ? 'true' : value);
};
var setArias = function setArias(node, data) {
return forEachObject(data, function (v, k) {
v || "" === v || 0 === v ? setAria(node, k, v) : letAria(node, k);
}), node;
};
var setAttribute = function setAttribute(node, attribute, value) {
if (true === value) {
value = attribute;
}
return node.setAttribute(attribute, _fromValue(value)), node;
};
var setAttributes = function setAttributes(node, attributes) {
return forEachObject(attributes, function (v, k) {
if ('aria' === k && isObject(v)) {
return setArias(node, v), 1;
}
if ('class' === k) {
return setClasses(node, v), 1;
}
if ('data' === k && isObject(v)) {
return setData(node, v), 1;
}
if ('style' === k && isObject(v)) {
return setStyles(node, v), 1;
}
v || "" === v || 0 === v ? setAttribute(node, k, v) : letAttribute(node, k);
}), node;
};
var setChildLast = function setChildLast(parent, node) {
return parent.append(node), node;
};
var setClass = function setClass(node, value) {
return node.classList.add(value), node;
};
var setClasses = function setClasses(node, classes) {
if (isArray(classes)) {
return forEachArray(classes, function (k) {
return setClass(node, k);
}), node;
}
if (isObject(classes)) {
return forEachObject(classes, function (v, k) {
return v ? setClass(node, k) : letClass(node, k);
}), node;
}
return node.className = classes, node;
};
var setData = function setData(node, data) {
return forEachObject(data, function (v, k) {
v || "" === v || 0 === v ? setDatum(node, k, v) : letDatum(node, k);
}), node;
};
var setDatum = function setDatum(node, datum, value) {
if (isArray(value) || isObject(value)) {
value = toJSON(value);
}
return setAttribute(node, 'data-' + datum, true === value ? 'true' : value);
};
var setElement = function setElement(node, content, attributes, options) {
node = isString(node) ? D.createElement(node, isString(options) ? {
is: options
} : options) : node;
if (isArray(content) && toCount(content)) {
letHTML(node);
forEachArray(content, function (v) {
return setChildLast(isString(v) ? setElementText(v) : v);
});
} else if (isObject(content)) {
attributes = content;
content = false;
}
if (isString(content)) {
setHTML(node, content);
}
if (isObject(attributes)) {
return setAttributes(node, attributes), node;
}
return node;
};
var setElementText = function setElementText(text) {
return isString(text) ? text = D.createTextNode(text) : text, text;
};
var setHTML = function setHTML(node, content, trim) {
if (trim === void 0) {
trim = true;
}
if (null === content) {
return node;
}
var state = 'innerHTML';
return hasState(node, state) && (node[state] = trim ? content.trim() : content), node;
};
var setID = function setID(node, value, batch) {
if (batch === void 0) {
batch = 'e:';
}
return setAttribute(node, 'id', isSet(value) ? value : getID(node, batch));
};
var setNext = function setNext(current, node) {
return current.after(node), node;
};
var setStyle = function setStyle(node, style, value) {
if (isNumber(value)) {
value += 'px';
}
return node.style[toCaseCamel(style)] = _fromValue(value), node;
};
var setStyles = function setStyles(node, styles) {
return forEachObject(styles, function (v, k) {
v || "" === v || 0 === v ? setStyle(node, k, v) : letStyle(node, k);
}), node;
};
var setText = function setText(node, content, trim) {
if (trim === void 0) {
trim = true;
}
if (null === content) {
return node;
}
var state = 'textContent';
return hasState(node, state) && (node[state] = trim ? content.trim() : content), node;
};
var setValue = function setValue(node, value) {
if (null === value) {
return letAttribute(node, 'value');
}
return node.value = _fromValue(value), node;
};
var theID = {};
var now = Date.now;
var history = new WeakMap();
var historyIndex = new WeakMap();
var _getSelection = function _getSelection() {
return D.getSelection();
};
var _setRange = function _setRange() {
return D.createRange();
};
// The `node` parameter is currently not in use
var hasSelection = function hasSelection(node, selection) {
return (selection || _getSelection()).rangeCount > 0;
};
// <https://stackoverflow.com/a/6691294/1163000>
// The `node` parameter is currently not in use
var insertAtSelection = function insertAtSelection(node, content, mode, selection) {
selection = selection || _getSelection();
var from, range, to;
if (!hasSelection(node, selection)) {
return false;
}
range = selection.getRangeAt(0);
range.deleteContents();
to = D.createDocumentFragment();
var nodeCurrent, nodeFirst, nodeLast;
if (isString(content)) {
from = setElement('div');
setHTML(from, content);
while (nodeCurrent = getChildFirst(from, 1)) {
nodeLast = setChildLast(to, nodeCurrent);
}
} else if (isArray(content)) {
forEachArray(content, function (v) {
return nodeLast = setChildLast(to, v);
});
} else {
nodeLast = setChildLast(to, content);
}
nodeFirst = getChildFirst(to, 1);
range.insertNode(to);
if (nodeLast) {
range = range.cloneRange();
range.setStartAfter(nodeLast);
range.setStartBefore(nodeFirst);
{
range.collapse();
}
setSelection(node, range, selectToNone(node, selection));
}
return selection;
};
// The `node` parameter is currently not in use
var letSelection = function letSelection(node, selection) {
selection = selection || _getSelection();
return selection.empty(), selection;
};
var redoState = function redoState(node, selection) {
var _getValueInMap, _getValueInMap2;
var h = (_getValueInMap = getValueInMap(node, history)) != null ? _getValueInMap : [],
i = (_getValueInMap2 = getValueInMap(node, historyIndex)) != null ? _getValueInMap2 : toCount(h) - 1,
j;
if (!(j = h[i + 1])) {
return restoreSelection(node, h[i][1], selection);
}
i++;
setValueInMap(node, i, historyIndex);
return setHTML(node, j[0]), restoreSelection(node, j[1], selection);
};
var resetState = function resetState(node, selection) {
letValueInMap(node, history);
letValueInMap(node, historyIndex);
return saveState(node, selection);
};
// <https://stackoverflow.com/a/13950376/1163000>
var restoreSelection = function restoreSelection(node, store, selection) {
var index = 0,
range = _setRange();
range.setStart(node, 0);
range.collapse(true);
var exit,
hasStart,
nodeCurrent,
nodeStack = [node];
while (!exit && (nodeCurrent = nodeStack.pop())) {
if (3 === getType(nodeCurrent)) {
var indexNext = index + toCount(nodeCurrent);
if (!hasStart && store[0] >= index && store[0] <= indexNext) {
range.setStart(nodeCurrent, store[0] - index);
hasStart = true;
}
if (hasStart && store[1] >= index && store[1] <= indexNext) {
exit = true;
range.setEnd(nodeCurrent, store[1] - index);
}
index = indexNext;
} else {
forEachArray(getChildren(nodeCurrent, null, 1), function (v) {
return nodeStack.push(v);
});
}
}
return setSelection(node, range, letSelection(node, selection));
};
// <https://stackoverflow.com/a/13950376/1163000>
var saveSelection = function saveSelection(node, selection) {
var range = (_getSelection()).getRangeAt(0),
rangeClone = range.cloneRange();
rangeClone.selectNodeContents(node);
rangeClone.setEnd(range.startContainer, range.startOffset);
var start = toCount(rangeClone + "");
return [start, start + toCount(range + "")];
};
var saveState = function saveState(node, selection) {
var _getValueInMap3, _getValueInMap4, _getHTML;
var h = (_getValueInMap3 = getValueInMap(node, history)) != null ? _getValueInMap3 : [],
i = (_getValueInMap4 = getValueInMap(node, historyIndex)) != null ? _getValueInMap4 : toCount(h) - 1,
j,
v = (_getHTML = getHTML(node)) != null ? _getHTML : "";
j = hasSelection(node, selection) ? saveSelection(node) : [];
if (h[i] && v === h[i][0] && j[0] === h[i][1][0] && j[1] === h[i][1][1]) {
return node; // No change
}
// Trim future history if `undoState()` was used
if (i < toCount(h) - 1) {
h.splice(i + 1);
}
h.push([v, j, now()]);
setValueInMap(node, h, history);
setValueInMap(node, ++i, historyIndex);
return node;
};
var selectTo = function selectTo(node, mode, selection) {
selection = selection || _getSelection();
letSelection(node, selection);
var range = _setRange();
range.selectNodeContents(node);
selection = setSelection(node, range, selection);
if (1 === mode) {
selection.collapseToEnd();
} else if (-1 === mode) {
selection.collapseToStart();
} else;
};
// The `node` parameter is currently not in use
var selectToNone = function selectToNone(node, selection) {
selection = selection || _getSelection();
// selection.removeAllRanges();
if (selection.rangeCount) {
selection.removeRange(selection.getRangeAt(0));
}
return selection;
};
// The `node` parameter is currently not in use
var setSelection = function setSelection(node, range, selection) {
selection = selection || _getSelection();
if (isArray(range)) {
return restoreSelection(node, range, selection);
}
return selection.addRange(range), selection;
};
var undoState = function undoState(node, selection) {
var _getValueInMap5, _getValueInMap6;
var h = (_getValueInMap5 = getValueInMap(node, history)) != null ? _getValueInMap5 : [],
i = (_getValueInMap6 = getValueInMap(node, historyIndex)) != null ? _getValueInMap6 : toCount(h) - 1,
j;
if (!(j = h[i - 1])) {
return restoreSelection(node, h[i][1], selection);
}
i--;
setValueInMap(node, i, historyIndex);
return setHTML(node, j[0]), restoreSelection(node, j[1], selection);
};
function _toArray(iterable) {
return Array.from(iterable);
}
var clearTimeout = W.clearTimeout,
setTimeout = W.setTimeout; // For better minification
var debounce = function debounce(task, time) {
var stickyTime = isInteger(time) && time >= 0,
timer;
return [function () {
var _this = this;
timer && clearTimeout(timer);
var lot = _toArray(arguments);
if (!stickyTime) {
time = lot.shift();
}
timer = setTimeout(function () {
return task.apply(_this, lot);
}, time);
}, function () {
timer = clearTimeout(timer);
}];
};
var delay = function delay(task, time) {
var stickyTime = isInteger(time) && time >= 0,
timer;
return [function () {
var _this2 = this;
var lot = _toArray(arguments);
if (!stickyTime) {
time = lot.shift();
}
timer = setTimeout(function () {
return task.apply(_this2, lot);
}, time);
}, function () {
timer && clearTimeout(timer);
}];
};
var getRect = function getRect(node) {
var h, rect, w, x, y, X, Y;
if (isWindow(node)) {
x = node.pageXOffset || R.scrollLeft || B.scrollLeft;
y = node.pageYOffset || R.scrollTop || B.scrollTop;
w = node.innerWidth;
h = node.innerHeight;
} else {
rect = node.getBoundingClientRect();
x = rect.left;
y = rect.top;
w = rect.width;
h = rect.height;
X = rect.right;
Y = rect.bottom;
}
return [x, y, w, h, X, Y];
};
var getScroll = function getScroll(node) {
return [node.scrollLeft, node.scrollTop];
};
var setScroll = function setScroll(node, data) {
node.scrollLeft = data[0];
node.scrollTop = data[1];
return node;
};
function hook($, $$) {
$$ = $$ || $;
$$.fire = function (event, data, that) {
var $ = this,
hooks = $.hooks;
if (!isSet(hooks[event])) {
return $;
}
return forEachArray(hooks[event], function (v) {
v.apply(that || $, data);
}), $;
};
$$.off = function (event, task) {
var $ = this,
hooks = $.hooks;
if (!isSet(event)) {
return hooks = {}, $;
}
if (isSet(hooks[event])) {
if (isSet(task)) {
var j = toCount(hooks[event]);
// Clean-up empty hook(s)
if (0 === j) {
delete hooks[event];
} else {
for (var i = 0; i < j; ++i) {
if (task === hooks[event][i]) {
hooks[event].splice(i, 1);
break;
}
}
}
} else {
delete hooks[event];
}
}
return $;
};
$$.on = function (event, task) {
var $ = this,
hooks = $.hooks;
if (!isSet(hooks[event])) {
hooks[event] = [];
}
if (isSet(task)) {
hooks[event].push(task);
}
return $;
};
return $.hooks = {}, $;
}
var offEvent = function offEvent(name, node, then) {
node.removeEventListener(name, then);
};
var offEventDefault = function offEventDefault(e) {
return e && e.preventDefault();
};
var offEventPropagation = function offEventPropagation(e) {
return e && e.stopPropagation();
};
var onEvent = function onEvent(name, node, then, options) {
if (options === void 0) {
options = false;
}
node.addEventListener(name, then, options);
};
var isPattern = function isPattern(pattern) {
return isInstance(pattern, RegExp);
};
var toPattern = function toPattern(pattern, opt) {
if (isPattern(pattern)) {
return pattern;
}
return new RegExp(pattern, isSet(opt) ? opt : 'g');
};
var EVENT_DOWN = 'down';
var EVENT_MOVE = 'move';
var EVENT_UP = 'up';
var EVENT_BLUR = 'blur';
var EVENT_CUT = 'cut';
var EVENT_FOCUS = 'focus';
var EVENT_INPUT = 'input';
var EVENT_INVALID = 'invalid';
var EVENT_KEY = 'key';
var EVENT_KEY_DOWN = EVENT_KEY + EVENT_DOWN;
var EVENT_MOUSE = 'mouse';
var EVENT_MOUSE_DOWN = EVENT_MOUSE + EVENT_DOWN;
var EVENT_MOUSE_MOVE = EVENT_MOUSE + EVENT_MOVE;
var EVENT_MOUSE_UP = EVENT_MOUSE + EVENT_UP;
var EVENT_PASTE = 'paste';
var EVENT_RESET = 'reset';
var EVENT_RESIZE = 'resize';
var EVENT_SCROLL = 'scroll';
var EVENT_SUBMIT = 'submit';
var EVENT_TOUCH = 'touch';
var EVENT_TOUCH_END = EVENT_TOUCH + 'end';
var EVENT_TOUCH_MOVE = EVENT_TOUCH + EVENT_MOVE;
var EVENT_TOUCH_START = EVENT_TOUCH + 'start';
var EVENT_WHEEL = 'wheel';
var KEY_DOWN = 'Down';
var KEY_LEFT = 'Left';
var KEY_RIGHT = 'Right';
var KEY_UP = 'Up';
var KEY_ARROW = 'Arrow';
var KEY_ARROW_DOWN = KEY_ARROW + KEY_DOWN;
var KEY_ARROW_LEFT = KEY_ARROW + KEY_LEFT;
var KEY_ARROW_RIGHT = KEY_ARROW + KEY_RIGHT;
var KEY_ARROW_UP = KEY_ARROW + KEY_UP;
var KEY_BEGIN = 'Home';
var KEY_DELETE_LEFT = 'Backspace';
var KEY_DELETE_RIGHT = 'Delete';
var KEY_END = 'End';
var KEY_ENTER = 'Enter';
var KEY_ESCAPE = 'Escape';
var KEY_PAGE = 'Page';
var KEY_PAGE_DOWN = KEY_PAGE + KEY_DOWN;
var KEY_PAGE_UP = KEY_PAGE + KEY_UP;
var KEY_TAB = 'Tab';
var KEY_Y = 'y';
var KEY_Z = 'z';
var OPTION_SELF = 0;
var OPTION_TEXT = 1;
var TOKEN_CONTENTEDITABLE = 'contenteditable';
var TOKEN_DISABLED = 'disabled';
var TOKEN_FALSE = 'false';
var TOKEN_GROUP = 'group';
var TOKEN_INVALID = 'invalid';
var TOKEN_OPTGROUP = 'opt' + TOKEN_GROUP;
var TOKEN_READONLY = 'readonly';
var TOKEN_READ_ONLY = 'readOnly';
var TOKEN_REQUIRED = 'required';
var TOKEN_SELECTED = 'selected';
var TOKEN_TABINDEX = 'tabindex';
var TOKEN_TAB_INDEX = 'tabIndex';
var TOKEN_TEXT = 'text';
var TOKEN_TRUE = 'true';
var TOKEN_VALUE = 'value';
var TOKEN_VALUES = TOKEN_VALUE + 's';
var TOKEN_VISIBILITY = 'visibility';
var VALUE_SELF = 0;
var VALUE_TEXT = 1;
var VALUE_X = 2;
var filter = debounce(function ($, input, _options, selectOnly) {
var query = isString(input) ? input : getText(input) || "",
q = toCaseLower(query),
_mask = $._mask,
mask = $.mask,
self = $.self,
state = $.state,
options = _mask.options,
pattern = self.pattern,
strict = state.strict,
option;
var count = _options.count();
if (selectOnly) {
forEachMap(_options, function (v) {
if ("" !== q && (q === toCaseLower(getText(v[2]).replace(/\u200C/g, "")).slice(0, toCount(q)) || q === toCaseLower(getOptionValue(v[2])).slice(0, toCount(q))) && !getAria(v[2], TOKEN_DISABLED)) {
selectToOption(v[2], $);
return 0;
}
--count;
});
} else {
forEachMap(_options, function (v) {
if ("" === q || hasValue(q, toCaseLower(getText(v[2]).replace(/\u200C/g, "") + '\t' + getOptionValue(v[2])))) {
v[2].hidden = false;
} else {
v[2].hidden = true;
--count;
}
});
options.hidden = !count;
selectToOptionsNone($);
if (strict) {
// Silently select the first option without affecting the currently typed query and focus/select state
if (count && "" !== q && (option = goToOptionFirst($))) {
letAria(mask, TOKEN_INVALID);
setAria(option, TOKEN_SELECTED, true);
option.$[OPTION_SELF][TOKEN_SELECTED] = true;
setValue(self, getOptionValue(option));
} else {
// No other option(s) are available to query
if ("" !== q) {
setAria(mask, TOKEN_INVALID, true);
} else {
letAria(mask, TOKEN_INVALID);
}
setValue(self, "");
}
} else {
letAria(mask, TOKEN_INVALID);
setValue(self, query);
if (pattern) {
if (!count && "" !== q && !toPattern('^' + pattern + '$', "").test(query)) {
setAria(mask, TOKEN_INVALID, true);
}
}
}
}
$.fire('search', [query = "" !== query ? query : null]);
var call = state.options;
// Only fetch when no other option(s) are available to query, or when the current search query is empty
if ((0 === count || "" === q) && isFunction(call)) {
setAria(mask, 'busy', true);
call = call.call($, query);
if (isInstance(call, Promise)) {
call.then(function (v) {
createOptions($, v);
letAria(mask, 'busy');
$.fire('load', [query, $[TOKEN_VALUES]])[goToOptionFirst($) ? 'enter' : 'exit']().fit();
});
} else {
createOptions($, call);
}
}
})[0];
var _delay = delay(function (picker) {
letAria(picker.mask, TOKEN_INVALID);
}),
_delay2 = _maybeArrayLike(_slicedToArray, _delay, 2),
letError = _delay2[0],
letErrorAbort = _delay2[1];
var setError = function setError(picker) {
var mask = picker.mask,
state = picker.state,
time = state.time,
error = time.error;
if (isInteger(error) && error > 0) {
setAria(mask, TOKEN_INVALID, true);
}
};
var _delay3 = delay(function ($) {
saveState($);
}, 1),
_delay4 = _maybeArrayLike(_slicedToArray, _delay3, 1),
saveStateLazy = _delay4[0];
var _delay5 = delay(function (picker) {
var _mask = picker._mask,
input = _mask.input;
toggleHintByValue(picker, getText(input, 0));
}),
_delay6 = _maybeArrayLike(_slicedToArray, _delay5, 1),
toggleHint = _delay6[0];
var toggleHintByValue = function toggleHintByValue(picker, value) {
var _mask = picker._mask,
hint = _mask.hint;
value ? setStyle(hint, TOKEN_VISIBILITY, 'hidden') : letStyle(hint, TOKEN_VISIBILITY);
};
var name = 'OptionPicker';
function createOptions($, options) {
var map = isInstance(options, Map) ? options : new Map();
if (isArray(options)) {
forEachArray(options, function (option) {
if (isArray(option)) {
var _option$, _option$2, _option$1$TOKEN_VALUE;
option[0] = (_option$ = option[0]) != null ? _option$ : "";
option[1] = (_option$2 = option[1]) != null ? _option$2 : {};
setValueInMap(_toValue((_option$1$TOKEN_VALUE = option[1][TOKEN_VALUE]) != null ? _option$1$TOKEN_VALUE : option[0]), option, map);
} else {
setValueInMap(_toValue(option), [option, {}], map);
}
});
} else if (isObject(options, 0)) {
forEachObject(options, function (v, k) {
if (isArray(v)) {
var _v$, _v$2, _v$1$TOKEN_VALUE;
options[k][0] = (_v$ = v[0]) != null ? _v$ : "";
options[k][1] = (_v$2 = v[1]) != null ? _v$2 : {};
setValueInMap(_toValue((_v$1$TOKEN_VALUE = v[1][TOKEN_VALUE]) != null ? _v$1$TOKEN_VALUE : k), v, map);
} else {
setValueInMap(_toValue(k), [v, {}], map);
}
});
}
var _options = $._options,
self = $.self,
state = $.state;
state.n;
var r = [],
value = getValue(self);
// Reset the option(s) data, but leave the typed query in place, and do not fire the `let.options` hook
_options.let(null, 0, 0);
forEachMap(map, function (v, k) {
var _v$1$TOKEN_VALUE3;
if (isArray(v) && v[1] && (!getState(v[1], 'active') || v[1].active) && v[1].mark) {
var _v$1$TOKEN_VALUE2;
r.push((_v$1$TOKEN_VALUE2 = v[1][TOKEN_VALUE]) != null ? _v$1$TOKEN_VALUE2 : k);
}
// Set the option data, but do not fire the `set.option` hook
_options.set(_toValue(isArray(v) && v[1] ? (_v$1$TOKEN_VALUE3 = v[1][TOKEN_VALUE]) != null ? _v$1$TOKEN_VALUE3 : k : k), v, 0);
});
if (!isFunction(state.options)) {
state.options = map;
}
if (0 === toCount(r)) {
// If there is no selected option(s), get it from the current value
if (hasKeyInMap(_toValue(value), map)) {
return [value];
}
// Or get it from the first option
if (value = getOptionSelected($)) {
return [getOptionValue(value)];
}
}
return r;
}
function focusTo(node) {
return node.focus(), node;
}
function focusToOption(option, picker) {
if (option) {
return focusTo(option), option;
}
}
function focusToOptionFirst(picker, k) {
var option;
if (option = goToOptionFirst(picker, k)) {
return focusToOption(option);
}
}
function focusToOptionLast(picker) {
return focusToOptionFirst(picker, 'Last');
}
function getOptionNext(option) {
var optionNext = getNext(option),
optionParent;
// Skip disabled and hidden option(s)…
while (optionNext && (getAria(optionNext, TOKEN_DISABLED) || optionNext.hidden)) {
optionNext = getNext(optionNext);
}
if (optionNext) {
// Next option is a group?
if (TOKEN_GROUP === getRole(optionNext)) {
optionNext = getChildFirst(optionNext);
}
// Is the last option?
} else {
// Is in a group?
if ((optionParent = getParent(option)) && TOKEN_GROUP === getRole(optionParent)) {
optionNext = getNext(optionParent);
}
// Next option is a group?
if (optionNext && TOKEN_GROUP === getRole(optionNext)) {
optionNext = getChildFirst(optionNext);
}
}
// Skip disabled and hidden option(s)…
while (optionNext && (getAria(optionNext, TOKEN_DISABLED) || optionNext.hidden)) {
optionNext = getNext(optionNext);
}
return optionNext;
}
function getOptionPrev(option) {
var optionParent,
optionPrev = getPrev(option);
// Skip disabled and hidden option(s)…
while (optionPrev && (getAria(optionPrev, TOKEN_DISABLED) || optionPrev.hidden)) {
optionPrev = getPrev(optionPrev);
}
if (optionPrev) {
// Previous option is a group?
if (TOKEN_GROUP === getRole(optionPrev)) {
optionPrev = getChildLast(optionPrev);
}
// Is the first option?
} else {
// Is in a group?
if ((optionParent = getParent(option)) && TOKEN_GROUP === getRole(optionParent)) {
optionPrev = getPrev(optionParent);
}
// Previous option is a group?
if (optionPrev && TOKEN_GROUP === getRole(optionPrev)) {
optionPrev = getChildLast(optionPrev);
}
}
// Skip disabled and hidden option(s)…
while (optionPrev && (getAria(optionPrev, TOKEN_DISABLED) || optionPrev.hidden)) {
optionPrev = getPrev(optionPrev);
}
return optionPrev;
}
function getOptionSelected($, strict) {
var _options = $._options,
self = $.self,
selected;
forEachMap(_options, function (v, k) {
if (isArray(v) && v[2] && !getAria(v[2], TOKEN_DISABLED) && getAria(v[2], TOKEN_SELECTED)) {
return selected = v[2], 0;
}
});
if (!isSet(selected) && (strict || !isInput(self))) {
// Select the first option
forEachMap(_options, function (v, k) {
return selected = v[2], 0;
});
}
return selected;
}
function getOptionValue(option, parseValue) {
return getValue(option, parseValue);
}
function getOptions(self) {
var map = new Map();
var item,
items,
itemsParent,
selected = [],
value = getValue(self);
if (isInput(self)) {
items = (itemsParent = self.list) ? getChildren(itemsParent) : [];
} else {
items = getChildren(itemsParent = self);
}
forEachArray(items, function (v, k) {
var attributes = getAttributes(v);
attributes.active = true;
attributes.mark = false;
if (hasState(attributes, TOKEN_DISABLED)) {
attributes.active = "" === attributes[TOKEN_DISABLED] ? false : !!attributes[TOKEN_DISABLED];
delete attributes[TOKEN_DISABLED];
} else if (hasState(attributes, TOKEN_SELECTED)) {
attributes.mark = "" === attributes[TOKEN_SELECTED] ? true : !!attributes[TOKEN_SELECTED];
delete attributes[TOKEN_SELECTED];
}
if (TOKEN_OPTGROUP === ge