diff --git a/app/javascript/shared/polyfills.js b/app/javascript/shared/polyfills.js index 5ff61d17c..a19bbef8c 100644 --- a/app/javascript/shared/polyfills.js +++ b/app/javascript/shared/polyfills.js @@ -3,3 +3,5 @@ // required by the browsers we support will be included. import '@babel/polyfill'; import 'dom4'; +import './polyfills/insertAdjacentElement'; +import './polyfills/dataset'; diff --git a/app/javascript/shared/polyfills/dataset.js b/app/javascript/shared/polyfills/dataset.js new file mode 100644 index 000000000..00d648ea1 --- /dev/null +++ b/app/javascript/shared/polyfills/dataset.js @@ -0,0 +1,75 @@ +/* + @preserve dataset polyfill for IE < 11. See https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset and http://caniuse.com/#search=dataset + + @author ShirtlessKirk copyright 2015 + @license WTFPL (http://www.wtfpl.net/txt/copying) +*/ + +const dash = /-([a-z])/gi; +const dataRegEx = /^data-(.+)/; +const hasEventListener = !!document.addEventListener; +const test = document.createElement('_'); +const DOMAttrModified = 'DOMAttrModified'; + +let mutationSupport = false; + +function clearDataset(event) { + delete event.target._datasetCache; +} + +function toCamelCase(string) { + return string.replace(dash, function(_, letter) { + return letter.toUpperCase(); + }); +} + +function getDataset() { + const dataset = {}; + + for (let attribute of this.attributes) { + let match = attribute.name.match(dataRegEx); + if (match) { + dataset[toCamelCase(match[1])] = attribute.value; + } + } + + return dataset; +} + +function mutation() { + if (hasEventListener) { + test.removeEventListener(DOMAttrModified, mutation, false); + } else { + test.detachEvent(`on${DOMAttrModified}`, mutation); + } + + mutationSupport = true; +} + +if (!test.dataset) { + if (hasEventListener) { + test.addEventListener(DOMAttrModified, mutation, false); + } else { + test.attachEvent(`on${DOMAttrModified}`, mutation); + } + + // trigger event (if supported) + test.setAttribute('foo', 'bar'); + + Object.defineProperty(Element.prototype, 'dataset', { + get: mutationSupport + ? function get() { + if (!this._datasetCache) { + this._datasetCache = getDataset.call(this); + } + + return this._datasetCache; + } + : getDataset + }); + + if (mutationSupport && hasEventListener) { + // < IE9 supports neither + document.addEventListener(DOMAttrModified, clearDataset, false); + } +} diff --git a/app/javascript/shared/polyfills/insertAdjacentElement.js b/app/javascript/shared/polyfills/insertAdjacentElement.js new file mode 100644 index 000000000..4df8a031c --- /dev/null +++ b/app/javascript/shared/polyfills/insertAdjacentElement.js @@ -0,0 +1,47 @@ +/* + Updated w/ insertAdjacentElement + @author Dan Levy @justsml + 2016-06-23 + + Credit: @lyleunderwood - afterend patch/fix + + 2011-10-10 + + By Eli Grey, http://eligrey.com + Public Domain. + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +*/ + +function insertAdjacentElement(position, elem) { + const _this = this; + const parent = this.parentNode; + let node, first; + + switch (position.toLowerCase()) { + case 'beforebegin': + while ((node = elem.firstChild)) { + parent.insertBefore(node, _this); + } + break; + case 'afterbegin': + first = _this.firstChild; + while ((node = elem.lastChild)) { + first = _this.insertBefore(node, first); + } + break; + case 'beforeend': + while ((node = elem.firstChild)) { + _this.appendChild(node); + } + break; + case 'afterend': + parent.insertBefore(elem, _this.nextSibling); + break; + } + return elem; +} + +// Method missing in Firefox < 48 +if (!HTMLElement.prototype.insertAdjacentElement) { + HTMLElement.prototype.insertAdjacentElement = insertAdjacentElement; +}