mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-02-22 14:00:03 +00:00
Make the macrocall widget delegate to the transclude widget
This commit is contained in:
parent
4f2f689ab9
commit
64448ae774
@ -28,6 +28,8 @@ var AudioParser = function(type,text,options) {
|
||||
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
||||
}
|
||||
this.tree = [element];
|
||||
this.source = text;
|
||||
this.type = type;
|
||||
};
|
||||
|
||||
exports["audio/ogg"] = AudioParser;
|
||||
|
@ -64,6 +64,8 @@ var BinaryParser = function(type,text,options) {
|
||||
children: [warn, link]
|
||||
}
|
||||
this.tree = [element];
|
||||
this.source = text;
|
||||
this.type = type;
|
||||
};
|
||||
|
||||
exports["application/octet-stream"] = BinaryParser;
|
||||
|
@ -45,6 +45,8 @@ var CsvParser = function(type,text,options) {
|
||||
this.tree[0].children[0].children[0].children.push(row);
|
||||
}
|
||||
}
|
||||
this.source = text;
|
||||
this.type = type;
|
||||
};
|
||||
|
||||
exports["text/csv"] = CsvParser;
|
||||
|
@ -29,6 +29,8 @@ var HtmlParser = function(type,text,options) {
|
||||
if($tw.wiki.getTiddlerText("$:/config/HtmlParser/DisableSandbox","no") !== "yes") {
|
||||
this.tree[0].attributes.sandbox = {type: "string", value: $tw.wiki.getTiddlerText("$:/config/HtmlParser/SandboxTokens","")};
|
||||
}
|
||||
this.source = text;
|
||||
this.type = type;
|
||||
};
|
||||
|
||||
exports["text/html"] = HtmlParser;
|
||||
|
@ -28,6 +28,8 @@ var ImageParser = function(type,text,options) {
|
||||
}
|
||||
}
|
||||
this.tree = [element];
|
||||
this.source = text;
|
||||
this.type = type;
|
||||
};
|
||||
|
||||
exports["image/svg+xml"] = ImageParser;
|
||||
|
@ -25,6 +25,8 @@ var ImageParser = function(type,text,options) {
|
||||
element.attributes.src = {type: "string", value: "data:application/pdf;base64," + text};
|
||||
}
|
||||
this.tree = [element];
|
||||
this.source = text;
|
||||
this.type = type;
|
||||
};
|
||||
|
||||
exports["application/pdf"] = ImageParser;
|
||||
|
@ -20,6 +20,8 @@ var TextParser = function(type,text,options) {
|
||||
language: {type: "string", value: type}
|
||||
}
|
||||
}];
|
||||
this.source = text;
|
||||
this.type = type;
|
||||
};
|
||||
|
||||
exports["text/plain"] = TextParser;
|
||||
|
@ -28,6 +28,8 @@ var VideoParser = function(type,text,options) {
|
||||
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
||||
}
|
||||
this.tree = [element];
|
||||
this.source = text;
|
||||
this.type = type;
|
||||
};
|
||||
|
||||
exports["video/ogg"] = VideoParser;
|
||||
|
@ -37,7 +37,7 @@ MacroCallWidget.prototype.render = function(parent,nextSibling) {
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
MacroCallWidget.prototype.execute = function() {
|
||||
// Get the parse type if specified
|
||||
this.macroName = this.parseTreeNode.name || this.getAttribute("$name"),
|
||||
this.parseType = this.getAttribute("$type","text/vnd.tiddlywiki");
|
||||
this.renderOutput = this.getAttribute("$output","text/html");
|
||||
// Merge together the parameters specified in the parse tree with the specified attributes
|
||||
@ -47,49 +47,26 @@ MacroCallWidget.prototype.execute = function() {
|
||||
params.push({name: name, value: attribute});
|
||||
}
|
||||
});
|
||||
// Get the macro value
|
||||
var macroName = this.parseTreeNode.name || this.getAttribute("$name"),
|
||||
variableInfo = this.getVariableInfo(macroName,{params: params}),
|
||||
text = variableInfo.text,
|
||||
parseTreeNodes;
|
||||
// Are we rendering to HTML?
|
||||
if(this.renderOutput === "text/html") {
|
||||
// If so we'll return the parsed macro
|
||||
// Check if we've already cached parsing this macro
|
||||
var mode = this.parseTreeNode.isBlock ? "blockParser" : "inlineParser",
|
||||
parser;
|
||||
if(variableInfo.srcVariable && variableInfo.srcVariable[mode]) {
|
||||
parser = variableInfo.srcVariable[mode];
|
||||
} else {
|
||||
parser = this.wiki.parseText(this.parseType,text,
|
||||
{parseAsInline: !this.parseTreeNode.isBlock});
|
||||
if(variableInfo.isCacheable && variableInfo.srcVariable) {
|
||||
variableInfo.srcVariable[mode] = parser;
|
||||
}
|
||||
}
|
||||
var parseTreeNodes = parser ? parser.tree : [];
|
||||
// Wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
||||
var attributes = {};
|
||||
$tw.utils.each(variableInfo.params,function(param) {
|
||||
var name = "__" + param.name + "__";
|
||||
attributes[name] = {
|
||||
name: name,
|
||||
type: "string",
|
||||
value: param.value
|
||||
};
|
||||
});
|
||||
// Make a transclude widget
|
||||
var positionalName = 0,
|
||||
parseTreeNodes = [{
|
||||
type: "vars",
|
||||
attributes: attributes,
|
||||
children: parseTreeNodes
|
||||
type: "transclude",
|
||||
isBlock: this.parseTreeNode.isBlock
|
||||
}];
|
||||
} else if(this.renderOutput === "text/raw") {
|
||||
parseTreeNodes = [{type: "text", text: text}];
|
||||
} else {
|
||||
// Otherwise, we'll render the text
|
||||
var plainText = this.wiki.renderText("text/plain",this.parseType,text,{parentWidget: this});
|
||||
parseTreeNodes = [{type: "text", text: plainText}];
|
||||
}
|
||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$variable",this.macroName);
|
||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$type",this.parseType);
|
||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$output",this.renderOutput);
|
||||
$tw.utils.each(params,function(param) {
|
||||
var name = param.name;
|
||||
if(name) {
|
||||
if(name.charAt(0) === "$") {
|
||||
name = "$" + name;
|
||||
}
|
||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],name,param.value);
|
||||
} else {
|
||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],(positionalName++) + "",param.value);
|
||||
}
|
||||
});
|
||||
// Construct the child widgets
|
||||
this.makeChildWidgets(parseTreeNodes);
|
||||
};
|
||||
|
@ -44,9 +44,24 @@ TranscludeWidget.prototype.execute = function() {
|
||||
// Get the parse tree nodes that we are transcluding
|
||||
var target = this.getTransclusionTarget(),
|
||||
parseTreeNodes = target.parseTreeNodes;
|
||||
this.sourceText = target.source;
|
||||
this.sourceText = target.text;
|
||||
this.sourceType = target.type;
|
||||
this.parseAsInline = target.parseAsInline;
|
||||
// Process the transclusion according to the output type
|
||||
switch(this.transcludeOutput || "text/html") {
|
||||
case "text/html":
|
||||
// No further processing required
|
||||
break;
|
||||
case "text/raw":
|
||||
// Just return the raw text
|
||||
parseTreeNodes = [{type: "text", text: this.sourceText}];
|
||||
break;
|
||||
default:
|
||||
// text/plain
|
||||
var plainText = this.wiki.renderText("text/plain",this.sourceType,this.sourceText,{parentWidget: this});
|
||||
parseTreeNodes = [{type: "text", text: plainText}];
|
||||
break;
|
||||
}
|
||||
// Set context variables for recursion detection
|
||||
var recursionMarker = this.makeLegacyRecursionMarker(),
|
||||
newRecursionMarker = this.makeRecursionMarker();
|
||||
@ -91,6 +106,7 @@ TranscludeWidget.prototype.collectAttributes = function() {
|
||||
} else {
|
||||
this.transcludeVariable = this.getAttribute("$variable");
|
||||
this.transcludeType = this.getAttribute("$type");
|
||||
this.transcludeOutput = this.getAttribute("$output","text/html");
|
||||
this.transcludeTitle = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
|
||||
this.transcludeSubTiddler = this.getAttribute("$subtiddler");
|
||||
this.transcludeField = this.getAttribute("$field");
|
||||
@ -157,7 +173,7 @@ TranscludeWidget.prototype.collectSlotValueParameters = function() {
|
||||
Get transcluded parse tree nodes as an object {parser:,text:,type:}
|
||||
*/
|
||||
TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||
// Parse the text reference
|
||||
// Determine whether we're being used in inline or block mode
|
||||
var parseAsInline = !this.parseTreeNode.isBlock;
|
||||
if(this.transcludeMode === "inline") {
|
||||
parseAsInline = true;
|
||||
@ -165,9 +181,11 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||
parseAsInline = false;
|
||||
}
|
||||
var parser;
|
||||
// Get the parse tree
|
||||
if(this.transcludeVariable) {
|
||||
// Transcluding a variable
|
||||
var variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()}),
|
||||
srcVariable = variableInfo.srcVariable;
|
||||
srcVariable = variableInfo && variableInfo.srcVariable;
|
||||
if(srcVariable) {
|
||||
var mode = parseAsInline ? "inlineParser" : "blockParser";
|
||||
if(srcVariable.isCacheable && srcVariable[mode]) {
|
||||
@ -179,6 +197,7 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||
}
|
||||
}
|
||||
if(parser) {
|
||||
// Add parameters widget for functions
|
||||
if(srcVariable.isFunctionDefinition) {
|
||||
parser = {
|
||||
tree: [
|
||||
@ -186,20 +205,24 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||
type: "parameters",
|
||||
children: parser.tree
|
||||
}
|
||||
]
|
||||
],
|
||||
source: parser.source,
|
||||
type: parser.type
|
||||
}
|
||||
$tw.utils.each(srcVariable.params,function(param) {
|
||||
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],param.name,param["default"])
|
||||
});
|
||||
} else if(srcVariable.isMacroDefinition) {
|
||||
// Wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
||||
// For macros, wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
||||
parser = {
|
||||
tree: [
|
||||
{
|
||||
type: "vars",
|
||||
children: parser.tree
|
||||
}
|
||||
]
|
||||
],
|
||||
source: parser.source,
|
||||
type: parser.type
|
||||
}
|
||||
$tw.utils.each(variableInfo.params,function(param) {
|
||||
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],"__" + param.name + "__",param.value)
|
||||
@ -208,6 +231,7 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Transcluding a text reference
|
||||
parser = this.wiki.parseTextReference(
|
||||
this.transcludeTitle,
|
||||
this.transcludeField,
|
||||
@ -217,6 +241,7 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||
subTiddler: this.transcludeSubTiddler
|
||||
});
|
||||
}
|
||||
// Return the parse tree
|
||||
if(parser) {
|
||||
return {
|
||||
parser: parser,
|
||||
@ -226,6 +251,7 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||
type: parser.type
|
||||
};
|
||||
} else {
|
||||
// If there's no parse tree then return the missing slot value
|
||||
return {
|
||||
parser: null,
|
||||
parseTreeNodes: (this.slotValueParseTrees["ts-missing"] || []),
|
||||
@ -364,7 +390,7 @@ TranscludeWidget.prototype.makeLegacyRecursionMarker = function() {
|
||||
};
|
||||
|
||||
TranscludeWidget.prototype.parserNeedsRefresh = function() {
|
||||
// TODO: Doesn't consider transcluded variables
|
||||
// Doesn't need to consider transcluded variables because a parent variable can't change once a widget has been created
|
||||
var parserInfo = this.wiki.getTextReferenceParserInfo(this.transcludeTitle,this.transcludeField,this.transcludeIndex,{subTiddler:this.transcludeSubTiddler});
|
||||
return (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType)
|
||||
};
|
||||
|
17
editions/test/tiddlers/tests/data/transclude/Macro-Plain.tid
Normal file
17
editions/test/tiddlers/tests/data/transclude/Macro-Plain.tid
Normal file
@ -0,0 +1,17 @@
|
||||
title: Transclude/Macro/Plain
|
||||
description: Transcluding a macro as plain text
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$let currentTab="Jeremy">
|
||||
<$macrocall $name="currentTab" $type="text/plain" $output="text/plain"/>
|
||||
|
|
||||
<$transclude $variable="currentTab" $type="text/plain" $output="text/plain"/>
|
||||
</$let>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>Jeremy|Jeremy</p>
|
@ -124,7 +124,7 @@ describe("Wiki.parseTextReference tests", function() {
|
||||
// Non-existent subtiddler of a plugin
|
||||
expect(parseAndGetSource("$:/ShadowPlugin","text",null,"MyMissingTiddler")).toEqual(null);
|
||||
// Plain text tiddler
|
||||
expect(parseAndGetSource("TiddlerNine")).toEqual(undefined);
|
||||
expect(parseAndGetSource("TiddlerNine")).toEqual("this is plain text");
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -74,7 +74,7 @@ describe("Tabs-macro HTML tests", function() {
|
||||
expect(wiki.renderTiddler("text/html","test-tabs-macro-horizontal")).toBe(expected.fields.text.replace(/\n/g,""));
|
||||
});
|
||||
|
||||
it("should render 'horizontal' tabs from v5.2.2 and up with whitespace trim", function() {
|
||||
it("should render all 'horizontal' tabs from v5.2.2 and up with whitespace trim", function() {
|
||||
expect(wiki.renderTiddler("text/html","test-tabs-macro-horizontal-all")).toBe(expectedAll.fields.text.replace(/\n/g,""));
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user