MDL-63667 amd: Check for parent template recursion
authorAndrew Nicols <andrew@nicols.co.uk>
Thu, 18 Oct 2018 03:54:27 +0000 (11:54 +0800)
committerDamyon Wiese <damyon@moodle.com>
Thu, 18 Oct 2018 04:04:19 +0000 (12:04 +0800)
lib/amd/build/templates.min.js
lib/amd/src/templates.js

index ee1ca1d..f85887e 100644 (file)
Binary files a/lib/amd/build/templates.min.js and b/lib/amd/build/templates.min.js differ
index e0d3db2..dd49428 100644 (file)
@@ -657,24 +657,39 @@ define(['core/mustache',
             return cachePartialPromises[searchKey];
         }
 
-        var cachePartialPromise = this.getTemplate(templateName).then(function(templateSource) {
+        // This promise will not be resolved until all child partials are also resolved and ready.
+        // We create it here to allow us to check for recursive inclusion of templates.
+        cachePartialPromises[searchKey] = $.Deferred();
+
+        this.getTemplate(templateName)
+        .then(function(templateSource) {
             var partials = this.scanForPartials(templateSource);
-            // Ignore templates that include themselves.
             var uniquePartials = partials.filter(function(partialName) {
+                // Check for recursion.
+
+                if (typeof cachePartialPromises[this.currentThemeName + '/' + partialName] !== 'undefined') {
+                    // Ignore templates which include their parent.
+                    return false;
+                }
+
+                // Ignore templates that include themselves.
                 return partialName != templateName;
-            });
+            }.bind(this));
+
+            // Fetch any partial which has not already been fetched.
             var fetchThemAll = uniquePartials.map(function(partialName) {
                 return this.cachePartials(partialName);
             }.bind(this));
 
-            return $.when.apply($, fetchThemAll).then(function() {
-                return templateSource;
+            // Resolve the templateName promise when all of the children are resolved.
+            return $.when.apply($, fetchThemAll)
+            .then(function() {
+                return cachePartialPromises[searchKey].resolve(templateSource);
             });
-        }.bind(this));
-
-        cachePartialPromises[searchKey] = cachePartialPromise;
+        }.bind(this))
+        .catch(cachePartialPromises[searchKey].reject);
 
-        return cachePartialPromise;
+        return cachePartialPromises[searchKey];
     };
 
     /**