diff --git a/core/assets/vendor/jquery-once/jquery.once.js b/core/assets/vendor/jquery-once/jquery.once.js index 5363945..71adb8a 100644 --- a/core/assets/vendor/jquery-once/jquery.once.js +++ b/core/assets/vendor/jquery-once/jquery.once.js @@ -1,92 +1,173 @@ -/** - * jQuery Once Plugin 1.2.3 - * http://plugins.jquery.com/once/ - * - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - */ +/*! +* jQuery Once v2.0.0 - http://github.com/robloach/jquery-once +* @license MIT, GPL-2.0 +* http://opensource.org/licenses/MIT +* http://opensource.org/licenses/GPL-2.0 +*/ +/** +* Universal Module Definition +* +* jQuery Once has a dependency on jQuery, so we wrap the code with a UMD +* pattern in order to allow loading jQuery and jQuery Once through a module +* definition like CommonJS, AMD, or through a global object. +* +* @see {@link http://github.com/umdjs/umd} +*/ (function (factory) { "use strict"; - if (typeof exports === 'object') { - factory(require('jquery')); - } else if (typeof define === 'function' && define.amd) { - define(['jquery'], factory); + if (typeof exports === "object") { + // CommonJS + factory(require("jquery")); + } else if (typeof define === "function" && define.amd) { + // AMD + define(["jquery"], factory); } else { + // Global object factory(jQuery); } }(function ($) { "use strict"; - var cache = {}, uuid = 0; /** - * Filters elements by whether they have not yet been processed. - * - * @param id - * (Optional) If this is a string, then it will be used as the CSS class - * name that is applied to the elements for determining whether it has - * already been processed. The elements will get a class in the form of - * "id-processed". - * - * If the id parameter is a function, it will be passed off to the fn - * parameter and the id will become a unique identifier, represented as a - * number. - * - * When the id is neither a string or a function, it becomes a unique - * identifier, depicted as a number. The element's class will then be - * represented in the form of "jquery-once-#-processed". - * - * Take note that the id must be valid for usage as an element's class name. - * @param fn - * (Optional) If given, this function will be called for each element that - * has not yet been processed. The function's return value follows the same - * logic as $.each(). Returning true will continue to the next matched - * element in the set, while returning false will entirely break the - * iteration. - * - * @api public - */ - $.fn.once = function (id, fn) { - if (typeof id !== 'string') { - // Generate a numeric ID if the id passed can't be used as a CSS class. - if (!(id in cache)) { - cache[id] = ++uuid; - } - // When the fn parameter is not passed, we interpret it from the id. - if (!fn) { - fn = id; - } - id = 'jquery-once-' + cache[id]; + * Ensures that the given ID is valid, returning "once" if one is not given. + * + * @param {string} [id="once"] + * A string representing the ID to check. Defaults to `"once"`. + * + * @returns The valid ID name. + * + * @throws Error when an ID is provided, but not a string. + * @private + */ + var checkId = function(id) { + id = id || "once"; + if (typeof id !== "string") { + throw new Error("The jQuery Once id parameter must be a string"); } - // Remove elements from the set that have already been processed. - var name = id + '-processed'; - var elements = this.not('.' + name).addClass(name); + return id; + }; + + /** + * Filter elements that have yet to be processed by the given data ID. + * + * @param {string} [id="once"] + * The data ID used to determine whether the given elements have already + * been processed or not. Defaults to `"once"`. + * + * @returns jQuery collection of elements that have now run once by + * the given ID. + * + * @example + * ``` javascript + * // The following will change the color of each paragraph to red, just once + * // for the "changecolor" key. + * $('p').once('changecolor').css('color', 'red'); + * + * // .once() will return a set of elements that yet to have the once ID + * // associated with them. You can return to the original collection set by + * // using .end(). + * $('p') + * .once("changecolorblue") + * .css("color", "blue") + * .end() + * .css("color", "red"); + * + * // To execute a function on the once set, you can use jQuery's each(). + * $('div.calendar').once().each(function() { + * // Since there is no once ID provided here, the key will be "once". + * }); + * ``` + * + * @see removeOnce + * @see findOnce + * @this jQuery + * + * @global + * @public + */ + $.fn.once = function (id) { + // Build the jQuery Once data name from the provided ID. + var name = "jquery-once-" + checkId(id); + + // Find elements that don't have the jQuery Once data applied to them yet. + return this.filter(function() { + return $(this).data(name) !== true; + }).data(name, true); + }; - return $.isFunction(fn) ? elements.each(fn) : elements; + /** + * Removes the once data from elements, based on the given ID. + * + * @param {string} [id="once"] + * A string representing the name of the data ID which should be used when + * filtering the elements. This only filters elements that have already been + * processed by the once function. The ID should be the same ID that was + * originally passed to the once() function. Defaults to `"once"`. + * + * @returns jQuery collection of elements that were acted upon to remove their + * once data. + * + * @example + * ``` javascript + * // Remove once data with the "changecolor" ID. The result set is the + * // elements that had their once data removed. + * $('p').removeOnce("changecolor").css("color", ""); + * + * // Any jQuery function can be performed on the result set. + * $("div.calendar").removeOnce().each(function() { + * // Remove the calendar behavior. + * }); + * ``` + * + * @see once + * @this jQuery + * + * @global + * @public + */ + $.fn.removeOnce = function (id) { + // Filter through the elements to find the once'd elements. + return this.findOnce(id).removeData("jquery-once-" + checkId(id)); }; /** - * Filters elements that have been processed once already. - * - * @param id - * A required string representing the name of the class which should be used - * when filtering the elements. This only filters elements that have already - * been processed by the once function. The id should be the same id that - * was originally passed to the once() function. - * @param fn - * (Optional) If given, this function will be called for each element that - * has not yet been processed. The function's return value follows the same - * logic as $.each(). Returning true will continue to the next matched - * element in the set, while returning false will entirely break the - * iteration. - * - * @api public - */ - $.fn.removeOnce = function (id, fn) { - var name = id + '-processed'; - var elements = this.filter('.' + name).removeClass(name); + * Filters elements that have already been processed once. + * + * @param {string} [id="once"] + * A string representing the name of the data id which should be used when + * filtering the elements. This only filters elements that have already + * been processed by the once function. The id should be the same id that + * was originally passed to the once() function. Defaults to "once". + * + * @returns jQuery collection of elements that have been run once. + * + * @example + * ``` javascript + * // Find all elements that have been changecolor'ed once. + * $('p').findOnce('changecolor').each(function() { + * // This function is called for all elements that has already once'd. + * }); + * + * // Find all elements that have been acted on with the default "once" key. + * $('p').findOnce().each(function() { + * // This function is called for all elements that have been acted on with + * // a "once" action. + * }); + * ``` + * + * @see once + * @this jQuery + * + * @global + * @public + */ + $.fn.findOnce = function (id) { + // Filter the elements by which do have the data. + var name = "jquery-once-" + checkId(id); - return $.isFunction(fn) ? elements.each(fn) : elements; + return this.filter(function() { + return $(this).data(name) === true; + }); }; })); diff --git a/core/core.libraries.yml b/core/core.libraries.yml index 825ed77..f57f910 100644 --- a/core/core.libraries.yml +++ b/core/core.libraries.yml @@ -392,10 +392,10 @@ jquery.joyride: jquery.once: remote: https://github.com/RobLoach/jquery-once - version: 1.2.3 + version: 2.0.0 license: name: GNU-GPL-2.0-or-later - url: https://github.com/RobLoach/jquery-once/blob/1.2.3/LICENSE + url: https://github.com/RobLoach/jquery-once/blob/master/LICENSE.md gpl-compatible: true js: assets/vendor/jquery-once/jquery.once.js: { weight: -19 } diff --git a/core/misc/ajax.js b/core/misc/ajax.js index ac90282..48a840b 100644 --- a/core/misc/ajax.js +++ b/core/misc/ajax.js @@ -27,7 +27,7 @@ if (typeof element_settings.selector === 'undefined') { element_settings.selector = '#' + base; } - $(element_settings.selector).once('drupal-ajax', function () { + $(element_settings.selector).once('drupal-ajax').each(function () { element_settings.element = this; Drupal.ajax[element_settings.selector] = new Drupal.ajax(base, this, element_settings); }); @@ -41,7 +41,7 @@ } // Bind Ajax behaviors to all items showing the class. - $('.use-ajax').once('ajax', function () { + $('.use-ajax').once('ajax').each(function () { var element_settings = {}; // Clicked links look better with the throbber than the progress bar. element_settings.progress = {'type': 'throbber'}; @@ -59,7 +59,7 @@ }); // This class means to submit the form to the action using Ajax. - $('.use-ajax-submit').once('ajax', function () { + $('.use-ajax-submit').once('ajax').each(function () { var element_settings = {}; // Ajax submits specified in this manner automatically submit to the diff --git a/core/misc/collapse.js b/core/misc/collapse.js index 9115dd6..1a98e54 100644 --- a/core/misc/collapse.js +++ b/core/misc/collapse.js @@ -98,7 +98,7 @@ if (Modernizr.details) { return; } - var $collapsibleDetails = $(context).find('details').once('collapse'); + 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])); diff --git a/core/misc/drupal.js b/core/misc/drupal.js index 4244ed6..6517e57 100644 --- a/core/misc/drupal.js +++ b/core/misc/drupal.js @@ -111,10 +111,10 @@ if (window.jQuery) { * to be processed, in order to allow special behaviors to detach from the * content. * - * Such implementations should look for the class name that was added in their - * corresponding Drupal.behaviors.behaviorName.attach implementation, i.e. - * behaviorName-processed, to ensure the behavior is detached only from - * previously processed elements. + * Such implementations should use .findOnce() and .removeOnce() to find + * elements with their corresponding Drupal.behaviors.behaviorName.attach + * implementation, i.e. .removeOnce('behaviorName'), to ensure the behavior is + * detached only from previously processed elements. * * @param context * An element to detach behaviors from. If none is given, the document element diff --git a/core/misc/tabledrag.js b/core/misc/tabledrag.js index 0795e30..bc21b41 100644 --- a/core/misc/tabledrag.js +++ b/core/misc/tabledrag.js @@ -225,7 +225,7 @@ } // Trigger an event to allow other scripts to react to this display change. // Force the extra parameter as a bool. - $('table.tabledrag-processed').trigger('columnschange', !!displayWeight); + $('table').findOnce('tabledrag').trigger('columnschange', !!displayWeight); }; /** @@ -250,7 +250,7 @@ * Undo showColumns(). */ Drupal.tableDrag.prototype.hideColumns = function () { - var $tables = $('table.tabledrag-processed'); + var $tables = $('table').findOnce('tabledrag'); // Hide weight/parent cells and headers. $tables.find('.tabledrag-hide').css('display', 'none'); // Show TableDrag handles. @@ -268,7 +268,7 @@ * Undo hideColumns(). */ Drupal.tableDrag.prototype.showColumns = function () { - var $tables = $('table.tabledrag-processed'); + var $tables = $('table').findOnce('tabledrag'); // Show weight/parent cells and headers. $tables.find('.tabledrag-hide').css('display', ''); // Hide TableDrag handles. diff --git a/core/misc/tableselect.js b/core/misc/tableselect.js index 60bb0e1..8f91d5e 100644 --- a/core/misc/tableselect.js +++ b/core/misc/tableselect.js @@ -5,7 +5,7 @@ Drupal.behaviors.tableSelect = { attach: function (context, settings) { // Select the inner-most table in case of nested tables. - $(context).find('th.select-all').closest('table').once('table-select', Drupal.tableSelect); + $(context).find('th.select-all').closest('table').once('table-select').each(Drupal.tableSelect); } }; diff --git a/core/misc/vertical-tabs.js b/core/misc/vertical-tabs.js index 11fca70..89b123a 100644 --- a/core/misc/vertical-tabs.js +++ b/core/misc/vertical-tabs.js @@ -20,7 +20,7 @@ return; } - $(context).find('[data-vertical-tabs-panes]').once('vertical-tabs', function () { + $(context).find('[data-vertical-tabs-panes]').once('vertical-tabs').each(function () { var $this = $(this).addClass('vertical-tabs-panes'); var focusID = $this.find(':hidden.vertical-tabs-active-tab').val(); var tab_focus; diff --git a/core/modules/block/js/block.admin.js b/core/modules/block/js/block.admin.js index 422a83a..89739c7 100644 --- a/core/modules/block/js/block.admin.js +++ b/core/modules/block/js/block.admin.js @@ -74,7 +74,7 @@ Drupal.behaviors.blockHighlightPlacement = { attach: function (context, settings) { if (settings.blockPlacement) { - $('#blocks').once('block-highlight', function () { + $('#blocks').once('block-highlight').each(function () { var $container = $(this); // Just scrolling the document.body will not work in Firefox. The html // element is needed as well. diff --git a/core/modules/block/js/block.js b/core/modules/block/js/block.js index c25842f..2b727c4 100644 --- a/core/modules/block/js/block.js +++ b/core/modules/block/js/block.js @@ -91,7 +91,7 @@ }; // Add the behavior to each region select list. - $(context).find('select.block-region-select').once('block-region-select', function () { + $(context).find('select.block-region-select').once('block-region-select').each(function () { $(this).on('change', function (event) { // Make our new row and select field. var row = $(this).closest('tr'); diff --git a/core/modules/ckeditor/js/ckeditor.admin.js b/core/modules/ckeditor/js/ckeditor.admin.js index 671313a..7df2d54 100644 --- a/core/modules/ckeditor/js/ckeditor.admin.js +++ b/core/modules/ckeditor/js/ckeditor.admin.js @@ -11,8 +11,8 @@ Drupal.behaviors.ckeditorAdmin = { attach: function (context) { // Process the CKEditor configuration fragment once. - var $configurationForm = $(context).find('.ckeditor-toolbar-configuration'); - if ($configurationForm.once('ckeditor-configuration').length) { + var $configurationForm = $(context).find('.ckeditor-toolbar-configuration').once('ckeditor-configuration'); + if ($configurationForm.length) { var $textarea = $configurationForm // Hide the textarea that contains the serialized representation of the // CKEditor configuration. @@ -55,7 +55,7 @@ // really means that all CKEditor toolbar buttons have been removed. Hence, // all editor features will be removed, so any reactions from filters will // be undone. - var $configurationForm = $(context).find('.ckeditor-toolbar-configuration.ckeditor-configuration-processed'); + var $configurationForm = $(context).find('.ckeditor-toolbar-configuration').findOnce('ckeditor-configuration'); if ($configurationForm.length && Drupal.ckeditor.models && Drupal.ckeditor.models.Model) { var config = Drupal.ckeditor.models.Model.toJSON().activeEditorConfig; var buttons = Drupal.ckeditor.views.controller.getButtonList(config); diff --git a/core/modules/content_translation/content_translation.admin.js b/core/modules/content_translation/content_translation.admin.js index c10efa1..1f4224b 100644 --- a/core/modules/content_translation/content_translation.admin.js +++ b/core/modules/content_translation/content_translation.admin.js @@ -70,7 +70,7 @@ attach: function (context) { // Initially hide all field rows for non translatable bundles and all column // rows for non translatable fields. - $(context).find('table .bundle-settings .translatable :input').once('translation-entity-admin-hide', function () { + $(context).find('table .bundle-settings .translatable :input').once('translation-entity-admin-hide').each(function () { var $input = $(this); var $bundleSettings = $input.closest('.bundle-settings'); if (!$input.is(':checked')) { diff --git a/core/modules/editor/js/editor.admin.js b/core/modules/editor/js/editor.admin.js index 74a38b2..cbd1510 100644 --- a/core/modules/editor/js/editor.admin.js +++ b/core/modules/editor/js/editor.admin.js @@ -714,7 +714,7 @@ attach: function (context, settings) { var $context = $(context); - $context.find('#filters-status-wrapper input.form-checkbox').once('filter-editor-status', function () { + $context.find('#filters-status-wrapper input.form-checkbox').once('filter-editor-status').each(function () { var $checkbox = $(this); var nameAttribute = $checkbox.attr('name'); diff --git a/core/modules/editor/js/editor.js b/core/modules/editor/js/editor.js index 022bc9f..c6bbfd6 100644 --- a/core/modules/editor/js/editor.js +++ b/core/modules/editor/js/editor.js @@ -140,7 +140,7 @@ return; } - $(context).find('.editor').once('editor', function () { + $(context).find('.editor').once('editor').each(function () { var $this = $(this); var activeFormatID = $this.val(); $this.attr('data-editor-active-text-format', activeFormatID); @@ -188,7 +188,7 @@ if (trigger === 'serialize') { // Removing the editor-processed class guarantees that the editor will // be reattached. Only do this if we're planning to destroy the editor. - editors = $(context).find('.editor-processed'); + editors = $(context).find('.editor').findOnce('editor'); } else { editors = $(context).find('.editor').removeOnce('editor'); diff --git a/core/modules/field_ui/field_ui.js b/core/modules/field_ui/field_ui.js index 6394c3e..11e6981 100644 --- a/core/modules/field_ui/field_ui.js +++ b/core/modules/field_ui/field_ui.js @@ -54,7 +54,7 @@ Drupal.behaviors.fieldUIDisplayOverview = { attach: function (context, settings) { - $(context).find('table#field-display-overview').once('field-display-overview', function () { + $(context).find('table#field-display-overview').once('field-display-overview').each(function () { Drupal.fieldUIOverview.attach(this, settings.fieldUIRowsData, Drupal.fieldUIDisplayOverview); }); } diff --git a/core/modules/file/file.js b/core/modules/file/file.js index fcefad1..b704542 100644 --- a/core/modules/file/file.js +++ b/core/modules/file/file.js @@ -134,10 +134,10 @@ * Prevent file uploads when using buttons not intended to upload. */ disableFields: function (event) { - var $clickedButton = $(this); + var $clickedButton = $(this).findOnce('ajax'); // Only disable upload fields for Ajax buttons. - if (!$clickedButton.hasClass('ajax-processed')) { + if (!$clickedButton.length) { return; } diff --git a/core/modules/filter/filter.admin.js b/core/modules/filter/filter.admin.js index 959442a..ba650c8 100644 --- a/core/modules/filter/filter.admin.js +++ b/core/modules/filter/filter.admin.js @@ -10,7 +10,7 @@ Drupal.behaviors.filterStatus = { attach: function (context, settings) { var $context = $(context); - $context.find('#filters-status-wrapper input.form-checkbox').once('filter-status', function () { + $context.find('#filters-status-wrapper input.form-checkbox').once('filter-status').each(function () { var $checkbox = $(this); // Retrieve the tabledrag row belonging to this filter. var $row = $context.find('#' + $checkbox.attr('id').replace(/-status$/, '-weight')).closest('tr'); diff --git a/core/modules/filter/filter.filter_html.admin.js b/core/modules/filter/filter.filter_html.admin.js index a11fca5..a74b938 100644 --- a/core/modules/filter/filter.filter_html.admin.js +++ b/core/modules/filter/filter.filter_html.admin.js @@ -55,7 +55,7 @@ attach: function (context, settings) { var that = this; - $(context).find('[name="filters[filter_html][settings][allowed_html]"]').once('filter-filter_html-updating', function () { + $(context).find('[name="filters[filter_html][settings][allowed_html]"]').once('filter-filter_html-updating').each(function () { that.$allowedHTMLFormItem = $(this); that.$allowedHTMLDescription = that.$allowedHTMLFormItem.closest('.form-item').find('.description'); that.userTags = that._parseSetting(this.value); diff --git a/core/modules/menu_ui/menu_ui.admin.js b/core/modules/menu_ui/menu_ui.admin.js index 4a04ab0..06a9f34 100644 --- a/core/modules/menu_ui/menu_ui.admin.js +++ b/core/modules/menu_ui/menu_ui.admin.js @@ -4,15 +4,15 @@ Drupal.behaviors.menuUiChangeParentItems = { attach: function (context, settings) { - var $menu = $('#edit-menu'); - $menu.once('menu-parent', function () { + var $menu = $('#edit-menu').once('menu-parent'); + if ($menu.length) { // Update the list of available parent menu items to match the initial // available menus. Drupal.menuUiUpdateParentList(); // Update list of available parent menu items. $menu.on('change', 'input', Drupal.menuUiUpdateParentList); - }); + } } }; diff --git a/core/modules/quickedit/js/quickedit.js b/core/modules/quickedit/js/quickedit.js index 539fc3e..238ba0d 100644 --- a/core/modules/quickedit/js/quickedit.js +++ b/core/modules/quickedit/js/quickedit.js @@ -66,7 +66,7 @@ Drupal.behaviors.quickedit = { attach: function (context) { // Initialize the Quick Edit app once per page load. - $('body').once('quickedit-init', initQuickEdit); + $('body').once('quickedit-init').each(initQuickEdit); // Find all in-place editable fields, if any. var $fields = $(context).find('[data-quickedit-field-id]').once('quickedit'); diff --git a/core/modules/simpletest/simpletest.js b/core/modules/simpletest/simpletest.js index 7e365bd..b1c63de 100644 --- a/core/modules/simpletest/simpletest.js +++ b/core/modules/simpletest/simpletest.js @@ -7,7 +7,7 @@ */ Drupal.behaviors.simpleTestGroupCollapse = { attach: function (context) { - $(context).find('.simpletest-group').once('simpletest-group-collapse', function () { + $(context).find('.simpletest-group').once('simpletest-group-collapse').each(function () { var $group = $(this); var $image = $group.find('.simpletest-image'); $image @@ -28,7 +28,7 @@ */ Drupal.behaviors.simpleTestSelectAll = { attach: function (context) { - $(context).find('.simpletest-group').once('simpletest-group-select-all', function () { + $(context).find('.simpletest-group').once('simpletest-group-select-all').each(function () { var $group = $(this); var $cell = $group.find('.simpletest-group-select-all'); var $groupCheckbox = $(''); diff --git a/core/modules/text/text.js b/core/modules/text/text.js index 10aed14..0895415 100644 --- a/core/modules/text/text.js +++ b/core/modules/text/text.js @@ -7,7 +7,7 @@ */ Drupal.behaviors.textSummary = { attach: function (context, settings) { - $(context).find('.text-summary').once('text-summary', function () { + $(context).find('.text-summary').once('text-summary').each(function () { var $widget = $(this).closest('.text-format-wrapper'); var $summary = $widget.find('.text-summary-wrapper'); diff --git a/core/modules/toolbar/js/toolbar.js b/core/modules/toolbar/js/toolbar.js index dcfbb2a..efbad03 100644 --- a/core/modules/toolbar/js/toolbar.js +++ b/core/modules/toolbar/js/toolbar.js @@ -43,7 +43,7 @@ return; } // Process the administrative toolbar. - $(context).find('#toolbar-administration').once('toolbar', function () { + $(context).find('#toolbar-administration').once('toolbar').each(function () { // Establish the toolbar models and views. var model = Drupal.toolbar.models.toolbarModel = new Drupal.toolbar.ToolbarModel({ diff --git a/core/modules/tour/js/tour.js b/core/modules/tour/js/tour.js index cee9feb..f8bc85f 100644 --- a/core/modules/tour/js/tour.js +++ b/core/modules/tour/js/tour.js @@ -23,7 +23,7 @@ */ Drupal.behaviors.tour = { attach: function (context) { - $('body').once('tour', function (index, element) { + $('body').once('tour').each(function() { var model = new Drupal.tour.models.StateModel(); new Drupal.tour.views.ToggleTourView({ el: $(context).find('#toolbar-tab-tour'), @@ -42,7 +42,6 @@ if (/tour=?/i.test(queryString)) { model.set('isActive', true); } - }); } }; diff --git a/core/modules/user/user.js b/core/modules/user/user.js index 51fb591..f9dc00e 100644 --- a/core/modules/user/user.js +++ b/core/modules/user/user.js @@ -9,7 +9,7 @@ Drupal.behaviors.password = { attach: function (context, settings) { var translate = settings.password; - $(context).find('input.password-field').once('password', function () { + $(context).find('input.password-field').once('password').each(function () { var passwordInput = $(this); var innerWrapper = $(this).parent(); var outerWrapper = $(this).parent().parent(); diff --git a/core/modules/user/user.permissions.js b/core/modules/user/user.permissions.js index 415fc53..d47ee9a 100644 --- a/core/modules/user/user.permissions.js +++ b/core/modules/user/user.permissions.js @@ -8,7 +8,7 @@ Drupal.behaviors.permissions = { attach: function (context) { var self = this; - $('table#permissions').once('permissions', function () { + $('table#permissions').once('permissions').each(function () { // On a site with many roles and permissions, this behavior initially has // to perform thousands of DOM manipulations to inject checkboxes and hide // them. By detaching the table from the DOM, all operations can be diff --git a/core/modules/views/js/ajax_view.js b/core/modules/views/js/ajax_view.js index 3139112..3e0b680 100644 --- a/core/modules/views/js/ajax_view.js +++ b/core/modules/views/js/ajax_view.js @@ -63,14 +63,14 @@ // Add the ajax to exposed forms. this.$exposed_form = $('form#views-exposed-form-' + settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-')); - this.$exposed_form.once('exposed-form', jQuery.proxy(this.attachExposedFormAjax, this)); + this.$exposed_form.once('exposed-form').each(jQuery.proxy(this.attachExposedFormAjax, this)); // Add the ajax to pagers. this.$view // Don't attach to nested views. Doing so would attach multiple behaviors // to a given element. .filter(jQuery.proxy(this.filterNestedViews, this)) - .once('ajax-pager', jQuery.proxy(this.attachPagerAjax, this)); + .once('ajax-pager').each(jQuery.proxy(this.attachPagerAjax, this)); // Add a trigger to update this view specifically. In order to trigger a // refresh use the following code. diff --git a/core/modules/views_ui/js/views-admin.js b/core/modules/views_ui/js/views-admin.js index 5310062..9c2378b 100644 --- a/core/modules/views_ui/js/views-admin.js +++ b/core/modules/views_ui/js/views-admin.js @@ -233,7 +233,7 @@ Drupal.behaviors.viewsUiRenderAddViewButton = { attach: function (context) { // Build the add display menu and pull the display input buttons into it. - var $menu = $(context).find('#views-display-menu-tabs').once('views-ui-render-add-view-button-processed'); + var $menu = $(context).find('#views-display-menu-tabs').once('views-ui-render-add-view-button'); if (!$menu.length) { return; } @@ -795,9 +795,7 @@ */ Drupal.behaviors.viewsRemoveIconClass = { attach: function (context) { - $(context).find('.dropbutton').once('dropbutton-icon', function () { - $(this).find('.icon').removeClass('icon'); - }); + $(context).find('.dropbutton').once('dropbutton-icon').find('.icon').removeClass('icon'); } }; @@ -874,7 +872,7 @@ */ Drupal.behaviors.viewsUiOverrideSelect = { attach: function (context) { - $(context).find('#edit-override-dropdown').once('views-ui-override-button-text', function () { + $(context).find('#edit-override-dropdown').once('views-ui-override-button-text').each(function () { // Closures! :( var $context = $(context); var $submit = $context.find('[id^=edit-submit]');