1 |
efrain |
1 |
// This file is part of Moodle - http://moodle.org/
|
|
|
2 |
//
|
|
|
3 |
// Moodle is free software: you can redistribute it and/or modify
|
|
|
4 |
// it under the terms of the GNU General Public License as published by
|
|
|
5 |
// the Free Software Foundation, either version 3 of the License, or
|
|
|
6 |
// (at your option) any later version.
|
|
|
7 |
//
|
|
|
8 |
// Moodle is distributed in the hope that it will be useful,
|
|
|
9 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
10 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
11 |
// GNU General Public License for more details.
|
|
|
12 |
//
|
|
|
13 |
// You should have received a copy of the GNU General Public License
|
|
|
14 |
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
|
15 |
|
|
|
16 |
/**
|
|
|
17 |
* @module moodle-core-event
|
|
|
18 |
*/
|
|
|
19 |
|
|
|
20 |
var LOGNAME = 'moodle-core-event';
|
|
|
21 |
|
|
|
22 |
/**
|
|
|
23 |
* List of published global JS events in Moodle. This is a collection
|
|
|
24 |
* of global events that can be subscribed to, or fired from any plugin.
|
|
|
25 |
*
|
|
|
26 |
* @namespace M.core
|
|
|
27 |
* @class event
|
|
|
28 |
*/
|
|
|
29 |
M.core = M.core || {};
|
|
|
30 |
|
|
|
31 |
var eventsConfigured = !!M.core.event;
|
|
|
32 |
|
|
|
33 |
M.core.event = M.core.event || {
|
|
|
34 |
|
|
|
35 |
/**
|
|
|
36 |
* This event is triggered when a page has added dynamic nodes to a page
|
|
|
37 |
* that should be processed by the filter system. An example is loading
|
|
|
38 |
* user text that could have equations in it. MathJax can typeset the equations
|
|
|
39 |
* but only if it is notified that there are new nodes in the page that need processing.
|
|
|
40 |
* To trigger this event use M.core.Event.fire(M.core.Event.FILTER_CONTENT_UPDATED, {nodes: list});
|
|
|
41 |
*
|
|
|
42 |
* @event "filter-content-updated"
|
|
|
43 |
* @param nodes {Y.NodeList} List of nodes added to the DOM.
|
|
|
44 |
*/
|
|
|
45 |
FILTER_CONTENT_UPDATED: "filter-content-updated",
|
|
|
46 |
|
|
|
47 |
/**
|
|
|
48 |
* This event is triggered when an editor has recovered some draft text.
|
|
|
49 |
* It can be used to determine let other sections know that they should reset their
|
|
|
50 |
* form comparison for changes.
|
|
|
51 |
*
|
|
|
52 |
* @event "editor-content-restored"
|
|
|
53 |
*/
|
|
|
54 |
EDITOR_CONTENT_RESTORED: "editor-content-restored",
|
|
|
55 |
|
|
|
56 |
/**
|
|
|
57 |
* This event is triggered when an mform is about to be submitted via ajax.
|
|
|
58 |
*
|
|
|
59 |
* @event "form-submit-ajax"
|
|
|
60 |
*/
|
|
|
61 |
FORM_SUBMIT_AJAX: "form-submit-ajax"
|
|
|
62 |
|
|
|
63 |
};
|
|
|
64 |
|
|
|
65 |
M.core.globalEvents = M.core.globalEvents || {
|
|
|
66 |
/**
|
|
|
67 |
* This event is triggered when form has an error
|
|
|
68 |
*
|
|
|
69 |
* @event "form_error"
|
|
|
70 |
* @param formid {string} Id of form with error.
|
|
|
71 |
* @param elementid {string} Id of element with error.
|
|
|
72 |
*/
|
|
|
73 |
FORM_ERROR: "form_error",
|
|
|
74 |
|
|
|
75 |
/**
|
|
|
76 |
* This event is triggered when the content of a block has changed
|
|
|
77 |
*
|
|
|
78 |
* @event "block_content_updated"
|
|
|
79 |
* @param instanceid ID of the block instance that was updated
|
|
|
80 |
*/
|
|
|
81 |
BLOCK_CONTENT_UPDATED: "block_content_updated"
|
|
|
82 |
};
|
|
|
83 |
|
|
|
84 |
|
|
|
85 |
if (!eventsConfigured) {
|
|
|
86 |
var eventDefaultConfig = {
|
|
|
87 |
emitFacade: true,
|
|
|
88 |
defaultFn: function(e) {
|
|
|
89 |
Y.log('Event fired: ' + e.type, 'debug', LOGNAME);
|
|
|
90 |
},
|
|
|
91 |
preventedFn: function(e) {
|
|
|
92 |
Y.log('Event prevented: ' + e.type, 'debug', LOGNAME);
|
|
|
93 |
},
|
|
|
94 |
stoppedFn: function(e) {
|
|
|
95 |
Y.log('Event stopped: ' + e.type, 'debug', LOGNAME);
|
|
|
96 |
}
|
|
|
97 |
};
|
|
|
98 |
|
|
|
99 |
// Publish events with a custom config here.
|
|
|
100 |
|
|
|
101 |
// Publish all the events with a standard config.
|
|
|
102 |
var key;
|
|
|
103 |
for (key in M.core.event) {
|
|
|
104 |
if (M.core.event.hasOwnProperty(key) && Y.getEvent(M.core.event[key]) === null) {
|
|
|
105 |
Y.publish(M.core.event[key], eventDefaultConfig);
|
|
|
106 |
}
|
|
|
107 |
}
|
|
|
108 |
|
|
|
109 |
// Publish global events.
|
|
|
110 |
for (key in M.core.globalEvents) {
|
|
|
111 |
// Make sure the key exists and that the event has not yet been published. Otherwise, skip publishing.
|
|
|
112 |
if (M.core.globalEvents.hasOwnProperty(key) && Y.Global.getEvent(M.core.globalEvents[key]) === null) {
|
|
|
113 |
Y.Global.publish(M.core.globalEvents[key], Y.merge(eventDefaultConfig, {broadcast: true}));
|
|
|
114 |
Y.log('Global event published: ' + key, 'debug', LOGNAME);
|
|
|
115 |
}
|
|
|
116 |
}
|
|
|
117 |
|
|
|
118 |
/**
|
|
|
119 |
* Apply a callback when the DOM is modified and matchecs the supplied targetSelector.
|
|
|
120 |
*
|
|
|
121 |
* @method listen
|
|
|
122 |
* @param {String} targetSelector The selector to apply
|
|
|
123 |
* @param {Function} applyCallback The function to call on the found node
|
|
|
124 |
*/
|
|
|
125 |
var listenForMutation = function(targetSelector, applyCallback) {
|
|
|
126 |
// Add a MutationObserver to check for new children to the tree.
|
|
|
127 |
var newNodeObserver = new MutationObserver(function(mutationList) {
|
|
|
128 |
mutationList.forEach(function(mutation) {
|
|
|
129 |
mutation.addedNodes.forEach(function(node) {
|
|
|
130 |
if (node instanceof Element && node.matches(targetSelector)) {
|
|
|
131 |
applyCallback(node);
|
|
|
132 |
}
|
|
|
133 |
});
|
|
|
134 |
});
|
|
|
135 |
});
|
|
|
136 |
|
|
|
137 |
newNodeObserver.observe(document, {childList: true, subtree: true});
|
|
|
138 |
};
|
|
|
139 |
|
|
|
140 |
|
|
|
141 |
// YUI Custom Events do not bubble up the DOM, only up the inheritance path of custom classes.
|
|
|
142 |
// We have to add a Node Observer to watch for new forms that may need to be watched in future.
|
|
|
143 |
require(['core_form/events'], function(formEvents) {
|
|
|
144 |
listenForMutation('form', function(form) {
|
|
|
145 |
Y.one(form).on(M.core.event.FORM_SUBMIT_AJAX, function(e) {
|
|
|
146 |
// Prevent cyclical calls.
|
|
|
147 |
if (e && e.fallbackHandled) {
|
|
|
148 |
return;
|
|
|
149 |
}
|
|
|
150 |
|
|
|
151 |
formEvents.notifyFormSubmittedByJavascript(form, window.skipValidation, true);
|
|
|
152 |
});
|
|
|
153 |
});
|
|
|
154 |
});
|
|
|
155 |
}
|