From a9938a6c671f40de4e5ad70d60149721c37ad7a2 Mon Sep 17 00:00:00 2001 From: "jeremy@jermolene.com" Date: Fri, 6 May 2022 15:00:10 +0100 Subject: [PATCH] Improve recursion detection While retaining backwards compatibility --- core/modules/widgets/transclude.js | 35 +++++++++++++++++---- editions/test/tiddlers/tests/test-widget.js | 2 +- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/core/modules/widgets/transclude.js b/core/modules/widgets/transclude.js index f3122b092..787e6a26d 100755 --- a/core/modules/widgets/transclude.js +++ b/core/modules/widgets/transclude.js @@ -48,13 +48,15 @@ TranscludeWidget.prototype.execute = function() { this.sourceType = target.type; this.parseAsInline = target.parseAsInline; // Set context variables for recursion detection - var recursionMarker = this.makeRecursionMarker(); + var recursionMarker = this.makeLegacyRecursionMarker(), + newRecursionMarker = this.makeRecursionMarker(); if(this.recursionMarker === "yes") { this.setVariable("transclusion",recursionMarker); + this.setVariable("$transclusion",newRecursionMarker); } // Check for recursion if(target.parser) { - if(this.parentWidget && this.parentWidget.hasVariable("transclusion",recursionMarker)) { + if(this.parentWidget && this.parentWidget.hasVariable("$transclusion",newRecursionMarker)) { parseTreeNodes = [{type: "element", tag: "span", attributes: { "class": {type: "string", value: "tc-error"} }, children: [ @@ -273,18 +275,39 @@ TranscludeWidget.prototype.getTransclusionSlotValue = function(name,defaultParse }; /* -Compose a string comprising the title, field and/or index to identify this transclusion for recursion detection +Compose a string comprising the attributes and variables to identify this transclusion for recursion detection */ TranscludeWidget.prototype.makeRecursionMarker = function() { - var attributes = Object.create(null); + var marker = { + attributes: {}, + variables: {} + } $tw.utils.each(this.attributes,function(value,name) { - attributes[name] = value; + marker.attributes[name] = value; }); + for(var name in this.variables) { + if(name !== "$transclusion") { + marker.variables[name] = this.getVariable(name); + } + }; + return JSON.stringify(marker); +}; + +/* +Compose a string comprising the title, field and/or index to identify this transclusion for recursion detection +*/ +TranscludeWidget.prototype.makeLegacyRecursionMarker = function() { var output = []; output.push("{"); output.push(this.getVariable("currentTiddler",{defaultValue: ""})); output.push("|"); - output.push(JSON.stringify(attributes)); + output.push(this.transcludeTitle || ""); + output.push("|"); + output.push(this.transcludeField || ""); + output.push("|"); + output.push(this.transcludeIndex || ""); + output.push("|"); + output.push(this.transcludeSubTiddler || ""); output.push("}"); return output.join(""); }; diff --git a/editions/test/tiddlers/tests/test-widget.js b/editions/test/tiddlers/tests/test-widget.js index 8d9c734a0..10c45317e 100755 --- a/editions/test/tiddlers/tests/test-widget.js +++ b/editions/test/tiddlers/tests/test-widget.js @@ -157,7 +157,7 @@ describe("Widget module", function() { // Render the widget node to the DOM var wrapper = renderWidgetNode(widgetNode); // Test the rendering - expect(wrapper.innerHTML).toBe("Recursive transclusion error in transclude widget\n"); + expect(wrapper.innerHTML).toBe("Recursive transclusion error in transclude widget\n\n"); }); it("should deal with SVG elements", function() {