__ __ __ __ _____ _ _ _____ _ _ _ | \/ | \ \ / / | __ \ (_) | | / ____| | | | | | \ / |_ __\ V / | |__) | __ ___ ____ _| |_ ___ | (___ | |__ ___| | | | |\/| | '__|> < | ___/ '__| \ \ / / _` | __/ _ \ \___ \| '_ \ / _ \ | | | | | | |_ / . \ | | | | | |\ V / (_| | || __/ ____) | | | | __/ | | |_| |_|_(_)_/ \_\ |_| |_| |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1 if you need WebShell for Seo everyday contact me on Telegram Telegram Address : @jackleetFor_More_Tools:
// 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 <http://www.gnu.org/licenses/>.
/**
* Notification manager for in-page notifications in Moodle.
*
* @module core/notification
* @copyright 2015 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 2.9
*/
import Pending from 'core/pending';
import Log from 'core/log';
let currentContextId = M.cfg.contextid;
const notificationTypes = {
success: 'core/notification_success',
info: 'core/notification_info',
warning: 'core/notification_warning',
error: 'core/notification_error',
};
const notificationRegionId = 'user-notifications';
const Selectors = {
notificationRegion: `#${notificationRegionId}`,
fallbackRegionParents: [
'#region-main',
'[role="main"]',
'body',
],
};
const setupTargetRegion = () => {
let targetRegion = getNotificationRegion();
if (targetRegion) {
return false;
}
const newRegion = document.createElement('span');
newRegion.id = notificationRegionId;
return Selectors.fallbackRegionParents.some(selector => {
const targetRegion = document.querySelector(selector);
if (targetRegion) {
targetRegion.prepend(newRegion);
return true;
}
return false;
});
};
/**
* A notification object displayed to a user.
*
* @typedef {Object} Notification
* @property {string} message The body of the notification
* @property {string} type The type of notification to add (error, warning, info, success).
* @property {Boolean} closebutton Whether to show the close button.
* @property {Boolean} announce Whether to announce to screen readers.
*/
/**
* Poll the server for any new notifications.
*
* @method
* @returns {Promise}
*/
export const fetchNotifications = async() => {
const Ajax = await import('core/ajax');
return Ajax.call([{
methodname: 'core_fetch_notifications',
args: {
contextid: currentContextId
}
}])[0]
.then(addNotifications);
};
/**
* Add all of the supplied notifications.
*
* @method
* @param {Notification[]} notifications The list of notificaitons
* @returns {Promise}
*/
const addNotifications = notifications => {
if (!notifications.length) {
return Promise.resolve();
}
const pendingPromise = new Pending('core/notification:addNotifications');
notifications.forEach(notification => renderNotification(notification.template, notification.variables));
return pendingPromise.resolve();
};
/**
* Add a notification to the page.
*
* Note: This does not cause the notification to be added to the session.
*
* @method
* @param {Notification} notification The notification to add.
* @returns {Promise}
*/
export const addNotification = notification => {
const pendingPromise = new Pending('core/notification:addNotifications');
let template = notificationTypes.error;
notification = {
closebutton: true,
announce: true,
type: 'error',
...notification,
};
if (notification.template) {
template = notification.template;
delete notification.template;
} else if (notification.type) {
if (typeof notificationTypes[notification.type] !== 'undefined') {
template = notificationTypes[notification.type];
}
delete notification.type;
}
return renderNotification(template, notification)
.then(pendingPromise.resolve);
};
const renderNotification = async(template, variables) => {
if (typeof variables.message === 'undefined' || !variables.message) {
Log.debug('Notification received without content. Skipping.');
return;
}
const pendingPromise = new Pending('core/notification:renderNotification');
const Templates = await import('core/templates');
Templates.renderForPromise(template, variables)
.then(({html, js = ''}) => {
Templates.prependNodeContents(getNotificationRegion(), html, js);
return;
})
.then(pendingPromise.resolve)
.catch(exception);
};
const getNotificationRegion = () => document.querySelector(Selectors.notificationRegion);
/**
* Alert dialogue.
*
* @method
* @param {String|Promise} title
* @param {String|Promise} message
* @param {String|Promise} cancelText
* @returns {Promise}
*/
export const alert = async(title, message, cancelText) => {
var pendingPromise = new Pending('core/notification:alert');
const AlertModal = await import('core/local/modal/alert');
const modal = await AlertModal.create({
body: message,
title: title,
buttons: {
cancel: cancelText,
},
removeOnClose: true,
show: true,
});
pendingPromise.resolve();
return modal;
};
/**
* The confirm has now been replaced with a save and cancel dialogue.
*
* @method
* @param {String|Promise} title
* @param {String|Promise} question
* @param {String|Promise} saveLabel
* @param {String|Promise} noLabel
* @param {String|Promise} saveCallback
* @param {String|Promise} cancelCallback
* @returns {Promise}
*/
export const confirm = (title, question, saveLabel, noLabel, saveCallback, cancelCallback) =>
saveCancel(title, question, saveLabel, saveCallback, cancelCallback);
/**
* The Save and Cancel dialogue helper.
*
* @method
* @param {String|Promise} title
* @param {String|Promise} question
* @param {String|Promise} saveLabel
* @param {String|Promise} saveCallback
* @param {String|Promise} cancelCallback
* @param {Object} options
* @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)
* @returns {Promise}
*/
export const saveCancel = async(title, question, saveLabel, saveCallback, cancelCallback, {
triggerElement = null,
} = {}) => {
const pendingPromise = new Pending('core/notification:confirm');
const [
SaveCancelModal,
ModalEvents,
] = await Promise.all([
import('core/modal_save_cancel'),
import('core/modal_events'),
]);
const modal = await SaveCancelModal.create({
title,
body: question,
buttons: {
// Note: The noLabel is no longer supported.
save: saveLabel,
},
removeOnClose: true,
show: true,
});
modal.getRoot().on(ModalEvents.save, saveCallback);
modal.getRoot().on(ModalEvents.cancel, cancelCallback);
modal.getRoot().on(ModalEvents.hidden, () => triggerElement?.focus());
pendingPromise.resolve();
return modal;
};
/**
* The Delete and Cancel dialogue helper.
*
* @method
* @param {String|Promise} title
* @param {String|Promise} question
* @param {String|Promise} deleteLabel
* @param {String|Promise} deleteCallback
* @param {String|Promise} cancelCallback
* @param {Object} options
* @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)
* @returns {Promise}
*/
export const deleteCancel = async(title, question, deleteLabel, deleteCallback, cancelCallback, {
triggerElement = null,
} = {}) => {
const pendingPromise = new Pending('core/notification:confirm');
const [
DeleteCancelModal,
ModalEvents,
] = await Promise.all([
import('core/modal_delete_cancel'),
import('core/modal_events'),
]);
const modal = await DeleteCancelModal.create({
title: title,
body: question,
buttons: {
'delete': deleteLabel
},
removeOnClose: true,
show: true,
});
modal.getRoot().on(ModalEvents.delete, deleteCallback);
modal.getRoot().on(ModalEvents.cancel, cancelCallback);
modal.getRoot().on(ModalEvents.hidden, () => triggerElement?.focus());
pendingPromise.resolve();
return modal;
};
/**
* Add all of the supplied notifications.
*
* @param {Promise|String} title The header of the modal
* @param {Promise|String} question What do we want the user to confirm
* @param {Promise|String} saveLabel The modal action link text
* @param {Object} options
* @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)
* @return {Promise}
*/
export const saveCancelPromise = (title, question, saveLabel, {
triggerElement = null,
} = {}) => new Promise((resolve, reject) => {
saveCancel(title, question, saveLabel, resolve, reject, {triggerElement});
});
/**
* Add all of the supplied notifications.
*
* @param {Promise|String} title The header of the modal
* @param {Promise|String} question What do we want the user to confirm
* @param {Promise|String} deleteLabel The modal action link text
* @param {Object} options
* @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)
* @return {Promise}
*/
export const deleteCancelPromise = (title, question, deleteLabel, {
triggerElement = null,
} = {}) => new Promise((resolve, reject) => {
deleteCancel(title, question, deleteLabel, resolve, reject, {triggerElement});
});
/**
* Wrap M.core.exception.
*
* @method
* @param {Error} ex
*/
export const exception = async ex => {
const pendingPromise = new Pending('core/notification:displayException');
// Fudge some parameters.
if (!ex.stack) {
ex.stack = '';
}
if (ex.debuginfo) {
ex.stack += ex.debuginfo + '\n';
}
if (!ex.backtrace && ex.stacktrace) {
ex.backtrace = ex.stacktrace;
}
if (ex.backtrace) {
ex.stack += ex.backtrace;
const ln = ex.backtrace.match(/line ([^ ]*) of/);
const fn = ex.backtrace.match(/ of ([^:]*): /);
if (ln && ln[1]) {
ex.lineNumber = ln[1];
}
if (fn && fn[1]) {
ex.fileName = fn[1];
if (ex.fileName.length > 30) {
ex.fileName = '...' + ex.fileName.substr(ex.fileName.length - 27);
}
}
}
if (typeof ex.name === 'undefined' && ex.errorcode) {
ex.name = ex.errorcode;
}
const Y = await import('core/yui');
Y.use('moodle-core-notification-exception', function() {
var modal = new M.core.exception(ex);
modal.show();
pendingPromise.resolve();
});
};
/**
* Initialise the page for the suppled context, and displaying the supplied notifications.
*
* @method
* @param {Number} contextId
* @param {Notification[]} notificationList
*/
export const init = (contextId, notificationList) => {
currentContextId = contextId;
// Setup the message target region if it isn't setup already.
setupTargetRegion();
// Add provided notifications.
addNotifications(notificationList);
};
// To maintain backwards compatability we export default here.
export default {
init,
fetchNotifications,
addNotification,
alert,
confirm,
saveCancel,
deleteCancel,
saveCancelPromise,
deleteCancelPromise,
exception,
};
| Name | Type | Size | Permission | Actions |
|---|---|---|---|---|
| bulkactions | Folder | 0777 |
|
|
| check | Folder | 0777 |
|
|
| comboboxsearch | Folder | 0777 |
|
|
| datafilter | Folder | 0777 |
|
|
| emoji | Folder | 0777 |
|
|
| local | Folder | 0777 |
|
|
| moodlenet | Folder | 0777 |
|
|
| adapter.js | File | 123.08 KB | 0777 |
|
| addblockmodal.js | File | 4.34 KB | 0777 |
|
| ajax.js | File | 11.97 KB | 0777 |
|
| aria.js | File | 1011 B | 0777 |
|
| auto_rows.js | File | 3.46 KB | 0777 |
|
| autoscroll.js | File | 6.49 KB | 0777 |
|
| backoff_timer.js | File | 4.98 KB | 0777 |
|
| chart_axis.js | File | 7.39 KB | 0777 |
|
| chart_bar.js | File | 3.08 KB | 0777 |
|
| chart_base.js | File | 11.36 KB | 0777 |
|
| chart_builder.js | File | 1.65 KB | 0777 |
|
| chart_line.js | File | 2.08 KB | 0777 |
|
| chart_output.js | File | 1.08 KB | 0777 |
|
| chart_output_base.js | File | 2.03 KB | 0777 |
|
| chart_output_chartjs.js | File | 11.5 KB | 0777 |
|
| chart_output_htmltable.js | File | 3.3 KB | 0777 |
|
| chart_pie.js | File | 3.03 KB | 0777 |
|
| chart_series.js | File | 8.35 KB | 0777 |
|
| chartjs-lazy.js | File | 497.88 KB | 0777 |
|
| chartjs.js | File | 913 B | 0777 |
|
| checkbox-toggleall.js | File | 12.78 KB | 0777 |
|
| config.js | File | 978 B | 0777 |
|
| copy_to_clipboard.js | File | 7.38 KB | 0777 |
|
| custom_interaction_events.js | File | 22.18 KB | 0777 |
|
| datafilter.js | File | 17.92 KB | 0777 |
|
| dragdrop.js | File | 12.92 KB | 0777 |
|
| drawer.js | File | 3.49 KB | 0777 |
|
| drawer_events.js | File | 967 B | 0777 |
|
| dropzone.js | File | 5.71 KB | 0777 |
|
| dynamic_tabs.js | File | 6.67 KB | 0777 |
|
| edit_switch.js | File | 3.45 KB | 0777 |
|
| event.js | File | 2.53 KB | 0777 |
|
| event_dispatcher.js | File | 2.79 KB | 0777 |
|
| fetch.js | File | 9.4 KB | 0777 |
|
| first.js | File | 1.33 KB | 0777 |
|
| form-autocomplete.js | File | 53.74 KB | 0777 |
|
| form-cohort-selector.js | File | 2.5 KB | 0777 |
|
| form-course-selector.js | File | 3.77 KB | 0777 |
|
| fragment.js | File | 5.03 KB | 0777 |
|
| fullscreen.js | File | 1.62 KB | 0777 |
|
| icon_system.js | File | 3.39 KB | 0777 |
|
| icon_system_fontawesome.js | File | 5.35 KB | 0777 |
|
| icon_system_standard.js | File | 1.96 KB | 0777 |
|
| inplace_editable.js | File | 16.82 KB | 0777 |
|
| key_codes.js | File | 1.34 KB | 0777 |
|
| loadingicon.js | File | 3.88 KB | 0777 |
|
| localstorage.js | File | 2.24 KB | 0777 |
|
| log.js | File | 1.74 KB | 0777 |
|
| loglevel.js | File | 12.38 KB | 0777 |
|
| menu_navigation.js | File | 9.2 KB | 0777 |
|
| modal.js | File | 36.33 KB | 0777 |
|
| modal_backdrop.js | File | 4.17 KB | 0777 |
|
| modal_cancel.js | File | 1.6 KB | 0777 |
|
| modal_copy_to_clipboard.js | File | 3.75 KB | 0777 |
|
| modal_delete_cancel.js | File | 2.36 KB | 0777 |
|
| modal_events.js | File | 1.28 KB | 0777 |
|
| modal_factory.js | File | 5.91 KB | 0777 |
|
| modal_registry.js | File | 2.26 KB | 0777 |
|
| modal_save_cancel.js | File | 2.34 KB | 0777 |
|
| moremenu.js | File | 10.3 KB | 0777 |
|
| mustache.js | File | 28.75 KB | 0777 |
|
| network.js | File | 9.66 KB | 0777 |
|
| normalise.js | File | 2.43 KB | 0777 |
|
| notification.js | File | 11.57 KB | 0777 |
|
| page_global.js | File | 5.38 KB | 0777 |
|
| paged_content.js | File | 2.87 KB | 0777 |
|
| paged_content_events.js | File | 1.17 KB | 0777 |
|
| paged_content_factory.js | File | 20.61 KB | 0777 |
|
| paged_content_pages.js | File | 11.75 KB | 0777 |
|
| paged_content_paging_bar.js | File | 20.36 KB | 0777 |
|
| paged_content_paging_bar_limit_selector.js | File | 2.36 KB | 0777 |
|
| paged_content_paging_dropdown.js | File | 7.36 KB | 0777 |
|
| pagehelpers.js | File | 5.38 KB | 0777 |
|
| pending.js | File | 4.46 KB | 0777 |
|
| permissionmanager.js | File | 9.77 KB | 0777 |
|
| popover_region_controller.js | File | 13.16 KB | 0777 |
|
| popper.js | File | 79.2 KB | 0777 |
|
| popper2.js | File | 61.59 KB | 0777 |
|
| prefetch.js | File | 5.82 KB | 0777 |
|
| process_monitor.js | File | 3.55 KB | 0777 |
|
| pubsub.js | File | 2.17 KB | 0777 |
|
| reactive.js | File | 1.38 KB | 0777 |
|
| scroll_manager.js | File | 5.5 KB | 0777 |
|
| sessionstorage.js | File | 2.22 KB | 0777 |
|
| showhidesettings.js | File | 11.82 KB | 0777 |
|
| showmore.js | File | 1.83 KB | 0777 |
|
| sortable_list.js | File | 29.62 KB | 0777 |
|
| sticky-footer.js | File | 3.16 KB | 0777 |
|
| storage_validation.js | File | 1.36 KB | 0777 |
|
| storagewrapper.js | File | 5.36 KB | 0777 |
|
| stored_progress.js | File | 3.15 KB | 0777 |
|
| str.js | File | 10.01 KB | 0777 |
|
| tag.js | File | 15.02 KB | 0777 |
|
| templates.js | File | 10.83 KB | 0777 |
|
| toast.js | File | 4.26 KB | 0777 |
|
| togglesensitive.js | File | 5.15 KB | 0777 |
|
| tooltip.js | File | 4.09 KB | 0777 |
|
| tree.js | File | 18.39 KB | 0777 |
|
| truncate.js | File | 6.56 KB | 0777 |
|
| url.js | File | 3.65 KB | 0777 |
|
| user_date.js | File | 9.27 KB | 0777 |
|
| userfeedback.js | File | 2.91 KB | 0777 |
|
| usermenu.js | File | 5.13 KB | 0777 |
|
| utility.js | File | 7.5 KB | 0777 |
|
| utils.js | File | 4.83 KB | 0777 |
|
| yui.js | File | 1.13 KB | 0777 |
|