mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 17:06:53 +02:00
MDL-57975 javascript: add userdate mustache js helper
Part of MDL-55611
This commit is contained in:
parent
b61015cfcd
commit
0e5b3e282f
2 changed files with 90 additions and 13 deletions
2
lib/amd/build/templates.min.js
vendored
2
lib/amd/build/templates.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -34,9 +34,11 @@ define(['core/mustache',
|
||||||
'core/localstorage',
|
'core/localstorage',
|
||||||
'core/event',
|
'core/event',
|
||||||
'core/yui',
|
'core/yui',
|
||||||
'core/log'
|
'core/log',
|
||||||
|
'core/user_date'
|
||||||
],
|
],
|
||||||
function(mustache, $, ajax, str, notification, coreurl, log, config, storage, event, Y, Log) {
|
function(mustache, $, ajax, str, notification, coreurl, log,
|
||||||
|
config, storage, event, Y, Log, UserDate) {
|
||||||
|
|
||||||
// Module variables.
|
// Module variables.
|
||||||
/** @var {Number} uniqInstances Count of times this constructor has been called. */
|
/** @var {Number} uniqInstances Count of times this constructor has been called. */
|
||||||
|
@ -56,6 +58,7 @@ define(['core/mustache',
|
||||||
var Renderer = function() {
|
var Renderer = function() {
|
||||||
this.requiredStrings = [];
|
this.requiredStrings = [];
|
||||||
this.requiredJS = [];
|
this.requiredJS = [];
|
||||||
|
this.requiredDates = [];
|
||||||
this.currentThemeName = '';
|
this.currentThemeName = '';
|
||||||
};
|
};
|
||||||
// Class variables and functions.
|
// Class variables and functions.
|
||||||
|
@ -63,6 +66,9 @@ define(['core/mustache',
|
||||||
/** @var {string[]} requiredStrings - Collection of strings found during the rendering of one template */
|
/** @var {string[]} requiredStrings - Collection of strings found during the rendering of one template */
|
||||||
Renderer.prototype.requiredStrings = null;
|
Renderer.prototype.requiredStrings = null;
|
||||||
|
|
||||||
|
/** @var {object[]} requiredDates - Collection of dates found during the rendering of one template */
|
||||||
|
Renderer.prototype.requiredDates = [];
|
||||||
|
|
||||||
/** @var {string[]} requiredJS - Collection of js blocks found during the rendering of one template */
|
/** @var {string[]} requiredJS - Collection of js blocks found during the rendering of one template */
|
||||||
Renderer.prototype.requiredJS = null;
|
Renderer.prototype.requiredJS = null;
|
||||||
|
|
||||||
|
@ -261,6 +267,32 @@ define(['core/mustache',
|
||||||
return '"' + content + '"';
|
return '"' + content + '"';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User date helper to render user dates from timestamps.
|
||||||
|
*
|
||||||
|
* @method userDateHelper
|
||||||
|
* @private
|
||||||
|
* @param {object} context The current mustache context.
|
||||||
|
* @param {string} sectionText The text to parse the arguments from.
|
||||||
|
* @param {function} helper Used to render subsections of the text.
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
Renderer.prototype.userDateHelper = function(context, sectionText, helper) {
|
||||||
|
// Non-greedy split on comma to grab the timestamp and format.
|
||||||
|
var regex = /(.*?),(.*)/;
|
||||||
|
var parts = sectionText.match(regex);
|
||||||
|
var timestamp = helper(parts[1].trim(), context);
|
||||||
|
var format = helper(parts[2].trim(), context);
|
||||||
|
var index = this.requiredDates.length;
|
||||||
|
|
||||||
|
this.requiredDates.push({
|
||||||
|
timestamp: timestamp,
|
||||||
|
format: format
|
||||||
|
});
|
||||||
|
|
||||||
|
return '[[_t_' + index + ']]';
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add some common helper functions to all context objects passed to templates.
|
* Add some common helper functions to all context objects passed to templates.
|
||||||
* These helpers match exactly the helpers available in php.
|
* These helpers match exactly the helpers available in php.
|
||||||
|
@ -287,6 +319,9 @@ define(['core/mustache',
|
||||||
context.quote = function() {
|
context.quote = function() {
|
||||||
return this.quoteHelper.bind(this, context);
|
return this.quoteHelper.bind(this, context);
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
context.userdate = function() {
|
||||||
|
return this.userDateHelper.bind(this, context);
|
||||||
|
}.bind(this);
|
||||||
context.globals = {config: config};
|
context.globals = {config: config};
|
||||||
context.currentTheme = themeName;
|
context.currentTheme = themeName;
|
||||||
};
|
};
|
||||||
|
@ -296,17 +331,15 @@ define(['core/mustache',
|
||||||
*
|
*
|
||||||
* @method getJS
|
* @method getJS
|
||||||
* @private
|
* @private
|
||||||
* @param {string[]} strings Replacement strings.
|
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
Renderer.prototype.getJS = function(strings) {
|
Renderer.prototype.getJS = function() {
|
||||||
var js = '';
|
var js = '';
|
||||||
if (this.requiredJS.length > 0) {
|
if (this.requiredJS.length > 0) {
|
||||||
js = this.requiredJS.join(";\n");
|
js = this.requiredJS.join(";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-render to get the final strings.
|
return js;
|
||||||
return this.treatStringsInContent(js, strings);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -378,6 +411,26 @@ define(['core/mustache',
|
||||||
return content;
|
return content;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Treat strings in content.
|
||||||
|
*
|
||||||
|
* The purpose of this method is to replace the date placeholders found in the
|
||||||
|
* content with the their respective translated dates.
|
||||||
|
*
|
||||||
|
* @param {String} content The content in which string placeholders are to be found.
|
||||||
|
* @param {Array} strings The strings to replace with.
|
||||||
|
* @return {String} The treated content.
|
||||||
|
*/
|
||||||
|
Renderer.prototype.treatDatesInContent = function(content, dates) {
|
||||||
|
dates.forEach(function(date, index) {
|
||||||
|
var key = '\\[\\[_t_' + index + '\\]\\]';
|
||||||
|
var re = new RegExp(key, 'g');
|
||||||
|
content = content.replace(re, date);
|
||||||
|
});
|
||||||
|
|
||||||
|
return content;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a template and then call the callback with the result.
|
* Render a template and then call the callback with the result.
|
||||||
*
|
*
|
||||||
|
@ -394,23 +447,47 @@ define(['core/mustache',
|
||||||
return this.getTemplate('core/pix_icon').then(function() {
|
return this.getTemplate('core/pix_icon').then(function() {
|
||||||
this.addHelpers(context, themeName);
|
this.addHelpers(context, themeName);
|
||||||
var result = mustache.render(templateSource, context, this.partialHelper.bind(this));
|
var result = mustache.render(templateSource, context, this.partialHelper.bind(this));
|
||||||
|
return $.Deferred().resolve(result.trim(), this.getJS()).promise();
|
||||||
|
}.bind(this))
|
||||||
|
.then(function(html, js) {
|
||||||
if (this.requiredStrings.length > 0) {
|
if (this.requiredStrings.length > 0) {
|
||||||
return str.get_strings(this.requiredStrings).then(function(strings) {
|
return str.get_strings(this.requiredStrings).then(function(strings) {
|
||||||
|
|
||||||
|
// Make sure string substitutions are done for the userdate
|
||||||
|
// values as well.
|
||||||
|
this.requiredDates = this.requiredDates.map(function(date) {
|
||||||
|
return {
|
||||||
|
timestamp: this.treatStringsInContent(date.timestamp, strings),
|
||||||
|
format: this.treatStringsInContent(date.format, strings)
|
||||||
|
};
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
// Why do we not do another call the render here?
|
// Why do we not do another call the render here?
|
||||||
//
|
//
|
||||||
// Because that would expose DOS holes. E.g.
|
// Because that would expose DOS holes. E.g.
|
||||||
// I create an assignment called "{{fish" which
|
// I create an assignment called "{{fish" which
|
||||||
// would get inserted in the template in the first pass
|
// would get inserted in the template in the first pass
|
||||||
// and cause the template to die on the second pass (unbalanced).
|
// and cause the template to die on the second pass (unbalanced).
|
||||||
|
html = this.treatStringsInContent(html, strings);
|
||||||
result = this.treatStringsInContent(result, strings);
|
js = this.treatStringsInContent(js, strings);
|
||||||
return $.Deferred().resolve(result, this.getJS(strings)).promise();
|
return $.Deferred().resolve(html, js).promise();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
} else {
|
|
||||||
return $.Deferred().resolve(result.trim(), this.getJS([])).promise();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $.Deferred().resolve(html, js).promise();
|
||||||
|
}.bind(this))
|
||||||
|
.then(function(html, js) {
|
||||||
|
// This has to happen after the strings replacement because you can
|
||||||
|
// use the string helper in content for the user date helper.
|
||||||
|
if (this.requiredDates.length > 0) {
|
||||||
|
return UserDate.get(this.requiredDates).then(function(dates) {
|
||||||
|
html = this.treatDatesInContent(html, dates);
|
||||||
|
js = this.treatDatesInContent(js, dates);
|
||||||
|
return $.Deferred().resolve(html, js).promise();
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.Deferred().resolve(html, js).promise();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue