From d926ce71739300fc15ee232673467e72608ad3e4 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 24 Apr 2014 15:13:19 +0800 Subject: [PATCH] MDL-45254 atto_equation: Allow insertion of macros at the beginning of words --- .../moodle-atto_equation-button-debug.js | 40 ++++++++++++++----- .../moodle-atto_equation-button-min.js | 4 +- .../moodle-atto_equation-button.js | 40 ++++++++++++++----- .../equation/yui/src/button/js/button.js | 40 ++++++++++++++----- 4 files changed, 89 insertions(+), 35 deletions(-) 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 2392b18b7a7..c906f26ad50 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 @@ -419,17 +419,22 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto. e.preventDefault(); } + // Move the cursor so it does not break expressions. + // Start at the very beginning. if (!currentPos) { currentPos = 0; } - // Move the cursor so it does not break expressions. - // - while (equation.charAt(currentPos) === '\\' && currentPos > 0) { + + // First move back to the beginning of the line. + while (equation.charAt(currentPos) === '\\' && currentPos >= 0) { currentPos -= 1; } isChar = /[a-zA-Z\{\}]/; - while (isChar.test(equation.charAt(currentPos)) && currentPos < equation.length) { - currentPos += 1; + if (currentPos !== 0) { + // Now match to the end of the line. + while (isChar.test(equation.charAt(currentPos)) && currentPos < equation.length && isChar.test(equation.charAt(currentPos-1))) { + currentPos += 1; + } } // Save the cursor position - for insertion from the library. this._lastCursorPos = currentPos; @@ -561,7 +566,11 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto. * @private */ _selectLibraryItem: function(e) { - var tex = e.currentTarget.getAttribute('data-tex'); + var tex = e.currentTarget.getAttribute('data-tex'), + oldValue, + newValue, + input, + focusPoint = 0; e.preventDefault(); @@ -570,15 +579,24 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto. input = e.currentTarget.ancestor('.atto_form').one('textarea'); - value = input.get('value'); + oldValue = input.get('value'); - value = value.substring(0, this._lastCursorPos) + tex + value.substring(this._lastCursorPos, value.length); + newValue = oldValue.substring(0, this._lastCursorPos); + if (newValue.charAt(newValue.length - 1) !== ' ') { + newValue += ' '; + } + newValue += tex; + focusPoint = newValue.length; - input.set('value', value); + if (oldValue.charAt(this._lastCursorPos) !== ' ') { + newValue += ' '; + } + newValue += oldValue.substring(this._lastCursorPos, oldValue.length); + + input.set('value', newValue); input.focus(); - var focusPoint = this._lastCursorPos + tex.length, - realInput = input.getDOMNode(); + var realInput = input.getDOMNode(); if (typeof realInput.selectionStart === "number") { // Modern browsers have selectionStart and selectionEnd to control the cursor position. realInput.selectionStart = realInput.selectionEnd = focusPoint; 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 8db10819068..ce063111aec 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}}}

',LIBRARY:'
{{#each library}}
{{#split "\n" elements}}{{/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}),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="\\square ",c,h;t&&t.preventDefault(),a||(a=0);while(r.charAt(a)==="\\"&&a>0)a-=1;c=/[a-zA-Z\{\}]/;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");e.preventDefault(),this._setGroupTabFocus(e.currentTarget.get("parentNode"),e.currentTarget),input=e.currentTarget.ancestor(".atto_form").one("textarea"),value=input.get("value"),value=value.substring(0,this._lastCursorPos)+t+value.substring(this._lastCursorPos,value.length),input.set("value",value),input.focus();var n=this._lastCursorPos+t.length,r=input.getDOMNode();if(typeof r.selectionStart=="number")r.selectionStart=r.selectionEnd=n;else if(typeof r.createTextRange!="undefined"){var i=r.createTextRange();i.moveToPoint(n),i.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}}}

',LIBRARY:'
{{#each library}}
{{#split "\n" elements}}{{/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}),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="\\square ",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 e6bd1110fe1..0f3affd106b 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 @@ -419,17 +419,22 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto. e.preventDefault(); } + // Move the cursor so it does not break expressions. + // Start at the very beginning. if (!currentPos) { currentPos = 0; } - // Move the cursor so it does not break expressions. - // - while (equation.charAt(currentPos) === '\\' && currentPos > 0) { + + // First move back to the beginning of the line. + while (equation.charAt(currentPos) === '\\' && currentPos >= 0) { currentPos -= 1; } isChar = /[a-zA-Z\{\}]/; - while (isChar.test(equation.charAt(currentPos)) && currentPos < equation.length) { - currentPos += 1; + if (currentPos !== 0) { + // Now match to the end of the line. + while (isChar.test(equation.charAt(currentPos)) && currentPos < equation.length && isChar.test(equation.charAt(currentPos-1))) { + currentPos += 1; + } } // Save the cursor position - for insertion from the library. this._lastCursorPos = currentPos; @@ -560,7 +565,11 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto. * @private */ _selectLibraryItem: function(e) { - var tex = e.currentTarget.getAttribute('data-tex'); + var tex = e.currentTarget.getAttribute('data-tex'), + oldValue, + newValue, + input, + focusPoint = 0; e.preventDefault(); @@ -569,15 +578,24 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto. input = e.currentTarget.ancestor('.atto_form').one('textarea'); - value = input.get('value'); + oldValue = input.get('value'); - value = value.substring(0, this._lastCursorPos) + tex + value.substring(this._lastCursorPos, value.length); + newValue = oldValue.substring(0, this._lastCursorPos); + if (newValue.charAt(newValue.length - 1) !== ' ') { + newValue += ' '; + } + newValue += tex; + focusPoint = newValue.length; - input.set('value', value); + if (oldValue.charAt(this._lastCursorPos) !== ' ') { + newValue += ' '; + } + newValue += oldValue.substring(this._lastCursorPos, oldValue.length); + + input.set('value', newValue); input.focus(); - var focusPoint = this._lastCursorPos + tex.length, - realInput = input.getDOMNode(); + var realInput = input.getDOMNode(); if (typeof realInput.selectionStart === "number") { // Modern browsers have selectionStart and selectionEnd to control the cursor position. realInput.selectionStart = realInput.selectionEnd = focusPoint; 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 e57555d87d5..4bf44917491 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 @@ -417,17 +417,22 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto. e.preventDefault(); } + // Move the cursor so it does not break expressions. + // Start at the very beginning. if (!currentPos) { currentPos = 0; } - // Move the cursor so it does not break expressions. - // - while (equation.charAt(currentPos) === '\\' && currentPos > 0) { + + // First move back to the beginning of the line. + while (equation.charAt(currentPos) === '\\' && currentPos >= 0) { currentPos -= 1; } isChar = /[a-zA-Z\{\}]/; - while (isChar.test(equation.charAt(currentPos)) && currentPos < equation.length) { - currentPos += 1; + if (currentPos !== 0) { + // Now match to the end of the line. + while (isChar.test(equation.charAt(currentPos)) && currentPos < equation.length && isChar.test(equation.charAt(currentPos-1))) { + currentPos += 1; + } } // Save the cursor position - for insertion from the library. this._lastCursorPos = currentPos; @@ -559,7 +564,11 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto. * @private */ _selectLibraryItem: function(e) { - var tex = e.currentTarget.getAttribute('data-tex'); + var tex = e.currentTarget.getAttribute('data-tex'), + oldValue, + newValue, + input, + focusPoint = 0; e.preventDefault(); @@ -568,15 +577,24 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto. input = e.currentTarget.ancestor('.atto_form').one('textarea'); - value = input.get('value'); + oldValue = input.get('value'); - value = value.substring(0, this._lastCursorPos) + tex + value.substring(this._lastCursorPos, value.length); + newValue = oldValue.substring(0, this._lastCursorPos); + if (newValue.charAt(newValue.length - 1) !== ' ') { + newValue += ' '; + } + newValue += tex; + focusPoint = newValue.length; - input.set('value', value); + if (oldValue.charAt(this._lastCursorPos) !== ' ') { + newValue += ' '; + } + newValue += oldValue.substring(this._lastCursorPos, oldValue.length); + + input.set('value', newValue); input.focus(); - var focusPoint = this._lastCursorPos + tex.length, - realInput = input.getDOMNode(); + var realInput = input.getDOMNode(); if (typeof realInput.selectionStart === "number") { // Modern browsers have selectionStart and selectionEnd to control the cursor position. realInput.selectionStart = realInput.selectionEnd = focusPoint;