diff --git a/lib/editor/atto/plugins/equation/tests/behat/equation.feature b/lib/editor/atto/plugins/equation/tests/behat/equation.feature
index 0b20f4602e4..9a24ad2dc31 100644
--- a/lib/editor/atto/plugins/equation/tests/behat/equation.feature
+++ b/lib/editor/atto/plugins/equation/tests/behat/equation.feature
@@ -19,3 +19,17 @@ Feature: Atto equation editor
And I click on "Update profile" "button"
Then "\infty" "text" should exist
+ @javascript
+ Scenario: Edit an equation
+ Given I log in as "admin"
+ When I navigate to "Edit profile" node in "My profile settings"
+ And I set the field "Description" to "
\( \pi \)
"
+ # Set field on the bottom of page, so equation editor dialogue is visible.
+ And I expand all fieldsets
+ And I set the field "Picture description" to "Test"
+ And I select the text in the "Description" Atto editor
+ And I click on "Show more buttons" "button"
+ And I click on "Equation editor" "button"
+ Then the field "Edit equation using" matches value " \pi "
+ And I click on "Save equation" "button"
+ And the field "Description" matches value "\( \pi \)
"
diff --git a/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-debug.js b/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-debug.js
index 1f4b0d81b9b..83cdc400359 100644
--- a/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-debug.js
+++ b/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-debug.js
@@ -206,6 +206,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
return;
}
+ // This needs to be done before the dialogue is opened because the focus will shift to the dialogue.
+ var equation = this._resolveEquation();
+
var dialogue = this.getDialogue({
headerContent: M.util.get_string('pluginname', COMPONENTNAME),
focusAfterHide: true,
@@ -227,7 +230,6 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
// 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) {
content.one(SELECTORS.EQUATION_TEXT).set('text', equation);
}
@@ -250,7 +252,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
text,
returnValue = false;
- this.sourceEquation = null;
+ // Prevent resolving equations when we don't have focus.
+ if (!this.get('host').isActive()) {
+ return false;
+ }
// Note this is a document fragment and YUI doesn't like them.
if (!selectedNode) {
@@ -261,6 +266,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
if (!selection || selection.length === 0) {
return false;
}
+
+ this.sourceEquation = null;
+
selection = selection[0];
text = Y.one(selectedNode).get('text');
@@ -326,6 +334,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
}
}, this);
+ // We trim the equation when we load it and then add spaces when we save it.
+ if (returnValue !== false) {
+ returnValue = returnValue.trim();
+ }
return returnValue;
},
@@ -360,6 +372,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
// Replace the equation.
selectedNode = Y.one(host.getSelectionParentNode());
text = selectedNode.get('text');
+ value = ' ' + value + ' ';
newText = text.slice(0, this.sourceEquation.startInnerPosition) +
value +
text.slice(this.sourceEquation.endInnerPosition);
diff --git a/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-min.js b/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-min.js
index 42f68860524..99fc109f417 100644
--- a/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-min.js
+++ b/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-min.js
@@ -1,2 +1,2 @@
-YUI.add("moodle-atto_equation-button",function(e,t){var n="atto_equation",r="atto_equation",i={EQUATION_TEXT:"atto_equation_equation",EQUATION_PREVIEW:"atto_equation_preview",SUBMIT:"atto_equation_submit",LIBRARY:"atto_equation_library",LIBRARY_GROUPS:"atto_equation_groups",LIBRARY_GROUP_PREFIX:"atto_equation_group"},s={LIBRARY:"."+i.LIBRARY,LIBRARY_GROUP:"."+i.LIBRARY_GROUPS+" > div > div",EQUATION_TEXT:"."+i.EQUATION_TEXT,EQUATION_PREVIEW:"."+i.EQUATION_PREVIEW,SUBMIT:"."+i.SUBMIT,LIBRARY_BUTTON:"."+i.LIBRARY+" button"},o={START:"\\(",END:"\\)"},u={FORM:'',LIBRARY:'{{#each library}}
{{#split "\n" elements}}{{../../DELIMITERS.START}}{{this}}{{../../DELIMITERS.END}} {{/split}}
{{/each}}
'};e.namespace("M.atto_equation").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_currentSelection:null,_lastCursorPos:0,_content:null,_sourceEquation:null,_groupFocus:null,_equationPatterns:[/\$\$([\S\s]+?)\$\$/,/\\\(([\S\s]+?)\\\)/,/\\\[([\S\s]+?)\\\]/,/\[tex\]([\S\s]+?)\[\/tex\]/],initializer:function(){this._groupFocus={},this.get("texfilteractive")&&(this.addButton({icon:"e/math",callback:this._displayDialogue}),this.get("host").on("atto:selectionchanged",function(){this._resolveEquation()?this.highlightButtons():this.unHighlightButtons()},this),this.editor.all("tex").each(function(t){var n=e.Node.create(""+o.START+" "+t.get("text")+" "+o.END+" ");t.replace(n)}))},_displayDialogue:function(){this._currentSelection=this.get("host").getSelection();if(this._currentSelection===!1)return;var t=this.getDialogue({headerContent:M.util.get_string("pluginname",n),focusAfterHide:!0,width:600,focusOnShowSelector:s.EQUATION_TEXT}),r=this._getDialogueContent();t.set("bodyContent",r);var i=r.one(s.LIBRARY),o=new e.TabView({srcNode:i});o.render(),t.show(),e.fire(M.core.event.FILTER_CONTENT_UPDATED,{nodes:new e.NodeList(t.get("boundingBox"))});var u=this._resolveEquation();u&&r.one(s.EQUATION_TEXT).set("text",u),this._updatePreview(!1)},_resolveEquation:function(){var t=this.get("host").getSelectionParentNode(),n=this.get("host").getSelection(),r,i=!1;return this.sourceEquation=null,t?!n||n.length===0?!1:(n=n[0],r=e.one(t).get("text"),e.Array.find(this._equationPatterns,function(t){var s=r.match(new RegExp(t.source,"g"));if(s&&s.length)return e.Array.find(s,function(e){var s=0;while(r.indexOf(e,s)!==-1){var o=r.indexOf(e,s),u=o+e.length,a=n.startOffset>=o&&n.startOffseto;if(a&&f){var l=e.match(t);if(l&&l.length){var c=r.indexOf(l[1],o),h=c+l[1].length;return i=l[1],this.sourceEquation={startOuterPosition:o,endOuterPosition:u,outerMatch:e,startInnerPosition:c,endInnerPosition:h,innerMatch:l},!0}}s=u}},this)},this),i):!1},_setEquation:function(t){var n,r,i,s,u;u=this.get("host"),t.preventDefault(),this.getDialogue({focusAfterHide:null}).hide(),n=t.currentTarget.ancestor(".atto_form").one("textarea"),s=n.get("value"),s!==""&&(u.setSelection(this._currentSelection),this.sourceEquation?(r=e.one(u.getSelectionParentNode()),i=r.get("text"),newText=i.slice(0,this.sourceEquation.startInnerPosition)+s+i.slice(this.sourceEquation.endInnerPosition),r.set("text",newText)):(s=o.START+" "+s+" "+o.END,u.insertContentAtFocusPoint(s)),this.markUpdated())},_throttle:function(e,t){var n=null;return function(){var r=this,i=arguments;clearTimeout(n),n=setTimeout(function(){e.apply(r,i)},t)}},_updatePreview:function(t){var n=this._content.one(s.EQUATION_TEXT),r=n.get("value"),i,u,a=n.get("selectionStart"),f="",l="\\Downarrow ",c,h;t&&t.preventDefault(),a||(a=0);while(r.charAt(a)==="\\"&&a>=0)a-=1;c=/[a-zA-Z\{\}]/;if(a!==0)while(c.test(r.charAt(a))&&a=r.size()&&(s=0),o=r.item(s),this._setGroupTabFocus(n,o),o.focus()},_setGroupTabFocus:function(e,t){var n=e.generateID();typeof this._groupFocus[n]!="undefined"&&this._groupFocus[n].setAttribute("tabindex","-1"),this._groupFocus[n]=t,t.setAttribute("tabindex",0),e.setAttribute("aria-activedescendant",t.generateID())},_selectLibraryItem:function(e){var t=e.currentTarget.getAttribute("data-tex"),n,r,i,s=0;e.preventDefault(),this._setGroupTabFocus(e.currentTarget.get("parentNode"),e.currentTarget),i=e.currentTarget.ancestor(".atto_form").one("textarea"),n=i.get("value"),r=n.substring(0,this._lastCursorPos),r.charAt(r.length-1)!==" "&&(r+=" "),r+=t,s=r.length,n.charAt(this._lastCursorPos)!==" "&&(r+=" "),r+=n.substring(this._lastCursorPos,n.length),i.set("value",r),i.focus();var o=i.getDOMNode();if(typeof o.selectionStart=="number")o.selectionStart=o.selectionEnd=s;else if(typeof o.createTextRange!="undefined"){var u=o.createTextRange();u.moveToPoint(s),u.select()}this._updatePreview(!1)},_getLibraryContent:function(){var t=e.Handlebars.compile(u.LIBRARY),r=this.get("library"),s="";e.Handlebars.registerHelper("split",function(e,t,n){var r,i,s;if(typeof e=="undefined"||typeof t=="undefined")return"";s="",r=t.trim().split(e);while(r.length>0)i=r.shift().trim(),s+=n.fn(i);return s}),s=t({elementid:this.get("host").get("elementid"),component:n,library:r,CSS:i,DELIMITERS:o});var a=M.cfg.wwwroot+"/lib/editor/atto/plugins/equation/ajax.php",f={sesskey:M.cfg.sesskey,contextid:this.get("contextid"),action:"filtertext",text:s};return preview=e.io(a,{sync:!0,data:f,method:"POST"}),preview.status===200&&(s=preview.responseText),s}},{ATTRS:{texfilteractive:{value:!1},contextid:{value:null},library:{value:{}},texdocsurl:{value:null}}})},"@VERSION@",{requires:["moodle-editor_atto-plugin","moodle-core-event","io","event-valuechange","tabview","array-extras"]});
+YUI.add("moodle-atto_equation-button",function(e,t){var n="atto_equation",r="atto_equation",i={EQUATION_TEXT:"atto_equation_equation",EQUATION_PREVIEW:"atto_equation_preview",SUBMIT:"atto_equation_submit",LIBRARY:"atto_equation_library",LIBRARY_GROUPS:"atto_equation_groups",LIBRARY_GROUP_PREFIX:"atto_equation_group"},s={LIBRARY:"."+i.LIBRARY,LIBRARY_GROUP:"."+i.LIBRARY_GROUPS+" > div > div",EQUATION_TEXT:"."+i.EQUATION_TEXT,EQUATION_PREVIEW:"."+i.EQUATION_PREVIEW,SUBMIT:"."+i.SUBMIT,LIBRARY_BUTTON:"."+i.LIBRARY+" button"},o={START:"\\(",END:"\\)"},u={FORM:'{{{library}}}{{{get_string "editequation" component texdocsurl}}} {{get_string "preview" component}}
{{get_string "cursorinfo" component}}
{{get_string "saveequation" component}}
',LIBRARY:'{{#each library}}
{{#split "\n" elements}}{{../../DELIMITERS.START}}{{this}}{{../../DELIMITERS.END}} {{/split}}
{{/each}}
'};e.namespace("M.atto_equation").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_currentSelection:null,_lastCursorPos:0,_content:null,_sourceEquation:null,_groupFocus:null,_equationPatterns:[/\$\$([\S\s]+?)\$\$/,/\\\(([\S\s]+?)\\\)/,/\\\[([\S\s]+?)\\\]/,/\[tex\]([\S\s]+?)\[\/tex\]/],initializer:function(){this._groupFocus={},this.get("texfilteractive")&&(this.addButton({icon:"e/math",callback:this._displayDialogue}),this.get("host").on("atto:selectionchanged",function(){this._resolveEquation()?this.highlightButtons():this.unHighlightButtons()},this),this.editor.all("tex").each(function(t){var n=e.Node.create(""+o.START+" "+t.get("text")+" "+o.END+" ");t.replace(n)}))},_displayDialogue:function(){this._currentSelection=this.get("host").getSelection();if(this._currentSelection===!1)return;var t=this._resolveEquation(),r=this.getDialogue({headerContent:M.util.get_string("pluginname",n),focusAfterHide:!0,width:600,focusOnShowSelector:s.EQUATION_TEXT}),i=this._getDialogueContent();r.set("bodyContent",i);var o=i.one(s.LIBRARY),u=new e.TabView({srcNode:o});u.render(),r.show(),e.fire(M.core.event.FILTER_CONTENT_UPDATED,{nodes:new e.NodeList(r.get("boundingBox"))}),t&&i.one(s.EQUATION_TEXT).set("text",t),this._updatePreview(!1)},_resolveEquation:function(){var t=this.get("host").getSelectionParentNode(),n=this.get("host").getSelection(),r,i=!1;return this.get("host").isActive()?t?!n||n.length===0?!1:(this.sourceEquation=null,n=n[0],r=e.one(t).get("text"),e.Array.find(this._equationPatterns,function(t){var s=r.match(new RegExp(t.source,"g"));if(s&&s.length)return e.Array.find(s,function(e){var s=0;while(r.indexOf(e,s)!==-1){var o=r.indexOf(e,s),u=o+e.length,a=n.startOffset>=o&&n.startOffseto;if(a&&f){var l=e.match(t);if(l&&l.length){var c=r.indexOf(l[1],o),h=c+l[1].length;return i=l[1],this.sourceEquation={startOuterPosition:o,endOuterPosition:u,outerMatch:e,startInnerPosition:c,endInnerPosition:h,innerMatch:l},!0}}s=u}},this)},this),i!==!1&&(i=i.trim()),i):!1:!1},_setEquation:function(t){var n,r,i,s,u;u=this.get("host"),t.preventDefault(),this.getDialogue({focusAfterHide:null}).hide(),n=t.currentTarget.ancestor(".atto_form").one("textarea"),s=n.get("value"),s!==""&&(u.setSelection(this._currentSelection),this.sourceEquation?(r=e.one(u.getSelectionParentNode()),i=r.get("text"),s=" "+s+" ",newText=i.slice(0,this.sourceEquation.startInnerPosition)+s+i.slice(this.sourceEquation.endInnerPosition),r.set("text",newText)):(s=o.START+" "+s+" "+o.END,u.insertContentAtFocusPoint(s)),this.markUpdated())},_throttle:function(e,t){var n=null;return function(){var r=this,i=arguments;clearTimeout(n),n=setTimeout(function(){e.apply(r,i)},t)}},_updatePreview:function(t){var n=this._content.one(s.EQUATION_TEXT),r=n.get("value"),i,u,a=n.get("selectionStart"),f="",l="\\Downarrow ",c,h;t&&t.preventDefault(),a||(a=0);while(r.charAt(a)==="\\"&&a>=0)a-=1;c=/[a-zA-Z\{\}]/;if(a!==0)while(c.test(r.charAt(a))&&a=r.size()&&(s=0),o=r.item(s),this._setGroupTabFocus(n,o),o.focus()},_setGroupTabFocus:function(e,t){var n=e.generateID();typeof this._groupFocus[n]!="undefined"&&this._groupFocus[n].setAttribute("tabindex","-1"),this._groupFocus[n]=t,t.setAttribute("tabindex",0),e.setAttribute("aria-activedescendant",t.generateID())},_selectLibraryItem:function(e){var t=e.currentTarget.getAttribute("data-tex"),n,r,i,s=0;e.preventDefault(),this._setGroupTabFocus(e.currentTarget.get("parentNode"),e.currentTarget),i=e.currentTarget.ancestor(".atto_form").one("textarea"),n=i.get("value"),r=n.substring(0,this._lastCursorPos),r.charAt(r.length-1)!==" "&&(r+=" "),r+=t,s=r.length,n.charAt(this._lastCursorPos)!==" "&&(r+=" "),r+=n.substring(this._lastCursorPos,n.length),i.set("value",r),i.focus();var o=i.getDOMNode();if(typeof o.selectionStart=="number")o.selectionStart=o.selectionEnd=s;else if(typeof o.createTextRange!="undefined"){var u=o.createTextRange();u.moveToPoint(s),u.select()}this._updatePreview(!1)},_getLibraryContent:function(){var t=e.Handlebars.compile(u.LIBRARY),r=this.get("library"),s="";e.Handlebars.registerHelper("split",function(e,t,n){var r,i,s;if(typeof e=="undefined"||typeof t=="undefined")return"";s="",r=t.trim().split(e);while(r.length>0)i=r.shift().trim(),s+=n.fn(i);return s}),s=t({elementid:this.get("host").get("elementid"),component:n,library:r,CSS:i,DELIMITERS:o});var a=M.cfg.wwwroot+"/lib/editor/atto/plugins/equation/ajax.php",f={sesskey:M.cfg.sesskey,contextid:this.get("contextid"),action:"filtertext",text:s};return preview=e.io(a,{sync:!0,data:f,method:"POST"}),preview.status===200&&(s=preview.responseText),s}},{ATTRS:{texfilteractive:{value:!1},contextid:{value:null},library:{value:{}},texdocsurl:{value:null}}})},"@VERSION@",{requires:["moodle-editor_atto-plugin","moodle-core-event","io","event-valuechange","tabview","array-extras"]});
diff --git a/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button.js b/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button.js
index e5a5e72a765..b4429bce564 100644
--- a/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button.js
+++ b/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button.js
@@ -206,6 +206,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
return;
}
+ // This needs to be done before the dialogue is opened because the focus will shift to the dialogue.
+ var equation = this._resolveEquation();
+
var dialogue = this.getDialogue({
headerContent: M.util.get_string('pluginname', COMPONENTNAME),
focusAfterHide: true,
@@ -227,7 +230,6 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
// 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) {
content.one(SELECTORS.EQUATION_TEXT).set('text', equation);
}
@@ -250,7 +252,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
text,
returnValue = false;
- this.sourceEquation = null;
+ // Prevent resolving equations when we don't have focus.
+ if (!this.get('host').isActive()) {
+ return false;
+ }
// Note this is a document fragment and YUI doesn't like them.
if (!selectedNode) {
@@ -261,6 +266,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
if (!selection || selection.length === 0) {
return false;
}
+
+ this.sourceEquation = null;
+
selection = selection[0];
text = Y.one(selectedNode).get('text');
@@ -326,6 +334,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
}
}, this);
+ // We trim the equation when we load it and then add spaces when we save it.
+ if (returnValue !== false) {
+ returnValue = returnValue.trim();
+ }
return returnValue;
},
@@ -360,6 +372,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
// Replace the equation.
selectedNode = Y.one(host.getSelectionParentNode());
text = selectedNode.get('text');
+ value = ' ' + value + ' ';
newText = text.slice(0, this.sourceEquation.startInnerPosition) +
value +
text.slice(this.sourceEquation.endInnerPosition);
diff --git a/lib/editor/atto/plugins/equation/yui/src/button/js/button.js b/lib/editor/atto/plugins/equation/yui/src/button/js/button.js
index 59c07c921b7..11244960c4a 100644
--- a/lib/editor/atto/plugins/equation/yui/src/button/js/button.js
+++ b/lib/editor/atto/plugins/equation/yui/src/button/js/button.js
@@ -204,6 +204,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
return;
}
+ // This needs to be done before the dialogue is opened because the focus will shift to the dialogue.
+ var equation = this._resolveEquation();
+
var dialogue = this.getDialogue({
headerContent: M.util.get_string('pluginname', COMPONENTNAME),
focusAfterHide: true,
@@ -225,7 +228,6 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
// 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) {
content.one(SELECTORS.EQUATION_TEXT).set('text', equation);
}
@@ -248,7 +250,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
text,
returnValue = false;
- this.sourceEquation = null;
+ // Prevent resolving equations when we don't have focus.
+ if (!this.get('host').isActive()) {
+ return false;
+ }
// Note this is a document fragment and YUI doesn't like them.
if (!selectedNode) {
@@ -259,6 +264,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
if (!selection || selection.length === 0) {
return false;
}
+
+ this.sourceEquation = null;
+
selection = selection[0];
text = Y.one(selectedNode).get('text');
@@ -324,6 +332,10 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
}
}, this);
+ // We trim the equation when we load it and then add spaces when we save it.
+ if (returnValue !== false) {
+ returnValue = returnValue.trim();
+ }
return returnValue;
},
@@ -358,6 +370,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
// Replace the equation.
selectedNode = Y.one(host.getSelectionParentNode());
text = selectedNode.get('text');
+ value = ' ' + value + ' ';
newText = text.slice(0, this.sourceEquation.startInnerPosition) +
value +
text.slice(this.sourceEquation.endInnerPosition);