From 4f96d7ac924bef4c92f536cbeae3690b89d49acb Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Thu, 5 Aug 2021 17:15:49 +1000 Subject: [PATCH 1/3] MDL-70721 core: a new mustache helper to clean string after get_string --- lib/amd/build/templates.min.js | 2 +- lib/amd/build/templates.min.js.map | 2 +- lib/amd/src/templates.js | 36 ++++++++-- .../output/mustache_clean_string_helper.php | 68 +++++++++++++++++++ lib/outputrenderers.php | 2 + .../mustache_clean_string_helper_test.php | 56 +++++++++++++++ lib/upgrade.txt | 1 + 7 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 lib/classes/output/mustache_clean_string_helper.php create mode 100644 lib/tests/output/mustache_clean_string_helper_test.php diff --git a/lib/amd/build/templates.min.js b/lib/amd/build/templates.min.js index 36b4c671519..23d541ec828 100644 --- a/lib/amd/build/templates.min.js +++ b/lib/amd/build/templates.min.js @@ -1,2 +1,2 @@ -define ("core/templates",["core/mustache","jquery","core/ajax","core/str","core/notification","core/url","core/config","core/localstorage","core/icon_system","core_filters/events","core/yui","core/log","core/truncate","core/user_date","core/pending"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q={},r={},s={},t={},u=[],v=!1,w=["js"],x=function(a){if(a){if("moodle"!==a&&"core"!==a){return a}}return"core"},y=function(a){if(a in r){return r[a]}if(a in q){r[a]=b.Deferred().resolve(q[a]).promise();return r[a]}if(0>=M.cfg.templaterev){return null}var c=h.get("core_template/"+M.cfg.templaterev+":"+a);if(c){q[a]=c;r[a]=b.Deferred().resolve(c).promise();return r[a]}return null},z=function(){if(!u.length){return}if(v){return}v=!0;var a=u.slice(),e=b.Deferred(),f=[],g=a.map(function(a){var c=x(a.component),i=a.name,j=a.searchKey,k=a.theme,l=a.deferred,m=null,n=y(j);if(n){m=n}else{f.push({methodname:"core_output_load_template_with_dependencies",args:{component:c,template:i,themename:k,lang:b("html").attr("lang").replace(/-/g,"_")}});var o=f.length-1;m=e.promise().then(function(a){g[j]=a[o].then(function(a){var b=null;a.templates.forEach(function(a){a.component=x(a.component);var d=[k,a.component,a.name].join("/");q[d]=a.value;if(0=}}$1<%={{ }}=%>").replace(/(\r\n|\r|\n)/g," ");return"\""+d+"\""};A.prototype.shortenTextHelper=function(a,b,c){var d=b.match(/(.*?),(.*)/),e=d[1].trim(),f=d[2].trim(),g=c(f,a);return m.truncate(g,{length:e,words:!0,ellipsis:"..."})};A.prototype.userDateHelper=function(a,b,c){var d=b.match(/(.*?),(.*)/),e=c(d[1].trim(),a),f=c(d[2].trim(),a),g=this.requiredDates.length;this.requiredDates.push({timestamp:e,format:f});return"[[_t_"+g+"]]"};A.prototype.addHelperFunction=function(a,b){return function(){return function(c,d){var e=w.reduce(function(a,c){if(b.hasOwnProperty(c)){a[c]=b[c]}return a},{});w.forEach(function(a){b[a]=function(){return""}});var f=a.apply(this,[b,c,d]);for(var g in e){b[g]=e[g]}return f}.bind(this)}.bind(this)};A.prototype.addHelpers=function(a,b){this.currentThemeName=b;this.requiredStrings=[];this.requiredJS=[];a.uniqid=p++;a.str=this.addHelperFunction(this.stringHelper,a);a.pix=this.addHelperFunction(this.pixHelper,a);a.js=this.addHelperFunction(this.jsHelper,a);a.quote=this.addHelperFunction(this.quoteHelper,a);a.shortentext=this.addHelperFunction(this.shortenTextHelper,a);a.userdate=this.addHelperFunction(this.userDateHelper,a);a.globals={config:g};a.currentTheme=b};A.prototype.getJS=function(){var a="";if(0").attr("type","text/javascript").html(a);b("head").append(c)}},C=function(a,c,d,e){var f=b(a);if(f.length){var g=b(c),h=null;if(e){h=new k.NodeList(f.children().get());h.destroy(!0);f.empty();f.append(g)}else{h=new k.NodeList(f.get());h.destroy(!0);f.replaceWith(g)}B(d);j.notifyFilterContentUpdated(g);return g.get()}return[]};A.prototype.scanForPartials=function(b){var c=a.parse(b),d=[],e=function(a,b){var c,d;for(c=0;c"==d[0]||"<"==d[0]){b.push(d[1])}if(4=M.cfg.templaterev){return null}var c=h.get("core_template/"+M.cfg.templaterev+":"+a);if(c){q[a]=c;r[a]=b.Deferred().resolve(c).promise();return r[a]}return null},z=function(){if(!u.length){return}if(v){return}v=!0;var a=u.slice(),e=b.Deferred(),f=[],g=a.map(function(a){var c=x(a.component),i=a.name,j=a.searchKey,k=a.theme,l=a.deferred,m=null,n=y(j);if(n){m=n}else{f.push({methodname:"core_output_load_template_with_dependencies",args:{component:c,template:i,themename:k,lang:b("html").attr("lang").replace(/-/g,"_")}});var o=f.length-1;m=e.promise().then(function(a){g[j]=a[o].then(function(a){var b=null;a.templates.forEach(function(a){a.component=x(a.component);var d=[k,a.component,a.name].join("/");q[d]=a.value;if(0=}}$1<%={{ }}=%>").replace(/(\r\n|\r|\n)/g," ");return"\""+d+"\""};A.prototype.shortenTextHelper=function(a,b,c){var d=b.match(/(.*?),(.*)/),e=d[1].trim(),f=d[2].trim(),g=c(f,a);return m.truncate(g,{length:e,words:!0,ellipsis:"..."})};A.prototype.userDateHelper=function(a,b,c){var d=b.match(/(.*?),(.*)/),e=c(d[1].trim(),a),f=c(d[2].trim(),a),g=this.requiredDates.length;this.requiredDates.push({timestamp:e,format:f});return"[[_t_"+g+"]]"};A.prototype.addHelperFunction=function(a,b){return function(){return function(c,d){var e=w.reduce(function(a,c){if(b.hasOwnProperty(c)){a[c]=b[c]}return a},{});w.forEach(function(a){b[a]=function(){return""}});var f=a.apply(this,[b,c,d]);for(var g in e){b[g]=e[g]}return f}.bind(this)}.bind(this)};A.prototype.addHelpers=function(a,b){this.currentThemeName=b;this.requiredStrings=[];this.requiredJS=[];a.uniqid=p++;a.str=this.addHelperFunction(this.stringHelper,a);a.cleanstr=this.addHelperFunction(this.cleanStringHelper,a);a.pix=this.addHelperFunction(this.pixHelper,a);a.js=this.addHelperFunction(this.jsHelper,a);a.quote=this.addHelperFunction(this.quoteHelper,a);a.shortentext=this.addHelperFunction(this.shortenTextHelper,a);a.userdate=this.addHelperFunction(this.userDateHelper,a);a.globals={config:g};a.currentTheme=b};A.prototype.getJS=function(){var a="";if(0").attr("type","text/javascript").html(a);b("head").append(c)}},C=function(a,c,d,e){var f=b(a);if(f.length){var g=b(c),h=null;if(e){h=new k.NodeList(f.children().get());h.destroy(!0);f.empty();f.append(g)}else{h=new k.NodeList(f.get());h.destroy(!0);f.replaceWith(g)}B(d);j.notifyFilterContentUpdated(g);return g.get()}return[]};A.prototype.scanForPartials=function(b){var c=a.parse(b),d=[],e=function(a,b){var c,d;for(c=0;c"==d[0]||"<"==d[0]){b.push(d[1])}if(4.\n\n/**\n * Template renderer for Moodle. Load and render Moodle templates with Mustache.\n *\n * @module core/templates\n * @copyright 2015 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 2.9\n */\ndefine([\n 'core/mustache',\n 'jquery',\n 'core/ajax',\n 'core/str',\n 'core/notification',\n 'core/url',\n 'core/config',\n 'core/localstorage',\n 'core/icon_system',\n 'core_filters/events',\n 'core/yui',\n 'core/log',\n 'core/truncate',\n 'core/user_date',\n 'core/pending',\n],\nfunction(\n mustache,\n $,\n ajax,\n str,\n notification,\n coreurl,\n config,\n storage,\n IconSystem,\n filterEvents,\n Y,\n Log,\n Truncate,\n UserDate,\n Pending\n) {\n\n // Module variables.\n /** @var {Number} uniqInstances Count of times this constructor has been called. */\n var uniqInstances = 0;\n\n /** @var {String[]} templateCache - Cache of already loaded template strings */\n var templateCache = {};\n\n /** @var {Promise[]} templatePromises - Cache of already loaded template promises */\n var templatePromises = {};\n\n /** @var {Promise[]} cachePartialPromises - Cache of already loaded template partial promises */\n var cachePartialPromises = {};\n\n /** @var {Object} iconSystem - Object extending core/iconsystem */\n var iconSystem = {};\n\n /** @var {Object[]} loadTemplateBuffer - List of templates to be loaded */\n var loadTemplateBuffer = [];\n\n /** @var {Bool} isLoadingTemplates - Whether templates are currently being loaded */\n var isLoadingTemplates = false;\n\n /** @var {Array} disallowedNestedHelpers - List of helpers that can't be called within other helpers */\n var disallowedNestedHelpers = ['js'];\n\n /**\n * Normalise the provided component such that '', 'moodle', and 'core' are treated consistently.\n *\n * @param {String} component\n * @returns {String}\n */\n var getNormalisedComponent = function(component) {\n if (component) {\n if (component !== 'moodle' && component !== 'core') {\n return component;\n }\n }\n\n return 'core';\n };\n\n /**\n * Search the various caches for a template promise for the given search key.\n * The search key should be in the format //