MDL-60286 lib: Moodle additions to mustache.js
authorAdrian Greeve <adrian@moodle.com>
Fri, 6 Oct 2017 07:03:17 +0000 (15:03 +0800)
committerAdrian Greeve <adrian@moodle.com>
Mon, 9 Oct 2017 01:43:47 +0000 (09:43 +0800)
lib/amd/src/mustache.js
lib/thirdpartylibs.xml

index 413b6f2..29135a1 100644 (file)
@@ -1,9 +1,44 @@
+// The MIT License
+//
+// Copyright (c) 2009 Chris Wanstrath (Ruby)
+// Copyright (c) 2010-2014 Jan Lehnardt (JavaScript)
+// Copyright (c) 2010-2015 The mustache.js community
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+// Description of import into Moodle:
+// Checkout from https://github.com/moodle/custom-mustache.js
+// Rebase onto latest release tag from https://github.com/janl/mustache.js
+// Copy mustache.js into lib/amd/src/ in Moodle folder.
+// Add the license as a comment to the file and these instructions.
+// Add jshint tags so this file is not linted.
+// Remove the "global define:" comment (hint for linter)
+// Make sure that you have not removed the custom code for '$' and '<'.
+
 /*!
  * mustache.js - Logic-less {{mustache}} templates with JavaScript
  * http://github.com/janl/mustache.js
  */
 
-/*global define: false Mustache: true*/
+/* jshint ignore:start */
 
 (function defineMustache (global, factory) {
   if (typeof exports === 'object' && exports && typeof exports.nodeName !== 'string') {
   var spaceRe = /\s+/;
   var equalsRe = /\s*=/;
   var curlyRe = /\s*\}/;
-  var tagRe = /#|\^|\/|>|\{|&|=|!/;
+  var tagRe = /#|\^|\/|>|\{|&|=|!|\$|</;
 
   /**
    * Breaks up the given `template` string into a tree of tokens. If the `tags`
       token = [ type, value, start, scanner.pos ];
       tokens.push(token);
 
-      if (type === '#' || type === '^') {
+      if (type === '#' || type === '^' || type === '$' || type === '<') {
         sections.push(token);
       } else if (type === '/') {
         // Check section nesting.
       token = tokens[i];
 
       switch (token[0]) {
+        case '$':
+        case '<':
         case '#':
         case '^':
           collector.push(token);
    */
   function Context (view, parentContext) {
     this.view = view;
+    this.blocks = {};
     this.cache = { '.': this.view };
     this.parent = parentContext;
   }
     return new Context(view, this);
   };
 
+  /**
+   * Set a value in the current block context.
+   */
+  Context.prototype.setBlockVar = function set (name, value) {
+    var blocks = this.blocks;
+
+    blocks[name] = value;
+
+    return value;
+  };
+
+  /**
+   * Clear all current block vars.
+   */
+  Context.prototype.clearBlockVars = function clearBlockVars () {
+    this.blocks = {};
+  };
+
+  /**
+   * Get a value only from the current block context.
+   */
+  Context.prototype.getBlockVar = function getBlockVar (name) {
+    var blocks = this.blocks;
+
+    var value;
+    if (blocks.hasOwnProperty(name)) {
+      value = blocks[name];
+    } else {
+      if (this.parent) {
+        value = this.parent.getBlockVar(name);
+      }
+    }
+    // Can return undefined.
+    return value;
+  };
+
   /**
    * Returns the value of the given name in this context, traversing
    * up the context hierarchy if the value is absent in this context's view.
       if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate);
       else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate);
       else if (symbol === '>') value = this.renderPartial(token, context, partials, originalTemplate);
+      else if (symbol === '<') value = this.renderBlock(token, context, partials, originalTemplate);
+      else if (symbol === '$') value = this.renderBlockVariable(token, context, partials, originalTemplate);
       else if (symbol === '&') value = this.unescapedValue(token, context);
       else if (symbol === 'name') value = this.escapedValue(token, context);
       else if (symbol === 'text') value = this.rawValue(token);
       return this.renderTokens(this.parse(value), context, partials, value);
   };
 
+  Writer.prototype.renderBlock = function renderBlock (token, context, partials, originalTemplate) {
+    if (!partials) return;
+
+    var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
+    if (value != null)
+      // Ignore any wrongly set block vars before we started.
+      context.clearBlockVars();
+      // We are only rendering to record the default block variables.
+      this.renderTokens(token[4], context, partials, originalTemplate);
+      // Now we render and return the result.
+      var result = this.renderTokens(this.parse(value), context, partials, value);
+      // Don't leak the block variables outside this include.
+      context.clearBlockVars();
+      return result;
+  };
+
+  Writer.prototype.renderBlockVariable = function renderBlockVariable (token, context, partials, originalTemplate) {
+    var value = token[1];
+
+    var exists = context.getBlockVar(value);
+    if (!exists) {
+      context.setBlockVar(value, originalTemplate.slice(token[3], token[5]));
+      return this.renderTokens(token[4], context, partials, originalTemplate);
+    } else {
+      return this.renderTokens(this.parse(exists), context, partials, exists);
+    }
+  };
+
   Writer.prototype.unescapedValue = function unescapedValue (token, context) {
     var value = context.lookup(token[1]);
     if (value != null)
 
   return mustache;
 }));
+/* jshint ignore:end */
index 4d0b4e4..a4d6afd 100644 (file)
     <location>amd/src/mustache.js</location>
     <name>Mustache.js</name>
     <license>MIT</license>
-    <version>2.2.1</version>
+    <version>2.3.0</version>
   </library>
   <library>
     <location>graphlib.php</location>