mirror of
https://github.com/moodle/moodle.git
synced 2025-08-08 10:26:40 +02:00
Merge branch 'MDL-43856-master' of git://github.com/damyon/moodle
This commit is contained in:
commit
4834cfdf59
34 changed files with 1377 additions and 118 deletions
|
@ -1012,7 +1012,7 @@ class core_plugin_manager {
|
|||
|
||||
'filter' => array(
|
||||
'activitynames', 'algebra', 'censor', 'emailprotect',
|
||||
'emoticon', 'mediaplugin', 'multilang', 'tex', 'tidy',
|
||||
'emoticon', 'mathjaxloader', 'mediaplugin', 'multilang', 'tex', 'tidy',
|
||||
'urltolink', 'data', 'glossary'
|
||||
),
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ function atto_equation_params_for_js($elementid, $options, $fpoptions) {
|
|||
'elements' => get_config('atto_equation', 'librarygroup4'),
|
||||
));
|
||||
|
||||
return array('texfilteractive' => $texfilteractive, 'contextid' => $context->id, 'library' => $library,
|
||||
'texdocsurl' => get_docs_url('Using_TeX_Notation'));
|
||||
return array('texfilteractive' => $texfilteractive,
|
||||
'contextid' => $context->id,
|
||||
'library' => $library,
|
||||
'texdocsurl' => get_docs_url('Using_TeX_Notation'));
|
||||
}
|
||||
|
|
|
@ -71,9 +71,9 @@ if ($ADMIN->fulltree) {
|
|||
\neq
|
||||
';
|
||||
$setting = new admin_setting_configtextarea('atto_equation/librarygroup1',
|
||||
$name,
|
||||
$desc,
|
||||
$default);
|
||||
$name,
|
||||
$desc,
|
||||
$default);
|
||||
$settings->add($setting);
|
||||
|
||||
// Group 2
|
||||
|
@ -96,9 +96,9 @@ if ($ADMIN->fulltree) {
|
|||
\Leftrightarrow
|
||||
';
|
||||
$setting = new admin_setting_configtextarea('atto_equation/librarygroup2',
|
||||
$name,
|
||||
$desc,
|
||||
$default);
|
||||
$name,
|
||||
$desc,
|
||||
$default);
|
||||
$settings->add($setting);
|
||||
|
||||
// Group 3
|
||||
|
@ -141,9 +141,9 @@ if ($ADMIN->fulltree) {
|
|||
\Omega
|
||||
';
|
||||
$setting = new admin_setting_configtextarea('atto_equation/librarygroup3',
|
||||
$name,
|
||||
$desc,
|
||||
$default);
|
||||
$name,
|
||||
$desc,
|
||||
$default);
|
||||
$settings->add($setting);
|
||||
|
||||
// Group 4
|
||||
|
@ -161,8 +161,9 @@ if ($ADMIN->fulltree) {
|
|||
\left| \begin{matrix} a_1 & a_2 \\ a_3 & a_4 \end{matrix} \right|
|
||||
';
|
||||
$setting = new admin_setting_configtextarea('atto_equation/librarygroup4',
|
||||
$name,
|
||||
$desc,
|
||||
$default);
|
||||
$name,
|
||||
$desc,
|
||||
$default);
|
||||
$settings->add($setting);
|
||||
|
||||
}
|
||||
|
|
|
@ -48,6 +48,10 @@ var COMPONENTNAME = 'atto_equation',
|
|||
SUBMIT: '.' + CSS.SUBMIT,
|
||||
LIBRARY_BUTTON: '.' + CSS.LIBRARY + ' button'
|
||||
},
|
||||
DELIMITERS = {
|
||||
START: '\\(',
|
||||
END: '\\)'
|
||||
},
|
||||
TEMPLATES = {
|
||||
FORM: '' +
|
||||
'<form class="atto_form">' +
|
||||
|
@ -72,7 +76,7 @@ var COMPONENTNAME = 'atto_equation',
|
|||
'{{#each library}}' +
|
||||
'<div id="{{elementid}}_{{../CSS.LIBRARY_GROUP_PREFIX}}{{@key}}">' +
|
||||
'{{#split "\n" elements}}' +
|
||||
'<button data-tex="{{this}}" title="{{this}}">$${{this}}$$</button>' +
|
||||
'<button data-tex="{{this}}" title="{{this}}">{{../../DELIMITERS.START}}{{this}}{{../../DELIMITERS.END}}</button>' +
|
||||
'{{/split}}' +
|
||||
'</div>' +
|
||||
'{{/each}}' +
|
||||
|
@ -111,7 +115,17 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
*/
|
||||
_content: null,
|
||||
|
||||
/**
|
||||
* The source equation we are editing in the text.
|
||||
*
|
||||
* @property _sourceEquation
|
||||
* @type String
|
||||
* @private
|
||||
*/
|
||||
_sourceEquation: '',
|
||||
|
||||
initializer: function() {
|
||||
// If there is a tex filter active - enable this button.
|
||||
if (this.get('texfilteractive')) {
|
||||
// Add the button to the toolbar.
|
||||
this.addButton({
|
||||
|
@ -127,7 +141,14 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
this.unHighlightButtons();
|
||||
}
|
||||
}, this);
|
||||
|
||||
// We need to convert these to a non dom node based format.
|
||||
this.editor.all('tex').each(function (texNode) {
|
||||
var replacement = Y.Node.create('<span>' + DELIMITERS.START + ' ' + texNode.get('text') + ' ' + DELIMITERS.END + '</span>');
|
||||
texNode.replace(replacement);
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -160,6 +181,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
|
||||
tabview.render();
|
||||
dialogue.show();
|
||||
// Trigger any JS filters to reprocess the new nodes.
|
||||
Y.fire(M.core.event.FILTER_CONTENT_UPDATED, {nodes: (new Y.NodeList(dialogue.get('boundingBox')))});
|
||||
|
||||
var equation = this._resolveEquation();
|
||||
if (equation) {
|
||||
|
@ -181,7 +204,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
// Find the equation in the surrounding text.
|
||||
var selectedNode = this.get('host').getSelectionParentNode(),
|
||||
text,
|
||||
equation;
|
||||
equation,
|
||||
patterns = [], i;
|
||||
|
||||
// Note this is a document fragment and YUI doesn't like them.
|
||||
if (!selectedNode) {
|
||||
|
@ -190,14 +214,27 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
|
||||
text = Y.one(selectedNode).get('text');
|
||||
// We use space or not space because . does not match new lines.
|
||||
pattern = /\$\$[\S\s]*\$\$/;
|
||||
equation = pattern.exec(text);
|
||||
if (equation && equation.length) {
|
||||
equation = equation.pop();
|
||||
// Replace the equation.
|
||||
equation = equation.substring(2, equation.length - 2);
|
||||
return equation;
|
||||
// $$ blah $$.
|
||||
patterns.push(/\$\$([\S\s]*)\$\$/);
|
||||
// E.g. "\( blah \)".
|
||||
patterns.push(/\\\(([\S\s]*)\\\)/);
|
||||
// E.g. "\[ blah \]".
|
||||
patterns.push(/\\\[([\S\s]*)\\\]/);
|
||||
// E.g. "[tex] blah [/tex]".
|
||||
patterns.push(/\[tex\]([\S\s]*)\[\/tex\]/);
|
||||
|
||||
for (i = 0; i < patterns.length; i++) {
|
||||
pattern = patterns[i];
|
||||
equation = pattern.exec(text);
|
||||
if (equation && equation.length) {
|
||||
// Remember the inner match so we can replace it later.
|
||||
this.sourceEquation = equation = equation[1];
|
||||
|
||||
return equation;
|
||||
}
|
||||
}
|
||||
|
||||
this.sourceEquation = '';
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -212,11 +249,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
var input,
|
||||
selectedNode,
|
||||
text,
|
||||
pattern,
|
||||
equation,
|
||||
value;
|
||||
value,
|
||||
host;
|
||||
|
||||
var host = this.get('host');
|
||||
host = this.get('host');
|
||||
|
||||
e.preventDefault();
|
||||
this.getDialogue({
|
||||
|
@ -229,18 +265,16 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
if (value !== '') {
|
||||
host.setSelection(this._currentSelection);
|
||||
|
||||
value = '$$ ' + value.trim() + ' $$';
|
||||
selectedNode = Y.one(host.getSelectionParentNode());
|
||||
text = selectedNode.get('text');
|
||||
pattern = /\$\$[\S\s]*\$\$/;
|
||||
equation = pattern.exec(text);
|
||||
if (equation && equation.length) {
|
||||
if (this.sourceEquation.length) {
|
||||
// Replace the equation.
|
||||
equation = equation.pop();
|
||||
text = text.replace(equation, '$$' + value + '$$');
|
||||
selectedNode = Y.one(host.getSelectionParentNode());
|
||||
text = selectedNode.get('text');
|
||||
|
||||
text = text.replace(this.sourceEquation, value);
|
||||
selectedNode.set('text', text);
|
||||
} else {
|
||||
// Insert the new equation.
|
||||
value = DELIMITERS.START + ' ' + value + ' ' + DELIMITERS.END;
|
||||
host.insertContentAtFocusPoint(value);
|
||||
}
|
||||
|
||||
|
@ -249,6 +283,29 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Smart throttle, only call a function every delay milli seconds,
|
||||
* and always run the last call. Y.throttle does not work here,
|
||||
* because it calls the function immediately, the first time, and then
|
||||
* ignores repeated calls within X seconds. This does not guarantee
|
||||
* that the last call will be executed (which is required here).
|
||||
*
|
||||
* @param {function} fn
|
||||
* @param {Number} delay Delay in milliseconds
|
||||
* @method _throttle
|
||||
* @private
|
||||
*/
|
||||
_throttle: function(fn, delay) {
|
||||
var timer = null;
|
||||
return function () {
|
||||
var context = this, args = arguments;
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function () {
|
||||
fn.apply(context, args);
|
||||
}, delay);
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the preview div to match the current equation.
|
||||
*
|
||||
|
@ -264,8 +321,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
currentPos = textarea.get('selectionStart'),
|
||||
prefix = '',
|
||||
cursorLatex = '\\square ',
|
||||
isChar;
|
||||
|
||||
isChar,
|
||||
params;
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
|
@ -279,25 +336,33 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
while (equation.charAt(currentPos) === '\\' && currentPos > 0) {
|
||||
currentPos -= 1;
|
||||
}
|
||||
isChar = /[\w\{\}]/;
|
||||
isChar = /[a-zA-Z\{\}]/;
|
||||
while (isChar.test(equation.charAt(currentPos)) && currentPos < equation.length) {
|
||||
currentPos += 1;
|
||||
}
|
||||
// Save the cursor position - for insertion from the library.
|
||||
this._lastCursorPos = currentPos;
|
||||
equation = prefix + equation.substring(0, currentPos) + cursorLatex + equation.substring(currentPos);
|
||||
|
||||
var previewNode = this._content.one(SELECTORS.EQUATION_PREVIEW);
|
||||
equation = DELIMITERS.START + ' ' + equation + ' ' + DELIMITERS.END;
|
||||
// Make an ajax request to the filter.
|
||||
url = M.cfg.wwwroot + '/lib/editor/atto/plugins/equation/ajax.php';
|
||||
params = {
|
||||
sesskey: M.cfg.sesskey,
|
||||
contextid: this.get('contextid'),
|
||||
action: 'filtertext',
|
||||
text: '$$ ' + equation + ' $$'
|
||||
text: equation
|
||||
};
|
||||
|
||||
preview = Y.io(url, { sync: true,
|
||||
data: params });
|
||||
preview = Y.io(url, {
|
||||
sync: true,
|
||||
data: params
|
||||
});
|
||||
|
||||
if (preview.status === 200) {
|
||||
this._content.one(SELECTORS.EQUATION_PREVIEW).setHTML(preview.responseText);
|
||||
previewNode.setHTML(preview.responseText);
|
||||
Y.fire(M.core.event.FILTER_CONTENT_UPDATED, {nodes: (new Y.NodeList(previewNode))});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -322,9 +387,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
}));
|
||||
|
||||
this._content.one(SELECTORS.SUBMIT).on('click', this._setEquation, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('valuechange', this._updatePreview, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('mouseup', this._updatePreview, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('keyup', this._updatePreview, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('valuechange', this._throttle(this._updatePreview, 500), this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('mouseup', this._throttle(this._updatePreview, 500), this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('keyup', this._throttle(this._updatePreview, 500), this);
|
||||
this._content.delegate('click', this._selectLibraryItem, SELECTORS.LIBRARY_BUTTON, this);
|
||||
|
||||
return this._content;
|
||||
|
@ -392,7 +457,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
out = '';
|
||||
parts = str.trim().split(delimiter);
|
||||
while (parts.length > 0) {
|
||||
current = parts.shift();
|
||||
current = parts.shift().trim();
|
||||
out += options.fn(current);
|
||||
}
|
||||
|
||||
|
@ -402,7 +467,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
elementid: this.get('host').get('elementid'),
|
||||
component: COMPONENTNAME,
|
||||
library: library,
|
||||
CSS: CSS
|
||||
CSS: CSS,
|
||||
DELIMITERS: DELIMITERS
|
||||
});
|
||||
|
||||
var url = M.cfg.wwwroot + '/lib/editor/atto/plugins/equation/ajax.php';
|
||||
|
@ -435,6 +501,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
texfilteractive: {
|
||||
value: false
|
||||
},
|
||||
|
||||
/**
|
||||
* The contextid to use when generating this preview.
|
||||
*
|
||||
|
@ -464,8 +531,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
texdocsurl: {
|
||||
value: null
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin", "io", "event-valuechange", "tabview"]});
|
||||
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin", "moodle-core-event", "io", "event-valuechange", "tabview"]});
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -48,6 +48,10 @@ var COMPONENTNAME = 'atto_equation',
|
|||
SUBMIT: '.' + CSS.SUBMIT,
|
||||
LIBRARY_BUTTON: '.' + CSS.LIBRARY + ' button'
|
||||
},
|
||||
DELIMITERS = {
|
||||
START: '\\(',
|
||||
END: '\\)'
|
||||
},
|
||||
TEMPLATES = {
|
||||
FORM: '' +
|
||||
'<form class="atto_form">' +
|
||||
|
@ -72,7 +76,7 @@ var COMPONENTNAME = 'atto_equation',
|
|||
'{{#each library}}' +
|
||||
'<div id="{{elementid}}_{{../CSS.LIBRARY_GROUP_PREFIX}}{{@key}}">' +
|
||||
'{{#split "\n" elements}}' +
|
||||
'<button data-tex="{{this}}" title="{{this}}">$${{this}}$$</button>' +
|
||||
'<button data-tex="{{this}}" title="{{this}}">{{../../DELIMITERS.START}}{{this}}{{../../DELIMITERS.END}}</button>' +
|
||||
'{{/split}}' +
|
||||
'</div>' +
|
||||
'{{/each}}' +
|
||||
|
@ -111,7 +115,17 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
*/
|
||||
_content: null,
|
||||
|
||||
/**
|
||||
* The source equation we are editing in the text.
|
||||
*
|
||||
* @property _sourceEquation
|
||||
* @type String
|
||||
* @private
|
||||
*/
|
||||
_sourceEquation: '',
|
||||
|
||||
initializer: function() {
|
||||
// If there is a tex filter active - enable this button.
|
||||
if (this.get('texfilteractive')) {
|
||||
// Add the button to the toolbar.
|
||||
this.addButton({
|
||||
|
@ -127,7 +141,14 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
this.unHighlightButtons();
|
||||
}
|
||||
}, this);
|
||||
|
||||
// We need to convert these to a non dom node based format.
|
||||
this.editor.all('tex').each(function (texNode) {
|
||||
var replacement = Y.Node.create('<span>' + DELIMITERS.START + ' ' + texNode.get('text') + ' ' + DELIMITERS.END + '</span>');
|
||||
texNode.replace(replacement);
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -160,6 +181,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
|
||||
tabview.render();
|
||||
dialogue.show();
|
||||
// Trigger any JS filters to reprocess the new nodes.
|
||||
Y.fire(M.core.event.FILTER_CONTENT_UPDATED, {nodes: (new Y.NodeList(dialogue.get('boundingBox')))});
|
||||
|
||||
var equation = this._resolveEquation();
|
||||
if (equation) {
|
||||
|
@ -181,7 +204,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
// Find the equation in the surrounding text.
|
||||
var selectedNode = this.get('host').getSelectionParentNode(),
|
||||
text,
|
||||
equation;
|
||||
equation,
|
||||
patterns = [], i;
|
||||
|
||||
// Note this is a document fragment and YUI doesn't like them.
|
||||
if (!selectedNode) {
|
||||
|
@ -190,14 +214,27 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
|
||||
text = Y.one(selectedNode).get('text');
|
||||
// We use space or not space because . does not match new lines.
|
||||
pattern = /\$\$[\S\s]*\$\$/;
|
||||
equation = pattern.exec(text);
|
||||
if (equation && equation.length) {
|
||||
equation = equation.pop();
|
||||
// Replace the equation.
|
||||
equation = equation.substring(2, equation.length - 2);
|
||||
return equation;
|
||||
// $$ blah $$.
|
||||
patterns.push(/\$\$([\S\s]*)\$\$/);
|
||||
// E.g. "\( blah \)".
|
||||
patterns.push(/\\\(([\S\s]*)\\\)/);
|
||||
// E.g. "\[ blah \]".
|
||||
patterns.push(/\\\[([\S\s]*)\\\]/);
|
||||
// E.g. "[tex] blah [/tex]".
|
||||
patterns.push(/\[tex\]([\S\s]*)\[\/tex\]/);
|
||||
|
||||
for (i = 0; i < patterns.length; i++) {
|
||||
pattern = patterns[i];
|
||||
equation = pattern.exec(text);
|
||||
if (equation && equation.length) {
|
||||
// Remember the inner match so we can replace it later.
|
||||
this.sourceEquation = equation = equation[1];
|
||||
|
||||
return equation;
|
||||
}
|
||||
}
|
||||
|
||||
this.sourceEquation = '';
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -212,11 +249,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
var input,
|
||||
selectedNode,
|
||||
text,
|
||||
pattern,
|
||||
equation,
|
||||
value;
|
||||
value,
|
||||
host;
|
||||
|
||||
var host = this.get('host');
|
||||
host = this.get('host');
|
||||
|
||||
e.preventDefault();
|
||||
this.getDialogue({
|
||||
|
@ -229,18 +265,16 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
if (value !== '') {
|
||||
host.setSelection(this._currentSelection);
|
||||
|
||||
value = '$$ ' + value.trim() + ' $$';
|
||||
selectedNode = Y.one(host.getSelectionParentNode());
|
||||
text = selectedNode.get('text');
|
||||
pattern = /\$\$[\S\s]*\$\$/;
|
||||
equation = pattern.exec(text);
|
||||
if (equation && equation.length) {
|
||||
if (this.sourceEquation.length) {
|
||||
// Replace the equation.
|
||||
equation = equation.pop();
|
||||
text = text.replace(equation, '$$' + value + '$$');
|
||||
selectedNode = Y.one(host.getSelectionParentNode());
|
||||
text = selectedNode.get('text');
|
||||
|
||||
text = text.replace(this.sourceEquation, value);
|
||||
selectedNode.set('text', text);
|
||||
} else {
|
||||
// Insert the new equation.
|
||||
value = DELIMITERS.START + ' ' + value + ' ' + DELIMITERS.END;
|
||||
host.insertContentAtFocusPoint(value);
|
||||
}
|
||||
|
||||
|
@ -249,6 +283,29 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Smart throttle, only call a function every delay milli seconds,
|
||||
* and always run the last call. Y.throttle does not work here,
|
||||
* because it calls the function immediately, the first time, and then
|
||||
* ignores repeated calls within X seconds. This does not guarantee
|
||||
* that the last call will be executed (which is required here).
|
||||
*
|
||||
* @param {function} fn
|
||||
* @param {Number} delay Delay in milliseconds
|
||||
* @method _throttle
|
||||
* @private
|
||||
*/
|
||||
_throttle: function(fn, delay) {
|
||||
var timer = null;
|
||||
return function () {
|
||||
var context = this, args = arguments;
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function () {
|
||||
fn.apply(context, args);
|
||||
}, delay);
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the preview div to match the current equation.
|
||||
*
|
||||
|
@ -264,8 +321,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
currentPos = textarea.get('selectionStart'),
|
||||
prefix = '',
|
||||
cursorLatex = '\\square ',
|
||||
isChar;
|
||||
|
||||
isChar,
|
||||
params;
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
|
@ -279,25 +336,33 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
while (equation.charAt(currentPos) === '\\' && currentPos > 0) {
|
||||
currentPos -= 1;
|
||||
}
|
||||
isChar = /[\w\{\}]/;
|
||||
isChar = /[a-zA-Z\{\}]/;
|
||||
while (isChar.test(equation.charAt(currentPos)) && currentPos < equation.length) {
|
||||
currentPos += 1;
|
||||
}
|
||||
// Save the cursor position - for insertion from the library.
|
||||
this._lastCursorPos = currentPos;
|
||||
equation = prefix + equation.substring(0, currentPos) + cursorLatex + equation.substring(currentPos);
|
||||
|
||||
var previewNode = this._content.one(SELECTORS.EQUATION_PREVIEW);
|
||||
equation = DELIMITERS.START + ' ' + equation + ' ' + DELIMITERS.END;
|
||||
// Make an ajax request to the filter.
|
||||
url = M.cfg.wwwroot + '/lib/editor/atto/plugins/equation/ajax.php';
|
||||
params = {
|
||||
sesskey: M.cfg.sesskey,
|
||||
contextid: this.get('contextid'),
|
||||
action: 'filtertext',
|
||||
text: '$$ ' + equation + ' $$'
|
||||
text: equation
|
||||
};
|
||||
|
||||
preview = Y.io(url, { sync: true,
|
||||
data: params });
|
||||
preview = Y.io(url, {
|
||||
sync: true,
|
||||
data: params
|
||||
});
|
||||
|
||||
if (preview.status === 200) {
|
||||
this._content.one(SELECTORS.EQUATION_PREVIEW).setHTML(preview.responseText);
|
||||
previewNode.setHTML(preview.responseText);
|
||||
Y.fire(M.core.event.FILTER_CONTENT_UPDATED, {nodes: (new Y.NodeList(previewNode))});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -322,9 +387,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
}));
|
||||
|
||||
this._content.one(SELECTORS.SUBMIT).on('click', this._setEquation, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('valuechange', this._updatePreview, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('mouseup', this._updatePreview, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('keyup', this._updatePreview, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('valuechange', this._throttle(this._updatePreview, 500), this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('mouseup', this._throttle(this._updatePreview, 500), this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('keyup', this._throttle(this._updatePreview, 500), this);
|
||||
this._content.delegate('click', this._selectLibraryItem, SELECTORS.LIBRARY_BUTTON, this);
|
||||
|
||||
return this._content;
|
||||
|
@ -391,7 +456,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
out = '';
|
||||
parts = str.trim().split(delimiter);
|
||||
while (parts.length > 0) {
|
||||
current = parts.shift();
|
||||
current = parts.shift().trim();
|
||||
out += options.fn(current);
|
||||
}
|
||||
|
||||
|
@ -401,7 +466,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
elementid: this.get('host').get('elementid'),
|
||||
component: COMPONENTNAME,
|
||||
library: library,
|
||||
CSS: CSS
|
||||
CSS: CSS,
|
||||
DELIMITERS: DELIMITERS
|
||||
});
|
||||
|
||||
var url = M.cfg.wwwroot + '/lib/editor/atto/plugins/equation/ajax.php';
|
||||
|
@ -434,6 +500,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
texfilteractive: {
|
||||
value: false
|
||||
},
|
||||
|
||||
/**
|
||||
* The contextid to use when generating this preview.
|
||||
*
|
||||
|
@ -463,8 +530,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
texdocsurl: {
|
||||
value: null
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin", "io", "event-valuechange", "tabview"]});
|
||||
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin", "moodle-core-event", "io", "event-valuechange", "tabview"]});
|
||||
|
|
|
@ -46,6 +46,10 @@ var COMPONENTNAME = 'atto_equation',
|
|||
SUBMIT: '.' + CSS.SUBMIT,
|
||||
LIBRARY_BUTTON: '.' + CSS.LIBRARY + ' button'
|
||||
},
|
||||
DELIMITERS = {
|
||||
START: '\\(',
|
||||
END: '\\)'
|
||||
},
|
||||
TEMPLATES = {
|
||||
FORM: '' +
|
||||
'<form class="atto_form">' +
|
||||
|
@ -70,7 +74,7 @@ var COMPONENTNAME = 'atto_equation',
|
|||
'{{#each library}}' +
|
||||
'<div id="{{elementid}}_{{../CSS.LIBRARY_GROUP_PREFIX}}{{@key}}">' +
|
||||
'{{#split "\n" elements}}' +
|
||||
'<button data-tex="{{this}}" title="{{this}}">$${{this}}$$</button>' +
|
||||
'<button data-tex="{{this}}" title="{{this}}">{{../../DELIMITERS.START}}{{this}}{{../../DELIMITERS.END}}</button>' +
|
||||
'{{/split}}' +
|
||||
'</div>' +
|
||||
'{{/each}}' +
|
||||
|
@ -109,7 +113,17 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
*/
|
||||
_content: null,
|
||||
|
||||
/**
|
||||
* The source equation we are editing in the text.
|
||||
*
|
||||
* @property _sourceEquation
|
||||
* @type String
|
||||
* @private
|
||||
*/
|
||||
_sourceEquation: '',
|
||||
|
||||
initializer: function() {
|
||||
// If there is a tex filter active - enable this button.
|
||||
if (this.get('texfilteractive')) {
|
||||
// Add the button to the toolbar.
|
||||
this.addButton({
|
||||
|
@ -125,7 +139,14 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
this.unHighlightButtons();
|
||||
}
|
||||
}, this);
|
||||
|
||||
// We need to convert these to a non dom node based format.
|
||||
this.editor.all('tex').each(function (texNode) {
|
||||
var replacement = Y.Node.create('<span>' + DELIMITERS.START + ' ' + texNode.get('text') + ' ' + DELIMITERS.END + '</span>');
|
||||
texNode.replace(replacement);
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -158,6 +179,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
|
||||
tabview.render();
|
||||
dialogue.show();
|
||||
// Trigger any JS filters to reprocess the new nodes.
|
||||
Y.fire(M.core.event.FILTER_CONTENT_UPDATED, {nodes: (new Y.NodeList(dialogue.get('boundingBox')))});
|
||||
|
||||
var equation = this._resolveEquation();
|
||||
if (equation) {
|
||||
|
@ -179,7 +202,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
// Find the equation in the surrounding text.
|
||||
var selectedNode = this.get('host').getSelectionParentNode(),
|
||||
text,
|
||||
equation;
|
||||
equation,
|
||||
patterns = [], i;
|
||||
|
||||
// Note this is a document fragment and YUI doesn't like them.
|
||||
if (!selectedNode) {
|
||||
|
@ -188,14 +212,27 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
|
||||
text = Y.one(selectedNode).get('text');
|
||||
// We use space or not space because . does not match new lines.
|
||||
pattern = /\$\$[\S\s]*\$\$/;
|
||||
equation = pattern.exec(text);
|
||||
if (equation && equation.length) {
|
||||
equation = equation.pop();
|
||||
// Replace the equation.
|
||||
equation = equation.substring(2, equation.length - 2);
|
||||
return equation;
|
||||
// $$ blah $$.
|
||||
patterns.push(/\$\$([\S\s]*)\$\$/);
|
||||
// E.g. "\( blah \)".
|
||||
patterns.push(/\\\(([\S\s]*)\\\)/);
|
||||
// E.g. "\[ blah \]".
|
||||
patterns.push(/\\\[([\S\s]*)\\\]/);
|
||||
// E.g. "[tex] blah [/tex]".
|
||||
patterns.push(/\[tex\]([\S\s]*)\[\/tex\]/);
|
||||
|
||||
for (i = 0; i < patterns.length; i++) {
|
||||
pattern = patterns[i];
|
||||
equation = pattern.exec(text);
|
||||
if (equation && equation.length) {
|
||||
// Remember the inner match so we can replace it later.
|
||||
this.sourceEquation = equation = equation[1];
|
||||
|
||||
return equation;
|
||||
}
|
||||
}
|
||||
|
||||
this.sourceEquation = '';
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -210,11 +247,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
var input,
|
||||
selectedNode,
|
||||
text,
|
||||
pattern,
|
||||
equation,
|
||||
value;
|
||||
value,
|
||||
host;
|
||||
|
||||
var host = this.get('host');
|
||||
host = this.get('host');
|
||||
|
||||
e.preventDefault();
|
||||
this.getDialogue({
|
||||
|
@ -227,18 +263,16 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
if (value !== '') {
|
||||
host.setSelection(this._currentSelection);
|
||||
|
||||
value = '$$ ' + value.trim() + ' $$';
|
||||
selectedNode = Y.one(host.getSelectionParentNode());
|
||||
text = selectedNode.get('text');
|
||||
pattern = /\$\$[\S\s]*\$\$/;
|
||||
equation = pattern.exec(text);
|
||||
if (equation && equation.length) {
|
||||
if (this.sourceEquation.length) {
|
||||
// Replace the equation.
|
||||
equation = equation.pop();
|
||||
text = text.replace(equation, '$$' + value + '$$');
|
||||
selectedNode = Y.one(host.getSelectionParentNode());
|
||||
text = selectedNode.get('text');
|
||||
|
||||
text = text.replace(this.sourceEquation, value);
|
||||
selectedNode.set('text', text);
|
||||
} else {
|
||||
// Insert the new equation.
|
||||
value = DELIMITERS.START + ' ' + value + ' ' + DELIMITERS.END;
|
||||
host.insertContentAtFocusPoint(value);
|
||||
}
|
||||
|
||||
|
@ -247,6 +281,29 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Smart throttle, only call a function every delay milli seconds,
|
||||
* and always run the last call. Y.throttle does not work here,
|
||||
* because it calls the function immediately, the first time, and then
|
||||
* ignores repeated calls within X seconds. This does not guarantee
|
||||
* that the last call will be executed (which is required here).
|
||||
*
|
||||
* @param {function} fn
|
||||
* @param {Number} delay Delay in milliseconds
|
||||
* @method _throttle
|
||||
* @private
|
||||
*/
|
||||
_throttle: function(fn, delay) {
|
||||
var timer = null;
|
||||
return function () {
|
||||
var context = this, args = arguments;
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function () {
|
||||
fn.apply(context, args);
|
||||
}, delay);
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the preview div to match the current equation.
|
||||
*
|
||||
|
@ -262,8 +319,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
currentPos = textarea.get('selectionStart'),
|
||||
prefix = '',
|
||||
cursorLatex = '\\square ',
|
||||
isChar;
|
||||
|
||||
isChar,
|
||||
params;
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
|
@ -277,25 +334,33 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
while (equation.charAt(currentPos) === '\\' && currentPos > 0) {
|
||||
currentPos -= 1;
|
||||
}
|
||||
isChar = /[\w\{\}]/;
|
||||
isChar = /[a-zA-Z\{\}]/;
|
||||
while (isChar.test(equation.charAt(currentPos)) && currentPos < equation.length) {
|
||||
currentPos += 1;
|
||||
}
|
||||
// Save the cursor position - for insertion from the library.
|
||||
this._lastCursorPos = currentPos;
|
||||
equation = prefix + equation.substring(0, currentPos) + cursorLatex + equation.substring(currentPos);
|
||||
|
||||
var previewNode = this._content.one(SELECTORS.EQUATION_PREVIEW);
|
||||
equation = DELIMITERS.START + ' ' + equation + ' ' + DELIMITERS.END;
|
||||
// Make an ajax request to the filter.
|
||||
url = M.cfg.wwwroot + '/lib/editor/atto/plugins/equation/ajax.php';
|
||||
params = {
|
||||
sesskey: M.cfg.sesskey,
|
||||
contextid: this.get('contextid'),
|
||||
action: 'filtertext',
|
||||
text: '$$ ' + equation + ' $$'
|
||||
text: equation
|
||||
};
|
||||
|
||||
preview = Y.io(url, { sync: true,
|
||||
data: params });
|
||||
preview = Y.io(url, {
|
||||
sync: true,
|
||||
data: params
|
||||
});
|
||||
|
||||
if (preview.status === 200) {
|
||||
this._content.one(SELECTORS.EQUATION_PREVIEW).setHTML(preview.responseText);
|
||||
previewNode.setHTML(preview.responseText);
|
||||
Y.fire(M.core.event.FILTER_CONTENT_UPDATED, {nodes: (new Y.NodeList(previewNode))});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -320,9 +385,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
}));
|
||||
|
||||
this._content.one(SELECTORS.SUBMIT).on('click', this._setEquation, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('valuechange', this._updatePreview, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('mouseup', this._updatePreview, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('keyup', this._updatePreview, this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('valuechange', this._throttle(this._updatePreview, 500), this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('mouseup', this._throttle(this._updatePreview, 500), this);
|
||||
this._content.one(SELECTORS.EQUATION_TEXT).on('keyup', this._throttle(this._updatePreview, 500), this);
|
||||
this._content.delegate('click', this._selectLibraryItem, SELECTORS.LIBRARY_BUTTON, this);
|
||||
|
||||
return this._content;
|
||||
|
@ -390,7 +455,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
out = '';
|
||||
parts = str.trim().split(delimiter);
|
||||
while (parts.length > 0) {
|
||||
current = parts.shift();
|
||||
current = parts.shift().trim();
|
||||
out += options.fn(current);
|
||||
}
|
||||
|
||||
|
@ -400,7 +465,8 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
elementid: this.get('host').get('elementid'),
|
||||
component: COMPONENTNAME,
|
||||
library: library,
|
||||
CSS: CSS
|
||||
CSS: CSS,
|
||||
DELIMITERS: DELIMITERS
|
||||
});
|
||||
|
||||
var url = M.cfg.wwwroot + '/lib/editor/atto/plugins/equation/ajax.php';
|
||||
|
@ -433,6 +499,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
texfilteractive: {
|
||||
value: false
|
||||
},
|
||||
|
||||
/**
|
||||
* The contextid to use when generating this preview.
|
||||
*
|
||||
|
@ -462,5 +529,6 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
|||
texdocsurl: {
|
||||
value: null
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"moodle-atto_equation-button": {
|
||||
"requires": [
|
||||
"moodle-editor_atto-plugin",
|
||||
"moodle-core-event",
|
||||
"io",
|
||||
"event-valuechange",
|
||||
"tabview"
|
||||
|
|
72
lib/yui/build/moodle-core-event/moodle-core-event-debug.js
vendored
Normal file
72
lib/yui/build/moodle-core-event/moodle-core-event-debug.js
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
YUI.add('moodle-core-event', function (Y, NAME) {
|
||||
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @module moodle-core-event
|
||||
*/
|
||||
|
||||
var LOGNAME = 'moodle-core-event';
|
||||
|
||||
/**
|
||||
* List of published global JS events in Moodle. This is a collection
|
||||
* of global events that can be subscribed to, or fired from any plugin.
|
||||
*
|
||||
* @namespace M.core
|
||||
* @class event
|
||||
*/
|
||||
M.core = M.core || {};
|
||||
|
||||
M.core.event = {
|
||||
/**
|
||||
* This event is triggered when a page has added dynamic nodes to a page
|
||||
* that should be processed by the filter system. An example is loading
|
||||
* user text that could have equations in it. MathJax can typeset the equations
|
||||
* but only if it is notified that there are new nodes in the page that need processing.
|
||||
* To trigger this event use M.core.Event.fire(M.core.Event.FILTER_CONTENT_UPDATED, {nodes: list});
|
||||
*
|
||||
* @event "filter-content-updated"
|
||||
* @param nodes {Y.NodeList} List of nodes added to the DOM.
|
||||
*/
|
||||
FILTER_CONTENT_UPDATED: "filter-content-updated"
|
||||
};
|
||||
|
||||
|
||||
var eventDefaultConfig = {
|
||||
emitFacade: true,
|
||||
defaultFn: function(e) {
|
||||
Y.log('Event fired: ' + e.type, 'debug', LOGNAME);
|
||||
},
|
||||
preventedFn: function(e) {
|
||||
Y.log('Event prevented: ' + e.type, 'debug', LOGNAME);
|
||||
},
|
||||
stoppedFn: function(e) {
|
||||
Y.log('Event stopped: ' + e.type, 'debug', LOGNAME);
|
||||
}
|
||||
};
|
||||
|
||||
// Publish all the events with a standard config.
|
||||
var key;
|
||||
for (key in M.core.event) {
|
||||
if (M.core.event.hasOwnProperty(key)) {
|
||||
Y.publish(M.core.event[key], eventDefaultConfig);
|
||||
}
|
||||
}
|
||||
|
||||
// Publish events with a custom config here.
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["event-custom"]});
|
1
lib/yui/build/moodle-core-event/moodle-core-event-min.js
vendored
Normal file
1
lib/yui/build/moodle-core-event/moodle-core-event-min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
YUI.add("moodle-core-event",function(e,t){var n="moodle-core-event";M.core=M.core||{},M.core.event={FILTER_CONTENT_UPDATED:"filter-content-updated"};var r={emitFacade:!0,defaultFn:function(e){},preventedFn:function(e){},stoppedFn:function(e){}},i;for(i in M.core.event)M.core.event.hasOwnProperty(i)&&e.publish(M.core.event[i],r)},"@VERSION@",{requires:["event-custom"]});
|
69
lib/yui/build/moodle-core-event/moodle-core-event.js
vendored
Normal file
69
lib/yui/build/moodle-core-event/moodle-core-event.js
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
YUI.add('moodle-core-event', function (Y, NAME) {
|
||||
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @module moodle-core-event
|
||||
*/
|
||||
|
||||
var LOGNAME = 'moodle-core-event';
|
||||
|
||||
/**
|
||||
* List of published global JS events in Moodle. This is a collection
|
||||
* of global events that can be subscribed to, or fired from any plugin.
|
||||
*
|
||||
* @namespace M.core
|
||||
* @class event
|
||||
*/
|
||||
M.core = M.core || {};
|
||||
|
||||
M.core.event = {
|
||||
/**
|
||||
* This event is triggered when a page has added dynamic nodes to a page
|
||||
* that should be processed by the filter system. An example is loading
|
||||
* user text that could have equations in it. MathJax can typeset the equations
|
||||
* but only if it is notified that there are new nodes in the page that need processing.
|
||||
* To trigger this event use M.core.Event.fire(M.core.Event.FILTER_CONTENT_UPDATED, {nodes: list});
|
||||
*
|
||||
* @event "filter-content-updated"
|
||||
* @param nodes {Y.NodeList} List of nodes added to the DOM.
|
||||
*/
|
||||
FILTER_CONTENT_UPDATED: "filter-content-updated"
|
||||
};
|
||||
|
||||
|
||||
var eventDefaultConfig = {
|
||||
emitFacade: true,
|
||||
defaultFn: function(e) {
|
||||
},
|
||||
preventedFn: function(e) {
|
||||
},
|
||||
stoppedFn: function(e) {
|
||||
}
|
||||
};
|
||||
|
||||
// Publish all the events with a standard config.
|
||||
var key;
|
||||
for (key in M.core.event) {
|
||||
if (M.core.event.hasOwnProperty(key)) {
|
||||
Y.publish(M.core.event[key], eventDefaultConfig);
|
||||
}
|
||||
}
|
||||
|
||||
// Publish events with a custom config here.
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["event-custom"]});
|
10
lib/yui/src/event/build.json
Normal file
10
lib/yui/src/event/build.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "moodle-core-event",
|
||||
"builds": {
|
||||
"moodle-core-event": {
|
||||
"jsfiles": [
|
||||
"event.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
67
lib/yui/src/event/js/event.js
vendored
Normal file
67
lib/yui/src/event/js/event.js
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
// 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/>.
|
||||
|
||||
/**
|
||||
* @module moodle-core-event
|
||||
*/
|
||||
|
||||
var LOGNAME = 'moodle-core-event';
|
||||
|
||||
/**
|
||||
* List of published global JS events in Moodle. This is a collection
|
||||
* of global events that can be subscribed to, or fired from any plugin.
|
||||
*
|
||||
* @namespace M.core
|
||||
* @class event
|
||||
*/
|
||||
M.core = M.core || {};
|
||||
|
||||
M.core.event = {
|
||||
/**
|
||||
* This event is triggered when a page has added dynamic nodes to a page
|
||||
* that should be processed by the filter system. An example is loading
|
||||
* user text that could have equations in it. MathJax can typeset the equations
|
||||
* but only if it is notified that there are new nodes in the page that need processing.
|
||||
* To trigger this event use M.core.Event.fire(M.core.Event.FILTER_CONTENT_UPDATED, {nodes: list});
|
||||
*
|
||||
* @event "filter-content-updated"
|
||||
* @param nodes {Y.NodeList} List of nodes added to the DOM.
|
||||
*/
|
||||
FILTER_CONTENT_UPDATED: "filter-content-updated"
|
||||
};
|
||||
|
||||
|
||||
var eventDefaultConfig = {
|
||||
emitFacade: true,
|
||||
defaultFn: function(e) {
|
||||
Y.log('Event fired: ' + e.type, 'debug', LOGNAME);
|
||||
},
|
||||
preventedFn: function(e) {
|
||||
Y.log('Event prevented: ' + e.type, 'debug', LOGNAME);
|
||||
},
|
||||
stoppedFn: function(e) {
|
||||
Y.log('Event stopped: ' + e.type, 'debug', LOGNAME);
|
||||
}
|
||||
};
|
||||
|
||||
// Publish all the events with a standard config.
|
||||
var key;
|
||||
for (key in M.core.event) {
|
||||
if (M.core.event.hasOwnProperty(key)) {
|
||||
Y.publish(M.core.event[key], eventDefaultConfig);
|
||||
}
|
||||
}
|
||||
|
||||
// Publish events with a custom config here.
|
7
lib/yui/src/event/meta/event.json
Normal file
7
lib/yui/src/event/meta/event.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"moodle-core-event": {
|
||||
"requires": [
|
||||
"event-custom"
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue