Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in /home/monara/public_html/test.athavaneng.com/themes.php on line 99

Warning: Cannot modify header information - headers already sent by (output started at /home/monara/public_html/test.athavaneng.com/themes.php:1) in /home/monara/public_html/test.athavaneng.com/themes.php on line 226

Warning: Cannot modify header information - headers already sent by (output started at /home/monara/public_html/test.athavaneng.com/themes.php:1) in /home/monara/public_html/test.athavaneng.com/themes.php on line 227

Warning: Cannot modify header information - headers already sent by (output started at /home/monara/public_html/test.athavaneng.com/themes.php:1) in /home/monara/public_html/test.athavaneng.com/themes.php on line 228

Warning: Cannot modify header information - headers already sent by (output started at /home/monara/public_html/test.athavaneng.com/themes.php:1) in /home/monara/public_html/test.athavaneng.com/themes.php on line 229

Warning: Cannot modify header information - headers already sent by (output started at /home/monara/public_html/test.athavaneng.com/themes.php:1) in /home/monara/public_html/test.athavaneng.com/themes.php on line 230

Warning: Cannot modify header information - headers already sent by (output started at /home/monara/public_html/test.athavaneng.com/themes.php:1) in /home/monara/public_html/test.athavaneng.com/themes.php on line 231
// This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . /** * Autocomplete wrapper for select2 library. * * @module core/form-autocomplete * @copyright 2015 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since 3.0 */ define([ 'jquery', 'core/log', 'core/str', 'core/templates', 'core/notification', 'core/loadingicon', 'core/aria', 'core_form/changechecker', ], function( $, log, str, templates, notification, LoadingIcon, Aria, FormChangeChecker ) { // Private functions and variables. /** @var {Object} KEYS - List of keycode constants. */ var KEYS = { DOWN: 40, ENTER: 13, SPACE: 32, ESCAPE: 27, COMMA: 44, UP: 38, LEFT: 37, RIGHT: 39 }; var uniqueId = Date.now(); /** * Make an item in the selection list "active". * * @method activateSelection * @private * @param {Number} index The index in the current (visible) list of selection. * @param {Object} state State variables for this autocomplete element. * @return {Promise} */ var activateSelection = function(index, state) { // Find the elements in the DOM. var selectionElement = $(document.getElementById(state.selectionId)); // Count the visible items. var length = selectionElement.children('[aria-selected=true]').length; // Limit the index to the upper/lower bounds of the list (wrap in both directions). index = index % length; while (index < 0) { index += length; } // Find the specified element. var element = $(selectionElement.children('[aria-selected=true]').get(index)); // Create an id we can assign to this element. var itemId = state.selectionId + '-' + index; // Deselect all the selections. selectionElement.children().attr('data-active-selection', null).attr('id', ''); // Select only this suggestion and assign it the id. element.attr('data-active-selection', true).attr('id', itemId); // Tell the input field it has a new active descendant so the item is announced. selectionElement.attr('aria-activedescendant', itemId); selectionElement.attr('data-active-value', element.attr('data-value')); return $.Deferred().resolve(); }; /** * Get the actively selected element from the state object. * * @param {Object} state * @returns {jQuery} */ var getActiveElementFromState = function(state) { var selectionRegion = $(document.getElementById(state.selectionId)); var activeId = selectionRegion.attr('aria-activedescendant'); if (activeId) { var activeElement = $(document.getElementById(activeId)); if (activeElement.length) { // The active descendent still exists. return activeElement; } } // Ensure we are creating a properly formed selector based on the active value. var activeValue = selectionRegion.attr('data-active-value')?.replace(/"/g, '\\"'); return selectionRegion.find('[data-value="' + activeValue + '"]'); }; /** * Update the active selection from the given state object. * * @param {Object} state */ var updateActiveSelectionFromState = function(state) { var activeElement = getActiveElementFromState(state); var activeValue = activeElement.attr('data-value'); var selectionRegion = $(document.getElementById(state.selectionId)); if (activeValue) { // Find the index of the currently selected index. var activeIndex = selectionRegion.find('[aria-selected=true]').index(activeElement); if (activeIndex !== -1) { activateSelection(activeIndex, state); return; } } // Either the active index was not set, or it could not be found. // Select the first value instead. activateSelection(0, state); }; /** * Update the element that shows the currently selected items. * * @method updateSelectionList * @private * @param {Object} options Original options for this autocomplete element. * @param {Object} state State variables for this autocomplete element. * @param {JQuery} originalSelect The JQuery object matching the hidden select list. * @return {Promise} */ var updateSelectionList = function(options, state, originalSelect) { var pendingKey = 'form-autocomplete-updateSelectionList-' + state.inputId; M.util.js_pending(pendingKey); // Build up a valid context to re-render the template. var items = []; var newSelection = $(document.getElementById(state.selectionId)); originalSelect.children('option').each(function(index, ele) { if ($(ele).prop('selected')) { var label; if ($(ele).data('html')) { label = $(ele).data('html'); } else { label = $(ele).html(); } if (label !== '') { items.push({label: label, value: $(ele).attr('value')}); } } }); if (!hasItemListChanged(state, items)) { M.util.js_complete(pendingKey); return Promise.resolve(); } state.items = items; var context = $.extend(options, state); // Render the template. return templates.render(options.templates.items, context) .then(function(html, js) { // Add it to the page. templates.replaceNodeContents(newSelection, html, js); updateActiveSelectionFromState(state); return; }) .then(function() { return M.util.js_complete(pendingKey); }) .catch(notification.exception); }; /** * Check whether the list of items stored in the state has changed. * * @param {Object} state * @param {Array} items * @returns {Boolean} */ var hasItemListChanged = function(state, items) { if (state.items.length !== items.length) { return true; } // Check for any items in the state items which are not present in the new items list. return state.items.filter(item => items.indexOf(item) === -1).length > 0; }; /** * Notify of a change in the selection. * * @param {jQuery} originalSelect The jQuery object matching the hidden select list. */ var notifyChange = function(originalSelect) { FormChangeChecker.markFormChangedFromNode(originalSelect[0]); // Note, jQuery .change() was not working here. Better to // use plain JavaScript anyway. originalSelect[0].dispatchEvent(new Event('change')); }; /** * Remove the given item from the list of selected things. * * @method deselectItem * @private * @param {Object} options Original options for this autocomplete element. * @param {Object} state State variables for this autocomplete element. * @param {Element} item The item to be deselected. * @param {Element} originalSelect The original select list. * @return {Promise} */ var deselectItem = function(options, state, item, originalSelect) { var selectedItemValue = $(item).attr('data-value'); // Look for a match, and toggle the selected property if there is a match. originalSelect.children('option').each(function(index, ele) { if ($(ele).attr('value') == selectedItemValue) { $(ele).prop('selected', false); // We remove newly created custom tags from the suggestions list when they are deselected. if ($(ele).attr('data-iscustom')) { $(ele).remove(); } } }); // Rerender the selection list. return updateSelectionList(options, state, originalSelect) .then(function() { // Notify that the selection changed. notifyChange(originalSelect); return; }); }; /** * Make an item in the suggestions "active" (about to be selected). * * @method activateItem * @private * @param {Number} index The index in the current (visible) list of suggestions. * @param {Object} state State variables for this instance of autocomplete. * @return {Promise} */ var activateItem = function(index, state) { // Find the elements in the DOM. var inputElement = $(document.getElementById(state.inputId)); var suggestionsElement = $(document.getElementById(state.suggestionsId)); // Count the visible items. var length = suggestionsElement.children(':not([aria-hidden])').length; // Limit the index to the upper/lower bounds of the list (wrap in both directions). index = index % length; while (index < 0) { index += length; } // Find the specified element. var element = $(suggestionsElement.children(':not([aria-hidden])').get(index)); // Find the index of this item in the full list of suggestions (including hidden). var globalIndex = $(suggestionsElement.children('[role=option]')).index(element); // Create an id we can assign to this element. var itemId = state.suggestionsId + '-' + globalIndex; // Deselect all the suggestions. suggestionsElement.children().attr('aria-selected', false).attr('id', ''); // Select only this suggestion and assign it the id. element.attr('aria-selected', true).attr('id', itemId); // Tell the input field it has a new active descendant so the item is announced. inputElement.attr('aria-activedescendant', itemId); // Scroll it into view. var scrollPos = element.offset().top - suggestionsElement.offset().top + suggestionsElement.scrollTop() - (suggestionsElement.height() / 2); return suggestionsElement.animate({ scrollTop: scrollPos }, 100).promise(); }; /** * Find the index of the current active suggestion, and activate the next one. * * @method activateNextItem * @private * @param {Object} state State variable for this auto complete element. * @return {Promise} */ var activateNextItem = function(state) { // Find the list of suggestions. var suggestionsElement = $(document.getElementById(state.suggestionsId)); // Find the active one. var element = suggestionsElement.children('[aria-selected=true]'); // Find it's index. var current = suggestionsElement.children(':not([aria-hidden])').index(element); // Activate the next one. return activateItem(current + 1, state); }; /** * Find the index of the current active selection, and activate the previous one. * * @method activatePreviousSelection * @private * @param {Object} state State variables for this instance of autocomplete. * @return {Promise} */ var activatePreviousSelection = function(state) { // Find the list of selections. var selectionsElement = $(document.getElementById(state.selectionId)); // Find the active one. var element = selectionsElement.children('[data-active-selection]'); if (!element) { return activateSelection(0, state); } // Find it's index. var current = selectionsElement.children('[aria-selected=true]').index(element); // Activate the next one. return activateSelection(current - 1, state); }; /** * Find the index of the current active selection, and activate the next one. * * @method activateNextSelection * @private * @param {Object} state State variables for this instance of autocomplete. * @return {Promise} */ var activateNextSelection = function(state) { // Find the list of selections. var selectionsElement = $(document.getElementById(state.selectionId)); // Find the active one. var element = selectionsElement.children('[data-active-selection]'); var current = 0; if (element) { // The element was found. Determine the index and move to the next one. current = selectionsElement.children('[aria-selected=true]').index(element); current = current + 1; } else { // No selected item found. Move to the first. current = 0; } return activateSelection(current, state); }; /** * Find the index of the current active suggestion, and activate the previous one. * * @method activatePreviousItem * @private * @param {Object} state State variables for this autocomplete element. * @return {Promise} */ var activatePreviousItem = function(state) { // Find the list of suggestions. var suggestionsElement = $(document.getElementById(state.suggestionsId)); // Find the active one. var element = suggestionsElement.children('[aria-selected=true]'); // Find it's index. var current = suggestionsElement.children(':not([aria-hidden])').index(element); // Activate the previous one. return activateItem(current - 1, state); }; /** * Close the list of suggestions. * * @method closeSuggestions * @private * @param {Object} state State variables for this autocomplete element. * @return {Promise} */ var closeSuggestions = function(state) { // Find the elements in the DOM. var inputElement = $(document.getElementById(state.inputId)); var suggestionsElement = $(document.getElementById(state.suggestionsId)); if (inputElement.attr('aria-expanded') === "true") { // Announce the list of suggestions was closed. inputElement.attr('aria-expanded', false); } // Read the current list of selections. inputElement.attr('aria-activedescendant', state.selectionId); // Hide the suggestions list (from screen readers too). Aria.hide(suggestionsElement.get()); suggestionsElement.hide(); return $.Deferred().resolve(); }; /** * Rebuild the list of suggestions based on the current values in the select list, and the query. * * @method updateSuggestions * @private * @param {Object} options The original options for this autocomplete. * @param {Object} state The state variables for this autocomplete. * @param {String} query The current text for the search string. * @param {JQuery} originalSelect The JQuery object matching the hidden select list. * @return {Promise} */ var updateSuggestions = function(options, state, query, originalSelect) { var pendingKey = 'form-autocomplete-updateSuggestions-' + state.inputId; M.util.js_pending(pendingKey); // Find the elements in the DOM. var inputElement = $(document.getElementById(state.inputId)); var suggestionsElement = $(document.getElementById(state.suggestionsId)); // Used to track if we found any visible suggestions. var matchingElements = false; // Options is used by the context when rendering the suggestions from a template. var suggestions = []; originalSelect.children('option').each(function(index, option) { if ($(option).prop('selected') !== true) { suggestions[suggestions.length] = {label: option.innerHTML, value: $(option).attr('value')}; } }); // Re-render the list of suggestions. var searchquery = state.caseSensitive ? query : query.toLocaleLowerCase(); var context = $.extend({options: suggestions}, options, state); var returnVal = templates.render( 'core/form_autocomplete_suggestions', context ) .then(function(html, js) { // We have the new template, insert it in the page. templates.replaceNode(suggestionsElement, html, js); // Get the element again. suggestionsElement = $(document.getElementById(state.suggestionsId)); // Show it if it is hidden. Aria.unhide(suggestionsElement.get()); suggestionsElement.show(); // For each option in the list, hide it if it doesn't match the query. suggestionsElement.children().each(function(index, node) { node = $(node); if ((options.caseSensitive && node.text().indexOf(searchquery) > -1) || (!options.caseSensitive && node.text().toLocaleLowerCase().indexOf(searchquery) > -1)) { Aria.unhide(node.get()); node.show(); matchingElements = true; } else { node.hide(); Aria.hide(node.get()); } }); // If we found any matches, show the list. inputElement.attr('aria-expanded', true); if (originalSelect.attr('data-notice')) { // Display a notice rather than actual suggestions. suggestionsElement.html(originalSelect.attr('data-notice')); } else if (matchingElements) { // We only activate the first item in the list if tags is false, // because otherwise "Enter" would select the first item, instead of // creating a new tag. if (!options.tags) { activateItem(0, state); } } else { // Nothing matches. Tell them that. str.get_string('nosuggestions', 'form').done(function(nosuggestionsstr) { suggestionsElement.html(nosuggestionsstr); }); } return suggestionsElement; }) .then(function() { return M.util.js_complete(pendingKey); }) .catch(notification.exception); return returnVal; }; /** * Create a new item for the list (a tag). * * @method createItem * @private * @param {Object} options The original options for the autocomplete. * @param {Object} state State variables for the autocomplete. * @param {JQuery} originalSelect The JQuery object matching the hidden select list. * @return {Promise} */ var createItem = function(options, state, originalSelect) { // Find the element in the DOM. var inputElement = $(document.getElementById(state.inputId)); // Get the current text in the input field. var query = inputElement.val(); var tags = query.split(','); var found = false; $.each(tags, function(tagindex, tag) { // If we can only select one at a time, deselect any current value. tag = tag.trim(); if (tag !== '') { if (!options.multiple) { originalSelect.children('option').prop('selected', false); } // Look for an existing option in the select list that matches this new tag. originalSelect.children('option').each(function(index, ele) { if ($(ele).attr('value') == tag) { found = true; $(ele).prop('selected', true); } }); // Only create the item if it's new. if (!found) { var option = $('