HEX
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/8.0.30
System: Linux multiplicar 3.10.0-1160.102.1.el7.x86_64 #1 SMP Tue Oct 17 15:42:21 UTC 2023 x86_64
User: root (0)
PHP: 8.0.30
Disabled: NONE
Upload Files
File: /var/www/html/universidad.bristol.com.py/lib/amd/build/form-autocomplete.min.js.map
{"version":3,"file":"form-autocomplete.min.js","sources":["../src/form-autocomplete.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Autocomplete wrapper for select2 library.\n *\n * @module     core/form-autocomplete\n * @copyright  2015 Damyon Wiese <damyon@moodle.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since      3.0\n */\ndefine([\n    'jquery',\n    'core/log',\n    'core/str',\n    'core/templates',\n    'core/notification',\n    'core/loadingicon',\n    'core/aria',\n    'core_form/changechecker',\n], function(\n    $,\n    log,\n    str,\n    templates,\n    notification,\n    LoadingIcon,\n    Aria,\n    FormChangeChecker\n) {\n    // Private functions and variables.\n    /** @var {Object} KEYS - List of keycode constants. */\n    var KEYS = {\n        DOWN: 40,\n        ENTER: 13,\n        SPACE: 32,\n        ESCAPE: 27,\n        COMMA: 44,\n        UP: 38,\n        LEFT: 37,\n        RIGHT: 39\n    };\n\n    var uniqueId = Date.now();\n\n    /**\n     * Make an item in the selection list \"active\".\n     *\n     * @method activateSelection\n     * @private\n     * @param {Number} index The index in the current (visible) list of selection.\n     * @param {Object} state State variables for this autocomplete element.\n     * @return {Promise}\n     */\n    var activateSelection = function(index, state) {\n        // Find the elements in the DOM.\n        var selectionElement = $(document.getElementById(state.selectionId));\n\n        // Count the visible items.\n        var length = selectionElement.children('[aria-selected=true]').length;\n        // Limit the index to the upper/lower bounds of the list (wrap in both directions).\n        index = index % length;\n        while (index < 0) {\n            index += length;\n        }\n        // Find the specified element.\n        var element = $(selectionElement.children('[aria-selected=true]').get(index));\n        // Create an id we can assign to this element.\n        var itemId = state.selectionId + '-' + index;\n\n        // Deselect all the selections.\n        selectionElement.children().attr('data-active-selection', null).attr('id', '');\n\n        // Select only this suggestion and assign it the id.\n        element.attr('data-active-selection', true).attr('id', itemId);\n\n        // Tell the input field it has a new active descendant so the item is announced.\n        selectionElement.attr('aria-activedescendant', itemId);\n        selectionElement.attr('data-active-value', element.attr('data-value'));\n\n        return $.Deferred().resolve();\n    };\n\n    /**\n     * Get the actively selected element from the state object.\n     *\n     * @param   {Object} state\n     * @returns {jQuery}\n     */\n    var getActiveElementFromState = function(state) {\n        var selectionRegion = $(document.getElementById(state.selectionId));\n        var activeId = selectionRegion.attr('aria-activedescendant');\n\n        if (activeId) {\n            var activeElement = $(document.getElementById(activeId));\n            if (activeElement.length) {\n                // The active descendent still exists.\n                return activeElement;\n            }\n        }\n\n        // Ensure we are creating a properly formed selector based on the active value.\n        var activeValue = selectionRegion.attr('data-active-value')?.replace(/\"/g, '\\\\\"');\n        return selectionRegion.find('[data-value=\"' + activeValue + '\"]');\n    };\n\n    /**\n     * Update the active selection from the given state object.\n     *\n     * @param   {Object} state\n     */\n    var updateActiveSelectionFromState = function(state) {\n        var activeElement = getActiveElementFromState(state);\n        var activeValue = activeElement.attr('data-value');\n\n        var selectionRegion = $(document.getElementById(state.selectionId));\n        if (activeValue) {\n            // Find the index of the currently selected index.\n            var activeIndex = selectionRegion.find('[aria-selected=true]').index(activeElement);\n\n            if (activeIndex !== -1) {\n                activateSelection(activeIndex, state);\n                return;\n            }\n        }\n\n        // Either the active index was not set, or it could not be found.\n        // Select the first value instead.\n        activateSelection(0, state);\n    };\n\n    /**\n     * Update the element that shows the currently selected items.\n     *\n     * @method updateSelectionList\n     * @private\n     * @param {Object} options Original options for this autocomplete element.\n     * @param {Object} state State variables for this autocomplete element.\n     * @param {JQuery} originalSelect The JQuery object matching the hidden select list.\n     * @return {Promise}\n     */\n    var updateSelectionList = function(options, state, originalSelect) {\n        var pendingKey = 'form-autocomplete-updateSelectionList-' + state.inputId;\n        M.util.js_pending(pendingKey);\n\n        // Build up a valid context to re-render the template.\n        var items = [];\n        var newSelection = $(document.getElementById(state.selectionId));\n        originalSelect.children('option').each(function(index, ele) {\n            if ($(ele).prop('selected')) {\n                var label;\n                if ($(ele).data('html')) {\n                    label = $(ele).data('html');\n                } else {\n                    label = $(ele).html();\n                }\n                if (label !== '') {\n                    items.push({label: label, value: $(ele).attr('value')});\n                }\n            }\n        });\n\n        if (!hasItemListChanged(state, items)) {\n            M.util.js_complete(pendingKey);\n            return Promise.resolve();\n        }\n\n        state.items = items;\n\n        var context = $.extend(options, state);\n        // Render the template.\n        return templates.render(options.templates.items, context)\n        .then(function(html, js) {\n            // Add it to the page.\n            templates.replaceNodeContents(newSelection, html, js);\n\n            updateActiveSelectionFromState(state);\n\n            return;\n        })\n        .then(function() {\n            return M.util.js_complete(pendingKey);\n        })\n        .catch(notification.exception);\n    };\n\n    /**\n     * Check whether the list of items stored in the state has changed.\n     *\n     * @param   {Object} state\n     * @param   {Array} items\n     * @returns {Boolean}\n     */\n    var hasItemListChanged = function(state, items) {\n        if (state.items.length !== items.length) {\n            return true;\n        }\n\n        // Check for any items in the state items which are not present in the new items list.\n        return state.items.filter(item => items.indexOf(item) === -1).length > 0;\n    };\n\n    /**\n     * Notify of a change in the selection.\n     *\n     * @param {jQuery} originalSelect The jQuery object matching the hidden select list.\n     */\n    var notifyChange = function(originalSelect) {\n        FormChangeChecker.markFormChangedFromNode(originalSelect[0]);\n\n        // Note, jQuery .change() was not working here. Better to\n        // use plain JavaScript anyway.\n        originalSelect[0].dispatchEvent(new Event('change'));\n    };\n\n    /**\n     * Remove the given item from the list of selected things.\n     *\n     * @method deselectItem\n     * @private\n     * @param {Object} options Original options for this autocomplete element.\n     * @param {Object} state State variables for this autocomplete element.\n     * @param {Element} item The item to be deselected.\n     * @param {Element} originalSelect The original select list.\n     * @return {Promise}\n     */\n    var deselectItem = function(options, state, item, originalSelect) {\n        var selectedItemValue = $(item).attr('data-value');\n\n        // Preprend an empty option to the select list to avoid having a default selected option.\n        originalSelect.prepend($('<option>'));\n\n        // Look for a match, and toggle the selected property if there is a match.\n        originalSelect.children('option').each(function(index, ele) {\n            if ($(ele).attr('value') == selectedItemValue) {\n                $(ele).prop('selected', false);\n                // We remove newly created custom tags from the suggestions list when they are deselected.\n                if ($(ele).attr('data-iscustom')) {\n                    $(ele).remove();\n                }\n            }\n        });\n        // Rerender the selection list.\n        return updateSelectionList(options, state, originalSelect)\n        .then(function() {\n            // Notify that the selection changed.\n            notifyChange(originalSelect);\n\n            return;\n        });\n    };\n\n    /**\n     * Make an item in the suggestions \"active\" (about to be selected).\n     *\n     * @method activateItem\n     * @private\n     * @param {Number} index The index in the current (visible) list of suggestions.\n     * @param {Object} state State variables for this instance of autocomplete.\n     * @return {Promise}\n     */\n    var activateItem = function(index, state) {\n        // Find the elements in the DOM.\n        var inputElement = $(document.getElementById(state.inputId));\n        var suggestionsElement = $(document.getElementById(state.suggestionsId));\n\n        // Count the visible items.\n        var length = suggestionsElement.children(':not([aria-hidden])').length;\n        // Limit the index to the upper/lower bounds of the list (wrap in both directions).\n        index = index % length;\n        while (index < 0) {\n            index += length;\n        }\n        // Find the specified element.\n        var element = $(suggestionsElement.children(':not([aria-hidden])').get(index));\n        // Find the index of this item in the full list of suggestions (including hidden).\n        var globalIndex = $(suggestionsElement.children('[role=option]')).index(element);\n        // Create an id we can assign to this element.\n        var itemId = state.suggestionsId + '-' + globalIndex;\n\n        // Deselect all the suggestions.\n        suggestionsElement.children().attr('aria-selected', false).attr('id', '');\n        // Select only this suggestion and assign it the id.\n        element.attr('aria-selected', true).attr('id', itemId);\n        // Tell the input field it has a new active descendant so the item is announced.\n        inputElement.attr('aria-activedescendant', itemId);\n\n        // Scroll it into view.\n        var scrollPos = element.offset().top\n                       - suggestionsElement.offset().top\n                       + suggestionsElement.scrollTop()\n                       - (suggestionsElement.height() / 2);\n        return suggestionsElement.animate({\n            scrollTop: scrollPos\n        }, 100).promise();\n    };\n\n    /**\n     * Find the index of the current active suggestion, and activate the next one.\n     *\n     * @method activateNextItem\n     * @private\n     * @param {Object} state State variable for this auto complete element.\n     * @return {Promise}\n     */\n    var activateNextItem = function(state) {\n        // Find the list of suggestions.\n        var suggestionsElement = $(document.getElementById(state.suggestionsId));\n        // Find the active one.\n        var element = suggestionsElement.children('[aria-selected=true]');\n        // Find it's index.\n        var current = suggestionsElement.children(':not([aria-hidden])').index(element);\n        // Activate the next one.\n        return activateItem(current + 1, state);\n    };\n\n    /**\n     * Find the index of the current active selection, and activate the previous one.\n     *\n     * @method activatePreviousSelection\n     * @private\n     * @param {Object} state State variables for this instance of autocomplete.\n     * @return {Promise}\n     */\n    var activatePreviousSelection = function(state) {\n        // Find the list of selections.\n        var selectionsElement = $(document.getElementById(state.selectionId));\n        // Find the active one.\n        var element = selectionsElement.children('[data-active-selection]');\n        if (!element) {\n            return activateSelection(0, state);\n        }\n        // Find it's index.\n        var current = selectionsElement.children('[aria-selected=true]').index(element);\n        // Activate the next one.\n        return activateSelection(current - 1, state);\n    };\n\n    /**\n     * Find the index of the current active selection, and activate the next one.\n     *\n     * @method activateNextSelection\n     * @private\n     * @param {Object} state State variables for this instance of autocomplete.\n     * @return {Promise}\n     */\n    var activateNextSelection = function(state) {\n        // Find the list of selections.\n        var selectionsElement = $(document.getElementById(state.selectionId));\n\n        // Find the active one.\n        var element = selectionsElement.children('[data-active-selection]');\n        var current = 0;\n\n        if (element) {\n            // The element was found. Determine the index and move to the next one.\n            current = selectionsElement.children('[aria-selected=true]').index(element);\n            current = current + 1;\n        } else {\n            // No selected item found. Move to the first.\n            current = 0;\n        }\n\n        return activateSelection(current, state);\n    };\n\n    /**\n     * Find the index of the current active suggestion, and activate the previous one.\n     *\n     * @method activatePreviousItem\n     * @private\n     * @param {Object} state State variables for this autocomplete element.\n     * @return {Promise}\n     */\n    var activatePreviousItem = function(state) {\n        // Find the list of suggestions.\n        var suggestionsElement = $(document.getElementById(state.suggestionsId));\n\n        // Find the active one.\n        var element = suggestionsElement.children('[aria-selected=true]');\n\n        // Find it's index.\n        var current = suggestionsElement.children(':not([aria-hidden])').index(element);\n\n        // Activate the previous one.\n        return activateItem(current - 1, state);\n    };\n\n    /**\n     * Close the list of suggestions.\n     *\n     * @method closeSuggestions\n     * @private\n     * @param {Object} state State variables for this autocomplete element.\n     * @return {Promise}\n     */\n    var closeSuggestions = function(state) {\n        // Find the elements in the DOM.\n        var inputElement = $(document.getElementById(state.inputId));\n        var suggestionsElement = $(document.getElementById(state.suggestionsId));\n\n        if (inputElement.attr('aria-expanded') === \"true\") {\n            // Announce the list of suggestions was closed.\n            inputElement.attr('aria-expanded', false);\n        }\n        // Read the current list of selections.\n        inputElement.attr('aria-activedescendant', state.selectionId);\n\n        // Hide the suggestions list (from screen readers too).\n        Aria.hide(suggestionsElement.get());\n        suggestionsElement.hide();\n\n        return $.Deferred().resolve();\n    };\n\n    /**\n     * Rebuild the list of suggestions based on the current values in the select list, and the query.\n     *\n     * @method updateSuggestions\n     * @private\n     * @param {Object} options The original options for this autocomplete.\n     * @param {Object} state The state variables for this autocomplete.\n     * @param {String} query The current text for the search string.\n     * @param {JQuery} originalSelect The JQuery object matching the hidden select list.\n     * @return {Promise}\n     */\n    var updateSuggestions = function(options, state, query, originalSelect) {\n        var pendingKey = 'form-autocomplete-updateSuggestions-' + state.inputId;\n        M.util.js_pending(pendingKey);\n\n        // Find the elements in the DOM.\n        var inputElement = $(document.getElementById(state.inputId));\n        var suggestionsElement = $(document.getElementById(state.suggestionsId));\n\n        // Used to track if we found any visible suggestions.\n        var matchingElements = false;\n        // Options is used by the context when rendering the suggestions from a template.\n        var suggestions = [];\n        originalSelect.children('option').each(function(index, option) {\n            if ($(option).prop('selected') !== true) {\n                suggestions[suggestions.length] = {label: option.innerHTML, value: $(option).attr('value')};\n            }\n        });\n\n        // Re-render the list of suggestions.\n        var searchquery = state.caseSensitive ? query : query.toLocaleLowerCase();\n        var context = $.extend({options: suggestions}, options, state);\n        var returnVal = templates.render(\n            'core/form_autocomplete_suggestions',\n            context\n        )\n        .then(function(html, js) {\n            // We have the new template, insert it in the page.\n            templates.replaceNode(suggestionsElement, html, js);\n\n            // Get the element again.\n            suggestionsElement = $(document.getElementById(state.suggestionsId));\n\n            // Show it if it is hidden.\n            Aria.unhide(suggestionsElement.get());\n            suggestionsElement.show();\n\n            // For each option in the list, hide it if it doesn't match the query.\n            suggestionsElement.children().each(function(index, node) {\n                node = $(node);\n                if ((options.caseSensitive && node.text().indexOf(searchquery) > -1) ||\n                        (!options.caseSensitive && node.text().toLocaleLowerCase().indexOf(searchquery) > -1)) {\n                    Aria.unhide(node.get());\n                    node.show();\n                    matchingElements = true;\n                } else {\n                    node.hide();\n                    Aria.hide(node.get());\n                }\n            });\n            // If we found any matches, show the list.\n            inputElement.attr('aria-expanded', true);\n            if (originalSelect.attr('data-notice')) {\n                // Display a notice rather than actual suggestions.\n                suggestionsElement.html(originalSelect.attr('data-notice'));\n            } else if (matchingElements) {\n                // We only activate the first item in the list if tags is false,\n                // because otherwise \"Enter\" would select the first item, instead of\n                // creating a new tag.\n                if (!options.tags) {\n                    activateItem(0, state);\n                }\n            } else {\n                // Nothing matches. Tell them that.\n                str.get_string('nosuggestions', 'form').done(function(nosuggestionsstr) {\n                    suggestionsElement.html(nosuggestionsstr);\n                });\n            }\n\n            return suggestionsElement;\n        })\n        .then(function() {\n            return M.util.js_complete(pendingKey);\n        })\n        .catch(notification.exception);\n\n        return returnVal;\n    };\n\n    /**\n     * Create a new item for the list (a tag).\n     *\n     * @method createItem\n     * @private\n     * @param {Object} options The original options for the autocomplete.\n     * @param {Object} state State variables for the autocomplete.\n     * @param {JQuery} originalSelect The JQuery object matching the hidden select list.\n     * @return {Promise}\n     */\n    var createItem = function(options, state, originalSelect) {\n        // Find the element in the DOM.\n        var inputElement = $(document.getElementById(state.inputId));\n        // Get the current text in the input field.\n        var query = inputElement.val();\n        var tags = query.split(',');\n        var found = false;\n\n        $.each(tags, function(tagindex, tag) {\n            // If we can only select one at a time, deselect any current value.\n            tag = tag.trim();\n            if (tag !== '') {\n                if (!options.multiple) {\n                    originalSelect.children('option').prop('selected', false);\n                }\n                // Look for an existing option in the select list that matches this new tag.\n                originalSelect.children('option').each(function(index, ele) {\n                    if ($(ele).attr('value') == tag) {\n                        found = true;\n                        $(ele).prop('selected', true);\n                    }\n                });\n                // Only create the item if it's new.\n                if (!found) {\n                    var option = $('<option>');\n                    option.append(document.createTextNode(tag));\n                    option.attr('value', tag);\n                    originalSelect.append(option);\n                    option.prop('selected', true);\n                    // We mark newly created custom options as we handle them differently if they are \"deselected\".\n                    option.attr('data-iscustom', true);\n                }\n            }\n        });\n\n        return updateSelectionList(options, state, originalSelect)\n        .then(function() {\n            // Notify that the selection changed.\n            notifyChange(originalSelect);\n\n            return;\n        })\n        .then(function() {\n            // Clear the input field.\n            inputElement.val('');\n\n            return;\n        })\n        .then(function() {\n            // Close the suggestions list.\n            return closeSuggestions(state);\n        });\n    };\n\n    /**\n     * Select the currently active item from the suggestions list.\n     *\n     * @method selectCurrentItem\n     * @private\n     * @param {Object} options The original options for the autocomplete.\n     * @param {Object} state State variables for the autocomplete.\n     * @param {JQuery} originalSelect The JQuery object matching the hidden select list.\n     * @return {Promise}\n     */\n    var selectCurrentItem = function(options, state, originalSelect) {\n        // Find the elements in the page.\n        var inputElement = $(document.getElementById(state.inputId));\n        var suggestionsElement = $(document.getElementById(state.suggestionsId));\n        // Here loop through suggestions and set val to join of all selected items.\n\n        var selectedItemValue = suggestionsElement.children('[aria-selected=true]').attr('data-value');\n        // The select will either be a single or multi select, so the following will either\n        // select one or more items correctly.\n        // Take care to use 'prop' and not 'attr' for selected properties.\n        // If only one can be selected at a time, start by deselecting everything.\n        if (!options.multiple) {\n            originalSelect.children('option').prop('selected', false);\n        }\n        // Look for a match, and toggle the selected property if there is a match.\n        originalSelect.children('option').each(function(index, ele) {\n            if ($(ele).attr('value') == selectedItemValue) {\n                $(ele).prop('selected', true);\n            }\n        });\n\n        return updateSelectionList(options, state, originalSelect)\n        .then(function() {\n            // Notify that the selection changed.\n            notifyChange(originalSelect);\n\n            return;\n        })\n        .then(function() {\n            if (options.closeSuggestionsOnSelect) {\n                // Clear the input element.\n                inputElement.val('');\n                // Close the list of suggestions.\n                return closeSuggestions(state);\n            } else {\n                // Focus on the input element so the suggestions does not auto-close.\n                inputElement.focus();\n                // Remove the last selected item from the suggestions list.\n                return updateSuggestions(options, state, inputElement.val(), originalSelect);\n            }\n        });\n    };\n\n    /**\n     * Fetch a new list of options via ajax.\n     *\n     * @method updateAjax\n     * @private\n     * @param {Event} e The event that triggered this update.\n     * @param {Object} options The original options for the autocomplete.\n     * @param {Object} state The state variables for the autocomplete.\n     * @param {JQuery} originalSelect The JQuery object matching the hidden select list.\n     * @param {Object} ajaxHandler This is a module that does the ajax fetch and translates the results.\n     * @return {Promise}\n     */\n    var updateAjax = function(e, options, state, originalSelect, ajaxHandler) {\n        var pendingPromise = addPendingJSPromise('updateAjax');\n        // We need to show the indicator outside of the hidden select list.\n        // So we get the parent id of the hidden select list.\n        var parentElement = $(document.getElementById(state.selectId)).parent();\n        LoadingIcon.addIconToContainerRemoveOnCompletion(parentElement, pendingPromise);\n\n        // Get the query to pass to the ajax function.\n        var query = $(e.currentTarget).val();\n        // Call the transport function to do the ajax (name taken from Select2).\n        ajaxHandler.transport(options.selector, query, function(results) {\n            // We got a result - pass it through the translator before using it.\n            var processedResults = ajaxHandler.processResults(options.selector, results);\n            var existingValues = [];\n\n            // Now destroy all options that are not current\n            originalSelect.children('option').each(function(optionIndex, option) {\n                option = $(option);\n                if (!option.prop('selected')) {\n                    option.remove();\n                } else {\n                    existingValues.push(String(option.attr('value')));\n                }\n            });\n\n            if (!options.multiple && originalSelect.children('option').length === 0) {\n                // If this is a single select - and there are no current options\n                // the first option added will be selected by the browser. This causes a bug!\n                // We need to insert an empty option so that none of the real options are selected.\n                var option = $('<option>');\n                originalSelect.append(option);\n            }\n            if ($.isArray(processedResults)) {\n                // Add all the new ones returned from ajax.\n                $.each(processedResults, function(resultIndex, result) {\n                    if (existingValues.indexOf(String(result.value)) === -1) {\n                        var option = $('<option>');\n                        option.append(result.label);\n                        option.attr('value', result.value);\n                        originalSelect.append(option);\n                    }\n                });\n                originalSelect.attr('data-notice', '');\n            } else {\n                // The AJAX handler returned a string instead of the array.\n                originalSelect.attr('data-notice', processedResults);\n            }\n            // Update the list of suggestions now from the new values in the select list.\n            pendingPromise.resolve(updateSuggestions(options, state, '', originalSelect));\n        }, function(error) {\n            pendingPromise.reject(error);\n        });\n\n        return pendingPromise;\n    };\n\n    /**\n     * Add all the event listeners required for keyboard nav, blur clicks etc.\n     *\n     * @method addNavigation\n     * @private\n     * @param {Object} options The options used to create this autocomplete element.\n     * @param {Object} state State variables for this autocomplete element.\n     * @param {JQuery} originalSelect The JQuery object matching the hidden select list.\n     */\n    var addNavigation = function(options, state, originalSelect) {\n        // Start with the input element.\n        var inputElement = $(document.getElementById(state.inputId));\n        // Add keyboard nav with keydown.\n        inputElement.on('keydown', function(e) {\n            var pendingJsPromise = addPendingJSPromise('addNavigation-' + state.inputId + '-' + e.keyCode);\n\n            switch (e.keyCode) {\n                case KEYS.DOWN:\n                    // If the suggestion list is open, move to the next item.\n                    if (!options.showSuggestions) {\n                        // Do not consume this event.\n                        pendingJsPromise.resolve();\n                        return true;\n                    } else if (inputElement.attr('aria-expanded') === \"true\") {\n                        pendingJsPromise.resolve(activateNextItem(state));\n                    } else {\n                        // Handle ajax population of suggestions.\n                        if (!inputElement.val() && options.ajax) {\n                            require([options.ajax], function(ajaxHandler) {\n                                pendingJsPromise.resolve(updateAjax(e, options, state, originalSelect, ajaxHandler));\n                            });\n                        } else {\n                            // Open the suggestions list.\n                            pendingJsPromise.resolve(updateSuggestions(options, state, inputElement.val(), originalSelect));\n                        }\n                    }\n                    // We handled this event, so prevent it.\n                    e.preventDefault();\n                    return false;\n                case KEYS.UP:\n                    // Choose the previous active item.\n                    pendingJsPromise.resolve(activatePreviousItem(state));\n\n                    // We handled this event, so prevent it.\n                    e.preventDefault();\n                    return false;\n                case KEYS.ENTER:\n                    var suggestionsElement = $(document.getElementById(state.suggestionsId));\n                    if ((inputElement.attr('aria-expanded') === \"true\") &&\n                            (suggestionsElement.children('[aria-selected=true]').length > 0)) {\n                        // If the suggestion list has an active item, select it.\n                        pendingJsPromise.resolve(selectCurrentItem(options, state, originalSelect));\n                    } else if (options.tags) {\n                        // If tags are enabled, create a tag.\n                        pendingJsPromise.resolve(createItem(options, state, originalSelect));\n                    } else {\n                        pendingJsPromise.resolve();\n                    }\n\n                    // We handled this event, so prevent it.\n                    e.preventDefault();\n                    return false;\n                case KEYS.ESCAPE:\n                    if (inputElement.attr('aria-expanded') === \"true\") {\n                        // If the suggestion list is open, close it.\n                        pendingJsPromise.resolve(closeSuggestions(state));\n                    } else {\n                        pendingJsPromise.resolve();\n                    }\n                    // We handled this event, so prevent it.\n                    e.preventDefault();\n                    return false;\n            }\n            pendingJsPromise.resolve();\n            return true;\n        });\n        // Support multi lingual COMMA keycode (44).\n        inputElement.on('keypress', function(e) {\n\n            if (e.keyCode === KEYS.COMMA) {\n                if (options.tags) {\n                    // If we are allowing tags, comma should create a tag (or enter).\n                    addPendingJSPromise('keypress-' + e.keyCode)\n                    .resolve(createItem(options, state, originalSelect));\n                }\n                // We handled this event, so prevent it.\n                e.preventDefault();\n                return false;\n            }\n            return true;\n        });\n        // Support submitting the form without leaving the autocomplete element,\n        // or submitting too quick before the blur handler action is completed.\n        inputElement.closest('form').on('submit', function() {\n            if (options.tags) {\n                // If tags are enabled, create a tag.\n                addPendingJSPromise('form-autocomplete-submit')\n                .resolve(createItem(options, state, originalSelect));\n            }\n\n            return true;\n        });\n        inputElement.on('blur', function() {\n            var pendingPromise = addPendingJSPromise('form-autocomplete-blur');\n            window.setTimeout(function() {\n                // Get the current element with focus.\n                var focusElement = $(document.activeElement);\n                var timeoutPromise = $.Deferred();\n\n                // Only close the menu if the input hasn't regained focus and if the element still exists,\n                // and regain focus if the scrollbar is clicked.\n                // Due to the half a second delay, it is possible that the input element no longer exist\n                // by the time this code is being executed.\n                if (focusElement.is(document.getElementById(state.suggestionsId))) {\n                    inputElement.focus(); // Probably the scrollbar is clicked. Regain focus.\n                } else if (!focusElement.is(inputElement) && $(document.getElementById(state.inputId)).length) {\n                    if (options.tags) {\n                        timeoutPromise.then(function() {\n                            return createItem(options, state, originalSelect);\n                        })\n                        .catch();\n                    }\n                    timeoutPromise.then(function() {\n                        return closeSuggestions(state);\n                    })\n                    .catch();\n                }\n\n                timeoutPromise.then(function() {\n                    return pendingPromise.resolve();\n                })\n                .catch();\n                timeoutPromise.resolve();\n            }, 500);\n        });\n        if (options.showSuggestions) {\n            var arrowElement = $(document.getElementById(state.downArrowId));\n            arrowElement.on('click', function(e) {\n                var pendingPromise = addPendingJSPromise('form-autocomplete-show-suggestions');\n\n                // Prevent the close timer, or we will open, then close the suggestions.\n                inputElement.focus();\n\n                // Handle ajax population of suggestions.\n                if (!inputElement.val() && options.ajax) {\n                    require([options.ajax], function(ajaxHandler) {\n                        pendingPromise.resolve(updateAjax(e, options, state, originalSelect, ajaxHandler));\n                    });\n                } else {\n                    // Else - open the suggestions list.\n                    pendingPromise.resolve(updateSuggestions(options, state, inputElement.val(), originalSelect));\n                }\n            });\n        }\n\n        var suggestionsElement = $(document.getElementById(state.suggestionsId));\n        // Remove any click handler first.\n        suggestionsElement.parent().prop(\"onclick\", null).off(\"click\");\n        suggestionsElement.parent().on('click', `#${state.suggestionsId} [role=option]`, function(e) {\n            var pendingPromise = addPendingJSPromise('form-autocomplete-parent');\n            // Handle clicks on suggestions.\n            var element = $(e.currentTarget).closest('[role=option]');\n            var suggestionsElement = $(document.getElementById(state.suggestionsId));\n            // Find the index of the clicked on suggestion.\n            var current = suggestionsElement.children(':not([aria-hidden])').index(element);\n\n            // Activate it.\n            activateItem(current, state)\n            .then(function() {\n                // And select it.\n                return selectCurrentItem(options, state, originalSelect);\n            })\n            .then(function() {\n                return pendingPromise.resolve();\n            })\n            .catch();\n        });\n        var selectionElement = $(document.getElementById(state.selectionId));\n\n        // Handle clicks on the selected items (will unselect an item).\n        selectionElement.on('click', '[role=option]', function(e) {\n            var pendingPromise = addPendingJSPromise('form-autocomplete-clicks');\n\n            // Remove it from the selection.\n            pendingPromise.resolve(deselectItem(options, state, $(e.currentTarget), originalSelect));\n        });\n\n        // When listbox is focused, focus on the first option if there is no focused option.\n        selectionElement.on('focus', function() {\n            updateActiveSelectionFromState(state);\n        });\n\n        // Keyboard navigation for the selection list.\n        selectionElement.on('keydown', function(e) {\n            var pendingPromise = addPendingJSPromise('form-autocomplete-keydown-' + e.keyCode);\n            switch (e.keyCode) {\n                case KEYS.RIGHT:\n                case KEYS.DOWN:\n                    // We handled this event, so prevent it.\n                    e.preventDefault();\n\n                    // Choose the next selection item.\n                    pendingPromise.resolve(activateNextSelection(state));\n                    return;\n                case KEYS.LEFT:\n                case KEYS.UP:\n                    // We handled this event, so prevent it.\n                    e.preventDefault();\n\n                    // Choose the previous selection item.\n                    pendingPromise.resolve(activatePreviousSelection(state));\n                    return;\n                case KEYS.SPACE:\n                case KEYS.ENTER:\n                    // Get the item that is currently selected.\n                    var selectedItem = $(document.getElementById(state.selectionId)).children('[data-active-selection]');\n                    if (selectedItem) {\n                        e.preventDefault();\n\n                        // Unselect this item.\n                        pendingPromise.resolve(deselectItem(options, state, selectedItem, originalSelect));\n                    }\n                    return;\n            }\n\n            // Not handled. Resolve the promise.\n            pendingPromise.resolve();\n        });\n        // Whenever the input field changes, update the suggestion list.\n        if (options.showSuggestions) {\n            // Store the value of the field as its last value, when the field gains focus.\n            inputElement.on('focus', function(e) {\n                var query = $(e.currentTarget).val();\n                $(e.currentTarget).data('last-value', query);\n            });\n\n            // If this field uses ajax, set it up.\n            if (options.ajax) {\n                require([options.ajax], function(ajaxHandler) {\n                    // Creating throttled handlers free of race conditions, and accurate.\n                    // This code keeps track of a throttleTimeout, which is periodically polled.\n                    // Once the throttled function is executed, the fact that it is running is noted.\n                    // If a subsequent request comes in whilst it is running, this request is re-applied.\n                    var throttleTimeout = null;\n                    var inProgress = false;\n                    var pendingKey = 'autocomplete-throttledhandler';\n                    var handler = function(e) {\n                        // Empty the current timeout.\n                        throttleTimeout = null;\n\n                        // Mark this request as in-progress.\n                        inProgress = true;\n\n                        // Process the request.\n                        updateAjax(e, options, state, originalSelect, ajaxHandler)\n                        .then(function() {\n                            // Check if the throttleTimeout is still empty.\n                            // There's a potential condition whereby the JS request takes long enough to complete that\n                            // another task has been queued.\n                            // In this case another task will be kicked off and we must wait for that before marking htis as\n                            // complete.\n                            if (null === throttleTimeout) {\n                                // Mark this task as complete.\n                                M.util.js_complete(pendingKey);\n                            }\n                            inProgress = false;\n\n                            return arguments[0];\n                        })\n                        .catch(notification.exception);\n                    };\n\n                    // For input events, we do not want to trigger many, many updates.\n                    var throttledHandler = function(e) {\n                        window.clearTimeout(throttleTimeout);\n                        if (inProgress) {\n                            // A request is currently ongoing.\n                            // Delay this request another 100ms.\n                            throttleTimeout = window.setTimeout(throttledHandler.bind(this, e), 100);\n                            return;\n                        }\n\n                        if (throttleTimeout === null) {\n                            // There is currently no existing timeout handler, and it has not been recently cleared, so\n                            // this is the start of a throttling check.\n                            M.util.js_pending(pendingKey);\n                        }\n\n                        // There is currently no existing timeout handler, and it has not been recently cleared, so this\n                        // is the start of a throttling check.\n                        // Queue a call to the handler.\n                        throttleTimeout = window.setTimeout(handler.bind(this, e), 300);\n                    };\n\n                    // Trigger an ajax update after the text field value changes.\n                    inputElement.on('input', function(e) {\n                        var query = $(e.currentTarget).val();\n                        var last = $(e.currentTarget).data('last-value');\n                        // IE11 fires many more input events than required - even when the value has not changed.\n                        if (last !== query) {\n                            throttledHandler(e);\n                        }\n                        $(e.currentTarget).data('last-value', query);\n                    });\n                });\n            } else {\n                inputElement.on('input', function(e) {\n                    var query = $(e.currentTarget).val();\n                    var last = $(e.currentTarget).data('last-value');\n                    // IE11 fires many more input events than required - even when the value has not changed.\n                    // We need to only do this for real value changed events or the suggestions will be\n                    // unclickable on IE11 (because they will be rebuilt before the click event fires).\n                    // Note - because of this we cannot close the list when the query is empty or it will break\n                    // on IE11.\n                    if (last !== query) {\n                        updateSuggestions(options, state, query, originalSelect);\n                    }\n                    $(e.currentTarget).data('last-value', query);\n                });\n            }\n        }\n    };\n\n    /**\n     * Create and return an unresolved Promise for some pending JS.\n     *\n     * @param   {String} key The unique identifier for this promise\n     * @return  {Promise}\n     */\n    var addPendingJSPromise = function(key) {\n            var pendingKey = 'form-autocomplete:' + key;\n\n            M.util.js_pending(pendingKey);\n\n            var pendingPromise = $.Deferred();\n\n            pendingPromise\n            .then(function() {\n                M.util.js_complete(pendingKey);\n\n                return arguments[0];\n            })\n            .catch(notification.exception);\n\n            return pendingPromise;\n    };\n\n    return {\n        // Public variables and functions.\n        /**\n         * Turn a boring select box into an auto-complete beast.\n         *\n         * @method enhance\n         * @param {string} selector The selector that identifies the select box.\n         * @param {boolean} tags Whether to allow support for tags (can define new entries).\n         * @param {string} ajax Name of an AMD module to handle ajax requests. If specified, the AMD\n         *                      module must expose 2 functions \"transport\" and \"processResults\".\n         *                      These are modeled on Select2 see: https://select2.github.io/options.html#ajax\n         * @param {String} placeholder - The text to display before a selection is made.\n         * @param {Boolean} caseSensitive - If search has to be made case sensitive.\n         * @param {Boolean} showSuggestions - If suggestions should be shown\n         * @param {String} noSelectionString - Text to display when there is no selection\n         * @param {Boolean} closeSuggestionsOnSelect - Whether to close the suggestions immediately after making a selection.\n         * @param {Object} templateOverrides A set of templates to use instead of the standard templates\n         * @return {Promise}\n         */\n        enhance: function(selector, tags, ajax, placeholder, caseSensitive, showSuggestions, noSelectionString,\n                          closeSuggestionsOnSelect, templateOverrides) {\n            // Set some default values.\n            var options = {\n                selector: selector,\n                tags: false,\n                ajax: false,\n                placeholder: placeholder,\n                caseSensitive: false,\n                showSuggestions: true,\n                noSelectionString: noSelectionString,\n                templates: $.extend({\n                        input: 'core/form_autocomplete_input',\n                        items: 'core/form_autocomplete_selection_items',\n                        layout: 'core/form_autocomplete_layout',\n                        selection: 'core/form_autocomplete_selection',\n                        suggestions: 'core/form_autocomplete_suggestions',\n                    }, templateOverrides),\n            };\n            var pendingKey = 'autocomplete-setup-' + selector;\n            M.util.js_pending(pendingKey);\n            if (typeof tags !== \"undefined\") {\n                options.tags = tags;\n            }\n            if (typeof ajax !== \"undefined\") {\n                options.ajax = ajax;\n            }\n            if (typeof caseSensitive !== \"undefined\") {\n                options.caseSensitive = caseSensitive;\n            }\n            if (typeof showSuggestions !== \"undefined\") {\n                options.showSuggestions = showSuggestions;\n            }\n            if (typeof noSelectionString === \"undefined\") {\n                str.get_string('noselection', 'form').done(function(result) {\n                    options.noSelectionString = result;\n                }).fail(notification.exception);\n            }\n\n            // Look for the select element.\n            var originalSelect = $(selector);\n            if (!originalSelect) {\n                log.debug('Selector not found: ' + selector);\n                M.util.js_complete(pendingKey);\n                return false;\n            }\n\n            // Ensure we enhance the element only once.\n            if (originalSelect.data('enhanced') === 'enhanced') {\n                M.util.js_complete(pendingKey);\n                return false;\n            }\n            originalSelect.data('enhanced', 'enhanced');\n\n            // Hide the original select.\n            Aria.hide(originalSelect.get());\n            originalSelect.css('visibility', 'hidden');\n\n            // Find or generate some ids.\n            var state = {\n                selectId: originalSelect.attr('id'),\n                inputId: 'form_autocomplete_input-' + uniqueId,\n                suggestionsId: 'form_autocomplete_suggestions-' + uniqueId,\n                selectionId: 'form_autocomplete_selection-' + uniqueId,\n                downArrowId: 'form_autocomplete_downarrow-' + uniqueId,\n                items: [],\n            };\n\n            // Increment the unique counter so we don't get duplicates ever.\n            uniqueId++;\n\n            options.multiple = originalSelect.attr('multiple');\n            if (!options.multiple) {\n                // If this is a single select then there is no way to de-select the current value -\n                // unless we add a bogus blank option to be selected when nothing else is.\n                // This matches similar code in updateAjax above.\n                originalSelect.prepend('<option>');\n            }\n\n            if (typeof closeSuggestionsOnSelect !== \"undefined\") {\n                options.closeSuggestionsOnSelect = closeSuggestionsOnSelect;\n            } else {\n                // If not specified, this will close suggestions by default for single-select elements only.\n                options.closeSuggestionsOnSelect = !options.multiple;\n            }\n\n            var originalLabel = $('[for=' + state.selectId + ']');\n            // Create the new markup and insert it after the select.\n            var suggestions = [];\n            originalSelect.children('option').each(function(index, option) {\n                suggestions[index] = {label: option.innerHTML, value: $(option).attr('value')};\n            });\n\n            // Render all the parts of our UI.\n            var context = $.extend({}, options, state);\n            context.options = suggestions;\n            context.items = [];\n\n            // Collect rendered inline JS to be executed once the HTML is shown.\n            var collectedjs = '';\n\n            var renderLayout = templates.render(options.templates.layout, {})\n            .then(function(html) {\n                return $(html);\n            });\n\n            var renderInput = templates.render(options.templates.input, context).then(function(html, js) {\n                collectedjs += js;\n                return $(html);\n            });\n\n            var renderDatalist = templates.render(options.templates.suggestions, context).then(function(html, js) {\n                collectedjs += js;\n                return $(html);\n            });\n\n            var renderSelection = templates.render(options.templates.selection, context).then(function(html, js) {\n                collectedjs += js;\n                return $(html);\n            });\n\n            return $.when(renderLayout, renderInput, renderDatalist, renderSelection)\n            .then(function(layout, input, suggestions, selection) {\n                originalSelect.hide();\n                var container = originalSelect.parent();\n\n                // Ensure that the data-fieldtype is set for behat.\n                input.find('input').attr('data-fieldtype', 'autocomplete');\n\n                container.append(layout);\n                container.find('[data-region=\"form_autocomplete-input\"]').replaceWith(input);\n                container.find('[data-region=\"form_autocomplete-suggestions\"]').replaceWith(suggestions);\n                container.find('[data-region=\"form_autocomplete-selection\"]').replaceWith(selection);\n\n                templates.runTemplateJS(collectedjs);\n\n                // Update the form label to point to the text input.\n                originalLabel.attr('for', state.inputId);\n                // Add the event handlers.\n                addNavigation(options, state, originalSelect);\n\n                var suggestionsElement = $(document.getElementById(state.suggestionsId));\n                // Hide the suggestions by default.\n                suggestionsElement.hide();\n                Aria.hide(suggestionsElement.get());\n\n                return;\n            })\n            .then(function() {\n                // Show the current values in the selection list.\n                return updateSelectionList(options, state, originalSelect);\n            })\n            .then(function() {\n                return M.util.js_complete(pendingKey);\n            })\n            .catch(function(error) {\n                M.util.js_complete(pendingKey);\n                notification.exception(error);\n            });\n        }\n    };\n});\n"],"names":["define","$","log","str","templates","notification","LoadingIcon","Aria","FormChangeChecker","KEYS","uniqueId","Date","now","activateSelection","index","state","selectionElement","document","getElementById","selectionId","length","children","element","get","itemId","attr","Deferred","resolve","updateActiveSelectionFromState","activeElement","selectionRegion","activeId","activeValue","_selectionRegion$attr","replace","find","getActiveElementFromState","activeIndex","updateSelectionList","options","originalSelect","pendingKey","inputId","M","util","js_pending","items","newSelection","each","ele","label","prop","data","html","push","value","hasItemListChanged","js_complete","Promise","context","extend","render","then","js","replaceNodeContents","catch","exception","filter","item","indexOf","notifyChange","markFormChangedFromNode","dispatchEvent","Event","deselectItem","selectedItemValue","prepend","remove","activateItem","inputElement","suggestionsElement","suggestionsId","globalIndex","scrollPos","offset","top","scrollTop","height","animate","promise","closeSuggestions","hide","updateSuggestions","query","matchingElements","suggestions","option","innerHTML","searchquery","caseSensitive","toLocaleLowerCase","replaceNode","unhide","show","node","text","tags","get_string","done","nosuggestionsstr","createItem","val","split","found","tagindex","tag","trim","multiple","append","createTextNode","selectCurrentItem","closeSuggestionsOnSelect","focus","updateAjax","e","ajaxHandler","pendingPromise","addPendingJSPromise","parentElement","selectId","parent","addIconToContainerRemoveOnCompletion","currentTarget","transport","selector","results","processedResults","processResults","existingValues","optionIndex","String","isArray","resultIndex","result","error","reject","addNavigation","on","pendingJsPromise","keyCode","showSuggestions","current","activateNextItem","ajax","require","preventDefault","activatePreviousItem","closest","window","setTimeout","focusElement","timeoutPromise","is","downArrowId","off","selectionsElement","activateNextSelection","activatePreviousSelection","selectedItem","throttleTimeout","inProgress","handler","arguments","throttledHandler","clearTimeout","bind","this","key","enhance","placeholder","noSelectionString","templateOverrides","input","layout","selection","fail","debug","css","originalLabel","collectedjs","renderLayout","renderInput","renderDatalist","renderSelection","when","container","replaceWith","runTemplateJS"],"mappings":"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"}