Issue #2402103 by nod_, bnjmnm, larowlan, flxa, anmolgoyal74, droplet, xjm, catch, gabesullice, lauriii, Dries, justafish: Add once.js to core
parent
daf10a0695
commit
5bce5eeb25
|
@ -20,6 +20,7 @@
|
|||
"Modernizr": true,
|
||||
"Popper": true,
|
||||
"Sortable": true,
|
||||
"once": true,
|
||||
"CKEDITOR": true,
|
||||
"tabbable": true
|
||||
},
|
||||
|
|
|
@ -0,0 +1,387 @@
|
|||
/*! @drupal/once - v1.0.0 - 2021-03-04 */
|
||||
/**
|
||||
* Mark DOM elements as processed to prevent multiple initializations.
|
||||
*
|
||||
* @module @drupal/once
|
||||
*
|
||||
* @example <!-- Use as a module -->
|
||||
* <script type="module">
|
||||
* import once from 'https://unpkg.com/@drupal/once/src/once.js';
|
||||
* const elements = once('my-once-id', 'div');
|
||||
* // Initialize elements.
|
||||
* elements.forEach(el => el.innerHTML = 'processed');
|
||||
* </script>
|
||||
*
|
||||
* @example <!-- Use as a regular script -->
|
||||
* <script src="https://unpkg.com/@drupal/once"></script>
|
||||
* <script>
|
||||
* const elements = once('my-once-id', 'div');
|
||||
* // Initialize elements.
|
||||
* elements.forEach(el => el.innerHTML = 'processed');
|
||||
* </script>
|
||||
* @example <!-- Using a single element as input-->
|
||||
* <script src="https://unpkg.com/@drupal/once"></script>
|
||||
* <script>
|
||||
* // once methods always return an array, to simplify the use with a single
|
||||
* // element use destructuring or the shift method.
|
||||
* const [myElement] = once('my-once-id', document.body);
|
||||
* const myElement = once('my-once-id', document.body).shift();
|
||||
* </script>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Illegal spaces in ids.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @type {RegExp}
|
||||
*/
|
||||
const wsRE = /[\11\12\14\15\40]+/;
|
||||
|
||||
/**
|
||||
* Name of the HTML attribute containing an element's once ids.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
const attrName = 'data-once';
|
||||
|
||||
/**
|
||||
* Shortcut to access the html element.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @type {HTMLElement}
|
||||
*/
|
||||
const doc = document;
|
||||
|
||||
/**
|
||||
* Helper to access element attributes.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {Element} element
|
||||
* The Element to access the data-once attribute from.
|
||||
* @param {string} op
|
||||
* The action to take on the element.
|
||||
* @param {string} [value]
|
||||
* Optional value for setAttribute.
|
||||
*
|
||||
* @return {string|undefined|null|boolean}
|
||||
* Result of the attribute method.
|
||||
*/
|
||||
function attr(element, op, value) {
|
||||
return element[`${op}Attribute`](attrName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the attribute selector.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {string} id
|
||||
* The id passed by a call to a once() function.
|
||||
*
|
||||
* @return {string}
|
||||
* The full CSS attribute selector.
|
||||
*
|
||||
* @throws {TypeError|RangeError}
|
||||
*/
|
||||
function attrSelector(id) {
|
||||
// Verify the validity of the once id.
|
||||
if (typeof id !== 'string') {
|
||||
throw new TypeError('once ID must be a string');
|
||||
}
|
||||
if (id === '' || wsRE.test(id)) {
|
||||
throw new RangeError('once ID must not be empty or contain spaces');
|
||||
}
|
||||
// The id is valid, return the full CSS selector.
|
||||
return `[${attrName}~="${id}"]`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that an item is an instance of Element.
|
||||
*
|
||||
* This function is used during filtering to ensure only DOM elements are
|
||||
* processed. once() makes use of get/setAttribute, which are methods
|
||||
* inherited from the Element object, so only of Element can be used.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {*} itemToCheck
|
||||
* The item to check.
|
||||
*
|
||||
* @return {boolean}
|
||||
* True if the item is an instance of Element
|
||||
*
|
||||
* @throws {TypeError}
|
||||
*/
|
||||
function checkElement(itemToCheck) {
|
||||
if (!(itemToCheck instanceof Element)) {
|
||||
throw new TypeError('The element must be an instance of Element');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process arguments, query the DOM if necessary.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {NodeList|Array.<Element>|Element|string} selector
|
||||
* A NodeList or array of elements.
|
||||
* @param {Document|Element} [context=document]
|
||||
* An element to use as context for querySelectorAll.
|
||||
*
|
||||
* @return {Array.<Element>}
|
||||
* An array with the processed Id and the list of elements to process.
|
||||
*/
|
||||
function getElements(selector, context = doc) {
|
||||
if (!selector) {
|
||||
throw new TypeError('Selector must not be empty');
|
||||
}
|
||||
// Assume selector is an array-like value.
|
||||
let elements = selector;
|
||||
|
||||
// This is a selector, query the elements.
|
||||
if (
|
||||
typeof selector === 'string' &&
|
||||
(context === doc || checkElement(context))
|
||||
) {
|
||||
elements = context.querySelectorAll(selector);
|
||||
}
|
||||
// This is a single element.
|
||||
else if (selector instanceof Element) {
|
||||
elements = [selector];
|
||||
}
|
||||
|
||||
// Make sure an array is returned and not a NodeList or an Array-like object.
|
||||
return Array.prototype.slice.call(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper for applying DOM changes to a filtered set of elements.
|
||||
*
|
||||
* This makes it possible to filter items that are not instances of Element,
|
||||
* then modify their DOM attributes in a single array traversal.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {string} selector
|
||||
* A CSS selector to check against to each element in the array.
|
||||
* @param {Array.<Element>} elements
|
||||
* A NodeList or array of elements passed by a call to a once() function.
|
||||
* @param {function} [apply]
|
||||
* An optional function to apply on all matched elements.
|
||||
*
|
||||
* @return {Array.<Element>}
|
||||
* The array of elements that match the CSS selector.
|
||||
*/
|
||||
function filterAndModify(selector, elements, apply) {
|
||||
return elements.filter(element => {
|
||||
const selected = checkElement(element) && element.matches(selector);
|
||||
if (selected && apply) {
|
||||
apply(element);
|
||||
}
|
||||
return selected;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or remove an item from a list of once values.
|
||||
*
|
||||
* This function removes duplicates while adding or removing a once id in a
|
||||
* single array traversal.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {Element} element
|
||||
* A space separated string of once ids from a data-drupal-once attribute.
|
||||
* @param {string} [add]
|
||||
* The once id to add to the list of values.
|
||||
* @param {string} [remove]
|
||||
* The once id to remove from the list of values.
|
||||
*
|
||||
* @return {undefined}
|
||||
* Nothing to return this is a callback in a foreach.
|
||||
*/
|
||||
function updateAttribute(element, { add, remove }) {
|
||||
const result = [];
|
||||
if (attr(element, 'has')) {
|
||||
attr(element, 'get')
|
||||
.trim()
|
||||
.split(wsRE)
|
||||
.forEach(item => {
|
||||
if (result.indexOf(item) < 0 && item !== remove) {
|
||||
result.push(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (add) {
|
||||
result.push(add);
|
||||
}
|
||||
const attribute = result.join(' ');
|
||||
attr(element, attribute === '' ? 'remove' : 'set', attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures a JavaScript callback is only executed once on a set of elements.
|
||||
*
|
||||
* Filters a NodeList or array of elements, removing those already processed
|
||||
* by a callback with a given id.
|
||||
* This method adds a `data-once` attribute on DOM elements. The value of
|
||||
* this attribute identifies if a given callback has been executed on that
|
||||
* element.
|
||||
*
|
||||
* @global
|
||||
*
|
||||
* @example <caption>Basic usage</caption>
|
||||
* const elements = once('my-once-id', '[data-myelement]');
|
||||
* @example <caption>Input parameters accepted</caption>
|
||||
* // NodeList.
|
||||
* once('my-once-id', document.querySelectorAll('[data-myelement]'));
|
||||
* // Array or Array-like of Element.
|
||||
* once('my-once-id', jQuery('[data-myelement]'));
|
||||
* // A CSS selector without a context.
|
||||
* once('my-once-id', '[data-myelement]');
|
||||
* // A CSS selector with a context.
|
||||
* once('my-once-id', '[data-myelement]', document.head);
|
||||
* // Single Element.
|
||||
* once('my-once-id', document.querySelector('#some-id'));
|
||||
* @example <caption>Using a single element</caption>
|
||||
* // Once always returns an array, even when passing a single element. Some
|
||||
* // forms that can be used to keep code readable.
|
||||
* // Destructuring:
|
||||
* const [myElement] = once('my-once-id', document.body);
|
||||
* // By changing the resulting array, es5 compatible.
|
||||
* const myElement = once('my-once-id', document.body).shift();
|
||||
*
|
||||
* @param {string} id
|
||||
* The id of the once call.
|
||||
* @param {NodeList|Array.<Element>|Element|string} selector
|
||||
* A NodeList or array of elements.
|
||||
* @param {Document|Element} [context=document]
|
||||
* An element to use as context for querySelectorAll.
|
||||
*
|
||||
* @return {Array.<Element>}
|
||||
* An array of elements that have not yet been processed by a once call
|
||||
* with a given id.
|
||||
*/
|
||||
function once(id, selector, context) {
|
||||
return filterAndModify(
|
||||
`:not(${attrSelector(id)})`,
|
||||
getElements(selector, context),
|
||||
element => updateAttribute(element, { add: id }),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a once id from an element's data-drupal-once attribute value.
|
||||
*
|
||||
* If a once id is removed from an element's data-drupal-once attribute value,
|
||||
* the JavaScript callback associated with that id can be executed on that
|
||||
* element again.
|
||||
*
|
||||
* @method once.remove
|
||||
*
|
||||
* @example <caption>Basic usage</caption>
|
||||
* const elements = once.remove('my-once-id', '[data-myelement]');
|
||||
* @example <caption>Input parameters accepted</caption>
|
||||
* // NodeList.
|
||||
* once.remove('my-once-id', document.querySelectorAll('[data-myelement]'));
|
||||
* // Array or Array-like of Element.
|
||||
* once.remove('my-once-id', jQuery('[data-myelement]'));
|
||||
* // A CSS selector without a context.
|
||||
* once.remove('my-once-id', '[data-myelement]');
|
||||
* // A CSS selector with a context.
|
||||
* once.remove('my-once-id', '[data-myelement]', document.head);
|
||||
* // Single Element.
|
||||
* once.remove('my-once-id', document.querySelector('#some-id'));
|
||||
*
|
||||
* @param {string} id
|
||||
* The id of a once call.
|
||||
* @param {NodeList|Array.<Element>|Element|string} selector
|
||||
* A NodeList or array of elements to remove the once id from.
|
||||
* @param {Document|Element} [context=document]
|
||||
* An element to use as context for querySelectorAll.
|
||||
*
|
||||
* @return {Array.<Element>}
|
||||
* A filtered array of elements that had been processed by the provided id,
|
||||
* and are now able to be processed again.
|
||||
*/
|
||||
once.remove = (id, selector, context) => {
|
||||
return filterAndModify(
|
||||
attrSelector(id),
|
||||
getElements(selector, context),
|
||||
element => updateAttribute(element, { remove: id }),
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds elements that have been processed by a given once id.
|
||||
*
|
||||
* Behaves like {@link once} and {@link once.remove} without changing the DOM.
|
||||
* To select all DOM nodes processed by a given id, use {@link once.find}.
|
||||
*
|
||||
* @method once.filter
|
||||
*
|
||||
* @example <caption>Basic usage</caption>
|
||||
* const filteredElements = once.filter('my-once-id', '[data-myelement]');
|
||||
* @example <caption>Input parameters accepted</caption>
|
||||
* // NodeList.
|
||||
* once.filter('my-once-id', document.querySelectorAll('[data-myelement]'));
|
||||
* // Array or Array-like of Element.
|
||||
* once.filter('my-once-id', jQuery('[data-myelement]'));
|
||||
* // A CSS selector without a context.
|
||||
* once.filter('my-once-id', '[data-myelement]');
|
||||
* // A CSS selector with a context.
|
||||
* once.filter('my-once-id', '[data-myelement]', document.head);
|
||||
* // Single Element.
|
||||
* once.filter('my-once-id', document.querySelector('#some-id'));
|
||||
*
|
||||
* @param {string} id
|
||||
* The id of the once call.
|
||||
* @param {NodeList|Array.<Element>|Element|string} selector
|
||||
* A NodeList or array of elements to remove the once id from.
|
||||
* @param {Document|Element} [context=document]
|
||||
* An element to use as context for querySelectorAll.
|
||||
*
|
||||
* @return {Array.<Element>}
|
||||
* A filtered array of elements that have already been processed by the
|
||||
* provided once id.
|
||||
*/
|
||||
once.filter = (id, selector, context) =>
|
||||
filterAndModify(attrSelector(id), getElements(selector, context));
|
||||
|
||||
/**
|
||||
* Finds elements that have been processed by a given once id.
|
||||
*
|
||||
* Query the 'context' element for elements that already have the
|
||||
* corresponding once id value.
|
||||
*
|
||||
* @method once.find
|
||||
*
|
||||
* @example <caption>Basic usage</caption>
|
||||
* const oncedElements = once.find('my-once-id');
|
||||
* @example <caption>Input parameters accepted</caption>
|
||||
* // Call without parameters, return all elements with a `data-once` attribute.
|
||||
* once.find();
|
||||
* // Call without a context.
|
||||
* once.find('my-once-id');
|
||||
* // Call with a context.
|
||||
* once.find('my-once-id', document.head);
|
||||
*
|
||||
* @param {string} [id]
|
||||
* The id of the once call.
|
||||
* @param {Document|Element} [context=document]
|
||||
* Scope of the search for matching elements.
|
||||
*
|
||||
* @return {Array.<Element>}
|
||||
* A filtered array of elements that have already been processed by the
|
||||
* provided once id.
|
||||
*/
|
||||
once.find = (id, context) =>
|
||||
getElements(!id ? `[${attrName}]` : attrSelector(id), context);
|
||||
|
||||
export default once;
|
|
@ -0,0 +1,3 @@
|
|||
/*! @drupal/once - v1.0.0 - 2021-03-04 */
|
||||
var once=function(){"use strict";var n=/[\11\12\14\15\40]+/,t="data-once",e=document;function r(n,e,r){return n[e+"Attribute"](t,r)}function o(t){if("string"!=typeof t)throw new TypeError("once ID must be a string");if(""===t||n.test(t))throw new RangeError("once ID must not be empty or contain spaces");return'[data-once~="'+t+'"]'}function u(n){if(!(n instanceof Element))throw new TypeError("The element must be an instance of Element");return!0}function i(n,t){if(void 0===t&&(t=e),!n)throw new TypeError("Selector must not be empty");var r=n;return"string"!=typeof n||t!==e&&!u(t)?n instanceof Element&&(r=[n]):r=t.querySelectorAll(n),Array.prototype.slice.call(r)}function c(n,t,e){return t.filter((function(t){var r=u(t)&&t.matches(n);return r&&e&&e(t),r}))}function f(t,e){var o=e.add,u=e.remove,i=[];r(t,"has")&&r(t,"get").trim().split(n).forEach((function(n){i.indexOf(n)<0&&n!==u&&i.push(n)})),o&&i.push(o);var c=i.join(" ");r(t,""===c?"remove":"set",c)}function a(n,t,e){return c(":not("+o(n)+")",i(t,e),(function(t){return f(t,{add:n})}))}return a.remove=function(n,t,e){return c(o(n),i(t,e),(function(t){return f(t,{remove:n})}))},a.filter=function(n,t,e){return c(o(n),i(t,e))},a.find=function(n,t){return i(n?o(n):"[data-once]",t)},a}();
|
||||
//# sourceMappingURL=once.min.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"once.min.js","sources":["once.js"],"sourcesContent":null,"names":["const","wsRE","attrName","doc","document","attr","element","op","value","attrSelector","id","TypeError","test","RangeError","checkElement","itemToCheck","Element","getElements","selector","context","let","elements","querySelectorAll","Array","prototype","slice","call","filterAndModify","apply","filter","selected","matches","updateAttribute","result","trim","split","forEach","item","indexOf","remove","push","add","attribute","join","once","find"],"mappings":";iCAsCAA,IAAMC,EAAO,qBASPC,EAAW,YASXC,EAAMC,SAiBZ,SAASC,EAAKC,EAASC,EAAIC,GACzB,OAAOF,EAAWC,eAAeL,EAAUM,GAgB7C,SAASC,EAAaC,GAEpB,GAAkB,iBAAPA,EACT,MAAM,IAAIC,UAAU,4BAEtB,GAAW,KAAPD,GAAaT,EAAKW,KAAKF,GACzB,MAAM,IAAIG,WAAW,+CAGvB,sBAAyBH,OAoB3B,SAASI,EAAaC,GACpB,KAAMA,aAAuBC,SAC3B,MAAM,IAAIL,UAAU,8CAEtB,OAAO,EAgBT,SAASM,EAAYC,EAAUC,GAC7B,kBADuChB,IAClCe,EACH,MAAM,IAAIP,UAAU,8BAGtBS,IAAIC,EAAWH,EAef,MAXsB,iBAAbA,GACNC,IAAYhB,IAAOW,EAAaK,GAK1BD,aAAoBF,UAC3BK,EAAW,CAACH,IAJZG,EAAWF,EAAQG,iBAAiBJ,GAQ/BK,MAAMC,UAAUC,MAAMC,KAAKL,GAqBpC,SAASM,EAAgBT,EAAUG,EAAUO,GAC3C,OAAOP,EAASQ,iBAAOvB,GACrBN,IAAM8B,EAAWhB,EAAaR,IAAYA,EAAQyB,QAAQb,GAI1D,OAHIY,GAAYF,GACdA,EAAMtB,GAEDwB,KAsBX,SAASE,EAAgB1B,4BACjB2B,EAAS,GACX5B,EAAKC,EAAS,QAChBD,EAAKC,EAAS,OACX4B,OACAC,MAAMlC,GACNmC,kBAAQC,GACHJ,EAAOK,QAAQD,GAAQ,GAAKA,IAASE,GACvCN,EAAOO,KAAKH,MAIhBI,GACFR,EAAOO,KAAKC,GAEdzC,IAAM0C,EAAYT,EAAOU,KAAK,KAC9BtC,EAAKC,EAAuB,KAAdoC,EAAmB,SAAW,MAAOA,GA8CrD,SAASE,EAAKlC,EAAIQ,EAAUC,GAC1B,OAAOQ,UACGlB,EAAaC,OACrBO,EAAYC,EAAUC,aACtBb,UAAW0B,EAAgB1B,EAAS,CAAEmC,IAAK/B,cAsC/CkC,EAAKL,gBAAU7B,EAAIQ,EAAUC,GAC3B,OAAOQ,EACLlB,EAAaC,GACbO,EAAYC,EAAUC,aACtBb,UAAW0B,EAAgB1B,EAAS,CAAEiC,OAAQ7B,QAqClDkC,EAAKf,gBAAUnB,EAAIQ,EAAUC,UAC3BQ,EAAgBlB,EAAaC,GAAKO,EAAYC,EAAUC,KA6B1DyB,EAAKC,cAAQnC,EAAIS,UACfF,EAAaP,EAAuBD,EAAaC,iBAAKS"}
|
|
@ -181,7 +181,7 @@ drupal.date:
|
|||
dependencies:
|
||||
- core/drupal
|
||||
- core/modernizr
|
||||
- core/jquery.once
|
||||
- core/once
|
||||
|
||||
drupal.debounce:
|
||||
version: VERSION
|
||||
|
@ -279,6 +279,11 @@ drupal.dropbutton:
|
|||
- core/drupalSettings
|
||||
- core/jquery.once
|
||||
|
||||
drupal.element.matches:
|
||||
version: VERSION
|
||||
js:
|
||||
misc/polyfills/element.matches.js: { weight: -20 }
|
||||
|
||||
drupal.entity-form:
|
||||
version: VERSION
|
||||
js:
|
||||
|
@ -705,6 +710,18 @@ normalize:
|
|||
assets/vendor/normalize-css/normalize.css: { weight: -20 }
|
||||
misc/normalize-fixes.css: { weight: -19 }
|
||||
|
||||
once:
|
||||
remote: https://git.drupalcode.org/project/once
|
||||
version: "1.0.0"
|
||||
license:
|
||||
name: GNU-GPL-2.0-or-later
|
||||
url: https://git.drupalcode.org/project/once/-/raw/v1.0.0/LICENSE.md
|
||||
gpl-compatible: true
|
||||
js:
|
||||
assets/vendor/once/once.min.js: { weight: -19, minified: true }
|
||||
dependencies:
|
||||
- core/drupal.element.matches
|
||||
|
||||
picturefill:
|
||||
remote: https://github.com/scottjehl/picturefill
|
||||
version: "3.0.3"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Polyfill for HTML5 date input.
|
||||
*/
|
||||
|
||||
(function ($, Modernizr, Drupal) {
|
||||
(function ($, Modernizr, Drupal, once) {
|
||||
/**
|
||||
* Attach datepicker fallback on date elements.
|
||||
*
|
||||
|
@ -15,32 +15,10 @@
|
|||
*/
|
||||
Drupal.behaviors.date = {
|
||||
attach(context, settings) {
|
||||
const dataFieldElements = 'data-drupal-field-elements';
|
||||
const dataDatepickerProcessed = 'data-datepicker-is-processed';
|
||||
|
||||
/**
|
||||
* Returns a CSS selector for a date field to process.
|
||||
*
|
||||
* The dataDatepickerProcessed attribute prevents a field from being
|
||||
* selected and processed more than once.
|
||||
*
|
||||
* @param {string} elements
|
||||
* The data attribute value.
|
||||
*
|
||||
* @return {string}
|
||||
* A CSS Selector.
|
||||
*/
|
||||
const getDateSelector = (elements) =>
|
||||
[
|
||||
`[${dataFieldElements}="${elements}"]`,
|
||||
`:not([${dataDatepickerProcessed}="${elements}"])`,
|
||||
].join('');
|
||||
|
||||
// If the browser does not support a native datepicker, add date
|
||||
// formatting instructions on date/time fields.
|
||||
if (Modernizr.inputtypes.date === false) {
|
||||
Array.prototype.forEach.call(
|
||||
document.querySelectorAll(getDateSelector('date-time')),
|
||||
once('datepicker', '[data-drupal-field-elements="date-time"]').forEach(
|
||||
(dateTime) => {
|
||||
const dateInput = dateTime.querySelector('input[type="date"]');
|
||||
const timeInput = dateTime.querySelector('input[type="time"]');
|
||||
|
@ -63,14 +41,10 @@
|
|||
});
|
||||
|
||||
Drupal.DatepickerPolyfill.attachDescription(dateTime, help);
|
||||
|
||||
// Set attribute to prevent element from being processed again.
|
||||
dateTime.setAttribute(dataDatepickerProcessed, 'date-time');
|
||||
},
|
||||
);
|
||||
|
||||
Array.prototype.forEach.call(
|
||||
document.querySelectorAll(getDateSelector('date')),
|
||||
once('datepicker', '[data-drupal-field-elements="date"]').forEach(
|
||||
(date) => {
|
||||
const dateInput = date.querySelector('input[type="date"]');
|
||||
const help = Drupal.theme.dateHelp({
|
||||
|
@ -86,9 +60,6 @@
|
|||
// changed to reflect this.
|
||||
dateInput.setAttribute('type', 'text');
|
||||
Drupal.DatepickerPolyfill.attachDescription(date, help, id);
|
||||
|
||||
// Set attribute to prevent element from selection on next run.
|
||||
date.setAttribute(dataDatepickerProcessed, 'date');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -180,4 +151,4 @@
|
|||
`<div class="no-native-datepicker-help">
|
||||
<span id="${dateId}">${dateDesc}</span> <span id="${timeId}">${timeDesc}</span>
|
||||
</div>`;
|
||||
})(jQuery, Modernizr, Drupal);
|
||||
})(jQuery, Modernizr, Drupal, once);
|
||||
|
|
|
@ -11,18 +11,11 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
|
|||
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
||||
|
||||
(function ($, Modernizr, Drupal) {
|
||||
(function ($, Modernizr, Drupal, once) {
|
||||
Drupal.behaviors.date = {
|
||||
attach: function attach(context, settings) {
|
||||
var dataFieldElements = 'data-drupal-field-elements';
|
||||
var dataDatepickerProcessed = 'data-datepicker-is-processed';
|
||||
|
||||
var getDateSelector = function getDateSelector(elements) {
|
||||
return ["[".concat(dataFieldElements, "=\"").concat(elements, "\"]"), ":not([".concat(dataDatepickerProcessed, "=\"").concat(elements, "\"])")].join('');
|
||||
};
|
||||
|
||||
if (Modernizr.inputtypes.date === false) {
|
||||
Array.prototype.forEach.call(document.querySelectorAll(getDateSelector('date-time')), function (dateTime) {
|
||||
once('datepicker', '[data-drupal-field-elements="date-time"]').forEach(function (dateTime) {
|
||||
var dateInput = dateTime.querySelector('input[type="date"]');
|
||||
var timeInput = dateTime.querySelector('input[type="time"]');
|
||||
var help = Drupal.theme.dateTimeHelp({
|
||||
|
@ -36,9 +29,8 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
|
|||
input.setAttribute('type', 'text');
|
||||
});
|
||||
Drupal.DatepickerPolyfill.attachDescription(dateTime, help);
|
||||
dateTime.setAttribute(dataDatepickerProcessed, 'date-time');
|
||||
});
|
||||
Array.prototype.forEach.call(document.querySelectorAll(getDateSelector('date')), function (date) {
|
||||
once('datepicker', '[data-drupal-field-elements="date"]').forEach(function (date) {
|
||||
var dateInput = date.querySelector('input[type="date"]');
|
||||
var help = Drupal.theme.dateHelp({
|
||||
dateDesc: dateInput.dataset.help
|
||||
|
@ -47,7 +39,6 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
|
|||
dateInput.setAttribute('aria-describedby', id);
|
||||
dateInput.setAttribute('type', 'text');
|
||||
Drupal.DatepickerPolyfill.attachDescription(date, help, id);
|
||||
date.setAttribute(dataDatepickerProcessed, 'date');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -100,4 +91,4 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
|
|||
timeDesc = _ref2.timeDesc;
|
||||
return "<div class=\"no-native-datepicker-help\">\n <span id=\"".concat(dateId, "\">").concat(dateDesc, "</span> <span id=\"").concat(timeId, "\">").concat(timeDesc, "</span>\n </div>");
|
||||
};
|
||||
})(jQuery, Modernizr, Drupal);
|
||||
})(jQuery, Modernizr, Drupal, once);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* @file
|
||||
* Provides a polyfill for Element.prototype.matches().
|
||||
*
|
||||
* This is needed for Internet Explorer 9+
|
||||
*
|
||||
* This has been copied from MDN Web Docs code samples. Code samples in the MDN
|
||||
* Web Docs are licensed under CC0.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
|
||||
* @see https://developer.mozilla.org/en-US/docs/MDN/About#Code_samples_and_snippets
|
||||
*/
|
||||
if (!Element.prototype.matches) {
|
||||
Element.prototype.matches =
|
||||
Element.prototype.msMatchesSelector ||
|
||||
Element.prototype.webkitMatchesSelector;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
* DO NOT EDIT THIS FILE.
|
||||
* See the following change record for more information,
|
||||
* https://www.drupal.org/node/2815083
|
||||
* @preserve
|
||||
**/
|
||||
|
||||
if (!Element.prototype.matches) {
|
||||
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
|
||||
}
|
|
@ -208,6 +208,8 @@ autocomplete:
|
|||
version: VERSION
|
||||
js:
|
||||
js/autocomplete.js: {}
|
||||
dependencies:
|
||||
- core/once
|
||||
|
||||
drupal.shortcut:
|
||||
version: VERSION
|
||||
|
|
|
@ -3,13 +3,11 @@
|
|||
* Claro's enhancement for autocomplete form element.
|
||||
*/
|
||||
|
||||
(($, Drupal) => {
|
||||
(($, Drupal, once) => {
|
||||
Drupal.behaviors.claroAutoCompete = {
|
||||
attach(context) {
|
||||
$(context)
|
||||
.find('input.form-autocomplete')
|
||||
.once('claroAutoComplete')
|
||||
.each((index, value) => {
|
||||
once('claroAutoComplete', 'input.form-autocomplete', context).forEach(
|
||||
(value) => {
|
||||
const $input = $(value);
|
||||
const timeout = 400;
|
||||
let classRemoveTimeout;
|
||||
|
@ -37,7 +35,8 @@
|
|||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
};
|
||||
})(jQuery, Drupal);
|
||||
})(jQuery, Drupal, once);
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
* @preserve
|
||||
**/
|
||||
|
||||
(function ($, Drupal) {
|
||||
(function ($, Drupal, once) {
|
||||
Drupal.behaviors.claroAutoCompete = {
|
||||
attach: function attach(context) {
|
||||
$(context).find('input.form-autocomplete').once('claroAutoComplete').each(function (index, value) {
|
||||
once('claroAutoComplete', 'input.form-autocomplete', context).forEach(function (value) {
|
||||
var $input = $(value);
|
||||
var timeout = 400;
|
||||
var classRemoveTimeout;
|
||||
|
@ -30,4 +30,4 @@
|
|||
});
|
||||
}
|
||||
};
|
||||
})(jQuery, Drupal);
|
||||
})(jQuery, Drupal, once);
|
Loading…
Reference in New Issue