MDL-68677 core: Correct usage of templaterev for caching templates
[moodle.git] / lib / amd / build / templates.min.js.map
1 {"version":3,"sources":["../src/templates.js"],"names":["define","mustache","$","ajax","str","notification","coreurl","config","storage","IconSystem","event","Y","Log","Truncate","UserDate","Pending","uniqInstances","templateCache","templatePromises","cachePartialPromises","iconSystem","loadTemplateBuffer","isLoadingTemplates","blacklistedNestedHelpers","getTemplatePromiseFromCache","searchKey","Deferred","resolve","promise","M","cfg","templaterev","cached","get","processLoadTemplateBuffer","length","templatesToLoad","slice","serverRequestsDeferred","requests","map","templateData","component","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","quoteHelper","content","shortenTextHelper","match","truncate","words","ellipsis","userDateHelper","timestamp","format","addHelperFunction","helperFunction","originalHelpers","reduce","carry","hasOwnProperty","helperName","result","addHelpers","themeName","uniqid","pix","js","quote","shortentext","userdate","globals","getJS","treatStringsInContent","pattern","treated","strIndex","walker","char","strFinal","search","substring","substr","parseInt","debug","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","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 * @package    core\n * @class      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/event',\n        'core/yui',\n        'core/log',\n        'core/truncate',\n        'core/user_date',\n        'core/pending',\n    ],\n    function(mustache, $, ajax, str, notification, coreurl, config, storage, IconSystem, event, Y, Log, Truncate, UserDate,\n        Pending) {\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} blacklistedNestedHelpers - List of helpers that can't be called within other helpers */\n    var blacklistedNestedHelpers = ['js'];\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 = 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                                // 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: 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 = 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 = 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\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(key, component, title, template);\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\n        var searchKey = this.currentThemeName + '/' + templateName;\n        var template = templateCache[searchKey];\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(/&#x2F;/gi, '/');\n\n        return iconSystem.renderIcon(key, component, text, template);\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        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({key: key, component: component, param: param});\n\n        // The placeholder must not use {{}} as those can be misinterpreted by the engine.\n        return '[[_s' + index + ']]';\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(/([\\{\\}]{2,3})/g, '{{=<% %>=}}$1<%={{ }}=%>')\n            .replace(/(\\r\\n|\\r|\\n)/g, '&#x0a;')\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 blacklisted 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 blacklisted 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 = blacklistedNestedHelpers.reduce(function(carry, name) {\n                    if (context.hasOwnProperty(name)) {\n                        carry[name] = context[name];\n                    }\n\n                    return carry;\n                }, {});\n\n                blacklistedNestedHelpers.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 blacklisted nested helpers. This prevents the blacklisted\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.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\\d+\\]\\]/,\n            treated,\n            index,\n            strIndex,\n            walker,\n            char,\n            strFinal;\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                strIndex = '';\n                walker = 4; // 4 is the length of '[[_s'.\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 [[_s' + strIndex + ']].');\n                    strFinal = '';\n                }\n                treated += strFinal;\n                content = content.substr(6 + strIndex.length); // 6 is the length of the placeholder without the index: '[[_s]]'.\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     */\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            event.notifyFilterContentUpdated(newNodes);\n        }\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     */\n    var domPrepend = function(element, html, js) {\n        var node = $(element);\n        if (node.length) {\n            // Prepend the html.\n            node.prepend(html);\n            // Run any javascript associated with the new HTML.\n            runTemplateJS(js);\n            // Notify all filters about the new content.\n            event.notifyFilterContentUpdated(node);\n        }\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     */\n    var domAppend = function(element, html, js) {\n        var node = $(element);\n        if (node.length) {\n            // Append the html.\n            node.append(html);\n            // Run any javascript associated with the new HTML.\n            runTemplateJS(js);\n            // Notify all filters about the new content.\n            event.notifyFilterContentUpdated(node);\n        }\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(key, component, title);\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         */\n        replaceNodeContents: function(element, newHTML, newJS) {\n            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         */\n        replaceNode: function(element, newHTML, newJS) {\n            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         */\n        prependNodeContents: function(element, html, js) {\n            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         */\n        appendNodeContents: function(element, html, js) {\n            domAppend(element, html, js);\n        },\n    };\n});\n"],"file":"templates.min.js"}