1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-06-23 00:44:06 +00:00

Improve recursion detection

While retaining backwards compatibility
This commit is contained in:
jeremy@jermolene.com 2022-05-06 15:00:10 +01:00
parent 7caaf82571
commit a9938a6c67
2 changed files with 30 additions and 7 deletions

View File

@ -48,13 +48,15 @@ TranscludeWidget.prototype.execute = function() {
this.sourceType = target.type; this.sourceType = target.type;
this.parseAsInline = target.parseAsInline; this.parseAsInline = target.parseAsInline;
// Set context variables for recursion detection // Set context variables for recursion detection
var recursionMarker = this.makeRecursionMarker(); var recursionMarker = this.makeLegacyRecursionMarker(),
newRecursionMarker = this.makeRecursionMarker();
if(this.recursionMarker === "yes") { if(this.recursionMarker === "yes") {
this.setVariable("transclusion",recursionMarker); this.setVariable("transclusion",recursionMarker);
this.setVariable("$transclusion",newRecursionMarker);
} }
// Check for recursion // Check for recursion
if(target.parser) { 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: { parseTreeNodes = [{type: "element", tag: "span", attributes: {
"class": {type: "string", value: "tc-error"} "class": {type: "string", value: "tc-error"}
}, children: [ }, 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() { TranscludeWidget.prototype.makeRecursionMarker = function() {
var attributes = Object.create(null); var marker = {
attributes: {},
variables: {}
}
$tw.utils.each(this.attributes,function(value,name) { $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 = []; var output = [];
output.push("{"); output.push("{");
output.push(this.getVariable("currentTiddler",{defaultValue: ""})); output.push(this.getVariable("currentTiddler",{defaultValue: ""}));
output.push("|"); 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("}"); output.push("}");
return output.join(""); return output.join("");
}; };

View File

@ -157,7 +157,7 @@ describe("Widget module", function() {
// Render the widget node to the DOM // Render the widget node to the DOM
var wrapper = renderWidgetNode(widgetNode); var wrapper = renderWidgetNode(widgetNode);
// Test the rendering // Test the rendering
expect(wrapper.innerHTML).toBe("<span class=\"tc-error\">Recursive transclusion error in transclude widget</span>\n"); expect(wrapper.innerHTML).toBe("<span class=\"tc-error\">Recursive transclusion error in transclude widget</span>\n\n");
}); });
it("should deal with SVG elements", function() { it("should deal with SVG elements", function() {