Skip to content
Snippets Groups Projects
Commit 8287017e authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2818825 by drpal, nod_, droplet, cilefen: Rename all JS files to *.es6.js and compile them

parent 9a0e9a64
No related branches found
No related tags found
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
Showing
with 2598 additions and 1346 deletions
/**
* @file
* Attaches behaviors for Drupal's active link marking.
*/
(function (Drupal, drupalSettings) {
'use strict';
/**
* Append is-active class.
*
* The link is only active if its path corresponds to the current path, the
* language of the linked path is equal to the current language, and if the
* query parameters of the link equal those of the current request, since the
* same request with different query parameters may yield a different page
* (e.g. pagers, exposed View filters).
*
* Does not discriminate based on element type, so allows you to set the
* is-active class on any element: a, li…
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.activeLinks = {
attach: function (context) {
// Start by finding all potentially active links.
var path = drupalSettings.path;
var queryString = JSON.stringify(path.currentQuery);
var querySelector = path.currentQuery ? "[data-drupal-link-query='" + queryString + "']" : ':not([data-drupal-link-query])';
var originalSelectors = ['[data-drupal-link-system-path="' + path.currentPath + '"]'];
var selectors;
// If this is the front page, we have to check for the <front> path as
// well.
if (path.isFront) {
originalSelectors.push('[data-drupal-link-system-path="<front>"]');
}
// Add language filtering.
selectors = [].concat(
// Links without any hreflang attributes (most of them).
originalSelectors.map(function (selector) { return selector + ':not([hreflang])'; }),
// Links with hreflang equals to the current language.
originalSelectors.map(function (selector) { return selector + '[hreflang="' + path.currentLanguage + '"]'; })
);
// Add query string selector for pagers, exposed filters.
selectors = selectors.map(function (current) { return current + querySelector; });
// Query the DOM.
var activeLinks = context.querySelectorAll(selectors.join(','));
var il = activeLinks.length;
for (var i = 0; i < il; i++) {
activeLinks[i].classList.add('is-active');
}
},
detach: function (context, settings, trigger) {
if (trigger === 'unload') {
var activeLinks = context.querySelectorAll('[data-drupal-link-system-path].is-active');
var il = activeLinks.length;
for (var i = 0; i < il; i++) {
activeLinks[i].classList.remove('is-active');
}
}
}
};
})(Drupal, drupalSettings);
/**
* @file
* Attaches behaviors for Drupal's active link marking.
*/
* DO NOT EDIT THIS FILE.
* All changes should be applied to ./misc/active-link.es6.js
* See the following change record for more information,
* https://www.drupal.org/node/2873849
* @preserve
**/
(function (Drupal, drupalSettings) {
'use strict';
/**
* Append is-active class.
*
* The link is only active if its path corresponds to the current path, the
* language of the linked path is equal to the current language, and if the
* query parameters of the link equal those of the current request, since the
* same request with different query parameters may yield a different page
* (e.g. pagers, exposed View filters).
*
* Does not discriminate based on element type, so allows you to set the
* is-active class on any element: a, li…
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.activeLinks = {
attach: function (context) {
// Start by finding all potentially active links.
attach: function attach(context) {
var path = drupalSettings.path;
var queryString = JSON.stringify(path.currentQuery);
var querySelector = path.currentQuery ? "[data-drupal-link-query='" + queryString + "']" : ':not([data-drupal-link-query])';
var originalSelectors = ['[data-drupal-link-system-path="' + path.currentPath + '"]'];
var selectors;
// If this is the front page, we have to check for the <front> path as
// well.
if (path.isFront) {
originalSelectors.push('[data-drupal-link-system-path="<front>"]');
}
// Add language filtering.
selectors = [].concat(
// Links without any hreflang attributes (most of them).
originalSelectors.map(function (selector) { return selector + ':not([hreflang])'; }),
// Links with hreflang equals to the current language.
originalSelectors.map(function (selector) { return selector + '[hreflang="' + path.currentLanguage + '"]'; })
);
selectors = [].concat(originalSelectors.map(function (selector) {
return selector + ':not([hreflang])';
}), originalSelectors.map(function (selector) {
return selector + '[hreflang="' + path.currentLanguage + '"]';
}));
// Add query string selector for pagers, exposed filters.
selectors = selectors.map(function (current) { return current + querySelector; });
selectors = selectors.map(function (current) {
return current + querySelector;
});
// Query the DOM.
var activeLinks = context.querySelectorAll(selectors.join(','));
var il = activeLinks.length;
for (var i = 0; i < il; i++) {
activeLinks[i].classList.add('is-active');
}
},
detach: function (context, settings, trigger) {
detach: function detach(context, settings, trigger) {
if (trigger === 'unload') {
var activeLinks = context.querySelectorAll('[data-drupal-link-system-path].is-active');
var il = activeLinks.length;
......@@ -64,5 +48,4 @@
}
}
};
})(Drupal, drupalSettings);
})(Drupal, drupalSettings);
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
/**
* @file
* Adds an HTML element and method to trigger audio UAs to read system messages.
*
* Use {@link Drupal.announce} to indicate to screen reader users that an
* element on the page has changed state. For instance, if clicking a link
* loads 10 more items into a list, one might announce the change like this.
*
* @example
* $('#search-list')
* .on('itemInsert', function (event, data) {
* // Insert the new items.
* $(data.container.el).append(data.items.el);
* // Announce the change to the page contents.
* Drupal.announce(Drupal.t('@count items added to @container',
* {'@count': data.items.length, '@container': data.container.title}
* ));
* });
*/
(function (Drupal, debounce) {
'use strict';
var liveElement;
var announcements = [];
/**
* Builds a div element with the aria-live attribute and add it to the DOM.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches the behavior for drupalAnnouce.
*/
Drupal.behaviors.drupalAnnounce = {
attach: function (context) {
// Create only one aria-live element.
if (!liveElement) {
liveElement = document.createElement('div');
liveElement.id = 'drupal-live-announce';
liveElement.className = 'visually-hidden';
liveElement.setAttribute('aria-live', 'polite');
liveElement.setAttribute('aria-busy', 'false');
document.body.appendChild(liveElement);
}
}
};
/**
* Concatenates announcements to a single string; appends to the live region.
*/
function announce() {
var text = [];
var priority = 'polite';
var announcement;
// Create an array of announcement strings to be joined and appended to the
// aria live region.
var il = announcements.length;
for (var i = 0; i < il; i++) {
announcement = announcements.pop();
text.unshift(announcement.text);
// If any of the announcements has a priority of assertive then the group
// of joined announcements will have this priority.
if (announcement.priority === 'assertive') {
priority = 'assertive';
}
}
if (text.length) {
// Clear the liveElement so that repeated strings will be read.
liveElement.innerHTML = '';
// Set the busy state to true until the node changes are complete.
liveElement.setAttribute('aria-busy', 'true');
// Set the priority to assertive, or default to polite.
liveElement.setAttribute('aria-live', priority);
// Print the text to the live region. Text should be run through
// Drupal.t() before being passed to Drupal.announce().
liveElement.innerHTML = text.join('\n');
// The live text area is updated. Allow the AT to announce the text.
liveElement.setAttribute('aria-busy', 'false');
}
}
/**
* Triggers audio UAs to read the supplied text.
*
* The aria-live region will only read the text that currently populates its
* text node. Replacing text quickly in rapid calls to announce results in
* only the text from the most recent call to {@link Drupal.announce} being
* read. By wrapping the call to announce in a debounce function, we allow for
* time for multiple calls to {@link Drupal.announce} to queue up their
* messages. These messages are then joined and append to the aria-live region
* as one text node.
*
* @param {string} text
* A string to be read by the UA.
* @param {string} [priority='polite']
* A string to indicate the priority of the message. Can be either
* 'polite' or 'assertive'.
*
* @return {function}
* The return of the call to debounce.
*
* @see http://www.w3.org/WAI/PF/aria-practices/#liveprops
*/
Drupal.announce = function (text, priority) {
// Save the text and priority into a closure variable. Multiple simultaneous
// announcements will be concatenated and read in sequence.
announcements.push({
text: text,
priority: priority
});
// Immediately invoke the function that debounce returns. 200 ms is right at
// the cusp where humans notice a pause, so we will wait
// at most this much time before the set of queued announcements is read.
return (debounce(announce, 200)());
};
}(Drupal, Drupal.debounce));
/**
* @file
* Adds an HTML element and method to trigger audio UAs to read system messages.
*
* Use {@link Drupal.announce} to indicate to screen reader users that an
* element on the page has changed state. For instance, if clicking a link
* loads 10 more items into a list, one might announce the change like this.
*
* @example
* $('#search-list')
* .on('itemInsert', function (event, data) {
* // Insert the new items.
* $(data.container.el).append(data.items.el);
* // Announce the change to the page contents.
* Drupal.announce(Drupal.t('@count items added to @container',
* {'@count': data.items.length, '@container': data.container.title}
* ));
* });
*/
* DO NOT EDIT THIS FILE.
* All changes should be applied to ./misc/announce.es6.js
* See the following change record for more information,
* https://www.drupal.org/node/2873849
* @preserve
**/
(function (Drupal, debounce) {
......@@ -25,17 +13,8 @@
var liveElement;
var announcements = [];
/**
* Builds a div element with the aria-live attribute and add it to the DOM.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches the behavior for drupalAnnouce.
*/
Drupal.behaviors.drupalAnnounce = {
attach: function (context) {
// Create only one aria-live element.
attach: function attach(context) {
if (!liveElement) {
liveElement = document.createElement('div');
liveElement.id = 'drupal-live-announce';
......@@ -47,74 +26,40 @@
}
};
/**
* Concatenates announcements to a single string; appends to the live region.
*/
function announce() {
var text = [];
var priority = 'polite';
var announcement;
// Create an array of announcement strings to be joined and appended to the
// aria live region.
var il = announcements.length;
for (var i = 0; i < il; i++) {
announcement = announcements.pop();
text.unshift(announcement.text);
// If any of the announcements has a priority of assertive then the group
// of joined announcements will have this priority.
if (announcement.priority === 'assertive') {
priority = 'assertive';
}
}
if (text.length) {
// Clear the liveElement so that repeated strings will be read.
liveElement.innerHTML = '';
// Set the busy state to true until the node changes are complete.
liveElement.setAttribute('aria-busy', 'true');
// Set the priority to assertive, or default to polite.
liveElement.setAttribute('aria-live', priority);
// Print the text to the live region. Text should be run through
// Drupal.t() before being passed to Drupal.announce().
liveElement.innerHTML = text.join('\n');
// The live text area is updated. Allow the AT to announce the text.
liveElement.setAttribute('aria-busy', 'false');
}
}
/**
* Triggers audio UAs to read the supplied text.
*
* The aria-live region will only read the text that currently populates its
* text node. Replacing text quickly in rapid calls to announce results in
* only the text from the most recent call to {@link Drupal.announce} being
* read. By wrapping the call to announce in a debounce function, we allow for
* time for multiple calls to {@link Drupal.announce} to queue up their
* messages. These messages are then joined and append to the aria-live region
* as one text node.
*
* @param {string} text
* A string to be read by the UA.
* @param {string} [priority='polite']
* A string to indicate the priority of the message. Can be either
* 'polite' or 'assertive'.
*
* @return {function}
* The return of the call to debounce.
*
* @see http://www.w3.org/WAI/PF/aria-practices/#liveprops
*/
Drupal.announce = function (text, priority) {
// Save the text and priority into a closure variable. Multiple simultaneous
// announcements will be concatenated and read in sequence.
announcements.push({
text: text,
priority: priority
});
// Immediately invoke the function that debounce returns. 200 ms is right at
// the cusp where humans notice a pause, so we will wait
// at most this much time before the set of queued announcements is read.
return (debounce(announce, 200)());
return debounce(announce, 200)();
};
}(Drupal, Drupal.debounce));
})(Drupal, Drupal.debounce);
\ No newline at end of file
/**
* @file
* Autocomplete based on jQuery UI.
*/
(function ($, Drupal) {
'use strict';
var autocomplete;
/**
* Helper splitting terms from the autocomplete value.
*
* @function Drupal.autocomplete.splitValues
*
* @param {string} value
* The value being entered by the user.
*
* @return {Array}
* Array of values, split by comma.
*/
function autocompleteSplitValues(value) {
// We will match the value against comma-separated terms.
var result = [];
var quote = false;
var current = '';
var valueLength = value.length;
var character;
for (var i = 0; i < valueLength; i++) {
character = value.charAt(i);
if (character === '"') {
current += character;
quote = !quote;
}
else if (character === ',' && !quote) {
result.push(current.trim());
current = '';
}
else {
current += character;
}
}
if (value.length > 0) {
result.push($.trim(current));
}
return result;
}
/**
* Returns the last value of an multi-value textfield.
*
* @function Drupal.autocomplete.extractLastTerm
*
* @param {string} terms
* The value of the field.
*
* @return {string}
* The last value of the input field.
*/
function extractLastTerm(terms) {
return autocomplete.splitValues(terms).pop();
}
/**
* The search handler is called before a search is performed.
*
* @function Drupal.autocomplete.options.search
*
* @param {object} event
* The event triggered.
*
* @return {bool}
* Whether to perform a search or not.
*/
function searchHandler(event) {
var options = autocomplete.options;
if (options.isComposing) {
return false;
}
var term = autocomplete.extractLastTerm(event.target.value);
// Abort search if the first character is in firstCharacterBlacklist.
if (term.length > 0 && options.firstCharacterBlacklist.indexOf(term[0]) !== -1) {
return false;
}
// Only search when the term is at least the minimum length.
return term.length >= options.minLength;
}
/**
* JQuery UI autocomplete source callback.
*
* @param {object} request
* The request object.
* @param {function} response
* The function to call with the response.
*/
function sourceData(request, response) {
var elementId = this.element.attr('id');
if (!(elementId in autocomplete.cache)) {
autocomplete.cache[elementId] = {};
}
/**
* Filter through the suggestions removing all terms already tagged and
* display the available terms to the user.
*
* @param {object} suggestions
* Suggestions returned by the server.
*/
function showSuggestions(suggestions) {
var tagged = autocomplete.splitValues(request.term);
var il = tagged.length;
for (var i = 0; i < il; i++) {
var index = suggestions.indexOf(tagged[i]);
if (index >= 0) {
suggestions.splice(index, 1);
}
}
response(suggestions);
}
/**
* Transforms the data object into an array and update autocomplete results.
*
* @param {object} data
* The data sent back from the server.
*/
function sourceCallbackHandler(data) {
autocomplete.cache[elementId][term] = data;
// Send the new string array of terms to the jQuery UI list.
showSuggestions(data);
}
// Get the desired term and construct the autocomplete URL for it.
var term = autocomplete.extractLastTerm(request.term);
// Check if the term is already cached.
if (autocomplete.cache[elementId].hasOwnProperty(term)) {
showSuggestions(autocomplete.cache[elementId][term]);
}
else {
var options = $.extend({success: sourceCallbackHandler, data: {q: term}}, autocomplete.ajax);
$.ajax(this.element.attr('data-autocomplete-path'), options);
}
}
/**
* Handles an autocompletefocus event.
*
* @return {bool}
* Always returns false.
*/
function focusHandler() {
return false;
}
/**
* Handles an autocompleteselect event.
*
* @param {jQuery.Event} event
* The event triggered.
* @param {object} ui
* The jQuery UI settings object.
*
* @return {bool}
* Returns false to indicate the event status.
*/
function selectHandler(event, ui) {
var terms = autocomplete.splitValues(event.target.value);
// Remove the current input.
terms.pop();
// Add the selected item.
if (ui.item.value.search(',') > 0) {
terms.push('"' + ui.item.value + '"');
}
else {
terms.push(ui.item.value);
}
event.target.value = terms.join(', ');
// Return false to tell jQuery UI that we've filled in the value already.
return false;
}
/**
* Override jQuery UI _renderItem function to output HTML by default.
*
* @param {jQuery} ul
* jQuery collection of the ul element.
* @param {object} item
* The list item to append.
*
* @return {jQuery}
* jQuery collection of the ul element.
*/
function renderItem(ul, item) {
return $('<li>')
.append($('<a>').html(item.label))
.appendTo(ul);
}
/**
* Attaches the autocomplete behavior to all required fields.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches the autocomplete behaviors.
* @prop {Drupal~behaviorDetach} detach
* Detaches the autocomplete behaviors.
*/
Drupal.behaviors.autocomplete = {
attach: function (context) {
// Act on textfields with the "form-autocomplete" class.
var $autocomplete = $(context).find('input.form-autocomplete').once('autocomplete');
if ($autocomplete.length) {
// Allow options to be overriden per instance.
var blacklist = $autocomplete.attr('data-autocomplete-first-character-blacklist');
$.extend(autocomplete.options, {
firstCharacterBlacklist: (blacklist) ? blacklist : ''
});
// Use jQuery UI Autocomplete on the textfield.
$autocomplete.autocomplete(autocomplete.options)
.each(function () {
$(this).data('ui-autocomplete')._renderItem = autocomplete.options.renderItem;
});
// Use CompositionEvent to handle IME inputs. It requests remote server on "compositionend" event only.
$autocomplete.on('compositionstart.autocomplete', function () {
autocomplete.options.isComposing = true;
});
$autocomplete.on('compositionend.autocomplete', function () {
autocomplete.options.isComposing = false;
});
}
},
detach: function (context, settings, trigger) {
if (trigger === 'unload') {
$(context).find('input.form-autocomplete')
.removeOnce('autocomplete')
.autocomplete('destroy');
}
}
};
/**
* Autocomplete object implementation.
*
* @namespace Drupal.autocomplete
*/
autocomplete = {
cache: {},
// Exposes options to allow overriding by contrib.
splitValues: autocompleteSplitValues,
extractLastTerm: extractLastTerm,
// jQuery UI autocomplete options.
/**
* JQuery UI option object.
*
* @name Drupal.autocomplete.options
*/
options: {
source: sourceData,
focus: focusHandler,
search: searchHandler,
select: selectHandler,
renderItem: renderItem,
minLength: 1,
// Custom options, used by Drupal.autocomplete.
firstCharacterBlacklist: '',
// Custom options, indicate IME usage status.
isComposing: false
},
ajax: {
dataType: 'json'
}
};
Drupal.autocomplete = autocomplete;
})(jQuery, Drupal);
/**
* @file
* Autocomplete based on jQuery UI.
*/
* DO NOT EDIT THIS FILE.
* All changes should be applied to ./misc/autocomplete.es6.js
* See the following change record for more information,
* https://www.drupal.org/node/2873849
* @preserve
**/
(function ($, Drupal) {
......@@ -9,19 +12,7 @@
var autocomplete;
/**
* Helper splitting terms from the autocomplete value.
*
* @function Drupal.autocomplete.splitValues
*
* @param {string} value
* The value being entered by the user.
*
* @return {Array}
* Array of values, split by comma.
*/
function autocompleteSplitValues(value) {
// We will match the value against comma-separated terms.
var result = [];
var quote = false;
var current = '';
......@@ -33,12 +24,10 @@
if (character === '"') {
current += character;
quote = !quote;
}
else if (character === ',' && !quote) {
} else if (character === ',' && !quote) {
result.push(current.trim());
current = '';
}
else {
} else {
current += character;
}
}
......@@ -49,32 +38,10 @@
return result;
}
/**
* Returns the last value of an multi-value textfield.
*
* @function Drupal.autocomplete.extractLastTerm
*
* @param {string} terms
* The value of the field.
*
* @return {string}
* The last value of the input field.
*/
function extractLastTerm(terms) {
return autocomplete.splitValues(terms).pop();
}
/**
* The search handler is called before a search is performed.
*
* @function Drupal.autocomplete.options.search
*
* @param {object} event
* The event triggered.
*
* @return {bool}
* Whether to perform a search or not.
*/
function searchHandler(event) {
var options = autocomplete.options;
......@@ -83,22 +50,14 @@
}
var term = autocomplete.extractLastTerm(event.target.value);
// Abort search if the first character is in firstCharacterBlacklist.
if (term.length > 0 && options.firstCharacterBlacklist.indexOf(term[0]) !== -1) {
return false;
}
// Only search when the term is at least the minimum length.
return term.length >= options.minLength;
}
/**
* JQuery UI autocomplete source callback.
*
* @param {object} request
* The request object.
* @param {function} response
* The function to call with the response.
*/
function sourceData(request, response) {
var elementId = this.element.attr('id');
......@@ -106,13 +65,6 @@
autocomplete.cache[elementId] = {};
}
/**
* Filter through the suggestions removing all terms already tagged and
* display the available terms to the user.
*
* @param {object} suggestions
* Suggestions returned by the server.
*/
function showSuggestions(suggestions) {
var tagged = autocomplete.splitValues(request.term);
var il = tagged.length;
......@@ -125,113 +77,58 @@
response(suggestions);
}
/**
* Transforms the data object into an array and update autocomplete results.
*
* @param {object} data
* The data sent back from the server.
*/
function sourceCallbackHandler(data) {
autocomplete.cache[elementId][term] = data;
// Send the new string array of terms to the jQuery UI list.
showSuggestions(data);
}
// Get the desired term and construct the autocomplete URL for it.
var term = autocomplete.extractLastTerm(request.term);
// Check if the term is already cached.
if (autocomplete.cache[elementId].hasOwnProperty(term)) {
showSuggestions(autocomplete.cache[elementId][term]);
}
else {
var options = $.extend({success: sourceCallbackHandler, data: {q: term}}, autocomplete.ajax);
} else {
var options = $.extend({ success: sourceCallbackHandler, data: { q: term } }, autocomplete.ajax);
$.ajax(this.element.attr('data-autocomplete-path'), options);
}
}
/**
* Handles an autocompletefocus event.
*
* @return {bool}
* Always returns false.
*/
function focusHandler() {
return false;
}
/**
* Handles an autocompleteselect event.
*
* @param {jQuery.Event} event
* The event triggered.
* @param {object} ui
* The jQuery UI settings object.
*
* @return {bool}
* Returns false to indicate the event status.
*/
function selectHandler(event, ui) {
var terms = autocomplete.splitValues(event.target.value);
// Remove the current input.
terms.pop();
// Add the selected item.
if (ui.item.value.search(',') > 0) {
terms.push('"' + ui.item.value + '"');
}
else {
} else {
terms.push(ui.item.value);
}
event.target.value = terms.join(', ');
// Return false to tell jQuery UI that we've filled in the value already.
return false;
}
/**
* Override jQuery UI _renderItem function to output HTML by default.
*
* @param {jQuery} ul
* jQuery collection of the ul element.
* @param {object} item
* The list item to append.
*
* @return {jQuery}
* jQuery collection of the ul element.
*/
function renderItem(ul, item) {
return $('<li>')
.append($('<a>').html(item.label))
.appendTo(ul);
return $('<li>').append($('<a>').html(item.label)).appendTo(ul);
}
/**
* Attaches the autocomplete behavior to all required fields.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches the autocomplete behaviors.
* @prop {Drupal~behaviorDetach} detach
* Detaches the autocomplete behaviors.
*/
Drupal.behaviors.autocomplete = {
attach: function (context) {
// Act on textfields with the "form-autocomplete" class.
attach: function attach(context) {
var $autocomplete = $(context).find('input.form-autocomplete').once('autocomplete');
if ($autocomplete.length) {
// Allow options to be overriden per instance.
var blacklist = $autocomplete.attr('data-autocomplete-first-character-blacklist');
$.extend(autocomplete.options, {
firstCharacterBlacklist: (blacklist) ? blacklist : ''
firstCharacterBlacklist: blacklist ? blacklist : ''
});
$autocomplete.autocomplete(autocomplete.options).each(function () {
$(this).data('ui-autocomplete')._renderItem = autocomplete.options.renderItem;
});
// Use jQuery UI Autocomplete on the textfield.
$autocomplete.autocomplete(autocomplete.options)
.each(function () {
$(this).data('ui-autocomplete')._renderItem = autocomplete.options.renderItem;
});
// Use CompositionEvent to handle IME inputs. It requests remote server on "compositionend" event only.
$autocomplete.on('compositionstart.autocomplete', function () {
autocomplete.options.isComposing = true;
});
......@@ -240,32 +137,19 @@
});
}
},
detach: function (context, settings, trigger) {
detach: function detach(context, settings, trigger) {
if (trigger === 'unload') {
$(context).find('input.form-autocomplete')
.removeOnce('autocomplete')
.autocomplete('destroy');
$(context).find('input.form-autocomplete').removeOnce('autocomplete').autocomplete('destroy');
}
}
};
/**
* Autocomplete object implementation.
*
* @namespace Drupal.autocomplete
*/
autocomplete = {
cache: {},
// Exposes options to allow overriding by contrib.
splitValues: autocompleteSplitValues,
extractLastTerm: extractLastTerm,
// jQuery UI autocomplete options.
/**
* JQuery UI option object.
*
* @name Drupal.autocomplete.options
*/
options: {
source: sourceData,
focus: focusHandler,
......@@ -273,9 +157,9 @@
select: selectHandler,
renderItem: renderItem,
minLength: 1,
// Custom options, used by Drupal.autocomplete.
firstCharacterBlacklist: '',
// Custom options, indicate IME usage status.
isComposing: false
},
ajax: {
......@@ -284,5 +168,4 @@
};
Drupal.autocomplete = autocomplete;
})(jQuery, Drupal);
})(jQuery, Drupal);
\ No newline at end of file
/**
* @file
* Drupal's batch API.
*/
(function ($, Drupal) {
'use strict';
/**
* Attaches the batch behavior to progress bars.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.batch = {
attach: function (context, settings) {
var batch = settings.batch;
var $progress = $('[data-drupal-progress]').once('batch');
var progressBar;
// Success: redirect to the summary.
function updateCallback(progress, status, pb) {
if (progress === '100') {
pb.stopMonitoring();
window.location = batch.uri + '&op=finished';
}
}
function errorCallback(pb) {
$progress.prepend($('<p class="error"></p>').html(batch.errorMessage));
$('#wait').hide();
}
if ($progress.length) {
progressBar = new Drupal.ProgressBar('updateprogress', updateCallback, 'POST', errorCallback);
progressBar.setProgress(-1, batch.initMessage);
progressBar.startMonitoring(batch.uri + '&op=do', 10);
// Remove HTML from no-js progress bar.
$progress.empty();
// Append the JS progressbar element.
$progress.append(progressBar.element);
}
}
};
})(jQuery, Drupal);
/**
* @file
* Drupal's batch API.
*/
* DO NOT EDIT THIS FILE.
* All changes should be applied to ./misc/batch.es6.js
* See the following change record for more information,
* https://www.drupal.org/node/2873849
* @preserve
**/
(function ($, Drupal) {
'use strict';
/**
* Attaches the batch behavior to progress bars.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.batch = {
attach: function (context, settings) {
attach: function attach(context, settings) {
var batch = settings.batch;
var $progress = $('[data-drupal-progress]').once('batch');
var progressBar;
// Success: redirect to the summary.
function updateCallback(progress, status, pb) {
if (progress === '100') {
pb.stopMonitoring();
......@@ -35,12 +32,11 @@
progressBar = new Drupal.ProgressBar('updateprogress', updateCallback, 'POST', errorCallback);
progressBar.setProgress(-1, batch.initMessage);
progressBar.startMonitoring(batch.uri + '&op=do', 10);
// Remove HTML from no-js progress bar.
$progress.empty();
// Append the JS progressbar element.
$progress.append(progressBar.element);
}
}
};
})(jQuery, Drupal);
})(jQuery, Drupal);
\ No newline at end of file
/**
* @file
* Polyfill for HTML5 details elements.
*/
(function ($, Modernizr, Drupal) {
'use strict';
/**
* The collapsible details object represents a single details element.
*
* @constructor Drupal.CollapsibleDetails
*
* @param {HTMLElement} node
* The details element.
*/
function CollapsibleDetails(node) {
this.$node = $(node);
this.$node.data('details', this);
// Expand details if there are errors inside, or if it contains an
// element that is targeted by the URI fragment identifier.
var anchor = location.hash && location.hash !== '#' ? ', ' + location.hash : '';
if (this.$node.find('.error' + anchor).length) {
this.$node.attr('open', true);
}
// Initialize and setup the summary,
this.setupSummary();
// Initialize and setup the legend.
this.setupLegend();
}
$.extend(CollapsibleDetails, /** @lends Drupal.CollapsibleDetails */{
/**
* Holds references to instantiated CollapsibleDetails objects.
*
* @type {Array.<Drupal.CollapsibleDetails>}
*/
instances: []
});
$.extend(CollapsibleDetails.prototype, /** @lends Drupal.CollapsibleDetails# */{
/**
* Initialize and setup summary events and markup.
*
* @fires event:summaryUpdated
*
* @listens event:summaryUpdated
*/
setupSummary: function () {
this.$summary = $('<span class="summary"></span>');
this.$node
.on('summaryUpdated', $.proxy(this.onSummaryUpdated, this))
.trigger('summaryUpdated');
},
/**
* Initialize and setup legend markup.
*/
setupLegend: function () {
// Turn the summary into a clickable link.
var $legend = this.$node.find('> summary');
$('<span class="details-summary-prefix visually-hidden"></span>')
.append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show'))
.prependTo($legend)
.after(document.createTextNode(' '));
// .wrapInner() does not retain bound events.
$('<a class="details-title"></a>')
.attr('href', '#' + this.$node.attr('id'))
.prepend($legend.contents())
.appendTo($legend);
$legend
.append(this.$summary)
.on('click', $.proxy(this.onLegendClick, this));
},
/**
* Handle legend clicks.
*
* @param {jQuery.Event} e
* The event triggered.
*/
onLegendClick: function (e) {
this.toggle();
e.preventDefault();
},
/**
* Update summary.
*/
onSummaryUpdated: function () {
var text = $.trim(this.$node.drupalGetSummary());
this.$summary.html(text ? ' (' + text + ')' : '');
},
/**
* Toggle the visibility of a details element using smooth animations.
*/
toggle: function () {
var isOpen = !!this.$node.attr('open');
var $summaryPrefix = this.$node.find('> summary span.details-summary-prefix');
if (isOpen) {
$summaryPrefix.html(Drupal.t('Show'));
}
else {
$summaryPrefix.html(Drupal.t('Hide'));
}
// Delay setting the attribute to emulate chrome behavior and make
// details-aria.js work as expected with this polyfill.
setTimeout(function () {
this.$node.attr('open', !isOpen);
}.bind(this), 0);
}
});
/**
* Polyfill HTML5 details element.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches behavior for the details element.
*/
Drupal.behaviors.collapse = {
attach: function (context) {
if (Modernizr.details) {
return;
}
var $collapsibleDetails = $(context).find('details').once('collapse').addClass('collapse-processed');
if ($collapsibleDetails.length) {
for (var i = 0; i < $collapsibleDetails.length; i++) {
CollapsibleDetails.instances.push(new CollapsibleDetails($collapsibleDetails[i]));
}
}
}
};
// Expose constructor in the public space.
Drupal.CollapsibleDetails = CollapsibleDetails;
})(jQuery, Modernizr, Drupal);
/**
* @file
* Polyfill for HTML5 details elements.
*/
* DO NOT EDIT THIS FILE.
* All changes should be applied to ./misc/collapse.es6.js
* See the following change record for more information,
* https://www.drupal.org/node/2873849
* @preserve
**/
(function ($, Modernizr, Drupal) {
'use strict';
/**
* The collapsible details object represents a single details element.
*
* @constructor Drupal.CollapsibleDetails
*
* @param {HTMLElement} node
* The details element.
*/
function CollapsibleDetails(node) {
this.$node = $(node);
this.$node.data('details', this);
// Expand details if there are errors inside, or if it contains an
// element that is targeted by the URI fragment identifier.
var anchor = location.hash && location.hash !== '#' ? ', ' + location.hash : '';
if (this.$node.find('.error' + anchor).length) {
this.$node.attr('open', true);
}
// Initialize and setup the summary,
this.setupSummary();
// Initialize and setup the legend.
this.setupLegend();
}
$.extend(CollapsibleDetails, /** @lends Drupal.CollapsibleDetails */{
/**
* Holds references to instantiated CollapsibleDetails objects.
*
* @type {Array.<Drupal.CollapsibleDetails>}
*/
$.extend(CollapsibleDetails, {
instances: []
});
$.extend(CollapsibleDetails.prototype, /** @lends Drupal.CollapsibleDetails# */{
/**
* Initialize and setup summary events and markup.
*
* @fires event:summaryUpdated
*
* @listens event:summaryUpdated
*/
setupSummary: function () {
$.extend(CollapsibleDetails.prototype, {
setupSummary: function setupSummary() {
this.$summary = $('<span class="summary"></span>');
this.$node
.on('summaryUpdated', $.proxy(this.onSummaryUpdated, this))
.trigger('summaryUpdated');
this.$node.on('summaryUpdated', $.proxy(this.onSummaryUpdated, this)).trigger('summaryUpdated');
},
/**
* Initialize and setup legend markup.
*/
setupLegend: function () {
// Turn the summary into a clickable link.
setupLegend: function setupLegend() {
var $legend = this.$node.find('> summary');
$('<span class="details-summary-prefix visually-hidden"></span>')
.append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show'))
.prependTo($legend)
.after(document.createTextNode(' '));
$('<span class="details-summary-prefix visually-hidden"></span>').append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show')).prependTo($legend).after(document.createTextNode(' '));
// .wrapInner() does not retain bound events.
$('<a class="details-title"></a>')
.attr('href', '#' + this.$node.attr('id'))
.prepend($legend.contents())
.appendTo($legend);
$('<a class="details-title"></a>').attr('href', '#' + this.$node.attr('id')).prepend($legend.contents()).appendTo($legend);
$legend
.append(this.$summary)
.on('click', $.proxy(this.onLegendClick, this));
$legend.append(this.$summary).on('click', $.proxy(this.onLegendClick, this));
},
/**
* Handle legend clicks.
*
* @param {jQuery.Event} e
* The event triggered.
*/
onLegendClick: function (e) {
onLegendClick: function onLegendClick(e) {
this.toggle();
e.preventDefault();
},
/**
* Update summary.
*/
onSummaryUpdated: function () {
onSummaryUpdated: function onSummaryUpdated() {
var text = $.trim(this.$node.drupalGetSummary());
this.$summary.html(text ? ' (' + text + ')' : '');
},
/**
* Toggle the visibility of a details element using smooth animations.
*/
toggle: function () {
toggle: function toggle() {
var isOpen = !!this.$node.attr('open');
var $summaryPrefix = this.$node.find('> summary span.details-summary-prefix');
if (isOpen) {
$summaryPrefix.html(Drupal.t('Show'));
}
else {
} else {
$summaryPrefix.html(Drupal.t('Hide'));
}
// Delay setting the attribute to emulate chrome behavior and make
// details-aria.js work as expected with this polyfill.
setTimeout(function () {
this.$node.attr('open', !isOpen);
}.bind(this), 0);
}
});
/**
* Polyfill HTML5 details element.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches behavior for the details element.
*/
Drupal.behaviors.collapse = {
attach: function (context) {
attach: function attach(context) {
if (Modernizr.details) {
return;
}
......@@ -140,7 +83,5 @@
}
};
// Expose constructor in the public space.
Drupal.CollapsibleDetails = CollapsibleDetails;
})(jQuery, Modernizr, Drupal);
})(jQuery, Modernizr, Drupal);
\ No newline at end of file
/**
* @file
* Polyfill for HTML5 date input.
*/
(function ($, Modernizr, Drupal) {
'use strict';
/**
* Attach datepicker fallback on date elements.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches the behavior. Accepts in `settings.date` an object listing
* elements to process, keyed by the HTML ID of the form element containing
* the human-readable value. Each element is an datepicker settings object.
* @prop {Drupal~behaviorDetach} detach
* Detach the behavior destroying datepickers on effected elements.
*/
Drupal.behaviors.date = {
attach: function (context, settings) {
var $context = $(context);
// Skip if date are supported by the browser.
if (Modernizr.inputtypes.date === true) {
return;
}
$context.find('input[data-drupal-date-format]').once('datePicker').each(function () {
var $input = $(this);
var datepickerSettings = {};
var dateFormat = $input.data('drupalDateFormat');
// The date format is saved in PHP style, we need to convert to jQuery
// datepicker.
datepickerSettings.dateFormat = dateFormat
.replace('Y', 'yy')
.replace('m', 'mm')
.replace('d', 'dd');
// Add min and max date if set on the input.
if ($input.attr('min')) {
datepickerSettings.minDate = $input.attr('min');
}
if ($input.attr('max')) {
datepickerSettings.maxDate = $input.attr('max');
}
$input.datepicker(datepickerSettings);
});
},
detach: function (context, settings, trigger) {
if (trigger === 'unload') {
$(context).find('input[data-drupal-date-format]').findOnce('datePicker').datepicker('destroy');
}
}
};
})(jQuery, Modernizr, Drupal);
/**
* @file
* Polyfill for HTML5 date input.
*/
* DO NOT EDIT THIS FILE.
* All changes should be applied to ./misc/date.es6.js
* See the following change record for more information,
* https://www.drupal.org/node/2873849
* @preserve
**/
(function ($, Modernizr, Drupal) {
'use strict';
/**
* Attach datepicker fallback on date elements.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches the behavior. Accepts in `settings.date` an object listing
* elements to process, keyed by the HTML ID of the form element containing
* the human-readable value. Each element is an datepicker settings object.
* @prop {Drupal~behaviorDetach} detach
* Detach the behavior destroying datepickers on effected elements.
*/
Drupal.behaviors.date = {
attach: function (context, settings) {
attach: function attach(context, settings) {
var $context = $(context);
// Skip if date are supported by the browser.
if (Modernizr.inputtypes.date === true) {
return;
}
......@@ -30,13 +21,9 @@
var $input = $(this);
var datepickerSettings = {};
var dateFormat = $input.data('drupalDateFormat');
// The date format is saved in PHP style, we need to convert to jQuery
// datepicker.
datepickerSettings.dateFormat = dateFormat
.replace('Y', 'yy')
.replace('m', 'mm')
.replace('d', 'dd');
// Add min and max date if set on the input.
datepickerSettings.dateFormat = dateFormat.replace('Y', 'yy').replace('m', 'mm').replace('d', 'dd');
if ($input.attr('min')) {
datepickerSettings.minDate = $input.attr('min');
}
......@@ -46,11 +33,10 @@
$input.datepicker(datepickerSettings);
});
},
detach: function (context, settings, trigger) {
detach: function detach(context, settings, trigger) {
if (trigger === 'unload') {
$(context).find('input[data-drupal-date-format]').findOnce('datePicker').datepicker('destroy');
}
}
};
})(jQuery, Modernizr, Drupal);
})(jQuery, Modernizr, Drupal);
\ No newline at end of file
/**
* @file
* Adapted from underscore.js with the addition Drupal namespace.
*/
/**
* Limits the invocations of a function in a given time frame.
*
* The debounce function wrapper should be used sparingly. One clear use case
* is limiting the invocation of a callback attached to the window resize event.
*
* Before using the debounce function wrapper, consider first whether the
* callback could be attached to an event that fires less frequently or if the
* function can be written in such a way that it is only invoked under specific
* conditions.
*
* @param {function} func
* The function to be invoked.
* @param {number} wait
* The time period within which the callback function should only be
* invoked once. For example if the wait period is 250ms, then the callback
* will only be called at most 4 times per second.
* @param {bool} immediate
* Whether we wait at the beginning or end to execute the function.
*
* @return {function}
* The debounced function.
*/
Drupal.debounce = function (func, wait, immediate) {
'use strict';
var timeout;
var result;
return function () {
var context = this;
var args = arguments;
var later = function () {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
}
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
}
return result;
};
};
/**
* @file
* Adapted from underscore.js with the addition Drupal namespace.
*/
* DO NOT EDIT THIS FILE.
* All changes should be applied to ./misc/debounce.es6.js
* See the following change record for more information,
* https://www.drupal.org/node/2873849
* @preserve
**/
/**
* Limits the invocations of a function in a given time frame.
*
* The debounce function wrapper should be used sparingly. One clear use case
* is limiting the invocation of a callback attached to the window resize event.
*
* Before using the debounce function wrapper, consider first whether the
* callback could be attached to an event that fires less frequently or if the
* function can be written in such a way that it is only invoked under specific
* conditions.
*
* @param {function} func
* The function to be invoked.
* @param {number} wait
* The time period within which the callback function should only be
* invoked once. For example if the wait period is 250ms, then the callback
* will only be called at most 4 times per second.
* @param {bool} immediate
* Whether we wait at the beginning or end to execute the function.
*
* @return {function}
* The debounced function.
*/
Drupal.debounce = function (func, wait, immediate) {
'use strict';
......@@ -35,7 +15,7 @@ Drupal.debounce = function (func, wait, immediate) {
return function () {
var context = this;
var args = arguments;
var later = function () {
var later = function later() {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
......@@ -49,4 +29,4 @@ Drupal.debounce = function (func, wait, immediate) {
}
return result;
};
};
};
\ No newline at end of file
/**
* @file
* Add aria attribute handling for details and summary elements.
*/
(function ($, Drupal) {
'use strict';
/**
* Handles `aria-expanded` and `aria-pressed` attributes on details elements.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.detailsAria = {
attach: function () {
$('body').once('detailsAria').on('click.detailsAria', 'summary', function (event) {
var $summary = $(event.currentTarget);
var open = $(event.currentTarget.parentNode).attr('open') === 'open' ? 'false' : 'true';
$summary.attr({
'aria-expanded': open,
'aria-pressed': open
});
});
}
};
})(jQuery, Drupal);
/**
* @file
* Add aria attribute handling for details and summary elements.
*/
* DO NOT EDIT THIS FILE.
* All changes should be applied to ./misc/details-aria.es6.js
* See the following change record for more information,
* https://www.drupal.org/node/2873849
* @preserve
**/
(function ($, Drupal) {
'use strict';
/**
* Handles `aria-expanded` and `aria-pressed` attributes on details elements.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.detailsAria = {
attach: function () {
attach: function attach() {
$('body').once('detailsAria').on('click.detailsAria', 'summary', function (event) {
var $summary = $(event.currentTarget);
var open = $(event.currentTarget.parentNode).attr('open') === 'open' ? 'false' : 'true';
......@@ -25,5 +23,4 @@
});
}
};
})(jQuery, Drupal);
})(jQuery, Drupal);
\ No newline at end of file
/**
* @file
* Extends the Drupal AJAX functionality to integrate the dialog API.
*/
(function ($, Drupal) {
'use strict';
/**
* Initialize dialogs for Ajax purposes.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches the behaviors for dialog ajax functionality.
*/
Drupal.behaviors.dialog = {
attach: function (context, settings) {
var $context = $(context);
// Provide a known 'drupal-modal' DOM element for Drupal-based modal
// dialogs. Non-modal dialogs are responsible for creating their own
// elements, since there can be multiple non-modal dialogs at a time.
if (!$('#drupal-modal').length) {
// Add 'ui-front' jQuery UI class so jQuery UI widgets like autocomplete
// sit on top of dialogs. For more information see
// http://api.jqueryui.com/theming/stacking-elements/.
$('<div id="drupal-modal" class="ui-front"/>').hide().appendTo('body');
}
// Special behaviors specific when attaching content within a dialog.
// These behaviors usually fire after a validation error inside a dialog.
var $dialog = $context.closest('.ui-dialog-content');
if ($dialog.length) {
// Remove and replace the dialog buttons with those from the new form.
if ($dialog.dialog('option', 'drupalAutoButtons')) {
// Trigger an event to detect/sync changes to buttons.
$dialog.trigger('dialogButtonsChange');
}
// Force focus on the modal when the behavior is run.
$dialog.dialog('widget').trigger('focus');
}
var originalClose = settings.dialog.close;
// Overwrite the close method to remove the dialog on closing.
settings.dialog.close = function (event) {
originalClose.apply(settings.dialog, arguments);
$(event.target).remove();
};
},
/**
* Scan a dialog for any primary buttons and move them to the button area.
*
* @param {jQuery} $dialog
* An jQuery object containing the element that is the dialog target.
*
* @return {Array}
* An array of buttons that need to be added to the button area.
*/
prepareDialogButtons: function ($dialog) {
var buttons = [];
var $buttons = $dialog.find('.form-actions input[type=submit], .form-actions a.button');
$buttons.each(function () {
// Hidden form buttons need special attention. For browser consistency,
// the button needs to be "visible" in order to have the enter key fire
// the form submit event. So instead of a simple "hide" or
// "display: none", we set its dimensions to zero.
// See http://mattsnider.com/how-forms-submit-when-pressing-enter/
var $originalButton = $(this).css({
display: 'block',
width: 0,
height: 0,
padding: 0,
border: 0,
overflow: 'hidden'
});
buttons.push({
text: $originalButton.html() || $originalButton.attr('value'),
class: $originalButton.attr('class'),
click: function (e) {
// If the original button is an anchor tag, triggering the "click"
// event will not simulate a click. Use the click method instead.
if ($originalButton.is('a')) {
$originalButton[0].click();
}
else {
$originalButton.trigger('mousedown').trigger('mouseup').trigger('click');
e.preventDefault();
}
}
});
});
return buttons;
}
};
/**
* Command to open a dialog.
*
* @param {Drupal.Ajax} ajax
* The Drupal Ajax object.
* @param {object} response
* Object holding the server response.
* @param {number} [status]
* The HTTP status code.
*
* @return {bool|undefined}
* Returns false if there was no selector property in the response object.
*/
Drupal.AjaxCommands.prototype.openDialog = function (ajax, response, status) {
if (!response.selector) {
return false;
}
var $dialog = $(response.selector);
if (!$dialog.length) {
// Create the element if needed.
$dialog = $('<div id="' + response.selector.replace(/^#/, '') + '" class="ui-front"/>').appendTo('body');
}
// Set up the wrapper, if there isn't one.
if (!ajax.wrapper) {
ajax.wrapper = $dialog.attr('id');
}
// Use the ajax.js insert command to populate the dialog contents.
response.command = 'insert';
response.method = 'html';
ajax.commands.insert(ajax, response, status);
// Move the buttons to the jQuery UI dialog buttons area.
if (!response.dialogOptions.buttons) {
response.dialogOptions.drupalAutoButtons = true;
response.dialogOptions.buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog);
}
// Bind dialogButtonsChange.
$dialog.on('dialogButtonsChange', function () {
var buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog);
$dialog.dialog('option', 'buttons', buttons);
});
// Open the dialog itself.
response.dialogOptions = response.dialogOptions || {};
var dialog = Drupal.dialog($dialog.get(0), response.dialogOptions);
if (response.dialogOptions.modal) {
dialog.showModal();
}
else {
dialog.show();
}
// Add the standard Drupal class for buttons for style consistency.
$dialog.parent().find('.ui-dialog-buttonset').addClass('form-actions');
};
/**
* Command to close a dialog.
*
* If no selector is given, it defaults to trying to close the modal.
*
* @param {Drupal.Ajax} [ajax]
* The ajax object.
* @param {object} response
* Object holding the server response.
* @param {string} response.selector
* The selector of the dialog.
* @param {bool} response.persist
* Whether to persist the dialog element or not.
* @param {number} [status]
* The HTTP status code.
*/
Drupal.AjaxCommands.prototype.closeDialog = function (ajax, response, status) {
var $dialog = $(response.selector);
if ($dialog.length) {
Drupal.dialog($dialog.get(0)).close();
if (!response.persist) {
$dialog.remove();
}
}
// Unbind dialogButtonsChange.
$dialog.off('dialogButtonsChange');
};
/**
* Command to set a dialog property.
*
* JQuery UI specific way of setting dialog options.
*
* @param {Drupal.Ajax} [ajax]
* The Drupal Ajax object.
* @param {object} response
* Object holding the server response.
* @param {string} response.selector
* Selector for the dialog element.
* @param {string} response.optionsName
* Name of a key to set.
* @param {string} response.optionValue
* Value to set.
* @param {number} [status]
* The HTTP status code.
*/
Drupal.AjaxCommands.prototype.setDialogOption = function (ajax, response, status) {
var $dialog = $(response.selector);
if ($dialog.length) {
$dialog.dialog('option', response.optionName, response.optionValue);
}
};
/**
* Binds a listener on dialog creation to handle the cancel link.
*
* @param {jQuery.Event} e
* The event triggered.
* @param {Drupal.dialog~dialogDefinition} dialog
* The dialog instance.
* @param {jQuery} $element
* The jQuery collection of the dialog element.
* @param {object} [settings]
* Dialog settings.
*/
$(window).on('dialog:aftercreate', function (e, dialog, $element, settings) {
$element.on('click.dialog', '.dialog-cancel', function (e) {
dialog.close('cancel');
e.preventDefault();
e.stopPropagation();
});
});
/**
* Removes all 'dialog' listeners.
*
* @param {jQuery.Event} e
* The event triggered.
* @param {Drupal.dialog~dialogDefinition} dialog
* The dialog instance.
* @param {jQuery} $element
* jQuery collection of the dialog element.
*/
$(window).on('dialog:beforeclose', function (e, dialog, $element) {
$element.off('.dialog');
});
})(jQuery, Drupal);
/**
* @file
* Extends the Drupal AJAX functionality to integrate the dialog API.
*/
* DO NOT EDIT THIS FILE.
* All changes should be applied to ./misc/dialog/dialog.ajax.es6.js
* See the following change record for more information,
* https://www.drupal.org/node/2873849
* @preserve
**/
(function ($, Drupal) {
'use strict';
/**
* Initialize dialogs for Ajax purposes.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches the behaviors for dialog ajax functionality.
*/
Drupal.behaviors.dialog = {
attach: function (context, settings) {
attach: function attach(context, settings) {
var $context = $(context);
// Provide a known 'drupal-modal' DOM element for Drupal-based modal
// dialogs. Non-modal dialogs are responsible for creating their own
// elements, since there can be multiple non-modal dialogs at a time.
if (!$('#drupal-modal').length) {
// Add 'ui-front' jQuery UI class so jQuery UI widgets like autocomplete
// sit on top of dialogs. For more information see
// http://api.jqueryui.com/theming/stacking-elements/.
$('<div id="drupal-modal" class="ui-front"/>').hide().appendTo('body');
}
// Special behaviors specific when attaching content within a dialog.
// These behaviors usually fire after a validation error inside a dialog.
var $dialog = $context.closest('.ui-dialog-content');
if ($dialog.length) {
// Remove and replace the dialog buttons with those from the new form.
if ($dialog.dialog('option', 'drupalAutoButtons')) {
// Trigger an event to detect/sync changes to buttons.
$dialog.trigger('dialogButtonsChange');
}
// Force focus on the modal when the behavior is run.
$dialog.dialog('widget').trigger('focus');
}
var originalClose = settings.dialog.close;
// Overwrite the close method to remove the dialog on closing.
settings.dialog.close = function (event) {
originalClose.apply(settings.dialog, arguments);
$(event.target).remove();
};
},
/**
* Scan a dialog for any primary buttons and move them to the button area.
*
* @param {jQuery} $dialog
* An jQuery object containing the element that is the dialog target.
*
* @return {Array}
* An array of buttons that need to be added to the button area.
*/
prepareDialogButtons: function ($dialog) {
prepareDialogButtons: function prepareDialogButtons($dialog) {
var buttons = [];
var $buttons = $dialog.find('.form-actions input[type=submit], .form-actions a.button');
$buttons.each(function () {
// Hidden form buttons need special attention. For browser consistency,
// the button needs to be "visible" in order to have the enter key fire
// the form submit event. So instead of a simple "hide" or
// "display: none", we set its dimensions to zero.
// See http://mattsnider.com/how-forms-submit-when-pressing-enter/
var $originalButton = $(this).css({
display: 'block',
width: 0,
......@@ -80,13 +50,10 @@
buttons.push({
text: $originalButton.html() || $originalButton.attr('value'),
class: $originalButton.attr('class'),
click: function (e) {
// If the original button is an anchor tag, triggering the "click"
// event will not simulate a click. Use the click method instead.
click: function click(e) {
if ($originalButton.is('a')) {
$originalButton[0].click();
}
else {
} else {
$originalButton.trigger('mousedown').trigger('mouseup').trigger('click');
e.preventDefault();
}
......@@ -97,80 +64,44 @@
}
};
/**
* Command to open a dialog.
*
* @param {Drupal.Ajax} ajax
* The Drupal Ajax object.
* @param {object} response
* Object holding the server response.
* @param {number} [status]
* The HTTP status code.
*
* @return {bool|undefined}
* Returns false if there was no selector property in the response object.
*/
Drupal.AjaxCommands.prototype.openDialog = function (ajax, response, status) {
if (!response.selector) {
return false;
}
var $dialog = $(response.selector);
if (!$dialog.length) {
// Create the element if needed.
$dialog = $('<div id="' + response.selector.replace(/^#/, '') + '" class="ui-front"/>').appendTo('body');
}
// Set up the wrapper, if there isn't one.
if (!ajax.wrapper) {
ajax.wrapper = $dialog.attr('id');
}
// Use the ajax.js insert command to populate the dialog contents.
response.command = 'insert';
response.method = 'html';
ajax.commands.insert(ajax, response, status);
// Move the buttons to the jQuery UI dialog buttons area.
if (!response.dialogOptions.buttons) {
response.dialogOptions.drupalAutoButtons = true;
response.dialogOptions.buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog);
}
// Bind dialogButtonsChange.
$dialog.on('dialogButtonsChange', function () {
var buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog);
$dialog.dialog('option', 'buttons', buttons);
});
// Open the dialog itself.
response.dialogOptions = response.dialogOptions || {};
var dialog = Drupal.dialog($dialog.get(0), response.dialogOptions);
if (response.dialogOptions.modal) {
dialog.showModal();
}
else {
} else {
dialog.show();
}
// Add the standard Drupal class for buttons for style consistency.
$dialog.parent().find('.ui-dialog-buttonset').addClass('form-actions');
};
/**
* Command to close a dialog.
*
* If no selector is given, it defaults to trying to close the modal.
*
* @param {Drupal.Ajax} [ajax]
* The ajax object.
* @param {object} response
* Object holding the server response.
* @param {string} response.selector
* The selector of the dialog.
* @param {bool} response.persist
* Whether to persist the dialog element or not.
* @param {number} [status]
* The HTTP status code.
*/
Drupal.AjaxCommands.prototype.closeDialog = function (ajax, response, status) {
var $dialog = $(response.selector);
if ($dialog.length) {
......@@ -180,28 +111,9 @@
}
}
// Unbind dialogButtonsChange.
$dialog.off('dialogButtonsChange');
};
/**
* Command to set a dialog property.
*
* JQuery UI specific way of setting dialog options.
*
* @param {Drupal.Ajax} [ajax]
* The Drupal Ajax object.
* @param {object} response
* Object holding the server response.
* @param {string} response.selector
* Selector for the dialog element.
* @param {string} response.optionsName
* Name of a key to set.
* @param {string} response.optionValue
* Value to set.
* @param {number} [status]
* The HTTP status code.
*/
Drupal.AjaxCommands.prototype.setDialogOption = function (ajax, response, status) {
var $dialog = $(response.selector);
if ($dialog.length) {
......@@ -209,18 +121,6 @@
}
};
/**
* Binds a listener on dialog creation to handle the cancel link.
*
* @param {jQuery.Event} e
* The event triggered.
* @param {Drupal.dialog~dialogDefinition} dialog
* The dialog instance.
* @param {jQuery} $element
* The jQuery collection of the dialog element.
* @param {object} [settings]
* Dialog settings.
*/
$(window).on('dialog:aftercreate', function (e, dialog, $element, settings) {
$element.on('click.dialog', '.dialog-cancel', function (e) {
dialog.close('cancel');
......@@ -229,18 +129,7 @@
});
});
/**
* Removes all 'dialog' listeners.
*
* @param {jQuery.Event} e
* The event triggered.
* @param {Drupal.dialog~dialogDefinition} dialog
* The dialog instance.
* @param {jQuery} $element
* jQuery collection of the dialog element.
*/
$(window).on('dialog:beforeclose', function (e, dialog, $element) {
$element.off('.dialog');
});
})(jQuery, Drupal);
})(jQuery, Drupal);
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment