mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 14:27:22 +01:00
1 line
78 KiB
Plaintext
1 line
78 KiB
Plaintext
{"version":3,"sources":["../src/templates.js"],"names":["define","mustache","$","ajax","str","notification","coreurl","config","storage","IconSystem","filterEvents","Y","Log","Truncate","UserDate","Pending","uniqInstances","templateCache","templatePromises","cachePartialPromises","iconSystem","loadTemplateBuffer","isLoadingTemplates","disallowedNestedHelpers","getNormalisedComponent","component","getTemplatePromiseFromCache","searchKey","Deferred","resolve","promise","M","cfg","templaterev","cached","get","processLoadTemplateBuffer","length","templatesToLoad","slice","serverRequestsDeferred","requests","map","templateData","name","theme","templateDeferred","deferred","cachedPromise","push","methodname","args","template","themename","lang","attr","replace","index","then","promises","response","templateSource","templates","forEach","data","tempSearchKey","join","value","set","strings","cache_strings","key","source","catch","error","reject","call","when","apply","splice","Renderer","requiredStrings","requiredJS","requiredDates","currentThemeName","prototype","getTemplate","templateName","currentTheme","existingBufferRecords","filter","record","parts","split","shift","prefetchTemplates","templateNames","partialHelper","exception","Error","renderIcon","title","modulename","iconsystemmodule","ready","require","System","system","init","getTemplateName","bind","pixHelper","context","sectionText","helper","text","trim","jsHelper","stringHelper","param","indexOf","JSON","parse","cleanStringHelper","quoteHelper","content","shortenTextHelper","match","truncate","words","ellipsis","userDateHelper","timestamp","format","addHelperFunction","helperFunction","originalHelpers","reduce","carry","hasOwnProperty","helperName","result","addHelpers","themeName","uniqid","cleanstr","pix","js","quote","shortentext","userdate","globals","getJS","treatStringsInContent","pattern","treated","strIndex","walker","char","strFinal","isClean","search","substring","substr","parseInt","debug","escape","treatDatesInContent","dates","date","re","RegExp","doRender","iconTemplate","pendingPromise","render","html","get_strings","runTemplateJS","newscript","append","domReplace","element","newHTML","newJS","replaceChildNodes","replaceNode","newNodes","yuiNodes","NodeList","children","destroy","empty","replaceWith","notifyFilterContentUpdated","scanForPartials","tokens","partials","findPartial","i","token","cachePartials","parentage","uniquePartials","partialName","fetchThemAll","iconsystem","domPrepend","node","newContent","prepend","domAppend","renderer","renderForPromise","renderPix","replaceNodeContents","prependNodeContents","appendNodeContents"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Template renderer for Moodle. Load and render Moodle templates with Mustache.\n *\n * @module core/templates\n * @copyright 2015 Damyon Wiese <damyon@moodle.com>\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 <theme>/<component>/<template> e.g. boost/core/modal.\n *\n * If the template is found in any of the caches it will populate the other caches with\n * the same data as well.\n *\n * @param {String} searchKey The template search key in the format <theme>/<component>/<template> e.g. boost/core/modal\n * @return {Object} jQuery promise resolved with the template source\n */\n var getTemplatePromiseFromCache = function(searchKey) {\n // First try the cache of promises.\n if (searchKey in templatePromises) {\n return templatePromises[searchKey];\n }\n\n // Check the module cache.\n if (searchKey in templateCache) {\n // Add this to the promises cache for future.\n templatePromises[searchKey] = $.Deferred().resolve(templateCache[searchKey]).promise();\n return templatePromises[searchKey];\n }\n\n if (M.cfg.templaterev <= 0) {\n // Template caching is disabled. Do not store in persistent storage.\n return null;\n }\n\n // Now try local storage.\n var cached = storage.get('core_template/' + M.cfg.templaterev + ':' + searchKey);\n if (cached) {\n // Add this to the module cache for future.\n templateCache[searchKey] = cached;\n // Add this to the promises cache for future.\n templatePromises[searchKey] = $.Deferred().resolve(cached).promise();\n return templatePromises[searchKey];\n }\n\n return null;\n };\n\n /**\n * Take all of the templates waiting in the buffer and load them from the server\n * or from the cache.\n *\n * All of the templates that need to be loaded from the server will be batched up\n * and sent in a single network request.\n */\n var processLoadTemplateBuffer = function() {\n if (!loadTemplateBuffer.length) {\n return;\n }\n\n if (isLoadingTemplates) {\n return;\n }\n\n isLoadingTemplates = true;\n // Grab any templates waiting in the buffer.\n var templatesToLoad = loadTemplateBuffer.slice();\n // This will be resolved with the list of promises for the server request.\n var serverRequestsDeferred = $.Deferred();\n var requests = [];\n // Get a list of promises for each of the templates we need to load.\n var templatePromises = templatesToLoad.map(function(templateData) {\n var component = getNormalisedComponent(templateData.component);\n var name = templateData.name;\n var searchKey = templateData.searchKey;\n var theme = templateData.theme;\n var templateDeferred = templateData.deferred;\n var promise = null;\n\n // Double check to see if this template happened to have landed in the\n // cache as a dependency of an earlier template.\n var cachedPromise = getTemplatePromiseFromCache(searchKey);\n if (cachedPromise) {\n // We've seen this template so immediately resolve the existing promise.\n promise = cachedPromise;\n } else {\n // We haven't seen this template yet so we need to request it from\n // the server.\n requests.push({\n methodname: 'core_output_load_template_with_dependencies',\n args: {\n component: component,\n template: name,\n themename: theme,\n lang: $('html').attr('lang').replace(/-/g, '_')\n }\n });\n // Remember the index in the requests list for this template so that\n // we can get the appropriate promise back.\n var index = requests.length - 1;\n\n // The server deferred will be resolved with a list of all of the promises\n // that were sent in the order that they were added to the requests array.\n promise = serverRequestsDeferred.promise()\n .then(function(promises) {\n // The promise for this template will be the one that matches the index\n // for it's entry in the requests array.\n //\n // Make sure the promise is added to the promises cache for this template\n // search key so that we don't request it again.\n templatePromises[searchKey] = promises[index].then(function(response) {\n var templateSource = null;\n\n // Process all of the template dependencies for this template and add\n // them to the caches so that we don't request them again later.\n response.templates.forEach(function(data) {\n data.component = getNormalisedComponent(data.component);\n // Generate the search key for this template in the response so that we\n // can add it to the caches.\n var tempSearchKey = [theme, data.component, data.name].join('/');\n // Cache all of the dependent templates because we'll need them to render\n // the requested template.\n templateCache[tempSearchKey] = data.value;\n\n if (M.cfg.templaterev > 0) {\n // The template cache is enabled - set the value there.\n storage.set('core_template/' + M.cfg.templaterev + ':' + tempSearchKey, data.value);\n }\n\n if (data.component == component && data.name == name) {\n // This is the original template that was requested so remember it to return.\n templateSource = data.value;\n }\n });\n\n if (response.strings.length) {\n // If we have strings that the template needs then warm the string cache\n // with them now so that we don't need to re-fetch them.\n str.cache_strings(response.strings.map(function(data) {\n return {\n component: getNormalisedComponent(data.component),\n key: data.name,\n value: data.value\n };\n }));\n }\n\n // Return the original template source that the user requested.\n return templateSource;\n });\n\n return templatePromises[searchKey];\n });\n }\n\n return promise\n .then(function(source) {\n // When we've successfully loaded the template then resolve the deferred\n // in the buffer so that all of the calling code can proceed.\n return templateDeferred.resolve(source);\n })\n .catch(function(error) {\n // If there was an error loading the template then reject the deferred\n // in the buffer so that all of the calling code can proceed.\n templateDeferred.reject(error);\n // Rethrow for anyone else listening.\n throw error;\n });\n });\n\n if (requests.length) {\n // We have requests to send so resolve the deferred with the promises.\n serverRequestsDeferred.resolve(ajax.call(requests, true, false, false, 0, M.cfg.templaterev));\n } else {\n // Nothing to load so we can resolve our deferred.\n serverRequestsDeferred.resolve();\n }\n\n // Once we've finished loading all of the templates then recurse to process\n // any templates that may have been added to the buffer in the time that we\n // were fetching.\n $.when.apply(null, templatePromises)\n .then(function() {\n // Remove the templates we've loaded from the buffer.\n loadTemplateBuffer.splice(0, templatesToLoad.length);\n isLoadingTemplates = false;\n processLoadTemplateBuffer();\n return;\n })\n .catch(function() {\n // Remove the templates we've loaded from the buffer.\n loadTemplateBuffer.splice(0, templatesToLoad.length);\n isLoadingTemplates = false;\n processLoadTemplateBuffer();\n });\n };\n\n /**\n * Constructor\n *\n * Each call to templates.render gets it's own instance of this class.\n */\n var Renderer = function() {\n this.requiredStrings = [];\n this.requiredJS = [];\n this.requiredDates = [];\n this.currentThemeName = '';\n };\n // Class variables and functions.\n\n /** @var {string[]} requiredStrings - Collection of strings found during the rendering of one template */\n Renderer.prototype.requiredStrings = null;\n\n /** @var {object[]} requiredDates - Collection of dates found during the rendering of one template */\n Renderer.prototype.requiredDates = [];\n\n /** @var {string[]} requiredJS - Collection of js blocks found during the rendering of one template */\n Renderer.prototype.requiredJS = null;\n\n /** @var {String} themeName for the current render */\n Renderer.prototype.currentThemeName = '';\n\n /**\n * Load a template.\n *\n * @method getTemplate\n * @private\n * @param {string} templateName - should consist of the component and the name of the template like this:\n * core/menu (lib/templates/menu.mustache) or\n * tool_bananas/yellow (admin/tool/bananas/templates/yellow.mustache)\n * @return {Promise} JQuery promise object resolved when the template has been fetched.\n */\n Renderer.prototype.getTemplate = function(templateName) {\n var currentTheme = this.currentThemeName;\n var searchKey = currentTheme + '/' + templateName;\n\n // If we haven't already seen this template then buffer it.\n var cachedPromise = getTemplatePromiseFromCache(searchKey);\n if (cachedPromise) {\n return cachedPromise;\n }\n\n // Check the buffer to see if this template has already been added.\n var existingBufferRecords = loadTemplateBuffer.filter(function(record) {\n return record.searchKey == searchKey;\n });\n if (existingBufferRecords.length) {\n // This template is already in the buffer so just return the existing\n // promise. No need to add it to the buffer again.\n return existingBufferRecords[0].deferred.promise();\n }\n\n // This is the first time this has been requested so let's add it to the buffer\n // to be loaded.\n var parts = templateName.split('/');\n var component = getNormalisedComponent(parts.shift());\n var name = parts.join('/');\n var deferred = $.Deferred();\n\n // Add this template to the buffer to be loaded.\n loadTemplateBuffer.push({\n component: component,\n name: name,\n theme: currentTheme,\n searchKey: searchKey,\n deferred: deferred\n });\n\n // We know there is at least one thing in the buffer so kick off a processing run.\n processLoadTemplateBuffer();\n return deferred.promise();\n };\n\n /**\n * Prefetch a set of templates without rendering them.\n *\n * @param {Array} templateNames The list of templates to fetch\n * @param {String} currentTheme\n */\n Renderer.prototype.prefetchTemplates = function(templateNames, currentTheme) {\n templateNames.forEach(function(templateName) {\n var searchKey = currentTheme + '/' + templateName;\n\n // If we haven't already seen this template then buffer it.\n if (getTemplatePromiseFromCache(searchKey)) {\n return;\n }\n\n // Check the buffer to see if this template has already been added.\n var existingBufferRecords = loadTemplateBuffer.filter(function(record) {\n return record.searchKey == searchKey;\n });\n\n if (existingBufferRecords.length) {\n // This template is already in the buffer so just return the existing promise.\n // No need to add it to the buffer again.\n return;\n }\n\n // This is the first time this has been requested so let's add it to the buffer to be loaded.\n var parts = templateName.split('/');\n var component = getNormalisedComponent(parts.shift());\n var name = parts.join('/');\n\n // Add this template to the buffer to be loaded.\n loadTemplateBuffer.push({\n component: component,\n name: name,\n theme: currentTheme,\n searchKey: searchKey,\n deferred: $.Deferred(),\n });\n });\n\n processLoadTemplateBuffer();\n };\n\n /**\n * Load a partial from the cache or ajax.\n *\n * @method partialHelper\n * @private\n * @param {string} name The partial name to load.\n * @return {string}\n */\n Renderer.prototype.partialHelper = function(name) {\n\n var searchKey = this.currentThemeName + '/' + name;\n\n if (!(searchKey in templateCache)) {\n notification.exception(new Error('Failed to pre-fetch the template: ' + name));\n }\n\n return templateCache[searchKey];\n };\n\n /**\n * Render a single image icon.\n *\n * @method renderIcon\n * @private\n * @param {string} key The icon key.\n * @param {string} component The component name.\n * @param {string} title The icon title\n * @return {Promise}\n */\n Renderer.prototype.renderIcon = function(key, component, title) {\n // Preload the module to do the icon rendering based on the theme iconsystem.\n var modulename = config.iconsystemmodule;\n component = getNormalisedComponent(component);\n\n // RequireJS does not return a promise.\n var ready = $.Deferred();\n require([modulename], function(System) {\n var system = new System();\n if (!(system instanceof IconSystem)) {\n ready.reject('Invalid icon system specified' + config.iconsystemmodule);\n } else {\n iconSystem = system;\n system.init().then(ready.resolve).catch(notification.exception);\n }\n });\n\n return ready.then(function(iconSystem) {\n return this.getTemplate(iconSystem.getTemplateName());\n }.bind(this)).then(function(template) {\n return iconSystem.renderIcon(\n key,\n component,\n title,\n template\n );\n });\n };\n\n /**\n * Render image icons.\n *\n * @method pixHelper\n * @private\n * @param {object} context The mustache context\n * @param {string} sectionText The text to parse arguments from.\n * @param {function} helper Used to render the alt attribute of the text.\n * @return {string}\n */\n Renderer.prototype.pixHelper = function(context, sectionText, helper) {\n var parts = sectionText.split(',');\n var key = '';\n var component = '';\n var text = '';\n\n if (parts.length > 0) {\n key = helper(parts.shift().trim(), context);\n }\n if (parts.length > 0) {\n component = helper(parts.shift().trim(), context);\n }\n if (parts.length > 0) {\n text = helper(parts.join(',').trim(), context);\n }\n\n var templateName = iconSystem.getTemplateName();\n var searchKey = this.currentThemeName + '/' + templateName;\n var template = templateCache[searchKey];\n\n component = getNormalisedComponent(component);\n\n // The key might have been escaped by the JS Mustache engine which\n // converts forward slashes to HTML entities. Let us undo that here.\n key = key.replace(///gi, '/');\n\n return iconSystem.renderIcon(\n key,\n component,\n text,\n template\n );\n };\n\n /**\n * Render blocks of javascript and save them in an array.\n *\n * @method jsHelper\n * @private\n * @param {object} context The current mustache context.\n * @param {string} sectionText The text to save as a js block.\n * @param {function} helper Used to render the block.\n * @return {string}\n */\n Renderer.prototype.jsHelper = function(context, sectionText, helper) {\n this.requiredJS.push(helper(sectionText, context));\n return '';\n };\n\n /**\n * String helper used to render {{#str}}abd component { a : 'fish'}{{/str}}\n * into a get_string call.\n *\n * @method stringHelper\n * @private\n * @param {object} context The current mustache context.\n * @param {string} sectionText The text to parse the arguments from.\n * @param {function} helper Used to render subsections of the text.\n * @return {string}\n */\n Renderer.prototype.stringHelper = function(context, sectionText, helper) {\n var parts = sectionText.split(',');\n var key = '';\n var component = '';\n var param = '';\n if (parts.length > 0) {\n key = parts.shift().trim();\n }\n if (parts.length > 0) {\n component = parts.shift().trim();\n }\n if (parts.length > 0) {\n param = parts.join(',').trim();\n }\n\n component = getNormalisedComponent(component);\n\n if (param !== '') {\n // Allow variable expansion in the param part only.\n param = helper(param, context);\n }\n // Allow json formatted $a arguments.\n if ((param.indexOf('{') === 0) && (param.indexOf('{{') !== 0)) {\n param = JSON.parse(param);\n }\n\n var index = this.requiredStrings.length;\n this.requiredStrings.push({\n key: key,\n component: component,\n param: param\n });\n\n // The placeholder must not use {{}} as those can be misinterpreted by the engine.\n return '[[_s' + index + ']]';\n };\n\n /**\n * String helper to render {{#cleanstr}}abd component { a : 'fish'}{{/cleanstr}}\n * into a get_string following by an HTML escape.\n *\n * @method cleanStringHelper\n * @private\n * @param {object} context The current mustache context.\n * @param {string} sectionText The text to parse the arguments from.\n * @param {function} helper Used to render subsections of the text.\n * @return {string}\n */\n Renderer.prototype.cleanStringHelper = function(context, sectionText, helper) {\n var str = this.stringHelper(context, sectionText, helper);\n\n // We're going to use [[_cx]] format for clean strings, where x is a number.\n // Hence, replacing 's' with 'c' in the placeholder that stringHelper returns.\n return str.replace('s', 'c');\n };\n\n /**\n * Quote helper used to wrap content in quotes, and escape all quotes present in the content.\n *\n * @method quoteHelper\n * @private\n * @param {object} context The current mustache context.\n * @param {string} sectionText The text to parse the arguments from.\n * @param {function} helper Used to render subsections of the text.\n * @return {string}\n */\n Renderer.prototype.quoteHelper = function(context, sectionText, helper) {\n var content = helper(sectionText.trim(), context);\n\n // Escape the {{ and the \".\n // This involves wrapping {{, and }} in change delimeter tags.\n content = content\n .replace(/\"/g, '\\\\\"')\n .replace(/\\t/g, '	')\n .replace(/([{}]{2,3})/g, '{{=<% %>=}}$1<%={{ }}=%>')\n .replace(/(\\r\\n|\\r|\\n)/g, '
')\n ;\n return '\"' + content + '\"';\n };\n\n /**\n * Shorten text helper to truncate text and append a trailing ellipsis.\n *\n * @method shortenTextHelper\n * @private\n * @param {object} context The current mustache context.\n * @param {string} sectionText The text to parse the arguments from.\n * @param {function} helper Used to render subsections of the text.\n * @return {string}\n */\n Renderer.prototype.shortenTextHelper = function(context, sectionText, helper) {\n // Non-greedy split on comma to grab section text into the length and\n // text parts.\n var regex = /(.*?),(.*)/;\n var parts = sectionText.match(regex);\n // The length is the part matched in the first set of parethesis.\n var length = parts[1].trim();\n // The length is the part matched in the second set of parethesis.\n var text = parts[2].trim();\n var content = helper(text, context);\n return Truncate.truncate(content, {\n length: length,\n words: true,\n ellipsis: '...'\n });\n };\n\n /**\n * User date helper to render user dates from timestamps.\n *\n * @method userDateHelper\n * @private\n * @param {object} context The current mustache context.\n * @param {string} sectionText The text to parse the arguments from.\n * @param {function} helper Used to render subsections of the text.\n * @return {string}\n */\n Renderer.prototype.userDateHelper = function(context, sectionText, helper) {\n // Non-greedy split on comma to grab the timestamp and format.\n var regex = /(.*?),(.*)/;\n var parts = sectionText.match(regex);\n var timestamp = helper(parts[1].trim(), context);\n var format = helper(parts[2].trim(), context);\n var index = this.requiredDates.length;\n\n this.requiredDates.push({\n timestamp: timestamp,\n format: format\n });\n\n return '[[_t_' + index + ']]';\n };\n\n /**\n * Return a helper function to be added to the context for rendering the a\n * template.\n *\n * This will parse the provided text before giving it to the helper function\n * in order to remove any disallowed nested helpers to prevent one helper\n * from calling another.\n *\n * In particular to prevent the JS helper from being called from within another\n * helper because it can lead to security issues when the JS portion is user\n * provided.\n *\n * @param {function} helperFunction The helper function to add\n * @param {object} context The template context for the helper function\n * @return {Function} To be set in the context\n */\n Renderer.prototype.addHelperFunction = function(helperFunction, context) {\n return function() {\n return function(sectionText, helper) {\n // Override the disallowed helpers in the template context with\n // a function that returns an empty string for use when executing\n // other helpers. This is to prevent these helpers from being\n // executed as part of the rendering of another helper in order to\n // prevent any potential security issues.\n var originalHelpers = disallowedNestedHelpers.reduce(function(carry, name) {\n if (context.hasOwnProperty(name)) {\n carry[name] = context[name];\n }\n\n return carry;\n }, {});\n\n disallowedNestedHelpers.forEach(function(helperName) {\n context[helperName] = function() {\n return '';\n };\n });\n\n // Execute the helper with the modified context that doesn't include\n // the disallowed nested helpers. This prevents the disallowed\n // helpers from being called from within other helpers.\n var result = helperFunction.apply(this, [context, sectionText, helper]);\n\n // Restore the original helper implementation in the context so that\n // any further rendering has access to them again.\n for (var name in originalHelpers) {\n context[name] = originalHelpers[name];\n }\n\n return result;\n }.bind(this);\n }.bind(this);\n };\n\n /**\n * Add some common helper functions to all context objects passed to templates.\n * These helpers match exactly the helpers available in php.\n *\n * @method addHelpers\n * @private\n * @param {Object} context Simple types used as the context for the template.\n * @param {String} themeName We set this multiple times, because there are async calls.\n */\n Renderer.prototype.addHelpers = function(context, themeName) {\n this.currentThemeName = themeName;\n this.requiredStrings = [];\n this.requiredJS = [];\n context.uniqid = (uniqInstances++);\n context.str = this.addHelperFunction(this.stringHelper, context);\n context.cleanstr = this.addHelperFunction(this.cleanStringHelper, context);\n context.pix = this.addHelperFunction(this.pixHelper, context);\n context.js = this.addHelperFunction(this.jsHelper, context);\n context.quote = this.addHelperFunction(this.quoteHelper, context);\n context.shortentext = this.addHelperFunction(this.shortenTextHelper, context);\n context.userdate = this.addHelperFunction(this.userDateHelper, context);\n context.globals = {config: config};\n context.currentTheme = themeName;\n };\n\n /**\n * Get all the JS blocks from the last rendered template.\n *\n * @method getJS\n * @private\n * @return {string}\n */\n Renderer.prototype.getJS = function() {\n var js = '';\n if (this.requiredJS.length > 0) {\n js = this.requiredJS.join(\";\\n\");\n }\n\n return js;\n };\n\n /**\n * Treat strings in content.\n *\n * The purpose of this method is to replace the placeholders found in a string\n * with the their respective translated strings.\n *\n * Previously we were relying on String.replace() but the complexity increased with\n * the numbers of strings to replace. Now we manually walk the string and stop at each\n * placeholder we find, only then we replace it. Most of the time we will\n * replace all the placeholders in a single run, at times we will need a few\n * more runs when placeholders are replaced with strings that contain placeholders\n * themselves.\n *\n * @param {String} content The content in which string placeholders are to be found.\n * @param {Array} strings The strings to replace with.\n * @return {String} The treated content.\n */\n Renderer.prototype.treatStringsInContent = function(content, strings) {\n var pattern = /\\[\\[_(s|c)\\d+\\]\\]/,\n treated,\n index,\n strIndex,\n walker,\n char,\n strFinal,\n isClean;\n\n do {\n treated = '';\n index = content.search(pattern);\n while (index > -1) {\n\n // Copy the part prior to the placeholder to the treated string.\n treated += content.substring(0, index);\n content = content.substr(index);\n isClean = content[3] == 'c';\n strIndex = '';\n walker = 4; // 4 is the length of either '[[_s' or '[[_c'.\n\n // Walk the characters to manually extract the index of the string from the placeholder.\n char = content.substr(walker, 1);\n do {\n strIndex += char;\n walker++;\n char = content.substr(walker, 1);\n } while (char != ']');\n\n // Get the string, add it to the treated result, and remove the placeholder from the content to treat.\n strFinal = strings[parseInt(strIndex, 10)];\n if (typeof strFinal === 'undefined') {\n Log.debug('Could not find string for pattern [[_' + (isClean ? 'c' : 's') + strIndex + ']].');\n strFinal = '';\n }\n if (isClean) {\n strFinal = mustache.escape(strFinal);\n }\n treated += strFinal;\n content = content.substr(6 + strIndex.length); // 6 is the length of the placeholder without the index.\n // That's either '[[_s]]' or '[[_c]]'.\n\n // Find the next placeholder.\n index = content.search(pattern);\n }\n\n // The content becomes the treated part with the rest of the content.\n content = treated + content;\n\n // Check if we need to walk the content again, in case strings contained placeholders.\n index = content.search(pattern);\n\n } while (index > -1);\n\n return content;\n };\n\n /**\n * Treat strings in content.\n *\n * The purpose of this method is to replace the date placeholders found in the\n * content with the their respective translated dates.\n *\n * @param {String} content The content in which string placeholders are to be found.\n * @param {Array} dates The dates to replace with.\n * @return {String} The treated content.\n */\n Renderer.prototype.treatDatesInContent = function(content, dates) {\n dates.forEach(function(date, index) {\n var key = '\\\\[\\\\[_t_' + index + '\\\\]\\\\]';\n var re = new RegExp(key, 'g');\n content = content.replace(re, date);\n });\n\n return content;\n };\n\n /**\n * Render a template and then call the callback with the result.\n *\n * @method doRender\n * @private\n * @param {string} templateSource The mustache template to render.\n * @param {Object} context Simple types used as the context for the template.\n * @param {String} themeName Name of the current theme.\n * @return {Promise} object\n */\n Renderer.prototype.doRender = function(templateSource, context, themeName) {\n this.currentThemeName = themeName;\n var iconTemplate = iconSystem.getTemplateName();\n\n var pendingPromise = new Pending('core/templates:doRender');\n return this.getTemplate(iconTemplate).then(function() {\n this.addHelpers(context, themeName);\n var result = mustache.render(templateSource, context, this.partialHelper.bind(this));\n return $.Deferred().resolve(result.trim(), this.getJS()).promise();\n }.bind(this))\n .then(function(html, js) {\n if (this.requiredStrings.length > 0) {\n return str.get_strings(this.requiredStrings).then(function(strings) {\n\n // Make sure string substitutions are done for the userdate\n // values as well.\n this.requiredDates = this.requiredDates.map(function(date) {\n return {\n timestamp: this.treatStringsInContent(date.timestamp, strings),\n format: this.treatStringsInContent(date.format, strings)\n };\n }.bind(this));\n\n // Why do we not do another call the render here?\n //\n // Because that would expose DOS holes. E.g.\n // I create an assignment called \"{{fish\" which\n // would get inserted in the template in the first pass\n // and cause the template to die on the second pass (unbalanced).\n html = this.treatStringsInContent(html, strings);\n js = this.treatStringsInContent(js, strings);\n return $.Deferred().resolve(html, js).promise();\n }.bind(this));\n }\n\n return $.Deferred().resolve(html, js).promise();\n }.bind(this))\n .then(function(html, js) {\n // This has to happen after the strings replacement because you can\n // use the string helper in content for the user date helper.\n if (this.requiredDates.length > 0) {\n return UserDate.get(this.requiredDates).then(function(dates) {\n html = this.treatDatesInContent(html, dates);\n js = this.treatDatesInContent(js, dates);\n return $.Deferred().resolve(html, js).promise();\n }.bind(this));\n }\n\n return $.Deferred().resolve(html, js).promise();\n }.bind(this))\n .then(function(html, js) {\n pendingPromise.resolve();\n return $.Deferred().resolve(html, js).promise();\n });\n };\n\n /**\n * Execute a block of JS returned from a template.\n * Call this AFTER adding the template HTML into the DOM so the nodes can be found.\n *\n * @method runTemplateJS\n * @param {string} source - A block of javascript.\n */\n var runTemplateJS = function(source) {\n if (source.trim() !== '') {\n var newscript = $('<script>').attr('type', 'text/javascript').html(source);\n $('head').append(newscript);\n }\n };\n\n /**\n * Do some DOM replacement and trigger correct events and fire javascript.\n *\n * @method domReplace\n * @private\n * @param {JQuery} element - Element or selector to replace.\n * @param {String} newHTML - HTML to insert / replace.\n * @param {String} newJS - Javascript to run after the insertion.\n * @param {Boolean} replaceChildNodes - Replace only the childnodes, alternative is to replace the entire node.\n * @return {Array} The list of new DOM Nodes\n * @fires event:filterContentUpdated\n */\n var domReplace = function(element, newHTML, newJS, replaceChildNodes) {\n var replaceNode = $(element);\n if (replaceNode.length) {\n // First create the dom nodes so we have a reference to them.\n var newNodes = $(newHTML);\n var yuiNodes = null;\n // Do the replacement in the page.\n if (replaceChildNodes) {\n // Cleanup any YUI event listeners attached to any of these nodes.\n yuiNodes = new Y.NodeList(replaceNode.children().get());\n yuiNodes.destroy(true);\n\n // JQuery will cleanup after itself.\n replaceNode.empty();\n replaceNode.append(newNodes);\n } else {\n // Cleanup any YUI event listeners attached to any of these nodes.\n yuiNodes = new Y.NodeList(replaceNode.get());\n yuiNodes.destroy(true);\n\n // JQuery will cleanup after itself.\n replaceNode.replaceWith(newNodes);\n }\n // Run any javascript associated with the new HTML.\n runTemplateJS(newJS);\n // Notify all filters about the new content.\n filterEvents.notifyFilterContentUpdated(newNodes);\n\n return newNodes.get();\n }\n\n return [];\n };\n\n /**\n * Scan a template source for partial tags and return a list of the found partials.\n *\n * @method scanForPartials\n * @private\n * @param {string} templateSource - source template to scan.\n * @return {Array} List of partials.\n */\n Renderer.prototype.scanForPartials = function(templateSource) {\n var tokens = mustache.parse(templateSource),\n partials = [];\n\n var findPartial = function(tokens, partials) {\n var i, token;\n for (i = 0; i < tokens.length; i++) {\n token = tokens[i];\n if (token[0] == '>' || token[0] == '<') {\n partials.push(token[1]);\n }\n if (token.length > 4) {\n findPartial(token[4], partials);\n }\n }\n };\n\n findPartial(tokens, partials);\n\n return partials;\n };\n\n /**\n * Load a template and scan it for partials. Recursively fetch the partials.\n *\n * @method cachePartials\n * @private\n * @param {string} templateName - should consist of the component and the name of the template like this:\n * core/menu (lib/templates/menu.mustache) or\n * tool_bananas/yellow (admin/tool/bananas/templates/yellow.mustache)\n * @param {Array} parentage - A list of requested partials in this render chain.\n * @return {Promise} JQuery promise object resolved when all partials are in the cache.\n */\n Renderer.prototype.cachePartials = function(templateName, parentage) {\n var searchKey = this.currentThemeName + '/' + templateName;\n\n if (searchKey in cachePartialPromises) {\n return cachePartialPromises[searchKey];\n }\n\n // This promise will not be resolved until all child partials are also resolved and ready.\n // We create it here to allow us to check for recursive inclusion of templates.\n // Keep track of the requested partials in this chain.\n parentage = parentage || [searchKey];\n\n cachePartialPromises[searchKey] = $.Deferred();\n\n this.getTemplate(templateName)\n .then(function(templateSource) {\n var partials = this.scanForPartials(templateSource);\n var uniquePartials = partials.filter(function(partialName) {\n // Check for recursion.\n\n if (parentage.indexOf(this.currentThemeName + '/' + partialName) >= 0) {\n // Ignore templates which include a parent template already requested in the current chain.\n return false;\n }\n\n // Ignore templates that include themselves.\n return partialName != templateName;\n }.bind(this));\n\n // Fetch any partial which has not already been fetched.\n var fetchThemAll = uniquePartials.map(function(partialName) {\n parentage.push(this.currentThemeName + '/' + partialName);\n return this.cachePartials(partialName, parentage);\n }.bind(this));\n\n // Resolve the templateName promise when all of the children are resolved.\n return $.when.apply($, fetchThemAll)\n .then(function() {\n return cachePartialPromises[searchKey].resolve(templateSource);\n });\n }.bind(this))\n .catch(cachePartialPromises[searchKey].reject);\n\n return cachePartialPromises[searchKey];\n };\n\n /**\n * Load a template and call doRender on it.\n *\n * @method render\n * @private\n * @param {string} templateName - should consist of the component and the name of the template like this:\n * core/menu (lib/templates/menu.mustache) or\n * tool_bananas/yellow (admin/tool/bananas/templates/yellow.mustache)\n * @param {Object} context - Could be array, string or simple value for the context of the template.\n * @param {string} themeName - Name of the current theme.\n * @return {Promise} JQuery promise object resolved when the template has been rendered.\n */\n Renderer.prototype.render = function(templateName, context, themeName) {\n if (typeof (themeName) === \"undefined\") {\n // System context by default.\n themeName = config.theme;\n }\n\n this.currentThemeName = themeName;\n\n // Preload the module to do the icon rendering based on the theme iconsystem.\n var modulename = config.iconsystemmodule;\n\n var ready = $.Deferred();\n require([modulename], function(System) {\n var system = new System();\n if (!(system instanceof IconSystem)) {\n ready.reject('Invalid icon system specified' + config.iconsystem);\n } else {\n iconSystem = system;\n system.init().then(ready.resolve).catch(notification.exception);\n }\n });\n\n return ready.then(function() {\n return this.cachePartials(templateName);\n }.bind(this)).then(function(templateSource) {\n return this.doRender(templateSource, context, themeName);\n }.bind(this));\n };\n\n /**\n * Prepend some HTML to a node and trigger events and fire javascript.\n *\n * @method domPrepend\n * @private\n * @param {jQuery|String} element - Element or selector to prepend HTML to\n * @param {String} html - HTML to prepend\n * @param {String} js - Javascript to run after we prepend the html\n * @return {Array} The list of new DOM Nodes\n * @fires event:filterContentUpdated\n */\n var domPrepend = function(element, html, js) {\n var node = $(element);\n if (node.length) {\n // Prepend the html.\n var newContent = $(html);\n node.prepend(newContent);\n // Run any javascript associated with the new HTML.\n runTemplateJS(js);\n // Notify all filters about the new content.\n filterEvents.notifyFilterContentUpdated(node);\n\n return newContent.get();\n }\n\n return [];\n };\n\n /**\n * Append some HTML to a node and trigger events and fire javascript.\n *\n * @method domAppend\n * @private\n * @param {jQuery|String} element - Element or selector to append HTML to\n * @param {String} html - HTML to append\n * @param {String} js - Javascript to run after we append the html\n * @return {Array} The list of new DOM Nodes\n * @fires event:filterContentUpdated\n */\n var domAppend = function(element, html, js) {\n var node = $(element);\n if (node.length) {\n // Append the html.\n var newContent = $(html);\n node.append(newContent);\n // Run any javascript associated with the new HTML.\n runTemplateJS(js);\n // Notify all filters about the new content.\n filterEvents.notifyFilterContentUpdated(node);\n\n return newContent.get();\n }\n\n return [];\n };\n\n return /** @alias module:core/templates */ {\n // Public variables and functions.\n /**\n * Every call to render creates a new instance of the class and calls render on it. This\n * means each render call has it's own class variables.\n *\n * @method render\n * @private\n * @param {string} templateName - should consist of the component and the name of the template like this:\n * core/menu (lib/templates/menu.mustache) or\n * tool_bananas/yellow (admin/tool/bananas/templates/yellow.mustache)\n * @param {Object} context - Could be array, string or simple value for the context of the template.\n * @param {string} themeName - Name of the current theme.\n * @return {Promise} JQuery promise object resolved when the template has been rendered.\n */\n render: function(templateName, context, themeName) {\n var renderer = new Renderer();\n return renderer.render(templateName, context, themeName);\n },\n\n /**\n * Prefetch a set of templates without rendering them.\n *\n * @method getTemplate\n * @param {Array} templateNames The list of templates to fetch\n * @param {String} themeName\n * @returns {Promise}\n */\n prefetchTemplates: function(templateNames, themeName) {\n var renderer = new Renderer();\n\n if (typeof themeName === \"undefined\") {\n // System context by default.\n themeName = config.theme;\n }\n\n return renderer.prefetchTemplates(templateNames, themeName);\n },\n\n /**\n * Every call to render creates a new instance of the class and calls render on it. This\n * means each render call has it's own class variables.\n *\n * This alernate to the standard .render() function returns the html and js in a single object suitable for a\n * native Promise.\n *\n * @method renderForPromise\n * @private\n * @param {string} templateName - should consist of the component and the name of the template like this:\n * core/menu (lib/templates/menu.mustache) or\n * tool_bananas/yellow (admin/tool/bananas/templates/yellow.mustache)\n * @param {Object} context - Could be array, string or simple value for the context of the template.\n * @param {string} themeName - Name of the current theme.\n * @return {Promise} JQuery promise object resolved when the template has been rendered.\n */\n renderForPromise: function(templateName, context, themeName) {\n var renderer = new Renderer();\n return renderer.render(templateName, context, themeName)\n .then(function(html, js) {\n return {\n html: html,\n js: js,\n };\n });\n },\n\n /**\n * Every call to renderIcon creates a new instance of the class and calls renderIcon on it. This\n * means each render call has it's own class variables.\n *\n * @method renderIcon\n * @public\n * @param {string} key - Icon key.\n * @param {string} component - Icon component\n * @param {string} title - Icon title\n * @return {Promise} JQuery promise object resolved when the pix has been rendered.\n */\n renderPix: function(key, component, title) {\n var renderer = new Renderer();\n return renderer.renderIcon(\n key,\n getNormalisedComponent(component),\n title\n );\n },\n\n /**\n * Execute a block of JS returned from a template.\n * Call this AFTER adding the template HTML into the DOM so the nodes can be found.\n *\n * @method runTemplateJS\n * @param {string} source - A block of javascript.\n */\n runTemplateJS: runTemplateJS,\n\n /**\n * Replace a node in the page with some new HTML and run the JS.\n *\n * @method replaceNodeContents\n * @param {JQuery} element - Element or selector to replace.\n * @param {String} newHTML - HTML to insert / replace.\n * @param {String} newJS - Javascript to run after the insertion.\n * @return {Array} The list of new DOM Nodes\n */\n replaceNodeContents: function(element, newHTML, newJS) {\n return domReplace(element, newHTML, newJS, true);\n },\n\n /**\n * Insert a node in the page with some new HTML and run the JS.\n *\n * @method replaceNode\n * @param {JQuery} element - Element or selector to replace.\n * @param {String} newHTML - HTML to insert / replace.\n * @param {String} newJS - Javascript to run after the insertion.\n * @return {Array} The list of new DOM Nodes\n */\n replaceNode: function(element, newHTML, newJS) {\n return domReplace(element, newHTML, newJS, false);\n },\n\n /**\n * Prepend some HTML to a node and trigger events and fire javascript.\n *\n * @method prependNodeContents\n * @param {jQuery|String} element - Element or selector to prepend HTML to\n * @param {String} html - HTML to prepend\n * @param {String} js - Javascript to run after we prepend the html\n * @return {Array} The list of new DOM Nodes\n */\n prependNodeContents: function(element, html, js) {\n return domPrepend(element, html, js);\n },\n\n /**\n * Append some HTML to a node and trigger events and fire javascript.\n *\n * @method appendNodeContents\n * @param {jQuery|String} element - Element or selector to append HTML to\n * @param {String} html - HTML to append\n * @param {String} js - Javascript to run after we append the html\n * @return {Array} The list of new DOM Nodes\n */\n appendNodeContents: function(element, html, js) {\n return domAppend(element, html, js);\n },\n };\n});\n"],"file":"templates.min.js"} |