mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 06:18:28 +01:00
Merge branch 'MDL-45207-master' of git://github.com/andrewnicols/moodle
This commit is contained in:
commit
7b99722e93
@ -128,10 +128,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
||||
* The source equation we are editing in the text.
|
||||
*
|
||||
* @property _sourceEquation
|
||||
* @type String
|
||||
* @type Object
|
||||
* @private
|
||||
*/
|
||||
_sourceEquation: '',
|
||||
_sourceEquation: null,
|
||||
|
||||
/**
|
||||
* A reference to the tab focus set on each group.
|
||||
@ -144,6 +144,25 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
||||
*/
|
||||
_groupFocus: null,
|
||||
|
||||
/**
|
||||
* Regular Expression patterns used to pick out the equations in a String.
|
||||
*
|
||||
* @property _equationPatterns
|
||||
* @type Array
|
||||
* @private
|
||||
*/
|
||||
_equationPatterns: [
|
||||
// We use space or not space because . does not match new lines.
|
||||
// $$ blah $$.
|
||||
/\$\$([\S\s]+?)\$\$/,
|
||||
// E.g. "\( blah \)".
|
||||
/\\\(([\S\s]+?)\\\)/,
|
||||
// E.g. "\[ blah \]".
|
||||
/\\\[([\S\s]+?)\\\]/,
|
||||
// E.g. "[tex] blah [/tex]".
|
||||
/\[tex\]([\S\s]+?)\[\/tex\]/
|
||||
],
|
||||
|
||||
initializer: function() {
|
||||
this._groupFocus = {};
|
||||
|
||||
@ -225,39 +244,87 @@ 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(),
|
||||
selection = this.get('host').getSelection(),
|
||||
text,
|
||||
equation,
|
||||
patterns = [], i;
|
||||
returnValue = false;
|
||||
|
||||
this.sourceEquation = null;
|
||||
|
||||
// Note this is a document fragment and YUI doesn't like them.
|
||||
if (!selectedNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
text = Y.one(selectedNode).get('text');
|
||||
// We use space or not space because . does not match new lines.
|
||||
// $$ 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;
|
||||
}
|
||||
// We don't yet have a cursor selection somehow so we can't possible be resolving an equation that has selection.
|
||||
if (!selection || selection.length === 0) {
|
||||
return false;
|
||||
}
|
||||
selection = selection[0];
|
||||
|
||||
this.sourceEquation = '';
|
||||
return false;
|
||||
text = Y.one(selectedNode).get('text');
|
||||
|
||||
// For each of these patterns we have a RegExp which captures the inner component of the equation but also includes the delimiters.
|
||||
// We first run the RegExp adding the global flag ("g"). This ignores the capture, instead matching the entire
|
||||
// equation including delimiters and returning one entry per match of the whole equation.
|
||||
// We have to deal with multiple occurences of the same equation in a String so must be able to loop on the
|
||||
// match results.
|
||||
Y.Array.find(this._equationPatterns, function(pattern) {
|
||||
// For each pattern in turn, find all whole matches (including the delimiters).
|
||||
var patternMatches = text.match(new RegExp(pattern.source, "g"));
|
||||
|
||||
if (patternMatches && patternMatches.length) {
|
||||
// This pattern matches at least once. See if this pattern matches our current position.
|
||||
// Note: We return here to break the Y.Array.find loop - any truthy return will stop any subsequent
|
||||
// searches which is the required behaviour of this function.
|
||||
return Y.Array.find(patternMatches, function(match) {
|
||||
// Check each occurrence of this match.
|
||||
var startIndex = 0;
|
||||
while(text.indexOf(match, startIndex) !== -1) {
|
||||
// Determine whether the cursor is in the current occurrence of this string.
|
||||
// Note: We do not support a selection exceeding the bounds of an equation.
|
||||
var startOuter = text.indexOf(match, startIndex),
|
||||
endOuter = startOuter + match.length,
|
||||
startMatch = (selection.startOffset >= startOuter && selection.startOffset < endOuter),
|
||||
endMatch = (selection.endOffset <= endOuter && selection.endOffset > startOuter);
|
||||
|
||||
if (startMatch && endMatch) {
|
||||
// This match is in our current position - fetch the innerMatch data.
|
||||
var innerMatch = match.match(pattern);
|
||||
if (innerMatch && innerMatch.length) {
|
||||
// We need the start and end of the inner match for later.
|
||||
var startInner = text.indexOf(innerMatch[1], startOuter),
|
||||
endInner = startInner + innerMatch[1].length;
|
||||
|
||||
// We'll be returning the inner match for use in the editor itself.
|
||||
returnValue = innerMatch[1];
|
||||
|
||||
// Save all data for later.
|
||||
this.sourceEquation = {
|
||||
// Outer match data.
|
||||
startOuterPosition: startOuter,
|
||||
endOuterPosition: endOuter,
|
||||
outerMatch: match,
|
||||
|
||||
// Inner match data.
|
||||
startInnerPosition: startInner,
|
||||
endInnerPosition: endInner,
|
||||
innerMatch: innerMatch
|
||||
};
|
||||
|
||||
// This breaks out of both Y.Array.find functions.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the startIndex to match the end of the current match so that we can continue hunting
|
||||
// for further matches.
|
||||
startIndex = endOuter;
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
}, this);
|
||||
|
||||
return returnValue;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -287,13 +354,15 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
||||
if (value !== '') {
|
||||
host.setSelection(this._currentSelection);
|
||||
|
||||
if (this.sourceEquation.length) {
|
||||
if (this.sourceEquation) {
|
||||
// Replace the equation.
|
||||
selectedNode = Y.one(host.getSelectionParentNode());
|
||||
text = selectedNode.get('text');
|
||||
newText = text.slice(0, this.sourceEquation.startInnerPosition) +
|
||||
value +
|
||||
text.slice(this.sourceEquation.endInnerPosition);
|
||||
|
||||
text = text.replace(this.sourceEquation, value);
|
||||
selectedNode.set('text', text);
|
||||
selectedNode.set('text', newText);
|
||||
} else {
|
||||
// Insert the new equation.
|
||||
value = DELIMITERS.START + ' ' + value + ' ' + DELIMITERS.END;
|
||||
@ -627,4 +696,13 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
||||
});
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin", "moodle-core-event", "io", "event-valuechange", "tabview"]});
|
||||
}, '@VERSION@', {
|
||||
"requires": [
|
||||
"moodle-editor_atto-plugin",
|
||||
"moodle-core-event",
|
||||
"io",
|
||||
"event-valuechange",
|
||||
"tabview",
|
||||
"array-extras"
|
||||
]
|
||||
});
|
||||
|
File diff suppressed because one or more lines are too long
@ -128,10 +128,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
||||
* The source equation we are editing in the text.
|
||||
*
|
||||
* @property _sourceEquation
|
||||
* @type String
|
||||
* @type Object
|
||||
* @private
|
||||
*/
|
||||
_sourceEquation: '',
|
||||
_sourceEquation: null,
|
||||
|
||||
/**
|
||||
* A reference to the tab focus set on each group.
|
||||
@ -144,6 +144,25 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
||||
*/
|
||||
_groupFocus: null,
|
||||
|
||||
/**
|
||||
* Regular Expression patterns used to pick out the equations in a String.
|
||||
*
|
||||
* @property _equationPatterns
|
||||
* @type Array
|
||||
* @private
|
||||
*/
|
||||
_equationPatterns: [
|
||||
// We use space or not space because . does not match new lines.
|
||||
// $$ blah $$.
|
||||
/\$\$([\S\s]+?)\$\$/,
|
||||
// E.g. "\( blah \)".
|
||||
/\\\(([\S\s]+?)\\\)/,
|
||||
// E.g. "\[ blah \]".
|
||||
/\\\[([\S\s]+?)\\\]/,
|
||||
// E.g. "[tex] blah [/tex]".
|
||||
/\[tex\]([\S\s]+?)\[\/tex\]/
|
||||
],
|
||||
|
||||
initializer: function() {
|
||||
this._groupFocus = {};
|
||||
|
||||
@ -225,39 +244,87 @@ 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(),
|
||||
selection = this.get('host').getSelection(),
|
||||
text,
|
||||
equation,
|
||||
patterns = [], i;
|
||||
returnValue = false;
|
||||
|
||||
this.sourceEquation = null;
|
||||
|
||||
// Note this is a document fragment and YUI doesn't like them.
|
||||
if (!selectedNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
text = Y.one(selectedNode).get('text');
|
||||
// We use space or not space because . does not match new lines.
|
||||
// $$ 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;
|
||||
}
|
||||
// We don't yet have a cursor selection somehow so we can't possible be resolving an equation that has selection.
|
||||
if (!selection || selection.length === 0) {
|
||||
return false;
|
||||
}
|
||||
selection = selection[0];
|
||||
|
||||
this.sourceEquation = '';
|
||||
return false;
|
||||
text = Y.one(selectedNode).get('text');
|
||||
|
||||
// For each of these patterns we have a RegExp which captures the inner component of the equation but also includes the delimiters.
|
||||
// We first run the RegExp adding the global flag ("g"). This ignores the capture, instead matching the entire
|
||||
// equation including delimiters and returning one entry per match of the whole equation.
|
||||
// We have to deal with multiple occurences of the same equation in a String so must be able to loop on the
|
||||
// match results.
|
||||
Y.Array.find(this._equationPatterns, function(pattern) {
|
||||
// For each pattern in turn, find all whole matches (including the delimiters).
|
||||
var patternMatches = text.match(new RegExp(pattern.source, "g"));
|
||||
|
||||
if (patternMatches && patternMatches.length) {
|
||||
// This pattern matches at least once. See if this pattern matches our current position.
|
||||
// Note: We return here to break the Y.Array.find loop - any truthy return will stop any subsequent
|
||||
// searches which is the required behaviour of this function.
|
||||
return Y.Array.find(patternMatches, function(match) {
|
||||
// Check each occurrence of this match.
|
||||
var startIndex = 0;
|
||||
while(text.indexOf(match, startIndex) !== -1) {
|
||||
// Determine whether the cursor is in the current occurrence of this string.
|
||||
// Note: We do not support a selection exceeding the bounds of an equation.
|
||||
var startOuter = text.indexOf(match, startIndex),
|
||||
endOuter = startOuter + match.length,
|
||||
startMatch = (selection.startOffset >= startOuter && selection.startOffset < endOuter),
|
||||
endMatch = (selection.endOffset <= endOuter && selection.endOffset > startOuter);
|
||||
|
||||
if (startMatch && endMatch) {
|
||||
// This match is in our current position - fetch the innerMatch data.
|
||||
var innerMatch = match.match(pattern);
|
||||
if (innerMatch && innerMatch.length) {
|
||||
// We need the start and end of the inner match for later.
|
||||
var startInner = text.indexOf(innerMatch[1], startOuter),
|
||||
endInner = startInner + innerMatch[1].length;
|
||||
|
||||
// We'll be returning the inner match for use in the editor itself.
|
||||
returnValue = innerMatch[1];
|
||||
|
||||
// Save all data for later.
|
||||
this.sourceEquation = {
|
||||
// Outer match data.
|
||||
startOuterPosition: startOuter,
|
||||
endOuterPosition: endOuter,
|
||||
outerMatch: match,
|
||||
|
||||
// Inner match data.
|
||||
startInnerPosition: startInner,
|
||||
endInnerPosition: endInner,
|
||||
innerMatch: innerMatch
|
||||
};
|
||||
|
||||
// This breaks out of both Y.Array.find functions.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the startIndex to match the end of the current match so that we can continue hunting
|
||||
// for further matches.
|
||||
startIndex = endOuter;
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
}, this);
|
||||
|
||||
return returnValue;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -287,13 +354,15 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
||||
if (value !== '') {
|
||||
host.setSelection(this._currentSelection);
|
||||
|
||||
if (this.sourceEquation.length) {
|
||||
if (this.sourceEquation) {
|
||||
// Replace the equation.
|
||||
selectedNode = Y.one(host.getSelectionParentNode());
|
||||
text = selectedNode.get('text');
|
||||
newText = text.slice(0, this.sourceEquation.startInnerPosition) +
|
||||
value +
|
||||
text.slice(this.sourceEquation.endInnerPosition);
|
||||
|
||||
text = text.replace(this.sourceEquation, value);
|
||||
selectedNode.set('text', text);
|
||||
selectedNode.set('text', newText);
|
||||
} else {
|
||||
// Insert the new equation.
|
||||
value = DELIMITERS.START + ' ' + value + ' ' + DELIMITERS.END;
|
||||
@ -625,4 +694,13 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
||||
});
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin", "moodle-core-event", "io", "event-valuechange", "tabview"]});
|
||||
}, '@VERSION@', {
|
||||
"requires": [
|
||||
"moodle-editor_atto-plugin",
|
||||
"moodle-core-event",
|
||||
"io",
|
||||
"event-valuechange",
|
||||
"tabview",
|
||||
"array-extras"
|
||||
]
|
||||
});
|
||||
|
@ -126,10 +126,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
||||
* The source equation we are editing in the text.
|
||||
*
|
||||
* @property _sourceEquation
|
||||
* @type String
|
||||
* @type Object
|
||||
* @private
|
||||
*/
|
||||
_sourceEquation: '',
|
||||
_sourceEquation: null,
|
||||
|
||||
/**
|
||||
* A reference to the tab focus set on each group.
|
||||
@ -142,6 +142,25 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
||||
*/
|
||||
_groupFocus: null,
|
||||
|
||||
/**
|
||||
* Regular Expression patterns used to pick out the equations in a String.
|
||||
*
|
||||
* @property _equationPatterns
|
||||
* @type Array
|
||||
* @private
|
||||
*/
|
||||
_equationPatterns: [
|
||||
// We use space or not space because . does not match new lines.
|
||||
// $$ blah $$.
|
||||
/\$\$([\S\s]+?)\$\$/,
|
||||
// E.g. "\( blah \)".
|
||||
/\\\(([\S\s]+?)\\\)/,
|
||||
// E.g. "\[ blah \]".
|
||||
/\\\[([\S\s]+?)\\\]/,
|
||||
// E.g. "[tex] blah [/tex]".
|
||||
/\[tex\]([\S\s]+?)\[\/tex\]/
|
||||
],
|
||||
|
||||
initializer: function() {
|
||||
this._groupFocus = {};
|
||||
|
||||
@ -223,39 +242,87 @@ 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(),
|
||||
selection = this.get('host').getSelection(),
|
||||
text,
|
||||
equation,
|
||||
patterns = [], i;
|
||||
returnValue = false;
|
||||
|
||||
this.sourceEquation = null;
|
||||
|
||||
// Note this is a document fragment and YUI doesn't like them.
|
||||
if (!selectedNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
text = Y.one(selectedNode).get('text');
|
||||
// We use space or not space because . does not match new lines.
|
||||
// $$ 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;
|
||||
}
|
||||
// We don't yet have a cursor selection somehow so we can't possible be resolving an equation that has selection.
|
||||
if (!selection || selection.length === 0) {
|
||||
return false;
|
||||
}
|
||||
selection = selection[0];
|
||||
|
||||
this.sourceEquation = '';
|
||||
return false;
|
||||
text = Y.one(selectedNode).get('text');
|
||||
|
||||
// For each of these patterns we have a RegExp which captures the inner component of the equation but also includes the delimiters.
|
||||
// We first run the RegExp adding the global flag ("g"). This ignores the capture, instead matching the entire
|
||||
// equation including delimiters and returning one entry per match of the whole equation.
|
||||
// We have to deal with multiple occurences of the same equation in a String so must be able to loop on the
|
||||
// match results.
|
||||
Y.Array.find(this._equationPatterns, function(pattern) {
|
||||
// For each pattern in turn, find all whole matches (including the delimiters).
|
||||
var patternMatches = text.match(new RegExp(pattern.source, "g"));
|
||||
|
||||
if (patternMatches && patternMatches.length) {
|
||||
// This pattern matches at least once. See if this pattern matches our current position.
|
||||
// Note: We return here to break the Y.Array.find loop - any truthy return will stop any subsequent
|
||||
// searches which is the required behaviour of this function.
|
||||
return Y.Array.find(patternMatches, function(match) {
|
||||
// Check each occurrence of this match.
|
||||
var startIndex = 0;
|
||||
while(text.indexOf(match, startIndex) !== -1) {
|
||||
// Determine whether the cursor is in the current occurrence of this string.
|
||||
// Note: We do not support a selection exceeding the bounds of an equation.
|
||||
var startOuter = text.indexOf(match, startIndex),
|
||||
endOuter = startOuter + match.length,
|
||||
startMatch = (selection.startOffset >= startOuter && selection.startOffset < endOuter),
|
||||
endMatch = (selection.endOffset <= endOuter && selection.endOffset > startOuter);
|
||||
|
||||
if (startMatch && endMatch) {
|
||||
// This match is in our current position - fetch the innerMatch data.
|
||||
var innerMatch = match.match(pattern);
|
||||
if (innerMatch && innerMatch.length) {
|
||||
// We need the start and end of the inner match for later.
|
||||
var startInner = text.indexOf(innerMatch[1], startOuter),
|
||||
endInner = startInner + innerMatch[1].length;
|
||||
|
||||
// We'll be returning the inner match for use in the editor itself.
|
||||
returnValue = innerMatch[1];
|
||||
|
||||
// Save all data for later.
|
||||
this.sourceEquation = {
|
||||
// Outer match data.
|
||||
startOuterPosition: startOuter,
|
||||
endOuterPosition: endOuter,
|
||||
outerMatch: match,
|
||||
|
||||
// Inner match data.
|
||||
startInnerPosition: startInner,
|
||||
endInnerPosition: endInner,
|
||||
innerMatch: innerMatch
|
||||
};
|
||||
|
||||
// This breaks out of both Y.Array.find functions.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the startIndex to match the end of the current match so that we can continue hunting
|
||||
// for further matches.
|
||||
startIndex = endOuter;
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
}, this);
|
||||
|
||||
return returnValue;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -285,13 +352,15 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
|
||||
if (value !== '') {
|
||||
host.setSelection(this._currentSelection);
|
||||
|
||||
if (this.sourceEquation.length) {
|
||||
if (this.sourceEquation) {
|
||||
// Replace the equation.
|
||||
selectedNode = Y.one(host.getSelectionParentNode());
|
||||
text = selectedNode.get('text');
|
||||
newText = text.slice(0, this.sourceEquation.startInnerPosition) +
|
||||
value +
|
||||
text.slice(this.sourceEquation.endInnerPosition);
|
||||
|
||||
text = text.replace(this.sourceEquation, value);
|
||||
selectedNode.set('text', text);
|
||||
selectedNode.set('text', newText);
|
||||
} else {
|
||||
// Insert the new equation.
|
||||
value = DELIMITERS.START + ' ' + value + ' ' + DELIMITERS.END;
|
||||
|
@ -5,7 +5,8 @@
|
||||
"moodle-core-event",
|
||||
"io",
|
||||
"event-valuechange",
|
||||
"tabview"
|
||||
"tabview",
|
||||
"array-extras"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user