Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

datalist-polyfill

Package Overview
Dependencies
Maintainers
1
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

datalist-polyfill - npm Package Compare versions

Comparing version 1.17.0 to 1.18.0

2

bower.json
{
"name": "datalist-polyfill",
"description": "A minimal and dependency-free vanilla JavaScript datalist polyfill. Supports all standard's functionality as well as mimics other browsers behavior.",
"version": "1.17.0",
"version": "1.18.0",
"homepage": "https://github.com/mfranzke/datalist-polyfill",

@@ -6,0 +6,0 @@ "authors": [{

@@ -9,2 +9,11 @@ # Changelog

## [1.18.0] - 2018-07-10
### Changed
- Defined the system-font for the demo-page
- Renamed some variables to some more meaningful names
- Cleanup on some unnecessary variables & comments
### Removed
- Removed an old separation in between eventTarget-Tagnames of select and option, that was integrated due to the mouse-event, which has been replaced again a while ago
## [1.17.0] - 2018-07-07

@@ -11,0 +20,0 @@ ### Added

@@ -106,8 +106,8 @@ /*

if (input.value !== '') {
var dataList = datalistNeedsAnUpdate;
// Prepare the options and toggle the visiblity afterwards
toggleVisibility(
prepOptions(dataList, input),
dataList.getElementsByClassName(classNamePolyfillingSelect)[0]
prepOptions(datalistNeedsAnUpdate, input).length,
datalistNeedsAnUpdate.getElementsByClassName(
classNamePolyfillingSelect
)[0]
);

@@ -121,46 +121,44 @@ }

var inputInputList = function(event) {
var eventTarget = event.target,
eventTargetTagName = eventTarget.tagName.toLowerCase(),
dataList = eventTarget.list;
var input = event.target,
datalist = input.list;
// Check for whether the events target was an input datalist and still check for an existing instance
// Check for whether the events target was an input and still check for an existing instance of the datalist
if (
eventTargetTagName &&
eventTargetTagName === 'input' &&
dataList !== null
input.tagName &&
input.tagName.toLowerCase() === 'input' &&
datalist !== null
) {
var dataListSelect =
dataList.getElementsByClassName(classNamePolyfillingSelect)[0] ||
setUpPolyfillingSelect(eventTarget, dataList);
// Creating the select if there's no instance so far (e.g. because of that it hasn't been handled or it has been dynamically inserted)
var datalistSelect =
datalist.getElementsByClassName(classNamePolyfillingSelect)[0] ||
setUpPolyfillingSelect(input, datalist);
// Still check for an existing instance
if (dataListSelect !== undefined) {
if (datalistSelect !== undefined) {
var visible = false,
inputValue = eventTarget.value,
keyOpen = event.keyCode === keyUP || event.keyCode === keyDOWN;
// On an ESC or ENTER key press within the input, let's break here and afterwards hide the datalist select, and if the input contains a value
// On an ESC or ENTER key press within the input, let's break here and afterwards hide the datalist select, but if the input contains a value or one of the opening keys have been pressed ...
if (
event.keyCode !== keyESC &&
event.keyCode !== keyENTER &&
(inputValue !== '' || keyOpen)
(input.value !== '' || keyOpen)
) {
// Prepare the options
if (prepOptions(dataList, eventTarget)) {
// ... prepare the options
if (prepOptions(datalist, input).length > 0) {
visible = true;
}
var dataListSelectOptionsLength = dataListSelect.options.length,
firstEntry = 0,
lastEntry = dataListSelectOptionsLength - 1;
var firstEntry = 0,
lastEntry = datalistSelect.options.length - 1;
// ... preselect best fitting index
if (touched) {
// Preselect best fitting index
dataListSelect.selectedIndex = firstEntry;
datalistSelect.selectedIndex = firstEntry;
} else if (keyOpen) {
dataListSelect.selectedIndex =
datalistSelect.selectedIndex =
event.keyCode === keyUP ? lastEntry : firstEntry;
// On arrow up or down keys, focus the select
dataListSelect.focus();
// ... and on arrow up or down keys, focus the select
datalistSelect.focus();
}

@@ -170,3 +168,3 @@ }

// Toggle the visibility of the datalist select according to previous checks
toggleVisibility(visible, dataListSelect);
toggleVisibility(visible, datalistSelect);
}

@@ -177,3 +175,3 @@ }

// Function for preparing and sorting the options/suggestions
var prepOptions = function(dataList, input) {
var prepOptions = function(datalist, input) {
if (typeof obs !== 'undefined') {

@@ -183,6 +181,6 @@ obs.disconnect();

var dataListSelect =
dataList.getElementsByClassName(classNamePolyfillingSelect)[0] ||
setUpPolyfillingSelect(input, dataList),
dataListOptions = dataList.querySelectorAll('option:not(:disabled)'),
var // Creating the select if there's no instance so far (e.g. because of that it hasn't been handled or it has been dynamically inserted)
datalistSelect =
datalist.getElementsByClassName(classNamePolyfillingSelect)[0] ||
setUpPolyfillingSelect(input, datalist),
inputValue = input.value,

@@ -197,7 +195,6 @@ newSelectValues = document.createDocumentFragment(),

// ... create an array out of the options list
var nodeArray = Array.prototype.slice.call(dataListOptions);
// ... sort all entries and
nodeArray
// Create an array out of the options list
Array.prototype.slice
.call(datalist.querySelectorAll('option:not(:disabled)'))
// ... sort all entries and
.sort(function(a, b) {

@@ -224,3 +221,3 @@ return a.value.localeCompare(b.value);

// The innertext should be value / text in case they are different
// The innertext should be 'value seperator text' in case they are different
if (

@@ -246,18 +243,17 @@ text &&

// Input the options fragment into the datalists select
dataListSelect.appendChild(newSelectValues);
datalistSelect.appendChild(newSelectValues);
var dataListSelectOptionsLength = dataListSelect.options.length;
var datalistSelectOptionsLength = datalistSelect.options.length;
dataListSelect.size =
dataListSelectOptionsLength > 10 ? 10 : dataListSelectOptionsLength;
dataListSelect.multiple = !touched && dataListSelectOptionsLength < 2;
datalistSelect.size =
datalistSelectOptionsLength > 10 ? 10 : datalistSelectOptionsLength;
datalistSelect.multiple = !touched && datalistSelectOptionsLength < 2;
// Input the unused options as siblings next to the select - and differentiate in between the regular, and the IE9 fix syntax upfront
var dataListAppend =
dataList.getElementsByClassName('ie9_fix')[0] || dataList;
(datalist.getElementsByClassName('ie9_fix')[0] || datalist).appendChild(
disabledValues
);
dataListAppend.appendChild(disabledValues);
if (typeof obs !== 'undefined') {
obs.observe(dataList, {
obs.observe(datalist, {
childList: true

@@ -267,3 +263,3 @@ });

return dataListSelectOptionsLength;
return datalistSelect.options;
};

@@ -273,56 +269,53 @@

var changesInputList = function(event) {
var eventTarget = event.target,
eventTargetTagName = eventTarget.tagName.toLowerCase(),
dataList = eventTarget.list;
var input = event.target,
datalist = input.list;
// Check for whether the events target was an input datalist and still check for an existing instance
// Check for whether the events target was an input and still check for an existing instance of the datalist
if (
eventTargetTagName &&
eventTargetTagName === 'input' &&
dataList !== null
input.tagName &&
input.tagName.toLowerCase() === 'input' &&
datalist !== null
) {
var eventType = event.type,
// Creating the select if there's no instance so far (e.g. because of that it hasn't been handled or it has been dynamically inserted)
dataListSelect =
dataList.getElementsByClassName(classNamePolyfillingSelect)[0] ||
setUpPolyfillingSelect(eventTarget, dataList),
datalistSelect =
datalist.getElementsByClassName(classNamePolyfillingSelect)[0] ||
setUpPolyfillingSelect(input, datalist),
// Either have the select set to the state to get displayed in case of that it would have been focused or because it's the target on the inputs blur - and check for general existance of any option as suggestions
visible =
dataListSelect &&
dataListSelect.querySelector('option:not(:disabled)') &&
((eventType === 'focusin' && eventTarget.value !== '') ||
(event.relatedTarget && event.relatedTarget === dataListSelect));
datalistSelect &&
datalistSelect.querySelector('option:not(:disabled)') &&
((eventType === 'focusin' && input.value !== '') ||
(event.relatedTarget && event.relatedTarget === datalistSelect));
// Test for whether this input has already been enhanced by the polyfill
if (
(' ' + eventTarget.className + ' ').indexOf(
' ' + classNameInput + ' '
) < 0
(' ' + input.className + ' ').indexOf(' ' + classNameInput + ' ') < 0
) {
// We'd like to prevent autocomplete on the input datalist field
eventTarget.setAttribute('autocomplete', 'off');
input.setAttribute('autocomplete', 'off');
// WAI ARIA attributes
eventTarget.setAttribute('role', 'textbox');
eventTarget.setAttribute('aria-haspopup', 'true');
eventTarget.setAttribute('aria-autocomplete', 'list');
eventTarget.setAttribute('aria-owns', eventTarget.getAttribute('list'));
input.setAttribute('role', 'textbox');
input.setAttribute('aria-haspopup', 'true');
input.setAttribute('aria-autocomplete', 'list');
input.setAttribute('aria-owns', input.getAttribute('list'));
// Bind the keyup event on the related datalists input
if (eventType === 'focusin') {
eventTarget.addEventListener('keyup', inputInputList);
input.addEventListener('keyup', inputInputList);
eventTarget.addEventListener('focusout', changesInputList, true);
input.addEventListener('focusout', changesInputList, true);
} else if (eventType === 'blur') {
eventTarget.removeEventListener('keyup', inputInputList);
input.removeEventListener('keyup', inputInputList);
eventTarget.removeEventListener('focusout', changesInputList, true);
input.removeEventListener('focusout', changesInputList, true);
}
// Add class for identifying that this input is even already being polyfilled
eventTarget.className += ' ' + classNameInput;
input.className += ' ' + classNameInput;
}
// Toggle the visibility of the datalist select according to previous checks
toggleVisibility(visible, dataListSelect);
toggleVisibility(visible, datalistSelect);
}

@@ -332,36 +325,29 @@ };

// Define function for setting up the polyfilling select
var setUpPolyfillingSelect = function(input, dataList) {
var setUpPolyfillingSelect = function(input, datalist) {
// Check for whether it's of one of the supported input types defined at the beginning
if (supportedTypes.indexOf(input.type) > -1) {
// Still check for an existing instance
if (dataList !== null) {
var message = dataList.title,
rects = input.getClientRects(),
if (datalist !== null) {
var rects = input.getClientRects(),
// Measurements
inputStyles = window.getComputedStyle(input),
inputStyleMarginRight = parseFloat(
inputStyles.getPropertyValue('margin-right')
),
inputStyleMarginLeft = parseFloat(
inputStyles.getPropertyValue('margin-left')
),
dataListSelect = document.createElement('select');
datalistSelect = document.createElement('select');
// Setting a class for easier selecting that select afterwards
dataListSelect.setAttribute('class', classNamePolyfillingSelect);
// Setting a class for easier identifying that select afterwards
datalistSelect.setAttribute('class', classNamePolyfillingSelect);
// Set general styling related definitions
dataListSelect.style.position = 'absolute';
datalistSelect.style.position = 'absolute';
// Initially hiding the datalist select
toggleVisibility(false, dataListSelect);
toggleVisibility(false, datalistSelect);
// The select itself shouldn't be a possible target for tabbing
dataListSelect.setAttribute('tabindex', '-1');
datalistSelect.setAttribute('tabindex', '-1');
// WAI ARIA attributes
dataListSelect.setAttribute('aria-live', 'polite');
dataListSelect.setAttribute('role', 'listbox');
datalistSelect.setAttribute('aria-live', 'polite');
datalistSelect.setAttribute('role', 'listbox');
if (!touched) {
dataListSelect.setAttribute('aria-multiselectable', 'false');
datalistSelect.setAttribute('aria-multiselectable', 'false');
}

@@ -371,16 +357,22 @@

if (inputStyles.getPropertyValue('display') === 'block') {
dataListSelect.style.marginTop =
datalistSelect.style.marginTop =
'-' + inputStyles.getPropertyValue('margin-bottom');
} else {
if (inputStyles.getPropertyValue('direction') === 'rtl') {
dataListSelect.style.marginRight =
'-' + (rects[0].width + inputStyleMarginLeft) + 'px';
datalistSelect.style.marginRight =
'-' +
(rects[0].width +
parseFloat(inputStyles.getPropertyValue('margin-left'))) +
'px';
} else {
dataListSelect.style.marginLeft =
'-' + (rects[0].width + inputStyleMarginRight) + 'px';
datalistSelect.style.marginLeft =
'-' +
(rects[0].width +
parseFloat(inputStyles.getPropertyValue('margin-right'))) +
'px';
}
dataListSelect.style.marginTop =
datalistSelect.style.marginTop =
parseInt(
rects[0].height + (input.offsetTop - dataList.offsetTop),
rects[0].height + (input.offsetTop - datalist.offsetTop),
10

@@ -390,7 +382,7 @@ ) + 'px';

// Set the polyfilling selects border-radius equally as the one by the polyfilled input
dataListSelect.style.borderRadius = inputStyles.getPropertyValue(
// Set the polyfilling selects border-radius equally to the one by the polyfilled input
datalistSelect.style.borderRadius = inputStyles.getPropertyValue(
'border-radius'
);
dataListSelect.style.minWidth = rects[0].width + 'px';
datalistSelect.style.minWidth = rects[0].width + 'px';

@@ -401,3 +393,3 @@ if (touched) {

// ... and it's first entry should contain the localized message to select an entry
messageElement.innerText = message;
messageElement.innerText = datalist.title;
// ... and disable this option, as it shouldn't get selected by the user

@@ -408,20 +400,19 @@ messageElement.disabled = true;

// ... and finally insert it into the select
dataListSelect.appendChild(messageElement);
datalistSelect.appendChild(messageElement);
}
// Add select to datalist element ...
dataList.appendChild(dataListSelect);
datalist.appendChild(datalistSelect);
// ... and our upfollowing function to the change event
// ... and our upfollowing functions to the related event
if (touched) {
dataListSelect.addEventListener('change', changeDataListSelect);
datalistSelect.addEventListener('change', changeDataListSelect);
} else {
dataListSelect.addEventListener('click', changeDataListSelect);
datalistSelect.addEventListener('click', changeDataListSelect);
}
dataListSelect.addEventListener('blur', changeDataListSelect);
dataListSelect.addEventListener('keydown', changeDataListSelect);
dataListSelect.addEventListener('keypress', datalistSelectKeyPress);
datalistSelect.addEventListener('blur', changeDataListSelect);
datalistSelect.addEventListener('keydown', changeDataListSelect);
datalistSelect.addEventListener('keypress', datalistSelectKeyPress);
return dataListSelect;
return datalistSelect;
}

@@ -433,18 +424,12 @@ }

var datalistSelectKeyPress = function(event) {
var eventTarget = event.target,
eventTargetTagName = eventTarget.tagName.toLowerCase();
var datalistSelect = event.target;
// Check for whether the events target was a select or an option
// Check for whether the events target was a select
if (
eventTargetTagName &&
(eventTargetTagName === 'select' || eventTargetTagName === 'option')
datalistSelect.tagName &&
datalistSelect.tagName.toLowerCase() === 'select'
) {
var select =
eventTargetTagName === 'select'
? eventTarget
: eventTarget.parentNode,
datalist = select.parentNode,
var datalist = datalistSelect.parentNode,
inputList = document.querySelector('input[list="' + datalist.id + '"]');
// Change or mouseup event or ENTER key
if (

@@ -473,18 +458,12 @@ inputList !== null &&

var changeDataListSelect = function(event) {
var eventTarget = event.target,
eventTargetTagName = eventTarget.tagName.toLowerCase();
var datalistSelect = event.target;
// Check for whether the events target was a select or an option
// Check for whether the events target was a select
if (
eventTargetTagName &&
(eventTargetTagName === 'select' || eventTargetTagName === 'option')
datalistSelect.tagName &&
datalistSelect.tagName.toLowerCase() === 'select'
) {
var select =
eventTargetTagName === 'select'
? eventTarget
: eventTarget.parentNode,
datalist = select.parentNode,
var datalist = datalistSelect.parentNode,
inputList = document.querySelector('input[list="' + datalist.id + '"]'),
selectValue = select.value,
message = datalist.title,
datalistSelectValue = datalistSelect.value,
eventType = event.type,

@@ -496,3 +475,3 @@ // ENTER and ESC

// On change, click or ENTER or TAB key, input the selects value into the input on a change within the list
// On change, click or after pressing ENTER or TAB key, input the selects value into the input on a change within the list
if (

@@ -504,5 +483,5 @@ inputList !== null &&

(event.keyCode === keyENTER || event.key === 'Tab'))) &&
typeof selectValue !== 'undefined' &&
selectValue.length > 0 &&
selectValue !== message
typeof datalistSelectValue !== 'undefined' &&
datalistSelectValue.length > 0 &&
datalistSelectValue !== datalist.title
) {

@@ -516,4 +495,6 @@ var lastSeperator, evt;

(lastSeperator = inputList.value.lastIndexOf(',')) > -1
? inputList.value.slice(0, lastSeperator) + ',' + selectValue
: (inputList.value = selectValue);
? inputList.value.slice(0, lastSeperator) +
',' +
datalistSelectValue
: (inputList.value = datalistSelectValue);

@@ -541,3 +522,3 @@ // Create and dispatch the input event; divided for IE9 usage

// Toggle the visibility of the datalist select according to previous checks
toggleVisibility(visible, select);
toggleVisibility(visible, datalistSelect);
}

@@ -547,9 +528,9 @@ };

// Toggle the visibility of the datalist select
var toggleVisibility = function(visible, dataListSelect) {
var toggleVisibility = function(visible, datalistSelect) {
if (visible) {
dataListSelect.removeAttribute('hidden');
datalistSelect.removeAttribute('hidden');
} else {
dataListSelect.setAttributeNode(document.createAttribute('hidden'));
datalistSelect.setAttributeNode(document.createAttribute('hidden'));
}
dataListSelect.setAttribute('aria-hidden', (!visible).toString());
datalistSelect.setAttribute('aria-hidden', (!visible).toString());
};

@@ -556,0 +537,0 @@

@@ -6,2 +6,2 @@ /*

*/
!function(){"use strict";if("list"in document.createElement("input")&&Boolean(document.createElement("datalist")&&window.HTMLDataListElement))return!1;!function(e){e&&e.prototype&&void 0===e.prototype.list&&Object.defineProperty(e.prototype,"list",{get:function(){return"object"==typeof this&&this instanceof e?document.getElementById(this.getAttribute("list")):null}})}(window.HTMLInputElement),function(e){e&&e.prototype&&void 0===e.prototype.options&&Object.defineProperty(e.prototype,"options",{get:function(){return"object"==typeof this&&this instanceof e?this.getElementsByTagName("option"):null}})}(window.HTMLElement);var e=!1,t=13,i=27,n=38,o=40,a=" / ",l=["text","email","number","search","tel","url"],r="polyfilled",s="polyfilling";window.addEventListener("touchstart",function t(){e=!0,window.removeEventListener("touchstart",t)});var u=window.MutationObserver||window.WebKitMutationObserver,d;void 0!==u&&(d=new u(function(e){var t=!1;if(e.forEach(function(e){for(var i=0;i<e.addedNodes.length;++i)"datalist"===e.target.tagName.toLowerCase()&&(t=e.target)}),t){var i=document.querySelector('[list="'+t.id+'"]');if(""!==i.value){var n=t;g(c(n,i),n.getElementsByClassName("polyfilling")[0])}}}));var p=function(t){var i=t.target,n=i.tagName.toLowerCase(),o=i.list;if(n&&"input"===n&&null!==o){var a=o.getElementsByClassName("polyfilling")[0]||f(i,o);if(void 0!==a){var l=!1,r=i.value,s=38===t.keyCode||40===t.keyCode;if(27!==t.keyCode&&13!==t.keyCode&&(""!==r||s)){c(o,i)&&(l=!0);var u=a.options.length,d=0,p=u-1;e?a.selectedIndex=0:s&&(a.selectedIndex=38===t.keyCode?p:0,a.focus())}g(l,a)}}},c=function(t,i){void 0!==d&&d.disconnect();var n=t.getElementsByClassName("polyfilling")[0]||f(i,t),o=t.querySelectorAll("option:not(:disabled)"),a=i.value,l=document.createDocumentFragment(),r=document.createDocumentFragment();"email"===i.type&&i.multiple&&(a=a.substring(a.lastIndexOf(",")+1)),Array.prototype.slice.call(o).sort(function(e,t){return e.value.localeCompare(t.value)}).forEach(function(e){var t=e.value;if(""!==t&&-1!==t.toLowerCase().indexOf(a.toLowerCase())&&!1===e.disabled){var i=e.getAttribute("label"),n=e.text,o=n.substr(0,t.length+" / ".length),s=t+" / ";n&&!i&&n!==t&&o!==s?e.innerText=t+" / "+n:e.text||(e.innerText=i||t),l.appendChild(e)}else r.appendChild(e)}),n.appendChild(l);var s=n.options.length;return n.size=s>10?10:s,n.multiple=!e&&s<2,(t.getElementsByClassName("ie9_fix")[0]||t).appendChild(r),void 0!==d&&d.observe(t,{childList:!0}),s},y=function(e){var t=e.target,i=t.tagName.toLowerCase(),n=t.list;if(i&&"input"===i&&null!==n){var o=e.type,a=n.getElementsByClassName("polyfilling")[0]||f(t,n),l=a&&a.querySelector("option:not(:disabled)")&&("focusin"===o&&""!==t.value||e.relatedTarget&&e.relatedTarget===a);(" "+t.className+" ").indexOf(" polyfilled ")<0&&(t.setAttribute("autocomplete","off"),t.setAttribute("role","textbox"),t.setAttribute("aria-haspopup","true"),t.setAttribute("aria-autocomplete","list"),t.setAttribute("aria-owns",t.getAttribute("list")),"focusin"===o?(t.addEventListener("keyup",p),t.addEventListener("focusout",y,!0)):"blur"===o&&(t.removeEventListener("keyup",p),t.removeEventListener("focusout",y,!0)),t.className+=" polyfilled"),g(l,a)}},f=function(t,i){if(l.indexOf(t.type)>-1&&null!==i){var n=i.title,o=t.getClientRects(),a=window.getComputedStyle(t),r=parseFloat(a.getPropertyValue("margin-right")),s=parseFloat(a.getPropertyValue("margin-left")),u=document.createElement("select");if(u.setAttribute("class","polyfilling"),u.style.position="absolute",g(!1,u),u.setAttribute("tabindex","-1"),u.setAttribute("aria-live","polite"),u.setAttribute("role","listbox"),e||u.setAttribute("aria-multiselectable","false"),"block"===a.getPropertyValue("display")?u.style.marginTop="-"+a.getPropertyValue("margin-bottom"):("rtl"===a.getPropertyValue("direction")?u.style.marginRight="-"+(o[0].width+s)+"px":u.style.marginLeft="-"+(o[0].width+r)+"px",u.style.marginTop=parseInt(o[0].height+(t.offsetTop-i.offsetTop),10)+"px"),u.style.borderRadius=a.getPropertyValue("border-radius"),u.style.minWidth=o[0].width+"px",e){var d=document.createElement("option");d.innerText=n,d.disabled=!0,d.setAttribute("class","message"),u.appendChild(d)}return i.appendChild(u),e?u.addEventListener("change",m):u.addEventListener("click",m),u.addEventListener("blur",m),u.addEventListener("keydown",m),u.addEventListener("keypress",v),u}},v=function(e){var t=e.target,i=t.tagName.toLowerCase();if(i&&("select"===i||"option"===i)){var n="select"===i?t:t.parentNode,o=n.parentNode,a=document.querySelector('input[list="'+o.id+'"]');null===a||!e.key||"Backspace"!==e.key&&1!==e.key.length||(a.focus(),"Backspace"===e.key?a.value=a.value.substr(0,a.value.length-1):a.value+=e.key,c(o,a))}},m=function(e){var t=e.target,i=t.tagName.toLowerCase();if(i&&("select"===i||"option"===i)){var n="select"===i?t:t.parentNode,o=n.parentNode,a=document.querySelector('input[list="'+o.id+'"]'),l=n.value,r=o.title,s=e.type,u="keydown"===s&&13!==e.keyCode&&27!==e.keyCode;if(null!==a&&("change"===s||"click"===s||"keydown"===s&&(13===e.keyCode||"Tab"===e.key))&&void 0!==l&&l.length>0&&l!==r){var d,p;a.value="email"===a.type&&a.multiple&&(d=a.value.lastIndexOf(","))>-1?a.value.slice(0,d)+","+l:a.value=l,"function"==typeof Event?p=new Event("input",{bubbles:!0}):(p=document.createEvent("Event"),p.initEvent("input",!0,!1)),a.dispatchEvent(p),"Tab"!==e.key&&a.focus(),u=!1}g(u,n)}},g=function(e,t){e?t.removeAttribute("hidden"):t.setAttributeNode(document.createAttribute("hidden")),t.setAttribute("aria-hidden",(!e).toString())};document.addEventListener("focusin",y,!0)}();
!function(){"use strict";if("list"in document.createElement("input")&&Boolean(document.createElement("datalist")&&window.HTMLDataListElement))return!1;!function(e){e&&e.prototype&&void 0===e.prototype.list&&Object.defineProperty(e.prototype,"list",{get:function(){return"object"==typeof this&&this instanceof e?document.getElementById(this.getAttribute("list")):null}})}(window.HTMLInputElement),function(e){e&&e.prototype&&void 0===e.prototype.options&&Object.defineProperty(e.prototype,"options",{get:function(){return"object"==typeof this&&this instanceof e?this.getElementsByTagName("option"):null}})}(window.HTMLElement);var e=!1,t=13,i=27,n=38,a=40,o=" / ",l=["text","email","number","search","tel","url"],r="polyfilled",s="polyfilling";window.addEventListener("touchstart",function t(){e=!0,window.removeEventListener("touchstart",t)});var u=window.MutationObserver||window.WebKitMutationObserver,d;void 0!==u&&(d=new u(function(e){var t=!1;if(e.forEach(function(e){for(var i=0;i<e.addedNodes.length;++i)"datalist"===e.target.tagName.toLowerCase()&&(t=e.target)}),t){var i=document.querySelector('[list="'+t.id+'"]');""!==i.value&&g(c(t,i).length,t.getElementsByClassName("polyfilling")[0])}}));var p=function(t){var i=t.target,n=i.list;if(i.tagName&&"input"===i.tagName.toLowerCase()&&null!==n){var a=n.getElementsByClassName("polyfilling")[0]||m(i,n);if(void 0!==a){var o=!1,l=38===t.keyCode||40===t.keyCode;if(27!==t.keyCode&&13!==t.keyCode&&(""!==i.value||l)){c(n,i).length>0&&(o=!0);var r=0,s=a.options.length-1;e?a.selectedIndex=0:l&&(a.selectedIndex=38===t.keyCode?s:0,a.focus())}g(o,a)}}},c=function(t,i){void 0!==d&&d.disconnect();var n=t.getElementsByClassName("polyfilling")[0]||m(i,t),a=i.value,o=document.createDocumentFragment(),l=document.createDocumentFragment();"email"===i.type&&i.multiple&&(a=a.substring(a.lastIndexOf(",")+1)),Array.prototype.slice.call(t.querySelectorAll("option:not(:disabled)")).sort(function(e,t){return e.value.localeCompare(t.value)}).forEach(function(e){var t=e.value;if(""!==t&&-1!==t.toLowerCase().indexOf(a.toLowerCase())&&!1===e.disabled){var i=e.getAttribute("label"),n=e.text,r=n.substr(0,t.length+" / ".length),s=t+" / ";n&&!i&&n!==t&&r!==s?e.innerText=t+" / "+n:e.text||(e.innerText=i||t),o.appendChild(e)}else l.appendChild(e)}),n.appendChild(o);var r=n.options.length;return n.size=r>10?10:r,n.multiple=!e&&r<2,(t.getElementsByClassName("ie9_fix")[0]||t).appendChild(l),void 0!==d&&d.observe(t,{childList:!0}),n.options},y=function(e){var t=e.target,i=t.list;if(t.tagName&&"input"===t.tagName.toLowerCase()&&null!==i){var n=e.type,a=i.getElementsByClassName("polyfilling")[0]||m(t,i),o=a&&a.querySelector("option:not(:disabled)")&&("focusin"===n&&""!==t.value||e.relatedTarget&&e.relatedTarget===a);(" "+t.className+" ").indexOf(" polyfilled ")<0&&(t.setAttribute("autocomplete","off"),t.setAttribute("role","textbox"),t.setAttribute("aria-haspopup","true"),t.setAttribute("aria-autocomplete","list"),t.setAttribute("aria-owns",t.getAttribute("list")),"focusin"===n?(t.addEventListener("keyup",p),t.addEventListener("focusout",y,!0)):"blur"===n&&(t.removeEventListener("keyup",p),t.removeEventListener("focusout",y,!0)),t.className+=" polyfilled"),g(o,a)}},m=function(t,i){if(l.indexOf(t.type)>-1&&null!==i){var n=t.getClientRects(),a=window.getComputedStyle(t),o=document.createElement("select");if(o.setAttribute("class","polyfilling"),o.style.position="absolute",g(!1,o),o.setAttribute("tabindex","-1"),o.setAttribute("aria-live","polite"),o.setAttribute("role","listbox"),e||o.setAttribute("aria-multiselectable","false"),"block"===a.getPropertyValue("display")?o.style.marginTop="-"+a.getPropertyValue("margin-bottom"):("rtl"===a.getPropertyValue("direction")?o.style.marginRight="-"+(n[0].width+parseFloat(a.getPropertyValue("margin-left")))+"px":o.style.marginLeft="-"+(n[0].width+parseFloat(a.getPropertyValue("margin-right")))+"px",o.style.marginTop=parseInt(n[0].height+(t.offsetTop-i.offsetTop),10)+"px"),o.style.borderRadius=a.getPropertyValue("border-radius"),o.style.minWidth=n[0].width+"px",e){var r=document.createElement("option");r.innerText=i.title,r.disabled=!0,r.setAttribute("class","message"),o.appendChild(r)}return i.appendChild(o),e?o.addEventListener("change",v):o.addEventListener("click",v),o.addEventListener("blur",v),o.addEventListener("keydown",v),o.addEventListener("keypress",f),o}},f=function(e){var t=e.target;if(t.tagName&&"select"===t.tagName.toLowerCase()){var i=t.parentNode,n=document.querySelector('input[list="'+i.id+'"]');null===n||!e.key||"Backspace"!==e.key&&1!==e.key.length||(n.focus(),"Backspace"===e.key?n.value=n.value.substr(0,n.value.length-1):n.value+=e.key,c(i,n))}},v=function(e){var t=e.target;if(t.tagName&&"select"===t.tagName.toLowerCase()){var i=t.parentNode,n=document.querySelector('input[list="'+i.id+'"]'),a=t.value,o=e.type,l="keydown"===o&&13!==e.keyCode&&27!==e.keyCode;if(null!==n&&("change"===o||"click"===o||"keydown"===o&&(13===e.keyCode||"Tab"===e.key))&&void 0!==a&&a.length>0&&a!==i.title){var r,s;n.value="email"===n.type&&n.multiple&&(r=n.value.lastIndexOf(","))>-1?n.value.slice(0,r)+","+a:n.value=a,"function"==typeof Event?s=new Event("input",{bubbles:!0}):(s=document.createEvent("Event"),s.initEvent("input",!0,!1)),n.dispatchEvent(s),"Tab"!==e.key&&n.focus(),l=!1}g(l,t)}},g=function(e,t){e?t.removeAttribute("hidden"):t.setAttributeNode(document.createAttribute("hidden")),t.setAttribute("aria-hidden",(!e).toString())};document.addEventListener("focusin",y,!0)}();
{
"name": "datalist-polyfill",
"version": "1.17.0",
"version": "1.18.0",
"description": "A minimal and dependency-free vanilla JavaScript datalist polyfill. Supports all standard's functionality as well as mimics other browsers behavior.",

@@ -5,0 +5,0 @@ "main": "datalist-polyfill.js",

@@ -24,3 +24,3 @@ [npm]: https://npmjs.com/package/datalist-polyfill "datalist polyfill – on NPM"

## Features
* Lightweight: 6.07 kB of minified JavaScript, around 2.59 kB gzipped
* Lightweight: 5.98 kB of minified JavaScript, around 2.54 kB gzipped
* Fully flexible to change the datalist entries / `<option>`s

@@ -27,0 +27,0 @@ * Supporting:

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc