Prevent the JS mustache helper from being executed from within
the render call of another mustache helper because it can allow
users to inject JS into the page.
Changed the template loading to buffer the requests for templates
so that they can be sent in batches to the server to save large
volumes of network requests.
Changed the getTemplate function in templates.js to use the
core_output_load_template_with_dependencies function to load the
requested template and all of the dependencies required to render it.
The dependencies are added to the relevant caches so that when the
template is rendered they aren't re-requested from the server.
A template can include itself - e.g. by looping over the context children and rendering a tree.
Ensure this promise still resolves.
Example: admin/tool/lp/templates/competencies_tree.mustache.
There is a difference between how our PHP mustache engine and JS
mustache engine escaping works. If the icon key is not hard-coded in the
template but defined as a context variable, the JS mustache engine
escapes the forward slashes.
There is an edge case where we do not wait for all promises before
rendering a template. This can generate "failed to pre-fetch the template" JS errors.
Recursively pre-scan mustache templates to extract the list of blocks and partials. Then
we can pre-fetch them all and don't have to rely on jquery async ajax (which is deprecated).
This is part of a refactoring of the promises code in the templates module to prevent duplicate requests.
Prior to the patch the strings wrapped as the following one
where not found and replaced when rendering the template via Javascript
{{#quote}}{{#str}}string,component{{/str}}{{/quote}}
The native String.replace method in extremely slow when we are
dealing with a large string and large quantity of strings to replace.
This new solution walks through the string looking for placeholders
to replace.
Instead of injecting the HTML + JS directly - return a promise that is resolve with
the HTML and JS. This gives the caller control over how and when to inject the nodes
in the DOM. Also modify templates.replaceNode functions to cleanup YUI events mess.
Also pass the context to the callback so it can be verified.
Also pass the arguments to the callback as a named array - not a flat argument list.
Also - only load external scripts if they are not already loaded.
When nodes are added to the dom, they may need to be re-processed by a JS based
filter. To do this we need to trigger the legacy YUI event filter-content-updated.
To make this easier I added some wrappers to template that will insert the node, run any
JS and trigger the event.
I also changed existing yui code to call the amd function to trigger the event. This way
all jquery and yui listeners will always be notified.
Now the db/service.php array can contain these extra keys to provide information
on how a webservice may be called:
'ajax' => true (Default is false)
Replaces the xx_is_allowed_from_ajax callback.
'loginrequired' => false (Default is true)
Means that this webservice can be called through lib/ajax/service-nosession.php
which sets NO_MOODLE_COOKIES to true (faster). This is only safe for webservices returning
static public data (e.g. get_string).
The first ajax load fetches the template and puts it in localstorage + a js var
The second load gets it from local storage, but does not put it in the js var.
The pix_icon helper expects it to be in the js var always.