1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-27 05:13:40 +00:00

Compare commits

..

2 Commits

Author SHA1 Message Date
jeremy@jermolene.com
891f3a3f3a Make the dynamic button be a separate button
For backwards compatibility
2023-01-26 09:43:58 +00:00
jeremy@jermolene.com
ad5de5ab9c Make save wiki button be accessible to users without colour vision 2023-01-24 11:14:37 +00:00
308 changed files with 13452 additions and 6661 deletions

View File

@@ -5,7 +5,7 @@
# Default to the current version number for building the plugin library # Default to the current version number for building the plugin library
if [ -z "$TW5_BUILD_VERSION" ]; then if [ -z "$TW5_BUILD_VERSION" ]; then
TW5_BUILD_VERSION=v5.2.8 TW5_BUILD_VERSION=v5.2.6
fi fi
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]" echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"

View File

@@ -2,4 +2,4 @@
# Remove any output files # Remove any output files
find . -regex "^./editions/.*/output/.*" -delete find . -regex "^./editions/[a-z0-9\.-]*/output/.*" -delete

View File

@@ -40,7 +40,6 @@ Error/RetrievingSkinny: Error retrieving skinny tiddler list
Error/SavingToTWEdit: Error saving to TWEdit Error/SavingToTWEdit: Error saving to TWEdit
Error/WhileSaving: Error while saving Error/WhileSaving: Error while saving
Error/XMLHttpRequest: XMLHttpRequest error code Error/XMLHttpRequest: XMLHttpRequest error code
Error/ZoominTextNode: Story View Error: It appears you tried to interact with a tiddler that displays in a custom container. This is most likely caused by using `$:/tags/StoryTiddlerTemplateFilter` with a template that contains text or whitespace at the start. Please use the pragma `\whitespace trim` and ensure the whole contents of the tiddler is wrapped in a single HTML element. The text that caused this issue:
InternalJavaScriptError/Title: Internal JavaScript Error InternalJavaScriptError/Title: Internal JavaScript Error
InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser
LayoutSwitcher/Description: Open the layout switcher LayoutSwitcher/Description: Open the layout switcher

View File

@@ -0,0 +1,21 @@
title: $:/language/Modals/SaveInstructions
subtitle: Save your work
footer: <$button message="tm-close-tiddler">Close</$button>
help: https://tiddlywiki.com/static/SavingChanges.html
Your changes to this wiki need to be saved as a ~TiddlyWiki HTML file.
!!! Desktop browsers
# Select ''Save As'' from the ''File'' menu
# Choose a filename and location
#* Some browsers also require you to explicitly specify the file saving format as ''Webpage, HTML only'' or similar
# Close this tab
!!! Smartphone browsers
# Create a bookmark to this page
#* If you've got iCloud or Google Sync set up then the bookmark will automatically sync to your desktop where you can open it and save it as above
# Close this tab
//If you open the bookmark again in Mobile Safari you will see this message again. If you want to go ahead and use the file, just click the ''close'' button below//

View File

@@ -30,7 +30,7 @@ exports.textPrimitives.wikiLink = exports.textPrimitives.upperLetter + "+" +
exports.textPrimitives.upperLetter + exports.textPrimitives.upperLetter +
exports.textPrimitives.anyLetter + "*"; exports.textPrimitives.anyLetter + "*";
exports.htmlEntities = {quot:34, dollar:36, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 }; exports.htmlEntities = {quot:34, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };
exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(","); exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",");

View File

@@ -162,13 +162,13 @@ FramedEngine.prototype.fixHeight = function() {
if(this.widget.editAutoHeight) { if(this.widget.editAutoHeight) {
if(this.domNode && !this.domNode.isTiddlyWikiFakeDom) { if(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {
var newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight); var newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);
this.iframeNode.style.height = newHeight + "px"; this.iframeNode.style.height = (newHeight + 14) + "px"; // +14 for the border on the textarea
} }
} else { } else {
var fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,"400px"),10); var fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,"400px"),10);
fixedHeight = Math.max(fixedHeight,20); fixedHeight = Math.max(fixedHeight,20);
this.domNode.style.height = fixedHeight + "px"; this.domNode.style.height = fixedHeight + "px";
this.iframeNode.style.height = fixedHeight + "px"; this.iframeNode.style.height = (fixedHeight + 14) + "px";
} }
} }
}; };
@@ -177,11 +177,9 @@ FramedEngine.prototype.fixHeight = function() {
Focus the engine node Focus the engine node
*/ */
FramedEngine.prototype.focus = function() { FramedEngine.prototype.focus = function() {
if(this.domNode.focus) { if(this.domNode.focus && this.domNode.select) {
this.domNode.focus(); this.domNode.focus();
} this.domNode.select();
if(this.domNode.select) {
$tw.utils.setSelectionByPosition(this.domNode,this.widget.editFocusSelectFromStart,this.widget.editFocusSelectFromEnd);
} }
}; };

View File

@@ -119,12 +119,10 @@ SimpleEngine.prototype.fixHeight = function() {
/* /*
Focus the engine node Focus the engine node
*/ */
SimpleEngine.prototype.focus = function() { SimpleEngine.prototype.focus = function() {
if(this.domNode.focus) { if(this.domNode.focus && this.domNode.select) {
this.domNode.focus(); this.domNode.focus();
} this.domNode.select();
if(this.domNode.select) {
$tw.utils.setSelectionByPosition(this.domNode,this.widget.editFocusSelectFromStart,this.widget.editFocusSelectFromEnd);
} }
}; };

View File

@@ -180,8 +180,6 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
this.editMinHeight = this.getAttribute("minHeight",DEFAULT_MIN_TEXT_AREA_HEIGHT); this.editMinHeight = this.getAttribute("minHeight",DEFAULT_MIN_TEXT_AREA_HEIGHT);
this.editFocusPopup = this.getAttribute("focusPopup"); this.editFocusPopup = this.getAttribute("focusPopup");
this.editFocus = this.getAttribute("focus"); this.editFocus = this.getAttribute("focus");
this.editFocusSelectFromStart = $tw.utils.parseNumber(this.getAttribute("focusSelectFromStart","0"));
this.editFocusSelectFromEnd = $tw.utils.parseNumber(this.getAttribute("focusSelectFromEnd","0"));
this.editTabIndex = this.getAttribute("tabindex"); this.editTabIndex = this.getAttribute("tabindex");
this.editCancelPopups = this.getAttribute("cancelPopups","") === "yes"; this.editCancelPopups = this.getAttribute("cancelPopups","") === "yes";
this.editInputActions = this.getAttribute("inputActions"); this.editInputActions = this.getAttribute("inputActions");
@@ -220,7 +218,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
EditTextWidget.prototype.refresh = function(changedTiddlers) { EditTextWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes(); var changedAttributes = this.computeAttributes();
// Completely rerender if any of our attributes have changed // Completely rerender if any of our attributes have changed
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedTiddlers["$:/palette"] || changedAttributes.disabled || changedAttributes.fileDrop) { if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedAttributes.disabled || changedAttributes.fileDrop) {
this.refreshSelf(); this.refreshSelf();
return true; return true;
} else if (changedTiddlers[this.editRefreshTitle]) { } else if (changedTiddlers[this.editRefreshTitle]) {

View File

@@ -25,10 +25,20 @@ exports.cascade = function(operationSubFunction,options) {
if(!filterFnList[index]) { if(!filterFnList[index]) {
filterFnList[index] = options.wiki.compileFilter(filter); filterFnList[index] = options.wiki.compileFilter(filter);
} }
var output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({ var output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),{
"currentTiddler": "" + title, getVariable: function(name,opts) {
"..currentTiddler": widget.getVariable("currentTiddler","") opts = opts || {};
})); opts.variables = {
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler")
};
if(name in opts.variables) {
return opts.variables[name];
} else {
return widget.getVariable(name,opts);
}
}
});
if(output.length !== 0) { if(output.length !== 0) {
result = output[0]; result = output[0];
return false; return false;

View File

@@ -19,13 +19,23 @@ exports.filter = function(operationSubFunction,options) {
var resultsToRemove = [], var resultsToRemove = [],
index = 0; index = 0;
results.each(function(title) { results.each(function(title) {
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({ var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
"currentTiddler": "" + title, getVariable: function(name,opts) {
"..currentTiddler": widget.getVariable("currentTiddler",""), opts = opts || {};
"index": "" + index, opts.variables = {
"revIndex": "" + (results.length - 1 - index), "currentTiddler": "" + title,
"length": "" + results.length "..currentTiddler": widget.getVariable("currentTiddler"),
})); "index": "" + index,
"revIndex": "" + (results.length - 1 - index),
"length": "" + results.length
};
if(name in opts.variables) {
return opts.variables[name];
} else {
return widget.getVariable(name,opts);
}
}
});
if(filtered.length === 0) { if(filtered.length === 0) {
resultsToRemove.push(title); resultsToRemove.push(title);
} }

View File

@@ -21,13 +21,23 @@ exports.map = function(operationSubFunction,options) {
flatten = (suffixes[0] && suffixes[0][0] === "flat") ? true : false; flatten = (suffixes[0] && suffixes[0][0] === "flat") ? true : false;
results.clear(); results.clear();
$tw.utils.each(inputTitles,function(title) { $tw.utils.each(inputTitles,function(title) {
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({ var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
"currentTiddler": "" + title, getVariable: function(name,opts) {
"..currentTiddler": widget.getVariable("currentTiddler",""), opts = opts || {};
"index": "" + index, opts.variables = {
"revIndex": "" + (inputTitles.length - 1 - index), "currentTiddler": "" + title,
"length": "" + inputTitles.length "..currentTiddler": widget.getVariable("currentTiddler"),
})); "index": "" + index,
"revIndex": "" + (inputTitles.length - 1 - index),
"length": "" + inputTitles.length
};
if(name in opts.variables) {
return opts.variables[name];
} else {
return widget.getVariable(name,opts);
}
}
});
if(filtered.length && flatten) { if(filtered.length && flatten) {
$tw.utils.each(filtered,function(value) { $tw.utils.each(filtered,function(value) {
results.push(value); results.push(value);

View File

@@ -18,14 +18,24 @@ exports.reduce = function(operationSubFunction,options) {
var accumulator = "", var accumulator = "",
index = 0; index = 0;
results.each(function(title) { results.each(function(title) {
var list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({ var list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
"currentTiddler": "" + title, getVariable: function(name,opts) {
"..currentTiddler": widget.getVariable("currentTiddler"), opts = opts || {};
"index": "" + index, opts.variables = {
"revIndex": "" + (results.length - 1 - index), "currentTiddler": "" + title,
"length": "" + results.length, "..currentTiddler": widget.getVariable("currentTiddler"),
"accumulator": "" + accumulator "index": "" + index,
})); "revIndex": "" + (results.length - 1 - index),
"length": "" + results.length,
"accumulator": "" + accumulator
};
if(name in opts.variables) {
return opts.variables[name];
} else {
return widget.getVariable(name,opts);
}
}
});
if(list.length > 0) { if(list.length > 0) {
accumulator = "" + list[0]; accumulator = "" + list[0];
} }

View File

@@ -25,10 +25,20 @@ exports.sort = function(operationSubFunction,options) {
indexes = new Array(inputTitles.length), indexes = new Array(inputTitles.length),
compareFn; compareFn;
results.each(function(title) { results.each(function(title) {
var key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({ var key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
"currentTiddler": "" + title, getVariable: function(name,opts) {
"..currentTiddler": widget.getVariable("currentTiddler") opts = opts || {};
})); opts.variables = {
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler")
};
if(name in opts.variables) {
return opts.variables[name];
} else {
return widget.getVariable(name,opts);
}
}
});
sortKeys.push(key[0] || ""); sortKeys.push(key[0] || "");
}); });
results.clear(); results.clear();

View File

@@ -255,21 +255,19 @@ exports.compileFilter = function(filterString) {
var operands = [], var operands = [],
operatorFunction; operatorFunction;
if(!operator.operator) { if(!operator.operator) {
// Use the "title" operator if no operator is specified
operatorFunction = filterOperators.title; operatorFunction = filterOperators.title;
} else if(!filterOperators[operator.operator]) { } else if(!filterOperators[operator.operator]) {
// Unknown operators treated as "[unknown]" - at run time we can distinguish between a custom operator and falling back to the default "field" operator operatorFunction = filterOperators.field;
operatorFunction = filterOperators["[unknown]"];
} else { } else {
// Use the operator function
operatorFunction = filterOperators[operator.operator]; operatorFunction = filterOperators[operator.operator];
} }
$tw.utils.each(operator.operands,function(operand) { $tw.utils.each(operator.operands,function(operand) {
if(operand.indirect) { if(operand.indirect) {
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle); operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
} else if(operand.variable) { } else if(operand.variable) {
var varTree = $tw.utils.parseFilterVariable(operand.text); var varTree = $tw.utils.parseFilterVariable(operand.text);
operand.value = widget.evaluateVariable(varTree.name,{params: varTree.params, source: source})[0] || ""; operand.value = widget.getVariable(varTree.name,{params:varTree.params,defaultValue: ""});
} else { } else {
operand.value = operand.text; operand.value = operand.text;
} }

View File

@@ -16,22 +16,6 @@ Filter operator for applying decodeURIComponent() to each item.
Export our filter functions Export our filter functions
*/ */
exports.decodebase64 = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push($tw.utils.base64Decode(title));
});
return results;
};
exports.encodebase64 = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push($tw.utils.base64Encode(title));
});
return results;
};
exports.decodeuricomponent = function(source,operator,options) { exports.decodeuricomponent = function(source,operator,options) {
var results = []; var results = [];
source(function(tiddler,title) { source(function(tiddler,title) {

View File

@@ -20,10 +20,19 @@ exports.filter = function(source,operator,options) {
results = [], results = [],
target = operator.prefix !== "!"; target = operator.prefix !== "!";
source(function(tiddler,title) { source(function(tiddler,title) {
var list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),options.widget.makeFakeWidgetWithVariables({ var list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),{
"currentTiddler": "" + title, getVariable: function(name,opts) {
"..currentTiddler": options.widget.getVariable("currentTiddler","") opts = opts || {};
})); switch(name) {
case "currentTiddler":
return "" + title;
case "..currentTiddler":
return options.widget.getVariable("currentTiddler");
default:
return options.widget.getVariable(name,opts);
}
}
});
if((list.length > 0) === target) { if((list.length > 0) === target) {
results.push(title); results.push(title);
} }

View File

@@ -1,32 +0,0 @@
/*\
title: $:/core/modules/filters/function.js
type: application/javascript
module-type: filteroperator
Filter operator returning those input titles that are returned from a function
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.function = function(source,operator,options) {
var functionName = operator.operands[0],
variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(functionName);
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
return options.widget.evaluateVariable(functionName,{params: operator.operands.slice(1), source: source});
}
// Return the input list if the function wasn't found
var results = [];
source(function(tiddler,title) {
results.push(title);
});
return results;
};
})();

View File

@@ -26,14 +26,27 @@ exports.reduce = function(source,operator,options) {
accumulator = operator.operands[1] || ""; accumulator = operator.operands[1] || "";
for(var index=0; index<results.length; index++) { for(var index=0; index<results.length; index++) {
var title = results[index], var title = results[index],
list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),options.widget.makeFakeWidgetWithVariables({ list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),{
"currentTiddler": "" + title, getVariable: function(name,opts) {
"..currentTiddler": options.widget.getVariable("currentTiddler"), opts = opts || {};
"accumulator": "" + accumulator, switch(name) {
"index": "" + index, case "currentTiddler":
"revIndex": "" + (results.length - 1 - index), return "" + title;
"length": "" + results.length case "..currentTiddler":
})); return options.widget.getVariable("currentTiddler");
case "accumulator":
return "" + accumulator;
case "index":
return "" + index;
case "revIndex":
return "" + (results.length - 1 - index);
case "length":
return "" + results.length;
default:
return options.widget.getVariable(name,opts);
}
}
});
if(list.length > 0) { if(list.length > 0) {
accumulator = "" + list[0]; accumulator = "" + list[0];
} }

View File

@@ -25,10 +25,19 @@ exports.sortsub = function(source,operator,options) {
inputTitles.push(title); inputTitles.push(title);
var r = filterFn.call(options.wiki,function(iterator) { var r = filterFn.call(options.wiki,function(iterator) {
iterator(options.wiki.getTiddler(title),title); iterator(options.wiki.getTiddler(title),title);
},options.widget.makeFakeWidgetWithVariables({ },{
"currentTiddler": "" + title, getVariable: function(name,opts) {
"..currentTiddler": options.widget.getVariable("currentTiddler") opts = opts || {};
})); switch(name) {
case "currentTiddler":
return "" + title;
case "..currentTiddler":
return options.widget.getVariable("currentTiddler");
default:
return options.widget.getVariable(name,opts);
}
}
});
sortKeys.push(r[0] || ""); sortKeys.push(r[0] || "");
}); });
// Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays // Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays

View File

@@ -74,113 +74,6 @@ exports.join = makeStringReducingOperator(
},null },null
); );
var dmp = require("$:/core/modules/utils/diff-match-patch/diff_match_patch.js");
exports.levenshtein = makeStringBinaryOperator(
function(a,b) {
var dmpObject = new dmp.diff_match_patch(),
diffs = dmpObject.diff_main(a,b);
return [dmpObject.diff_levenshtein(diffs) + ""];
}
);
// these two functions are adapted from https://github.com/google/diff-match-patch/wiki/Line-or-Word-Diffs
function diffLineWordMode(text1,text2,mode) {
var dmpObject = new dmp.diff_match_patch();
var a = diffPartsToChars(text1,text2,mode);
var lineText1 = a.chars1;
var lineText2 = a.chars2;
var lineArray = a.lineArray;
var diffs = dmpObject.diff_main(lineText1,lineText2,false);
dmpObject.diff_charsToLines_(diffs,lineArray);
return diffs;
}
function diffPartsToChars(text1,text2,mode) {
var lineArray = [];
var lineHash = {};
lineArray[0] = '';
function diff_linesToPartsMunge_(text,mode) {
var chars = '';
var lineStart = 0;
var lineEnd = -1;
var lineArrayLength = lineArray.length,
regexpResult;
var searchRegexp = /\W+/g;
while(lineEnd < text.length - 1) {
if(mode === "words") {
regexpResult = searchRegexp.exec(text);
lineEnd = searchRegexp.lastIndex;
if(regexpResult === null) {
lineEnd = text.length;
}
lineEnd = --lineEnd;
} else {
lineEnd = text.indexOf('\n', lineStart);
if(lineEnd == -1) {
lineEnd = text.length - 1;
}
}
var line = text.substring(lineStart, lineEnd + 1);
if(lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : (lineHash[line] !== undefined)) {
chars += String.fromCharCode(lineHash[line]);
} else {
if (lineArrayLength == maxLines) {
line = text.substring(lineStart);
lineEnd = text.length;
}
chars += String.fromCharCode(lineArrayLength);
lineHash[line] = lineArrayLength;
lineArray[lineArrayLength++] = line;
}
lineStart = lineEnd + 1;
}
return chars;
}
var maxLines = 40000;
var chars1 = diff_linesToPartsMunge_(text1,mode);
maxLines = 65535;
var chars2 = diff_linesToPartsMunge_(text2,mode);
return {chars1: chars1, chars2: chars2, lineArray: lineArray};
};
exports.makepatches = function(source,operator,options) {
var dmpObject = new dmp.diff_match_patch(),
suffix = operator.suffix || "",
result = [];
source(function(tiddler,title) {
var diffs, patches;
if(suffix === "lines" || suffix === "words") {
diffs = diffLineWordMode(title,operator.operand,suffix);
patches = dmpObject.patch_make(title,diffs);
} else {
patches = dmpObject.patch_make(title,operator.operand);
}
Array.prototype.push.apply(result,[dmpObject.patch_toText(patches)]);
});
return result;
};
exports.applypatches = makeStringBinaryOperator(
function(a,b) {
var dmpObject = new dmp.diff_match_patch(),
patches;
try {
patches = dmpObject.patch_fromText(b);
} catch(e) {
}
if(patches) {
return [dmpObject.patch_apply(patches,a)[0]];
} else {
return [a];
}
}
);
function makeStringBinaryOperator(fnCalc) { function makeStringBinaryOperator(fnCalc) {
return function(source,operator,options) { return function(source,operator,options) {
var result = []; var result = [];
@@ -291,4 +184,4 @@ exports.charcode = function(source,operator,options) {
return [chars.join("")]; return [chars.join("")];
}; };
})(); })();

View File

@@ -1,45 +0,0 @@
/*\
title: $:/core/modules/filters/unknown.js
type: application/javascript
module-type: filteroperator
Filter operator for handling unknown filter operators.
Not intended to be used directly by end users, hence the square brackets around the name.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var fieldFilterOperatorFn = require("$:/core/modules/filters/field.js").field;
/*
Export our filter function
*/
exports["[unknown]"] = function(source,operator,options) {
// Check for a user defined filter operator
if(operator.operator.charAt(0) === ".") {
var variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(operator.operator);
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
var list = options.widget.evaluateVariable(operator.operator,{params: operator.operands, source: source});
if(operator.prefix === "!") {
var results = [];
source(function(tiddler,title) {
if(list.indexOf(title) === -1) {
results.push(title);
}
});
return results;
} else {
return list;
}
}
}
// Otherwise, use the "field" operator
return fieldFilterOperatorFn(source,operator,options);
};
})();

View File

@@ -32,18 +32,18 @@ FieldIndexer.prototype.setMaxIndexedValueLength = function(length) {
FieldIndexer.prototype.addIndexMethods = function() { FieldIndexer.prototype.addIndexMethods = function() {
var self = this; var self = this;
// get all tiddlers, including those overwrite shadow tiddlers
this.wiki.each.byField = function(name,value) { this.wiki.each.byField = function(name,value) {
var lookup = self.lookup(name,value); var titles = self.wiki.allTitles(),
lookup = self.lookup(name,value);
return lookup && lookup.filter(function(title) { return lookup && lookup.filter(function(title) {
return self.wiki.tiddlerExists(title) return titles.indexOf(title) !== -1;
}); });
}; };
// get shadow tiddlers, including shadow tiddlers that is overwritten
this.wiki.eachShadow.byField = function(name,value) { this.wiki.eachShadow.byField = function(name,value) {
var lookup = self.lookup(name,value); var titles = self.wiki.allShadowTitles(),
lookup = self.lookup(name,value);
return lookup && lookup.filter(function(title) { return lookup && lookup.filter(function(title) {
return self.wiki.isShadowTiddler(title) return titles.indexOf(title) !== -1;
}); });
}; };
this.wiki.eachTiddlerPlusShadows.byField = function(name,value) { this.wiki.eachTiddlerPlusShadows.byField = function(name,value) {

View File

@@ -28,8 +28,6 @@ var AudioParser = function(type,text,options) {
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text}; element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
} }
this.tree = [element]; this.tree = [element];
this.source = text;
this.type = type;
}; };
exports["audio/ogg"] = AudioParser; exports["audio/ogg"] = AudioParser;

View File

@@ -23,7 +23,7 @@ var BinaryParser = function(type,text,options) {
children: [{ children: [{
type: "transclude", type: "transclude",
attributes: { attributes: {
"$tiddler": {type: "string", value: BINARY_WARNING_MESSAGE} tiddler: {type: "string", value: BINARY_WARNING_MESSAGE}
} }
}] }]
}; };
@@ -38,7 +38,7 @@ var BinaryParser = function(type,text,options) {
children: [{ children: [{
type: "transclude", type: "transclude",
attributes: { attributes: {
"$tiddler": {type: "string", value: EXPORT_BUTTON_IMAGE} tiddler: {type: "string", value: EXPORT_BUTTON_IMAGE}
} }
}] }]
}; };
@@ -64,8 +64,6 @@ var BinaryParser = function(type,text,options) {
children: [warn, link] children: [warn, link]
} }
this.tree = [element]; this.tree = [element];
this.source = text;
this.type = type;
}; };
exports["application/octet-stream"] = BinaryParser; exports["application/octet-stream"] = BinaryParser;

View File

@@ -52,8 +52,6 @@ var CsvParser = function(type,text,options) {
tag = "td"; tag = "td";
this.tree[0].children[0].children[0].children.push(row); this.tree[0].children[0].children[0].children.push(row);
} }
this.source = text;
this.type = type;
}; };
exports["text/csv"] = CsvParser; exports["text/csv"] = CsvParser;

View File

@@ -29,8 +29,6 @@ var HtmlParser = function(type,text,options) {
if($tw.wiki.getTiddlerText("$:/config/HtmlParser/DisableSandbox","no") !== "yes") { if($tw.wiki.getTiddlerText("$:/config/HtmlParser/DisableSandbox","no") !== "yes") {
this.tree[0].attributes.sandbox = {type: "string", value: $tw.wiki.getTiddlerText("$:/config/HtmlParser/SandboxTokens","")}; this.tree[0].attributes.sandbox = {type: "string", value: $tw.wiki.getTiddlerText("$:/config/HtmlParser/SandboxTokens","")};
} }
this.source = text;
this.type = type;
}; };
exports["text/html"] = HtmlParser; exports["text/html"] = HtmlParser;

View File

@@ -28,8 +28,6 @@ var ImageParser = function(type,text,options) {
} }
} }
this.tree = [element]; this.tree = [element];
this.source = text;
this.type = type;
}; };
exports["image/svg+xml"] = ImageParser; exports["image/svg+xml"] = ImageParser;

View File

@@ -123,36 +123,6 @@ exports.parseStringLiteral = function(source,pos) {
} }
}; };
/*
Returns an array of {name:} with an optional "default" property. Options include:
requireParenthesis: require the parameter definition to be wrapped in parenthesis
*/
exports.parseParameterDefinition = function(paramString,options) {
options = options || {};
if(options.requireParenthesis) {
var parenMatch = /^\s*\((.*)\)\s*$/g.exec(paramString);
if(!parenMatch) {
return [];
}
paramString = parenMatch[1];
}
var params = [],
reParam = /\s*([^:),\s]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|([^,"'\s]+)))?/mg,
paramMatch = reParam.exec(paramString);
while(paramMatch) {
// Save the parameter details
var paramInfo = {name: paramMatch[1]},
defaultValue = paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5];
if(defaultValue !== undefined) {
paramInfo["default"] = defaultValue;
}
params.push(paramInfo);
// Look for the next parameter
paramMatch = reParam.exec(paramString);
}
return params;
};
exports.parseMacroParameters = function(node,source,pos) { exports.parseMacroParameters = function(node,source,pos) {
// Process parameters // Process parameters
var parameter = $tw.utils.parseMacroParameter(source,pos); var parameter = $tw.utils.parseMacroParameter(source,pos);
@@ -205,36 +175,7 @@ exports.parseMacroParameter = function(source,pos) {
}; };
/* /*
Look for a macro invocation. Returns null if not found, or {type: "transclude", attributes:, start:, end:} Look for a macro invocation. Returns null if not found, or {type: "macrocall", name:, parameters:, start:, end:}
*/
exports.parseMacroInvocationAsTransclusion = function(source,pos) {
var node = $tw.utils.parseMacroInvocation(source,pos);
if(node) {
var positionalName = 0,
transclusion = {
type: "transclude",
start: node.start,
end: node.end
};
$tw.utils.addAttributeToParseTreeNode(transclusion,"$variable",node.name);
$tw.utils.each(node.params,function(param) {
var name = param.name;
if(name) {
if(name.charAt(0) === "$") {
name = "$" + name;
}
$tw.utils.addAttributeToParseTreeNode(transclusion,{name: name,type: "string", value: param.value, start: param.start, end: param.end});
} else {
$tw.utils.addAttributeToParseTreeNode(transclusion,{name: (positionalName++) + "",type: "string", value: param.value, start: param.start, end: param.end});
}
});
return transclusion;
}
return node;
};
/*
Look for a macro invocation. Returns null if not found, or {type: "macrocall", name:, params:, start:, end:}
*/ */
exports.parseMacroInvocation = function(source,pos) { exports.parseMacroInvocation = function(source,pos) {
var node = { var node = {

View File

@@ -25,8 +25,6 @@ var ImageParser = function(type,text,options) {
element.attributes.src = {type: "string", value: "data:application/pdf;base64," + text}; element.attributes.src = {type: "string", value: "data:application/pdf;base64," + text};
} }
this.tree = [element]; this.tree = [element];
this.source = text;
this.type = type;
}; };
exports["application/pdf"] = ImageParser; exports["application/pdf"] = ImageParser;

View File

@@ -20,8 +20,6 @@ var TextParser = function(type,text,options) {
language: {type: "string", value: type} language: {type: "string", value: type}
} }
}]; }];
this.source = text;
this.type = type;
}; };
exports["text/plain"] = TextParser; exports["text/plain"] = TextParser;

View File

@@ -28,8 +28,6 @@ var VideoParser = function(type,text,options) {
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text}; element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
} }
this.tree = [element]; this.tree = [element];
this.source = text;
this.type = type;
}; };
exports["video/ogg"] = VideoParser; exports["video/ogg"] = VideoParser;

View File

@@ -1,97 +0,0 @@
/*\
title: $:/core/modules/parsers/wikiparser/rules/fnprocdef.js
type: application/javascript
module-type: wikirule
Wiki pragma rule for function, procedure and widget definitions
```
\function name(param:defaultvalue,param2:defaultvalue)
definition text
\end
\procedure name(param:defaultvalue,param2:defaultvalue)
definition text
\end
\widget $mywidget(param:defaultvalue,param2:defaultvalue)
definition text
\end
```
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.name = "fnprocdef";
exports.types = {pragma: true};
/*
Instantiate parse rule
*/
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /^\\(function|procedure|widget)\s+([^(\s]+)\((\s*([^)]*))?\)(\s*\r?\n)?/mg;
};
/*
Parse the most recent match
*/
exports.parse = function() {
// Move past the macro name and parameters
this.parser.pos = this.matchRegExp.lastIndex;
// Parse the parameters
var params = [];
if(this.match[3]) {
params = $tw.utils.parseParameterDefinition(this.match[4]);
}
// Is this a multiline definition?
var reEnd;
if(this.match[5]) {
// If so, the end of the body is marked with \end
reEnd = new RegExp("(\\r?\\n\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[2]) + ")?(?:$|\\r?\\n))","mg");
} else {
// Otherwise, the end of the definition is marked by the end of the line
reEnd = /($|\r?\n)/mg;
// Move past any whitespace
this.parser.pos = $tw.utils.skipWhiteSpace(this.parser.source,this.parser.pos);
}
// Find the end of the definition
reEnd.lastIndex = this.parser.pos;
var text,
endMatch = reEnd.exec(this.parser.source);
if(endMatch) {
text = this.parser.source.substring(this.parser.pos,endMatch.index);
this.parser.pos = endMatch.index + endMatch[0].length;
} else {
// We didn't find the end of the definition, so we'll make it blank
text = "";
}
// Save the macro definition
var parseTreeNodes = [{
type: "set",
attributes: {},
children: [],
params: params
}];
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"name",this.match[2]);
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"value",text);
if(this.match[1] === "function") {
parseTreeNodes[0].isFunctionDefinition = true;
} else if(this.match[1] === "procedure") {
parseTreeNodes[0].isProcedureDefinition = true;
} else if(this.match[1] === "widget") {
parseTreeNodes[0].isWidgetDefinition = true;
}
if(this.parser.configTrimWhiteSpace) {
parseTreeNodes[0].configTrimWhiteSpace = true;
}
return parseTreeNodes;
};
})();

View File

@@ -93,6 +93,9 @@ exports.parseTag = function(source,pos,options) {
return null; return null;
} }
node.tag = token.match[1]; node.tag = token.match[1];
if(node.tag.slice(1).indexOf("$") !== -1) {
return null;
}
if(node.tag.charAt(0) === "$") { if(node.tag.charAt(0) === "$") {
node.type = node.tag.substr(1); node.type = node.tag.substr(1);
} }

View File

@@ -27,7 +27,7 @@ exports.findNextMatch = function(startPos) {
var nextStart = startPos; var nextStart = startPos;
// Try parsing at all possible macrocall openers until we match // Try parsing at all possible macrocall openers until we match
while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) { while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) {
var nextCall = $tw.utils.parseMacroInvocationAsTransclusion(this.parser.source,nextStart); var nextCall = $tw.utils.parseMacroInvocation(this.parser.source,nextStart);
if(nextCall) { if(nextCall) {
var c = this.parser.source.charAt(nextCall.end); var c = this.parser.source.charAt(nextCall.end);
// Ensure EOL after parsed macro // Ensure EOL after parsed macro

View File

@@ -27,7 +27,7 @@ exports.findNextMatch = function(startPos) {
var nextStart = startPos; var nextStart = startPos;
// Try parsing at all possible macrocall openers until we match // Try parsing at all possible macrocall openers until we match
while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) { while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) {
this.nextCall = $tw.utils.parseMacroInvocationAsTransclusion(this.parser.source,nextStart); this.nextCall = $tw.utils.parseMacroInvocation(this.parser.source,nextStart);
if(this.nextCall) { if(this.nextCall) {
return nextStart; return nextStart;
} }

View File

@@ -58,7 +58,7 @@ exports.parse = function() {
var reEnd; var reEnd;
if(this.match[3]) { if(this.match[3]) {
// If so, the end of the body is marked with \end // If so, the end of the body is marked with \end
reEnd = new RegExp("(\\r?\\n[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?(?:$|\\r?\\n))","mg"); reEnd = new RegExp("(\\r?\\n\\s*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?(?:$|\\r?\\n))","mg");
} else { } else {
// Otherwise, the end of the definition is marked by the end of the line // Otherwise, the end of the definition is marked by the end of the line
reEnd = /($|\r?\n)/mg; reEnd = /($|\r?\n)/mg;
@@ -77,16 +77,16 @@ exports.parse = function() {
text = ""; text = "";
} }
// Save the macro definition // Save the macro definition
var parseTreeNodes = [{ return [{
type: "set", type: "set",
attributes: {}, attributes: {
name: {type: "string", value: this.match[1]},
value: {type: "string", value: text}
},
children: [], children: [],
params: params, params: params,
isMacroDefinition: true isMacroDefinition: true
}]; }];
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"name",this.match[1]);
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"value",text);
return parseTreeNodes;
}; };
})(); })();

View File

@@ -1,60 +0,0 @@
/*\
title: $:/core/modules/parsers/wikiparser/rules/parameters.js
type: application/javascript
module-type: wikirule
Wiki pragma rule for parameter definitions
```
\parameters(param:defaultvalue,param2:defaultvalue)
definition text
```
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.name = "parameters";
exports.types = {pragma: true};
/*
Instantiate parse rule
*/
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /^\\parameters\s*\(([^)]*)\)\s*\r?\n/mg;
};
/*
Parse the most recent match
*/
exports.parse = function() {
// Move past the macro name and parameters
this.parser.pos = this.matchRegExp.lastIndex;
// Parse the parameters
var params = $tw.utils.parseParameterDefinition(this.match[1]);
var attributes = Object.create(null),
orderedAttributes = [];
$tw.utils.each(params,function(param) {
var name = param.name;
// Parameter names starting with dollar must be escaped to double dollars for the parameters widget
if(name.charAt(0) === "$") {
name = "$" + name;
}
var attribute = {name: name, type: "string", value: param["default"] || ""};
attributes[name] = attribute;
orderedAttributes.push(attribute);
});
// Save the macro definition
return [{
type: "parameters",
attributes: attributes,
orderedAttributes: orderedAttributes
}];
};
})();

View File

@@ -23,7 +23,7 @@ exports.types = {block: true};
exports.init = function(parser) { exports.init = function(parser) {
this.parser = parser; this.parser = parser;
// Regexp to match // Regexp to match
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}(?:\r?\n|$)/mg; this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?\}\}(?:\r?\n|$)/mg;
}; };
exports.parse = function() { exports.parse = function() {
@@ -31,22 +31,13 @@ exports.parse = function() {
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Get the match details // Get the match details
var template = $tw.utils.trim(this.match[2]), var template = $tw.utils.trim(this.match[2]),
textRef = $tw.utils.trim(this.match[1]), textRef = $tw.utils.trim(this.match[1]);
params = this.match[3] ? this.match[3].split("|") : [];
// Prepare the transclude widget // Prepare the transclude widget
var transcludeNode = { var transcludeNode = {
type: "transclude", type: "transclude",
attributes: {}, attributes: {},
isBlock: true isBlock: true
}; };
$tw.utils.each(params,function(paramValue,index) {
var name = "" + index;
transcludeNode.attributes[name] = {
name: name,
type: "string",
value: paramValue
}
});
// Prepare the tiddler widget // Prepare the tiddler widget
var tr, targetTitle, targetField, targetIndex, tiddlerNode; var tr, targetTitle, targetField, targetIndex, tiddlerNode;
if(textRef) { if(textRef) {
@@ -57,14 +48,14 @@ exports.parse = function() {
tiddlerNode = { tiddlerNode = {
type: "tiddler", type: "tiddler",
attributes: { attributes: {
tiddler: {name: "tiddler", type: "string", value: targetTitle} tiddler: {type: "string", value: targetTitle}
}, },
isBlock: true, isBlock: true,
children: [transcludeNode] children: [transcludeNode]
}; };
} }
if(template) { if(template) {
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: template}; transcludeNode.attributes.tiddler = {type: "string", value: template};
if(textRef) { if(textRef) {
return [tiddlerNode]; return [tiddlerNode];
} else { } else {
@@ -72,12 +63,12 @@ exports.parse = function() {
} }
} else { } else {
if(textRef) { if(textRef) {
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: targetTitle}; transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
if(targetField) { if(targetField) {
transcludeNode.attributes["$field"] = {name: "$field", type: "string", value: targetField}; transcludeNode.attributes.field = {type: "string", value: targetField};
} }
if(targetIndex) { if(targetIndex) {
transcludeNode.attributes["$index"] = {name: "$index", type: "string", value: targetIndex}; transcludeNode.attributes.index = {type: "string", value: targetIndex};
} }
return [tiddlerNode]; return [tiddlerNode];
} else { } else {

View File

@@ -23,7 +23,7 @@ exports.types = {inline: true};
exports.init = function(parser) { exports.init = function(parser) {
this.parser = parser; this.parser = parser;
// Regexp to match // Regexp to match
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}/mg; this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?\}\}/mg;
}; };
exports.parse = function() { exports.parse = function() {
@@ -31,21 +31,12 @@ exports.parse = function() {
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Get the match details // Get the match details
var template = $tw.utils.trim(this.match[2]), var template = $tw.utils.trim(this.match[2]),
textRef = $tw.utils.trim(this.match[1]), textRef = $tw.utils.trim(this.match[1]);
params = this.match[3] ? this.match[3].split("|") : [];
// Prepare the transclude widget // Prepare the transclude widget
var transcludeNode = { var transcludeNode = {
type: "transclude", type: "transclude",
attributes: {} attributes: {}
}; };
$tw.utils.each(params,function(paramValue,index) {
var name = "" + index;
transcludeNode.attributes[name] = {
name: name,
type: "string",
value: paramValue
}
});
// Prepare the tiddler widget // Prepare the tiddler widget
var tr, targetTitle, targetField, targetIndex, tiddlerNode; var tr, targetTitle, targetField, targetIndex, tiddlerNode;
if(textRef) { if(textRef) {
@@ -56,13 +47,13 @@ exports.parse = function() {
tiddlerNode = { tiddlerNode = {
type: "tiddler", type: "tiddler",
attributes: { attributes: {
tiddler: {name: "tiddler", type: "string", value: targetTitle} tiddler: {type: "string", value: targetTitle}
}, },
children: [transcludeNode] children: [transcludeNode]
}; };
} }
if(template) { if(template) {
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: template}; transcludeNode.attributes.tiddler = {type: "string", value: template};
if(textRef) { if(textRef) {
return [tiddlerNode]; return [tiddlerNode];
} else { } else {
@@ -70,12 +61,12 @@ exports.parse = function() {
} }
} else { } else {
if(textRef) { if(textRef) {
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: targetTitle}; transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
if(targetField) { if(targetField) {
transcludeNode.attributes["$field"] = {name: "$field", type: "string", value: targetField}; transcludeNode.attributes.field = {type: "string", value: targetField};
} }
if(targetIndex) { if(targetIndex) {
transcludeNode.attributes["$index"] = {name: "$index", type: "string", value: targetIndex}; transcludeNode.attributes.index = {type: "string", value: targetIndex};
} }
return [tiddlerNode]; return [tiddlerNode];
} else { } else {

View File

@@ -32,7 +32,6 @@ options: see below:
parseAsInline: true to parse text as inline instead of block parseAsInline: true to parse text as inline instead of block
wiki: reference to wiki to use wiki: reference to wiki to use
_canonical_uri: optional URI of content if text is missing or empty _canonical_uri: optional URI of content if text is missing or empty
configTrimWhiteSpace: true to trim whitespace
*/ */
var WikiParser = function(type,text,options) { var WikiParser = function(type,text,options) {
this.wiki = options.wiki; this.wiki = options.wiki;
@@ -47,7 +46,7 @@ var WikiParser = function(type,text,options) {
this.source = text || ""; this.source = text || "";
this.sourceLength = this.source.length; this.sourceLength = this.source.length;
// Flag for ignoring whitespace // Flag for ignoring whitespace
this.configTrimWhiteSpace = options.configTrimWhiteSpace !== undefined ? options.configTrimWhiteSpace : false; this.configTrimWhiteSpace = false;
// Parser mode // Parser mode
this.parseAsInline = options.parseAsInline; this.parseAsInline = options.parseAsInline;
// Set current parse position // Set current parse position

View File

@@ -87,6 +87,13 @@ exports.startup = function() {
} }
}); });
} }
// If we're being viewed on a data: URI then give instructions for how to save
if(document.location.protocol === "data:") {
$tw.rootWidget.dispatchEvent({
type: "tm-modal",
param: "$:/language/Modals/SaveInstructions"
});
}
}; };
})(); })();

View File

@@ -17,10 +17,6 @@ var easing = "cubic-bezier(0.645, 0.045, 0.355, 1)"; // From http://easings.net/
var ZoominListView = function(listWidget) { var ZoominListView = function(listWidget) {
var self = this; var self = this;
this.listWidget = listWidget; this.listWidget = listWidget;
this.textNodeLogger = new $tw.utils.Logger("zoomin story river view", {
enable: true,
colour: 'red'
});
// Get the index of the tiddler that is at the top of the history // Get the index of the tiddler that is at the top of the history
var history = this.listWidget.wiki.getTiddlerDataCached(this.listWidget.historyTitle,[]), var history = this.listWidget.wiki.getTiddlerDataCached(this.listWidget.historyTitle,[]),
targetTiddler; targetTiddler;
@@ -52,10 +48,7 @@ ZoominListView.prototype.navigateTo = function(historyInfo) {
var listItemWidget = this.listWidget.children[listElementIndex], var listItemWidget = this.listWidget.children[listElementIndex],
targetElement = listItemWidget.findFirstDomNode(); targetElement = listItemWidget.findFirstDomNode();
// Abandon if the list entry isn't a DOM element (it might be a text node) // Abandon if the list entry isn't a DOM element (it might be a text node)
if(!targetElement) { if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
return;
} else if (targetElement.nodeType === Node.TEXT_NODE) {
this.logTextNodeRoot(targetElement);
return; return;
} }
// Make the new tiddler be position absolute and visible so that we can measure it // Make the new tiddler be position absolute and visible so that we can measure it
@@ -137,10 +130,7 @@ function findTitleDomNode(widget,targetClass) {
ZoominListView.prototype.insert = function(widget) { ZoominListView.prototype.insert = function(widget) {
var targetElement = widget.findFirstDomNode(); var targetElement = widget.findFirstDomNode();
// Abandon if the list entry isn't a DOM element (it might be a text node) // Abandon if the list entry isn't a DOM element (it might be a text node)
if(!targetElement) { if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
return;
} else if (targetElement.nodeType === Node.TEXT_NODE) {
this.logTextNodeRoot(targetElement);
return; return;
} }
// Make the newly inserted node position absolute and hidden // Make the newly inserted node position absolute and hidden
@@ -183,21 +173,16 @@ ZoominListView.prototype.remove = function(widget) {
var toWidgetDomNode = toWidget && toWidget.findFirstDomNode(); var toWidgetDomNode = toWidget && toWidget.findFirstDomNode();
// Set up the tiddler we're moving back in // Set up the tiddler we're moving back in
if(toWidgetDomNode) { if(toWidgetDomNode) {
if (toWidgetDomNode.nodeType === Node.TEXT_NODE) { $tw.utils.addClass(toWidgetDomNode,"tc-storyview-zoomin-tiddler");
this.logTextNodeRoot(toWidgetDomNode); $tw.utils.setStyle(toWidgetDomNode,[
toWidgetDomNode = null; {display: "block"},
} else { {transformOrigin: "50% 50%"},
$tw.utils.addClass(toWidgetDomNode,"tc-storyview-zoomin-tiddler"); {transform: "translateX(0px) translateY(0px) scale(10)"},
$tw.utils.setStyle(toWidgetDomNode,[ {transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms " + easing + ", opacity " + duration + "ms " + easing},
{display: "block"}, {opacity: "0"},
{transformOrigin: "50% 50%"}, {zIndex: "500"}
{transform: "translateX(0px) translateY(0px) scale(10)"}, ]);
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms " + easing + ", opacity " + duration + "ms " + easing}, this.currentTiddlerDomNode = toWidgetDomNode;
{opacity: "0"},
{zIndex: "500"}
]);
this.currentTiddlerDomNode = toWidgetDomNode;
}
} }
// Animate them both // Animate them both
// Force layout // Force layout
@@ -221,10 +206,6 @@ ZoominListView.prototype.remove = function(widget) {
return true; // Indicate that we'll delete the DOM node return true; // Indicate that we'll delete the DOM node
}; };
ZoominListView.prototype.logTextNodeRoot = function(node) {
this.textNodeLogger.log($tw.language.getString("Error/ZoominTextNode") + " " + node.textContent);
};
exports.zoomin = ZoominListView; exports.zoomin = ZoominListView;
})(); })();

View File

@@ -28,24 +28,6 @@ exports.domMatchesSelector = function(node,selector) {
return node.matches ? node.matches(selector) : node.msMatchesSelector(selector); return node.matches ? node.matches(selector) : node.msMatchesSelector(selector);
}; };
/*
Select text in a an input or textarea (setSelectionRange crashes on certain input types)
*/
exports.setSelectionRangeSafe = function(node,start,end,direction) {
try {
node.setSelectionRange(start,end,direction);
} catch(e) {
node.select();
}
};
/*
Select the text in an input or textarea by position
*/
exports.setSelectionByPosition = function(node,selectFromStart,selectFromEnd) {
$tw.utils.setSelectionRangeSafe(node,selectFromStart,node.value.length - selectFromEnd);
};
exports.removeChildren = function(node) { exports.removeChildren = function(node) {
while(node.hasChildNodes()) { while(node.hasChildNodes()) {
node.removeChild(node.firstChild); node.removeChild(node.firstChild);

View File

@@ -238,7 +238,7 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
} else { } else {
// Save as a .tid or a text/binary file plus a .meta file // Save as a .tid or a text/binary file plus a .meta file
var tiddlerType = tiddler.fields.type || "text/vnd.tiddlywiki"; var tiddlerType = tiddler.fields.type || "text/vnd.tiddlywiki";
if(tiddlerType === "text/vnd.tiddlywiki" || tiddler.hasField("_canonical_uri")) { if(tiddlerType === "text/vnd.tiddlywiki") {
// Save as a .tid file // Save as a .tid file
fileInfo.type = "application/x-tiddler"; fileInfo.type = "application/x-tiddler";
fileInfo.hasMetaFile = false; fileInfo.hasMetaFile = false;

View File

@@ -259,7 +259,7 @@ DropZoneWidget.prototype.handlePasteEvent = function(event) {
} }
}; };
// Let the browser handle it if we're in a textarea or input box // Let the browser handle it if we're in a textarea or input box
if(["TEXTAREA","INPUT"].indexOf(event.target.tagName) == -1 && !event.target.isContentEditable && !event.twEditor) { if(["TEXTAREA","INPUT"].indexOf(event.target.tagName) == -1 && !event.target.isContentEditable) {
var self = this, var self = this,
items = event.clipboardData.items; items = event.clipboardData.items;
// Enumerate the clipboard items // Enumerate the clipboard items

View File

@@ -1,30 +0,0 @@
/*\
title: $:/core/modules/widgets/fill.js
type: application/javascript
module-type: widget
Sub-widget used by the transclude widget for specifying values for slots within transcluded content. It doesn't do anything by itself because the transclude widget only ever deals with the parse tree nodes, and doesn't instantiate the widget itself
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var FillWidget = function(parseTreeNode,options) {
// Initialise
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
FillWidget.prototype = new Widget();
exports.fill = FillWidget;
})();

View File

@@ -46,7 +46,6 @@ GenesisWidget.prototype.execute = function() {
this.genesisRemappable = this.getAttribute("$remappable","yes") === "yes"; this.genesisRemappable = this.getAttribute("$remappable","yes") === "yes";
this.genesisNames = this.getAttribute("$names",""); this.genesisNames = this.getAttribute("$names","");
this.genesisValues = this.getAttribute("$values",""); this.genesisValues = this.getAttribute("$values","");
this.genesisIsBlock = this.getAttribute("$mode",this.parseTreeNode.isBlock && "block") === "block";
// Do not create a child widget if the $type attribute is missing or blank // Do not create a child widget if the $type attribute is missing or blank
if(!this.genesisType) { if(!this.genesisType) {
this.makeChildWidgets(this.parseTreeNode.children); this.makeChildWidgets(this.parseTreeNode.children);
@@ -61,7 +60,6 @@ GenesisWidget.prototype.execute = function() {
tag: nodeTag, tag: nodeTag,
attributes: {}, attributes: {},
orderedAttributes: [], orderedAttributes: [],
isBlock: this.genesisIsBlock,
children: this.parseTreeNode.children || [], children: this.parseTreeNode.children || [],
isNotRemappable: !this.genesisRemappable isNotRemappable: !this.genesisRemappable
}]; }];

View File

@@ -52,44 +52,38 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true}); var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true});
if(parser) { if(parser) {
var parseTreeNode = parser.tree[0]; var parseTreeNode = parser.tree[0];
while(parseTreeNode && ["setvariable","set","parameters"].indexOf(parseTreeNode.type) !== -1) { while(parseTreeNode && parseTreeNode.type === "set") {
var node = { var node = {
type: "set", type: "set",
attributes: parseTreeNode.attributes, attributes: parseTreeNode.attributes,
params: parseTreeNode.params, params: parseTreeNode.params,
isMacroDefinition: parseTreeNode.isMacroDefinition, isMacroDefinition: parseTreeNode.isMacroDefinition
isFunctionDefinition: parseTreeNode.isFunctionDefinition,
isProcedureDefinition: parseTreeNode.isProcedureDefinition,
isWidgetDefinition: parseTreeNode.isWidgetDefinition,
configTrimWhiteSpace: parseTreeNode.configTrimWhiteSpace
}; };
if(parseTreeNode.type === "set" || parseTreeNode.type === "setvariable") { if (parseTreeNode.isMacroDefinition) {
if(parseTreeNode.isMacroDefinition || parseTreeNode.isProcedureDefinition || parseTreeNode.isWidgetDefinition || parseTreeNode.isFunctionDefinition) { // Macro definitions can be folded into
// Macro definitions can be folded into // current widget instead of adding
// current widget instead of adding // another link to the chain.
// another link to the chain. var widget = widgetPointer.makeChildWidget(node);
var widget = widgetPointer.makeChildWidget(node); widget.computeAttributes();
widget.computeAttributes(); widget.execute();
widget.execute(); // We SHALLOW copy over all variables
// We SHALLOW copy over all variables // in widget. We can't use
// in widget. We can't use // $tw.utils.assign, because that copies
// $tw.utils.assign, because that copies // up the prototype chain, which we
// up the prototype chain, which we // don't want.
// don't want. $tw.utils.each(Object.keys(widget.variables), function(key) {
$tw.utils.each(Object.keys(widget.variables), function(key) { widgetPointer.variables[key] = widget.variables[key];
widgetPointer.variables[key] = widget.variables[key]; });
}); } else {
} else { widgetPointer.children = [widgetPointer.makeChildWidget(node)];
widgetPointer.children = [widgetPointer.makeChildWidget(node)]; // No more regenerating children for
// No more regenerating children for // this widget. If it needs to refresh,
// this widget. If it needs to refresh, // it'll do so along with the the whole
// it'll do so along with the the whole // importvariable tree.
// importvariable tree. if (widgetPointer != this) {
if (widgetPointer != this) { widgetPointer.makeChildWidgets = function(){};
widgetPointer.makeChildWidgets = function(){};
}
widgetPointer = widgetPointer.children[0];
} }
widgetPointer = widgetPointer.children[0];
} }
parseTreeNode = parseTreeNode.children && parseTreeNode.children[0]; parseTreeNode = parseTreeNode.children && parseTreeNode.children[0];
} }

View File

@@ -53,9 +53,7 @@ LetWidget.prototype.computeAttributes = function() {
name = attribute.name; name = attribute.name;
// Now that it's prepped, we're allowed to look this variable up // Now that it's prepped, we're allowed to look this variable up
// when defining later variables // when defining later variables
if(value !== undefined) { self.currentValueFor[name] = value;
self.currentValueFor[name] = value;
}
}); });
// Run through again, setting variables and looking for differences // Run through again, setting variables and looking for differences
$tw.utils.each(this.currentValueFor,function(value,name) { $tw.utils.each(this.currentValueFor,function(value,name) {

View File

@@ -37,7 +37,7 @@ MacroCallWidget.prototype.render = function(parent,nextSibling) {
Compute the internal state of the widget Compute the internal state of the widget
*/ */
MacroCallWidget.prototype.execute = function() { MacroCallWidget.prototype.execute = function() {
this.macroName = this.parseTreeNode.name || this.getAttribute("$name"), // Get the parse type if specified
this.parseType = this.getAttribute("$type","text/vnd.tiddlywiki"); this.parseType = this.getAttribute("$type","text/vnd.tiddlywiki");
this.renderOutput = this.getAttribute("$output","text/html"); this.renderOutput = this.getAttribute("$output","text/html");
// Merge together the parameters specified in the parse tree with the specified attributes // Merge together the parameters specified in the parse tree with the specified attributes
@@ -47,26 +47,49 @@ MacroCallWidget.prototype.execute = function() {
params.push({name: name, value: attribute}); params.push({name: name, value: attribute});
} }
}); });
// Make a transclude widget // Get the macro value
var positionalName = 0, var macroName = this.parseTreeNode.name || this.getAttribute("$name"),
parseTreeNodes = [{ variableInfo = this.getVariableInfo(macroName,{params: params}),
type: "transclude", text = variableInfo.text,
isBlock: this.parseTreeNode.isBlock parseTreeNodes;
}]; // Are we rendering to HTML?
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$variable",this.macroName); if(this.renderOutput === "text/html") {
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$type",this.parseType); // If so we'll return the parsed macro
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$output",this.renderOutput); // Check if we've already cached parsing this macro
$tw.utils.each(params,function(param) { var mode = this.parseTreeNode.isBlock ? "blockParser" : "inlineParser",
var name = param.name; parser;
if(name) { if(variableInfo.srcVariable && variableInfo.srcVariable[mode]) {
if(name.charAt(0) === "$") { parser = variableInfo.srcVariable[mode];
name = "$" + name;
}
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],name,param.value);
} else { } else {
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],(positionalName++) + "",param.value); 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
};
});
parseTreeNodes = [{
type: "vars",
attributes: attributes,
children: parseTreeNodes
}];
} 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}];
}
// Construct the child widgets // Construct the child widgets
this.makeChildWidgets(parseTreeNodes); this.makeChildWidgets(parseTreeNodes);
}; };

View File

@@ -499,8 +499,7 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
// Get the tiddlers // Get the tiddlers
var tiddlers = $tw.utils.parseJSONSafe(event.param,[]); var tiddlers = $tw.utils.parseJSONSafe(event.param,[]);
// Get the current $:/Import tiddler // Get the current $:/Import tiddler
var paramObject = event.paramObject || {}, var importTitle = event.importTitle ? event.importTitle : IMPORT_TITLE,
importTitle = event.importTitle || paramObject.importTitle || IMPORT_TITLE,
importTiddler = this.wiki.getTiddler(importTitle), importTiddler = this.wiki.getTiddler(importTitle),
importData = this.wiki.getTiddlerData(importTitle,{}), importData = this.wiki.getTiddlerData(importTitle,{}),
newFields = new Object({ newFields = new Object({
@@ -541,7 +540,7 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
newFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces); newFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces);
this.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields)); this.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields));
// Update the story and history details // Update the story and history details
var autoOpenOnImport = event.autoOpenOnImport || paramObject.autoOpenOnImport || this.getVariable("tv-auto-open-on-import"); var autoOpenOnImport = event.autoOpenOnImport ? event.autoOpenOnImport : this.getVariable("tv-auto-open-on-import");
if(autoOpenOnImport !== "no") { if(autoOpenOnImport !== "no") {
var storyList = this.getStoryList(), var storyList = this.getStoryList(),
history = []; history = [];

View File

@@ -1,96 +0,0 @@
/*\
title: $:/core/modules/widgets/parameters.js
type: application/javascript
module-type: widget
Widget for definition of transclusion parameters
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget,
TranscludeWidget = require("$:/core/modules/widgets/transclude.js").transclude;
var ParametersWidget = function(parseTreeNode,options) {
// Initialise
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
ParametersWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
ParametersWidget.prototype.render = function(parent,nextSibling) {
// Call the constructor
Widget.call(this);
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
this.renderChildren(parent,nextSibling);
};
/*
Compute the internal state of the widget
*/
ParametersWidget.prototype.execute = function() {
var self = this;
this.parametersDepth = Math.max(parseInt(this.getAttribute("$depth","1"),10) || 1,1);
// Find the parent transclusions
var pointer = this.parentWidget,
depth = this.parametersDepth;
while(pointer) {
if(pointer instanceof TranscludeWidget) {
depth--;
if(depth <= 0) {
break;
}
}
pointer = pointer.parentWidget;
}
// Process each parameter
if(pointer instanceof TranscludeWidget) {
// Get the value for each defined parameter
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(self.parseTreeNode),function(attr,index) {
var name = attr.name;
// If the attribute name starts with $$ then reduce to a single dollar
if(name.substr(0,2) === "$$") {
name = name.substr(1);
}
var value = pointer.getTransclusionParameter(name,index,self.getAttribute(attr.name,""));
self.setVariable(name,value);
});
// Assign any metaparameters
$tw.utils.each(pointer.getTransclusionMetaParameters(),function(getValue,name) {
var variableName = self.getAttribute("$" + name);
if(variableName) {
self.setVariable(variableName,getValue(name));
}
});
}
// Construct the child widgets
this.makeChildWidgets();
};
/*
Refresh the widget by ensuring our attributes are up to date
*/
ParametersWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(Object.keys(changedAttributes).length) {
this.refreshSelf();
return true;
}
return this.refreshChildren(changedTiddlers);
};
exports.parameters = ParametersWidget;
})();

View File

@@ -48,17 +48,7 @@ SetWidget.prototype.execute = function() {
this.setValue = this.getAttribute("value"); this.setValue = this.getAttribute("value");
this.setEmptyValue = this.getAttribute("emptyValue"); this.setEmptyValue = this.getAttribute("emptyValue");
// Set context variable // Set context variable
if(this.parseTreeNode.isMacroDefinition) { this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,!!this.parseTreeNode.isMacroDefinition);
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,true);
} else if(this.parseTreeNode.isFunctionDefinition) {
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isFunctionDefinition: true});
} else if(this.parseTreeNode.isProcedureDefinition) {
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isProcedureDefinition: true, configTrimWhiteSpace: this.parseTreeNode.configTrimWhiteSpace});
} else if(this.parseTreeNode.isWidgetDefinition) {
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isWidgetDefinition: true, configTrimWhiteSpace: this.parseTreeNode.configTrimWhiteSpace});
} else {
this.setVariable(this.setName,this.getValue());
}
// Construct the child widgets // Construct the child widgets
this.makeChildWidgets(); this.makeChildWidgets();
}; };

View File

@@ -1,82 +0,0 @@
/*\
title: $:/core/modules/widgets/slot.js
type: application/javascript
module-type: widget
Widget for definition of slots within transcluded content. The values provided by the translusion are passed to the slot.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget,
TranscludeWidget = require("$:/core/modules/widgets/transclude.js").transclude;
var SlotWidget = function(parseTreeNode,options) {
// Initialise
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
SlotWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
SlotWidget.prototype.render = function(parent,nextSibling) {
// Call the constructor
Widget.call(this);
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
this.renderChildren(parent,nextSibling);
};
/*
Compute the internal state of the widget
*/
SlotWidget.prototype.execute = function() {
var self = this;
this.slotName = this.getAttribute("$name");
this.slotDepth = parseInt(this.getAttribute("$depth","1"),10) || 1;
// Find the parent transclusions
var pointer = this.parentWidget,
depth = this.slotDepth;
while(pointer) {
if(pointer instanceof TranscludeWidget) {
depth--;
if(depth <= 0) {
break;
}
}
pointer = pointer.parentWidget;
}
var parseTreeNodes = [{type: "text", attributes: {text: {type: "string", value: "Missing slot reference!"}}}];
if(pointer instanceof TranscludeWidget) {
// Get the parse tree nodes comprising the slot contents
parseTreeNodes = pointer.getTransclusionSlotFill(this.slotName,this.parseTreeNode.children);
}
// Construct the child widgets
this.makeChildWidgets(parseTreeNodes);
};
/*
Refresh the widget by ensuring our attributes are up to date
*/
SlotWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes["$name"] || changedAttributes["$depth"]) {
this.refreshSelf();
return true;
}
return this.refreshChildren(changedTiddlers);
};
exports.slot = SlotWidget;
})();

View File

@@ -37,347 +37,46 @@ TranscludeWidget.prototype.render = function(parent,nextSibling) {
Compute the internal state of the widget Compute the internal state of the widget
*/ */
TranscludeWidget.prototype.execute = function() { TranscludeWidget.prototype.execute = function() {
// Get our attributes, string parameters, and slot values into properties of the widget object // Get our parameters
this.collectAttributes(); this.transcludeTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
this.collectStringParameters(); this.transcludeSubTiddler = this.getAttribute("subtiddler");
this.collectSlotFillParameters(); this.transcludeField = this.getAttribute("field");
// Get the parse tree nodes that we are transcluding this.transcludeIndex = this.getAttribute("index");
var target = this.getTransclusionTarget(), this.transcludeMode = this.getAttribute("mode");
parseTreeNodes = target.parseTreeNodes; this.recursionMarker = this.getAttribute("recursionMarker","yes");
this.sourceText = target.text; // Parse the text reference
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 the legacy transclusion context variables only if we're not transcluding a variable
if(!this.transcludeVariable) {
var recursionMarker = this.makeRecursionMarker();
this.setVariable("transclusion",recursionMarker);
}
// Construct the child widgets
this.makeChildWidgets(parseTreeNodes);
};
/*
Collect the attributes we need, in the process determining whether we're being used in legacy mode
*/
TranscludeWidget.prototype.collectAttributes = function() {
var self = this;
// Detect legacy mode
this.legacyMode = true;
$tw.utils.each(this.attributes,function(value,name) {
if(name.charAt(0) === "$") {
self.legacyMode = false;
}
});
// Get the attributes for the appropriate mode
if(this.legacyMode) {
this.transcludeTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
this.transcludeSubTiddler = this.getAttribute("subtiddler");
this.transcludeField = this.getAttribute("field");
this.transcludeIndex = this.getAttribute("index");
this.transcludeMode = this.getAttribute("mode");
this.recursionMarker = this.getAttribute("recursionMarker","yes");
} 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");
this.transcludeIndex = this.getAttribute("$index");
this.transcludeMode = this.getAttribute("$mode");
this.recursionMarker = this.getAttribute("$recursionMarker","yes");
}
};
/*
Collect string parameters
*/
TranscludeWidget.prototype.collectStringParameters = function() {
var self = this;
this.stringParametersByName = Object.create(null);
if(!this.legacyMode) {
$tw.utils.each(this.attributes,function(value,name) {
if(name.charAt(0) === "$") {
if(name.charAt(1) === "$") {
// Attributes starting $$ represent parameters starting with a single $
name = name.slice(1);
} else {
// Attributes starting with a single $ are reserved for the widget
return;
}
}
self.stringParametersByName[name] = value;
});
}
};
/*
Collect slot value parameters
*/
TranscludeWidget.prototype.collectSlotFillParameters = function() {
var self = this;
this.slotFillParseTrees = Object.create(null);
if(this.legacyMode) {
this.slotFillParseTrees["ts-missing"] = this.parseTreeNode.children;
} else {
this.slotFillParseTrees["ts-raw"] = this.parseTreeNode.children;
var noFillWidgetsFound = true,
searchParseTreeNodes = function(nodes) {
$tw.utils.each(nodes,function(node) {
if(node.type === "fill") {
if(node.attributes["$name"] && node.attributes["$name"].type === "string") {
var slotValueName = node.attributes["$name"].value;
self.slotFillParseTrees[slotValueName] = node.children || [];
}
noFillWidgetsFound = false;
} else {
searchParseTreeNodes(node.children);
}
});
};
searchParseTreeNodes(this.parseTreeNode.children);
if(noFillWidgetsFound) {
this.slotFillParseTrees["ts-missing"] = this.parseTreeNode.children;
}
}
};
/*
Get transcluded parse tree nodes as an object {parser:,text:,type:}
*/
TranscludeWidget.prototype.getTransclusionTarget = function() {
var self = this;
// Determine whether we're being used in inline or block mode
var parseAsInline = !this.parseTreeNode.isBlock; var parseAsInline = !this.parseTreeNode.isBlock;
if(this.transcludeMode === "inline") { if(this.transcludeMode === "inline") {
parseAsInline = true; parseAsInline = true;
} else if(this.transcludeMode === "block") { } else if(this.transcludeMode === "block") {
parseAsInline = false; parseAsInline = false;
} }
var parser; var parser = this.wiki.parseTextReference(
// Get the parse tree
if(this.transcludeVariable) {
// Transcluding a variable
var variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()}),
srcVariable = variableInfo && variableInfo.srcVariable;
if(srcVariable) {
if(srcVariable.isFunctionDefinition) {
// Function to return parameters by name or position
var fnGetParam = function(name,index) {
// Parameter names starting with dollar must be escaped to double dollars
if(name.charAt(0) === "$") {
name = "$" + name;
}
// Look for the parameter by name
if(self.hasAttribute(name)) {
return self.getAttribute(name);
// Look for the parameter by index
} else if(self.hasAttribute(index + "")) {
return self.getAttribute(index + "");
} else {
return undefined;
}
},
result = this.evaluateVariable(this.transcludeVariable,{params: fnGetParam})[0] || "";
parser = {
tree: [{
type: "text",
text: result
}],
source: result,
type: "text/vnd.tiddlywiki"
};
if(parseAsInline) {
parser.tree[0] = {
type: "text",
text: result
};
} else {
parser.tree[0] = {
type: "element",
tag: "p",
children: [{
type: "text",
text: result
}]
}
}
} else {
var cacheKey = (parseAsInline ? "inlineParser" : "blockParser") + (this.transcludeType || "");
if(variableInfo.isCacheable && srcVariable[cacheKey]) {
parser = srcVariable[cacheKey];
} else {
parser = this.wiki.parseText(this.transcludeType,variableInfo.text || "",{parseAsInline: parseAsInline, configTrimWhiteSpace: srcVariable.configTrimWhiteSpace});
if(variableInfo.isCacheable) {
srcVariable[cacheKey] = parser;
}
}
}
if(parser) {
// Add parameters widget for procedures and custom widgets
if(srcVariable.isProcedureDefinition || srcVariable.isWidgetDefinition) {
parser = {
tree: [
{
type: "parameters",
children: parser.tree
}
],
source: parser.source,
type: parser.type
}
$tw.utils.each(srcVariable.params,function(param) {
var name = param.name;
// Parameter names starting with dollar must be escaped to double dollars
if(name.charAt(0) === "$") {
name = "$" + name;
}
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],name,param["default"])
});
} else {
// For macros and ordinary variables, 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)
});
}
}
}
} else {
// Transcluding a text reference
parser = this.wiki.parseTextReference(
this.transcludeTitle, this.transcludeTitle,
this.transcludeField, this.transcludeField,
this.transcludeIndex, this.transcludeIndex,
{ {
parseAsInline: parseAsInline, parseAsInline: parseAsInline,
subTiddler: this.transcludeSubTiddler, subTiddler: this.transcludeSubTiddler
defaultType: this.transcludeType }),
}); parseTreeNodes = parser ? parser.tree : this.parseTreeNode.children;
this.sourceText = parser ? parser.source : null;
this.parserType = parser? parser.type : null;
// Set context variables for recursion detection
var recursionMarker = this.makeRecursionMarker();
if(this.recursionMarker === "yes") {
this.setVariable("transclusion",recursionMarker);
} }
// Return the parse tree // Check for recursion
if(parser) { if(parser) {
return { if(this.parentWidget && this.parentWidget.hasVariable("transclusion",recursionMarker)) {
parser: parser, parseTreeNodes = [{type: "error", attributes: {
parseTreeNodes: parser.tree, "$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")}
parseAsInline: parseAsInline, }}];
text: parser.source,
type: parser.type
};
} else {
// If there's no parse tree then return the missing slot value
return {
parser: null,
parseTreeNodes: (this.slotFillParseTrees["ts-missing"] || []),
parseAsInline: parseAsInline,
text: null,
type: null
};
}
};
/*
Fetch all the string parameters as an ordered array of {name:, value:} where the name is optional
*/
TranscludeWidget.prototype.getOrderedTransclusionParameters = function() {
var result = [];
// Collect the parameters
for(var name in this.stringParametersByName) {
var value = this.stringParametersByName[name];
result.push({name: name, value: value});
}
// Sort numerical parameter names first
result.sort(function(a,b) {
var aIsNumeric = !isNaN(a.name),
bIsNumeric = !isNaN(b.name);
if(aIsNumeric && bIsNumeric) {
return a.name - b.name;
} else if(aIsNumeric) {
return -1;
} else if(bIsNumeric) {
return 1;
} else {
return a.name === b.name ? 0 : (a.name < b.name ? -1 : 1);
}
});
// Remove names from numerical parameters
$tw.utils.each(result,function(param,index) {
if(!isNaN(param.name)) {
delete param.name;
}
});
return result;
};
/*
Fetch the value of a parameter
*/
TranscludeWidget.prototype.getTransclusionParameter = function(name,index,defaultValue) {
if(name in this.stringParametersByName) {
return this.stringParametersByName[name];
} else {
var name = "" + index;
if(name in this.stringParametersByName) {
return this.stringParametersByName[name];
} }
} }
return defaultValue; // Construct the child widgets
}; this.makeChildWidgets(parseTreeNodes);
/*
Get one of the special parameters to be provided by the parameters widget
*/
TranscludeWidget.prototype.getTransclusionMetaParameters = function() {
var self = this;
return {
"parseMode": function() {
return self.parseAsInline ? "inline" : "block";
},
"parseTreeNodes": function() {
return JSON.stringify(self.parseTreeNode.children || []);
},
"slotFillParseTreeNodes": function() {
return JSON.stringify(self.slotFillParseTrees);
},
"params": function() {
return JSON.stringify(self.stringParametersByName);
}
};
};
/*
Fetch the value of a slot
*/
TranscludeWidget.prototype.getTransclusionSlotFill = function(name,defaultParseTreeNodes) {
if(name && this.slotFillParseTrees[name] && this.slotFillParseTrees[name].length > 0) {
return this.slotFillParseTrees[name];
} else {
return defaultParseTreeNodes || [];
}
}; };
/* /*
@@ -400,7 +99,6 @@ TranscludeWidget.prototype.makeRecursionMarker = function() {
}; };
TranscludeWidget.prototype.parserNeedsRefresh = function() { TranscludeWidget.prototype.parserNeedsRefresh = function() {
// 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}); 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) return (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType)
}; };
@@ -410,7 +108,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/ */
TranscludeWidget.prototype.refresh = function(changedTiddlers) { TranscludeWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes(); var changedAttributes = this.computeAttributes();
if(($tw.utils.count(changedAttributes) > 0) || (!this.transcludeVariable && changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) { if(($tw.utils.count(changedAttributes) > 0) || (changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) {
this.refreshSelf(); this.refreshSelf();
return true; return true;
} else { } else {

View File

@@ -41,7 +41,10 @@ Widget.prototype.initialise = function(parseTreeNode,options) {
this.parseTreeNode = parseTreeNode; this.parseTreeNode = parseTreeNode;
this.wiki = options.wiki; this.wiki = options.wiki;
this.parentWidget = options.parentWidget; this.parentWidget = options.parentWidget;
this.variables = Object.create(this.parentWidget ? this.parentWidget.variables : null); this.variables = Object.create(null);
if(this.parentWidget) {
Object.setPrototypeOf(this.variables,this.parentWidget.variables);
}
this.document = options.document; this.document = options.document;
this.attributes = {}; this.attributes = {};
this.children = []; this.children = [];
@@ -89,22 +92,9 @@ name: name of the variable
value: value of the variable value: value of the variable
params: array of {name:, default:} for each parameter params: array of {name:, default:} for each parameter
isMacroDefinition: true if the variable is set via a \define macro pragma (and hence should have variable substitution performed) isMacroDefinition: true if the variable is set via a \define macro pragma (and hence should have variable substitution performed)
options includes:
isProcedureDefinition: true if the variable is set via a \procedure pragma (and hence should not have variable substitution performed)
isFunctionDefinition: true if the variable is set via a \function pragma (and hence should not have variable substitution performed)
isWidgetDefinition: true if the variable is set via a \widget pragma (and hence should not have variable substitution performed)
*/ */
Widget.prototype.setVariable = function(name,value,params,isMacroDefinition,options) { Widget.prototype.setVariable = function(name,value,params,isMacroDefinition) {
options = options || {}; this.variables[name] = {value: value, params: params, isMacroDefinition: !!isMacroDefinition};
this.variables[name] = {
value: value,
params: params,
isMacroDefinition: !!isMacroDefinition,
isFunctionDefinition: !!options.isFunctionDefinition,
isProcedureDefinition: !!options.isProcedureDefinition,
isWidgetDefinition: !!options.isWidgetDefinition,
configTrimWhiteSpace: !!options.configTrimWhiteSpace
};
}; };
/* /*
@@ -114,7 +104,6 @@ options: see below
Options include Options include
params: array of {name:, value:} for each parameter params: array of {name:, value:} for each parameter
defaultValue: default value if the variable is not defined defaultValue: default value if the variable is not defined
allowSelfAssigned: if true, includes the current widget in the context chain instead of just the parent
Returns an object with the following fields: Returns an object with the following fields:
@@ -123,27 +112,21 @@ text: text of variable, with parameters properly substituted
*/ */
Widget.prototype.getVariableInfo = function(name,options) { Widget.prototype.getVariableInfo = function(name,options) {
options = options || {}; options = options || {};
var self = this, var actualParams = options.params || [],
actualParams = options.params || [], parentWidget = this.parentWidget;
variable;
if(options.allowSelfAssigned) {
variable = this.variables[name];
} else {
variable = this.parentWidget && this.parentWidget.variables[name];
}
// Check for the variable defined in the parent widget (or an ancestor in the prototype chain) // Check for the variable defined in the parent widget (or an ancestor in the prototype chain)
if(variable) { if(parentWidget && name in parentWidget.variables) {
var originalValue = variable.value, var variable = parentWidget.variables[name],
originalValue = variable.value,
value = originalValue, value = originalValue,
params = []; params = this.resolveVariableParameters(variable.params,actualParams);
// Only substitute parameter and variable references if this variable was defined with the \define pragma // Substitute any parameters specified in the definition
$tw.utils.each(params,function(param) {
value = $tw.utils.replaceString(value,new RegExp("\\$" + $tw.utils.escapeRegExp(param.name) + "\\$","mg"),param.value);
});
// Only substitute variable references if this variable was defined with the \define pragma
if(variable.isMacroDefinition) { if(variable.isMacroDefinition) {
params = self.resolveVariableParameters(variable.params,actualParams); value = this.substituteVariableReferences(value,options);
// Substitute any parameters specified in the definition
$tw.utils.each(params,function(param) {
value = $tw.utils.replaceString(value,new RegExp("\\$" + $tw.utils.escapeRegExp(param.name) + "\\$","mg"),param.value);
});
value = self.substituteVariableReferences(value,options);
} }
return { return {
text: value, text: value,
@@ -153,13 +136,8 @@ Widget.prototype.getVariableInfo = function(name,options) {
}; };
} }
// If the variable doesn't exist in the parent widget then look for a macro module // If the variable doesn't exist in the parent widget then look for a macro module
var text = this.evaluateMacroModule(name,actualParams);
if(text === undefined) {
text = options.defaultValue;
}
return { return {
text: text, text: this.evaluateMacroModule(name,actualParams,options.defaultValue)
srcVariable: {}
}; };
}; };
@@ -170,11 +148,6 @@ Widget.prototype.getVariable = function(name,options) {
return this.getVariableInfo(name,options).text; return this.getVariableInfo(name,options).text;
}; };
/*
Maps actual parameters onto formal parameters, returning an array of {name:,value:} objects
formalParams - Array of {name:,default:} (default value is optional)
actualParams - Array of string values or {name:,value:} (name is optional)
*/
Widget.prototype.resolveVariableParameters = function(formalParams,actualParams) { Widget.prototype.resolveVariableParameters = function(formalParams,actualParams) {
formalParams = formalParams || []; formalParams = formalParams || [];
actualParams = actualParams || []; actualParams = actualParams || [];
@@ -187,7 +160,7 @@ Widget.prototype.resolveVariableParameters = function(formalParams,actualParams)
paramInfo = formalParams[p]; paramInfo = formalParams[p];
paramValue = undefined; paramValue = undefined;
for(var m=0; m<actualParams.length; m++) { for(var m=0; m<actualParams.length; m++) {
if(typeof actualParams[m] !== "string" && actualParams[m].name === paramInfo.name) { if(actualParams[m].name === paramInfo.name) {
paramValue = actualParams[m].value; paramValue = actualParams[m].value;
} }
} }
@@ -196,8 +169,7 @@ Widget.prototype.resolveVariableParameters = function(formalParams,actualParams)
nextAnonParameter++; nextAnonParameter++;
} }
if(paramValue === undefined && nextAnonParameter < actualParams.length) { if(paramValue === undefined && nextAnonParameter < actualParams.length) {
var param = actualParams[nextAnonParameter++]; paramValue = actualParams[nextAnonParameter++].value;
paramValue = typeof param === "string" ? param : param.value;
} }
// If we've still not got a value, use the default, if any // If we've still not got a value, use the default, if any
paramValue = paramValue || paramInfo["default"] || ""; paramValue = paramValue || paramInfo["default"] || "";
@@ -291,103 +263,12 @@ Widget.prototype.getStateQualifier = function(name) {
}; };
/* /*
Make a fake widget with specified variables, suitable for variable lookup in filters Compute the current values of the attributes of the widget. Returns a hashmap of the names of the attributes that have changed
*/ */
Widget.prototype.makeFakeWidgetWithVariables = function(variables) { Widget.prototype.computeAttributes = function() {
var self = this;
return {
getVariable: function(name,opts) {
if($tw.utils.hop(variables,name)) {
return variables[name];
} else {
opts = opts || {};
opts.variables = variables;
return self.getVariable(name,opts);
};
},
getVariableInfo: function(name,opts) {
if($tw.utils.hop(variables,name)) {
return {
text: variables[name]
};
} else {
opts = opts || {};
opts.variables = variables;
return self.getVariableInfo(name,opts);
};
},
makeFakeWidgetWithVariables: self.makeFakeWidgetWithVariables,
evaluateVariable: self.evaluateVariable,
resolveVariableParameters: self.resolveVariableParameters,
wiki: self.wiki
};
};
/*
Evaluate a variable and associated actual parameters and result the resulting array.
The way that the variable is evaluated depends upon its type:
* Functions are evaluated as parameterised filter strings
* Macros are returned as plain text with substitution of parameters
* Procedures and widgets are returned as plain text
Options are:
params - the actual parameters may be one of:
* an array of values that may be an anonymous string value, or a {name:, value:} pair
* a hashmap of {name: value} pairs
* a function invoked with parameters (name,index) that returns a parameter value by name or position
source - iterator for source tiddlers
*/
Widget.prototype.evaluateVariable = function(name,options) {
options = options || {};
var params = options.params || [];
// Get the details of the variable (includes processing text substitution for macros
var variableInfo = this.getVariableInfo(name,{params: params,defaultValue: ""});
// Process function parameters
var variables = Object.create(null);
if(variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
// Apply default parameter values
$tw.utils.each(variableInfo.srcVariable.params,function(param,index) {
if(param["default"]) {
variables[param.name] = param["default"];
}
});
if($tw.utils.isArray(params)) {
// Parameters are an array of values or {name:, value:} pairs
$tw.utils.each(this.resolveVariableParameters(variableInfo.srcVariable.params,params),function(param) {
variables[param.name] = param.value;
});
} else if(typeof params === "function") {
// Parameters are passed via a function
$tw.utils.each(variableInfo.srcVariable.params,function(param,index) {
variables[param.name] = params(param.name,index) || param["default"] || "";
});
} else {
// Parameters are a hashmap
$tw.utils.each(params,function(value,name) {
variables[name] = value;
});
}
return this.wiki.filterTiddlers(variableInfo.text,this.makeFakeWidgetWithVariables(variables),options.source);
} else {
return [variableInfo.text];
}
};
/*
Compute the current values of the attributes of the widget. Returns a hashmap of the names of the attributes that have changed.
Options include:
filterFn: only include attributes where filterFn(name) returns true
*/
Widget.prototype.computeAttributes = function(options) {
options = options || {};
var changedAttributes = {}, var changedAttributes = {},
self = this; self = this;
$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) { $tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {
if(options.filterFn) {
if(!options.filterFn(name)) {
return;
}
}
var value = self.computeAttribute(attribute); var value = self.computeAttribute(attribute);
if(self.attributes[name] !== value) { if(self.attributes[name] !== value) {
self.attributes[name] = value; self.attributes[name] = value;
@@ -398,21 +279,13 @@ Widget.prototype.computeAttributes = function(options) {
}; };
Widget.prototype.computeAttribute = function(attribute) { Widget.prototype.computeAttribute = function(attribute) {
var self = this, var value;
value;
if(attribute.type === "filtered") { if(attribute.type === "filtered") {
value = this.wiki.filterTiddlers(attribute.filter,this)[0] || ""; value = this.wiki.filterTiddlers(attribute.filter,this)[0] || "";
} else if(attribute.type === "indirect") { } else if(attribute.type === "indirect") {
value = this.wiki.getTextReference(attribute.textReference,"",this.getVariable("currentTiddler")); value = this.wiki.getTextReference(attribute.textReference,"",this.getVariable("currentTiddler"));
} else if(attribute.type === "macro") { } else if(attribute.type === "macro") {
var variableInfo = this.getVariableInfo(attribute.value.name,{params: attribute.value.params}); value = this.getVariable(attribute.value.name,{params: attribute.value.params});
if(variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
// It is a function definition. Go through each of the defined parameters, and make a variable with the value of the corresponding provided parameter
var paramArray = this.resolveVariableParameters(variableInfo.srcVariable.params,attribute.value.params);
value = this.evaluateVariable(attribute.value.name,{params: paramArray})[0] || "";
} else {
value = variableInfo.text;
}
} else { // String attribute } else { // String attribute
value = attribute.value; value = attribute.value;
} }
@@ -540,34 +413,7 @@ options include:
variables: optional hashmap of variables to wrap around the widget variables: optional hashmap of variables to wrap around the widget
*/ */
Widget.prototype.makeChildWidget = function(parseTreeNode,options) { Widget.prototype.makeChildWidget = function(parseTreeNode,options) {
var self = this;
options = options || {}; options = options || {};
// Check whether this node type is defined by a custom widget definition
var variableDefinitionName = "$" + parseTreeNode.type;
if(this.variables[variableDefinitionName]) {
var isOverrideable = function() {
// Widget is overrideable if it has a double dollar user defined name, or if it is an existing JS widget and we're not in safe mode
return parseTreeNode.type.charAt(0) === "$" || (!!self.widgetClasses[parseTreeNode.type] && !$tw.safeMode);
};
if(!parseTreeNode.isNotRemappable && isOverrideable()) {
var variableInfo = this.getVariableInfo(variableDefinitionName,{allowSelfAssigned: true});
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.value && variableInfo.srcVariable.isWidgetDefinition) {
var newParseTreeNode = {
type: "transclude",
children: parseTreeNode.children,
isBlock: parseTreeNode.isBlock
};
$tw.utils.addAttributeToParseTreeNode(newParseTreeNode,"$variable",variableDefinitionName);
$tw.utils.each(parseTreeNode.attributes,function(attr,name) {
// If the attribute starts with a dollar then add an extra dollar so that it doesn't clash with the $xxx attributes of transclude
name = name.charAt(0) === "$" ? "$" + name : name;
$tw.utils.addAttributeToParseTreeNode(newParseTreeNode,$tw.utils.extend({},attr,{name: name}));
});
parseTreeNode = newParseTreeNode;
}
}
}
// Get the widget class for this node type
var WidgetClass = this.widgetClasses[parseTreeNode.type]; var WidgetClass = this.widgetClasses[parseTreeNode.type];
if(!WidgetClass) { if(!WidgetClass) {
WidgetClass = this.widgetClasses.text; WidgetClass = this.widgetClasses.text;

View File

@@ -988,8 +988,7 @@ exports.parseText = function(type,text,options) {
return new Parser(type,text,{ return new Parser(type,text,{
parseAsInline: options.parseAsInline, parseAsInline: options.parseAsInline,
wiki: this, wiki: this,
_canonical_uri: options._canonical_uri, _canonical_uri: options._canonical_uri
configTrimWhiteSpace: options.configTrimWhiteSpace
}); });
}; };
@@ -1029,11 +1028,10 @@ exports.parseTextReference = function(title,field,index,options) {
}; };
exports.getTextReferenceParserInfo = function(title,field,index,options) { exports.getTextReferenceParserInfo = function(title,field,index,options) {
var defaultType = options.defaultType || "text/vnd.tiddlywiki", var tiddler,
tiddler,
parserInfo = { parserInfo = {
sourceText : null, sourceText : null,
parserType : defaultType parserType : "text/vnd.tiddlywiki"
}; };
if(options.subTiddler) { if(options.subTiddler) {
tiddler = this.getSubTiddler(title,options.subTiddler); tiddler = this.getSubTiddler(title,options.subTiddler);
@@ -1079,20 +1077,19 @@ exports.makeWidget = function(parser,options) {
children: [] children: []
}, },
currWidgetNode = widgetNode; currWidgetNode = widgetNode;
// Create let variable widget for variables // Create set variable widgets for each variable
if($tw.utils.count(options.variables) > 0) { $tw.utils.each(options.variables,function(value,name) {
var letVariableWidget = { var setVariableWidget = {
type: "let", type: "set",
attributes: { attributes: {
name: {type: "string", value: name},
value: {type: "string", value: value}
}, },
children: [] children: []
}; };
$tw.utils.each(options.variables,function(value,name) { currWidgetNode.children = [setVariableWidget];
$tw.utils.addAttributeToParseTreeNode(letVariableWidget,name,"" + value); currWidgetNode = setVariableWidget;
}); });
currWidgetNode.children = [letVariableWidget];
currWidgetNode = letVariableWidget;
}
// Add in the supplied parse tree nodes // Add in the supplied parse tree nodes
currWidgetNode.children = parser ? parser.tree : []; currWidgetNode.children = parser ? parser.tree : [];
// Create the widget // Create the widget

View File

@@ -14,7 +14,6 @@ extension: .html
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="generator" content="TiddlyWiki" /> <meta name="generator" content="TiddlyWiki" />
<meta name="tiddlywiki-version" content="{{$:/core/templates/version}}" /> <meta name="tiddlywiki-version" content="{{$:/core/templates/version}}" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<link id="faviconLink" rel="shortcut icon" href="favicon.ico"> <link id="faviconLink" rel="shortcut icon" href="favicon.ico">
<title>{{$:/core/wiki/title}}</title> <title>{{$:/core/wiki/title}}</title>

View File

@@ -1,48 +0,0 @@
title: $:/core/ui/VisibleTransclude
<!--
Import this component to make all the child transclusions visible.
Block transclusions are shown in red, and inline transclusions are shown in green.
-->
\widget $transclude()
<!-- Use a parameters widget so that we can access the `$params` data -->
<$parameters tiddler="" $$tiddler="" mode="" $$mode="" $parseMode="@parseMode" $params="@params">
<!-- Replicate the logic of the transclude widget to determine the output mode, and hence the tag and colour to use for output -->
<$let
mode={{{ [[$mode]is[variable]then<$mode>!is[blank]] :else[[mode]is[variable]then<mode>!is[blank]] :else[<@parseMode>] }}}
outputTag={{{ [<mode>match[inline]then[span]else[div]] }}}
outputColour={{{ [<mode>match[inline]then[green]else[red]] }}}
>
<!-- Use divs or spans according to the mode -->
<$genesis $type=<<outputTag>> style="color:white;padding:4px;" style.background=<<outputColour>>>
<$genesis $type=<<outputTag>> style="display: inline-block;">
<div style="background:white;color:black;font-size: 12px;line-height:1.2;text-align:left;font-weight:normal;padding:4px;margin:4px;">
<!-- Render the parameters to the transclusion -->
<$list filter="[<@params>jsonindexes[]]" emptyMessage="(none)">
<div>
<$text text=<<currentTiddler>>/><$text text=": "/><$text text={{{ [<@params>jsonget<currentTiddler>] }}}/>
</div>
</$list>
</div>
</$genesis>
<$genesis $type=<<outputTag>> style="background:white;color:black;padding:4px;">
<!-- Look for a parameter starting with $ to determine if we are in legacy mode -->
<$list filter="[<@params>jsonindexes[]] :filter[<currentTiddler>prefix[$]] +[limit[1]]" variable="ignore" emptyMessage="""
<!-- Legacy mode: we render the transclusion without a dollar sign for recursionMarker and mode -->
<$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" recursionMarker="no" mode=<<mode>>>
<!-- Reach back up to the grandparent transclusion to get the correct slot value -->
<$slot $name="ts-raw" $depth="2"/>
</$genesis>
""">
<!-- Non-legacy mode: we use dollar signs for the recursionMarker and mode -->
<$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" $$recursionMarker="no" $$mode=<<mode>>>
<!-- Reach back up to the grandparent transclusion to get the correct slot fill value -->
<$slot $name="ts-raw" $depth="2"/>
</$genesis>
</$list>
</$genesis>
</$genesis>
</$let>
</$parameters>
\end

View File

@@ -46,7 +46,9 @@ title: $:/core/ui/EditTemplate
<$keyboard key="((cancel-edit-tiddler))" actions=<<cancel-delete-tiddler-actions "cancel">> tag="div"> <$keyboard key="((cancel-edit-tiddler))" actions=<<cancel-delete-tiddler-actions "cancel">> tag="div">
<$keyboard key="((save-tiddler))" actions=<<save-tiddler-actions>> tag="div"> <$keyboard key="((save-tiddler))" actions=<<save-tiddler-actions>> tag="div">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]" variable="listItem"> <$list filter="[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]" variable="listItem">
<$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]">
<$transclude tiddler=<<listItem>>/> <$transclude tiddler=<<listItem>>/>
</$set>
</$list> </$list>
</$keyboard> </$keyboard>
</$keyboard> </$keyboard>

View File

@@ -7,6 +7,6 @@ $:/config/EditToolbarButtons/Visibility/$(listItem)$
\whitespace trim \whitespace trim
<div class="tc-tiddler-title tc-tiddler-edit-title"> <div class="tc-tiddler-title tc-tiddler-edit-title">
<$view field="title"/> <$view field="title"/>
<span class="tc-tiddler-controls tc-titlebar"><$list filter="[all[shadows+tiddlers]tag[$:/tags/EditToolbar]!has[draft.of]]" variable="listItem"><$let tv-config-toolbar-class={{{ [enlist<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]] +[join[ ]]}}}><$reveal type="nomatch" state=<<config-title>> text="hide"><$transclude tiddler=<<listItem>>/></$reveal></$let></$list></span> <span class="tc-tiddler-controls tc-titlebar"><$list filter="[all[shadows+tiddlers]tag[$:/tags/EditToolbar]!has[draft.of]]" variable="listItem"><$reveal type="nomatch" state=<<config-title>> text="hide"><$transclude tiddler=<<listItem>>/></$reveal></$list></span>
<div style="clear: both;"></div> <div style="clear: both;"></div>
</div> </div>

View File

@@ -6,7 +6,7 @@ description: {{$:/language/Buttons/NewHere/Hint}}
\whitespace trim \whitespace trim
\define newHereActions() \define newHereActions()
\whitespace trim \whitespace trim
<$set name="tags" filter="[<currentTiddler>] [enlist{$:/config/NewTiddler/Tags}]"> <$set name="tags" filter="[<currentTiddler>] [{$:/config/NewTiddler/Tags}]">
<$action-sendmessage $message="tm-new-tiddler" tags=<<tags>>/> <$action-sendmessage $message="tm-new-tiddler" tags=<<tags>>/>
</$set> </$set>
\end \end

View File

@@ -1,6 +1,6 @@
title: $:/config/OfficialPluginLibrary title: $:/config/OfficialPluginLibrary
tags: $:/tags/PluginLibrary tags: $:/tags/PluginLibrary
url: https://tiddlywiki.com/library/v5.2.8/index.html url: https://tiddlywiki.com/library/v5.2.6/index.html
caption: {{$:/language/OfficialPluginLibrary}} caption: {{$:/language/OfficialPluginLibrary}}
{{$:/language/OfficialPluginLibrary/Hint}} {{$:/language/OfficialPluginLibrary/Hint}}

View File

@@ -60,4 +60,4 @@ code-body: yes
</div> </div>
</$let> </$let>
</$qualify> </$qualify>
\end \end

View File

@@ -1,11 +1,11 @@
created: 20140923173639039 created: 20140923173639039
creator: pmario creator: pmario
modified: 20230307080008193 modified: 20140924155046340
modifier: pmario modifier: pmario
title: TaskManagement title: TaskManagement
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
In dieser Edition sind folgende Task Management Varianten beschrieben: In dieser Edition sind folgende Task Management Varianten beschreiben:
<<list-links filter:"[tag[TaskManagement]]">> <<list-links filter:"[tag[TaskManagement]]">>

View File

@@ -2,7 +2,7 @@ color: #37d011
created: 20140923104300415 created: 20140923104300415
creator: pmario creator: pmario
icon: $:/core/images/done-button icon: $:/core/images/done-button
modified: 20230307080039831 modified: 20140923105208878
modifier: ChrisK modifier: ChrisK
tags: done tags: done
title: done title: done
@@ -12,5 +12,5 @@ Diese Tag wird verwendet um "Tasks" als erledigt zu markieren.
Siehe auch: Siehe auch:
* [[Task Management|TaskManagement]] .. Beispiel * [[Task Management]] .. Beispiel
* [[Tag Manager|$:/TagManager]] .. Zuweisung der Farben und Symbole * [[Tag Manager|$:/TagManager]] .. Zuweisung der Farben und Symbole

View File

@@ -1,6 +0,0 @@
created: 20230307080413903
modified: 20230307080417122
title: Importieren von Tiddlern
type: text/vnd.tiddlywiki
https://tiddlywiki.com/#Importing%20Tiddlers

View File

@@ -1,11 +1,11 @@
created: 20140918094051245 created: 20140918094051245
creator: pmario creator: pmario
modified: 20230307080301079 modified: 20140918094948642
modifier: pmario modifier: pmario
tags: Referenz tags: Referenz
title: Liste aller HowTo's title: Liste aller HowTo's
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
Hier finden Sie eine Auflistung aller ~HowTo's Hier finden Sie eine Auflistung aller HowTo's
<<list-links "[tag[howto]]">> <<list-links "[tag[howto]]">>

View File

@@ -1,6 +0,0 @@
created: 20230307081437974
modified: 20230307081439303
title: Tagging
type: text/vnd.tiddlywiki
https://tiddlywiki.com/#Tagging

View File

@@ -1,6 +0,0 @@
created: 20230307080103029
modified: 20230307080103029
title: $:/themes/tiddlywiki/vanilla/options/sidebarlayout
type: text/vnd.tiddlywiki
fluid-fixed

View File

@@ -1,7 +0,0 @@
created: 20230307081923415
modified: 20230307081953759
tags: Widgets
title: ListWidget
type: text/vnd.tiddlywiki
https://tiddlywiki.com/#ListWidget

View File

@@ -1,7 +0,0 @@
created: 20230307082002353
modified: 20230307082023207
tags: Widgets
title: TranscludeWidget
type: text/vnd.tiddlywiki
https://tiddlywiki.com/#TranscludeWidget

View File

@@ -1,7 +1,7 @@
caption: Bilder caption: Bilder
created: 20131205160221762 created: 20131205160221762
creator: pmario creator: pmario
modified: 20230307081713229 modified: 20140921170652909
modifier: pmario modifier: pmario
tags: WikiText tags: WikiText
title: Bilder in WikiText title: Bilder in WikiText
@@ -25,7 +25,7 @@ oder
Wenn die Bildquelle der Titel eines existierenden Tiddlers ist, dann wird dieser direkt angezeigt. Ansonsten wird die Quelle als URL angesehen und ein HTML `<img>` Element wird erzeugt. Das `src` Attribut wird auf die [[URL]] gesetzt. Wenn die Bildquelle der Titel eines existierenden Tiddlers ist, dann wird dieser direkt angezeigt. Ansonsten wird die Quelle als URL angesehen und ein HTML `<img>` Element wird erzeugt. Das `src` Attribut wird auf die [[URL]] gesetzt.
Ein Tooltip kann ebenfalls angegeben werden: Ein [[Tooltip]] kann ebenfalls angegeben werden:
``` ```
[img[Ich bin der Tooltip text|Motovun Jack.jpg]] [img[Ich bin der Tooltip text|Motovun Jack.jpg]]
@@ -33,7 +33,7 @@ Ein Tooltip kann ebenfalls angegeben werden:
[img width=100 [Ich bin der Tooltip text|Motovun Jack.jpg]] [img width=100 [Ich bin der Tooltip text|Motovun Jack.jpg]]
Attribute wie z.B: CSS Klassen oder die Höhe und Breite können ebenfalls angegeben werden. Attribute wie zB: CSS Klassen oder die Höhe und Breite können ebenfalls angegeben werden.
``` ```
[img width=64 [Motovun Jack.jpg]] [img width=64 [Motovun Jack.jpg]]

View File

@@ -1,7 +1,7 @@
caption: Makros caption: Makros
created: 20131205160746466 created: 20131205160746466
creator: pmario creator: pmario
modified: 20230307080132949 modified: 20140922124415476
modifier: ChrisK modifier: ChrisK
tags: WikiText tags: WikiText
title: Makros in WikiText title: Makros in WikiText
@@ -15,7 +15,7 @@ Hallo, Ich bin $name$ und lebe in $adresse$
Hallo, Ich bin $name$ und würde gerne mal wieder nach $adresse$ fahren:) Hallo, Ich bin $name$ und würde gerne mal wieder nach $adresse$ fahren:)
\end \end
!! Makros definieren !! Makros Definieren
!!! Für die Ungeduldigen !!! Für die Ungeduldigen
@@ -76,7 +76,7 @@ Für einzeilige Makros kann die `\end` Markierung entfallen!
* Makros können mit dem ImportVariablesWidget importiert werden. (Für geübte Anwender) * Makros können mit dem ImportVariablesWidget importiert werden. (Für geübte Anwender)
!! Makros verwenden !! Makros Verwenden
``` ```
<<meinErstesMakro>> <<meinErstesMakro>>

View File

@@ -1,7 +0,0 @@
created: 20230307081757660
modified: 20230307081814992
tags: WikiText
title: Transclusion in WikiText
type: text/vnd.tiddlywiki
https://tiddlywiki.com/#Transclusion%20in%20WikiText

View File

@@ -0,0 +1,5 @@
created: 20201222190149806
list: [[Release 5.1.23]]
modified: 20201222190149806
title: $:/StoryList
type: text/vnd.tiddlywiki

View File

@@ -1,72 +1,39 @@
caption: 5.2.6 caption: 5.2.6
created: 20230320184352916 created: 20230119221001957
modified: 20230320184352916 modified: 20230119221001957
released: 20230320184352916
tags: ReleaseNotes tags: ReleaseNotes
title: Release 5.2.6 title: Release 5.2.6
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
//[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/v5.2.5...v5.2.6]]// //[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/v5.2.5...master]]//
<<.banner-credits
credit:"""Congratulations to [[StS|https://talk.tiddlywiki.org/u/StS]] for their winning design for the banner for this release (here is the [[competition thread|https://talk.tiddlywiki.org/t/new-release-banner-competition-for-tiddlywiki-v5-2-6/6403/3]] and the [[voting thread|https://talk.tiddlywiki.org/t/vote-for-the-tiddlywiki-banner-v5-2-6/6469]]).
"""
url:"https://raw.githubusercontent.com/Jermolene/TiddlyWiki5/3a2831870b4418b8b01d155b057db5b7485562c1/editions/tw5.com/tiddlers/images/New%20Release%20Banner.png"
>>
! Major Improvements
!! Improved Markdown Plugin
* <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/pull/6528">> the [[Markdown Plugin]] to use the newer and better maintained [[markdown-it|https://github.com/markdown-it/markdown-it]] library. The previous Markdown plugin remains available as "markdown-legacy"
!! Better Handling of Loss of Network Connectivity with Client Server Configuration
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7169">> integration between the [[BrowserStorage Plugin]] and the client-server configuration to allow changes to be made while offline and then later resynchronised with the server
!! New Diff-Match-Patch Primitives
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7290">> three new operators exposing previously hidden features of the [[Diff-Match-Patch|https://neil.fraser.name/software/diff_match_patch]] library that is integrated with TiddlyWiki:
** new [[levenshtein Operator]] to calculate the similarity of two strings as the number of characters that need to be inserted, deleted or modified in order to turn one into the other
** new [[makepatches Operator]] and [[applypatches Operator]] that can be used to make and apply patches that represent the difference between two different texts. See the [[examples|makepatches and applypatches Operator (Examples)]]
! Translation Improvements ! Translation Improvements
Improvements to the following translations: Improvements to the following translations:
* Chinese * Chinese
* German
* Italian * Italian
* Polish
! Plugin Improvements ! Plugin Improvements
* <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/pull/6528">> the [[Markdown Plugin]] to use the newer and better maintained [[markdown-it|https://github.com/markdown-it/markdown-it]] library. The previous Markdown plugin remains available as "markdown-legacy"
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7176">> [[Innerwiki Plugin]] to allow the `<$data>` widget to override existing tiddler fields * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7176">> [[Innerwiki Plugin]] to allow the `<$data>` widget to override existing tiddler fields
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7207">>, <<.link-badge-here "https://github.com/Jermolene/TiddlyWiki5/commit/c39ef398bffae12c0ed7324d9b6d9d29f0f2f9ff">> and <<.link-badge-here "https://github.com/Jermolene/TiddlyWiki5/commit/8f7441f296351a4dd0852c3c782f8874d398e052">> problem preventing [[Share Plugin]] from working properly * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7207">>, <<.link-badge-here "https://github.com/Jermolene/TiddlyWiki5/commit/c39ef398bffae12c0ed7324d9b6d9d29f0f2f9ff">> and <<.link-badge-here "https://github.com/Jermolene/TiddlyWiki5/commit/8f7441f296351a4dd0852c3c782f8874d398e052">> problem preventing [[Share Plugin]] from working properly
* <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/commit/524cee1489f260375cac8cfe878fdc5942a4596e">> [[XLSX Plugin|XLSX Utilities Edition]] to handle importing numeric fields
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/81f514116657d0d567be7a4c45762a85beaa8bc0">> Dynannotate plugin crash when using the fake DOM used for static rendering
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7281">> bug where pasting text into the CodeMirror editor also opened an `$:/Import` tiddler
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7334">> documentation for the [[Railroad Plugin]]
! Accessibility Improvements
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7232">> appearance of save wiki button so that it is accessible to users without colour vision
! Usability Improvements ! Usability Improvements
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7217">> consistency of tiddler deletion by allowing missing tiddlers to be 'deleted', which just results in them being closed * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7217">> consistency of tiddler deletion by allowing missing tiddlers to be 'deleted', which just results in them being closed
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/commit/34643a42790777f1b235f57b5093bb29bd0b3a14">> layout switcher to include an optional icon for each layout * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/commit/34643a42790777f1b235f57b5093bb29bd0b3a14">> layout switcher to include an optional icon for each layout
* <<.link-badge-removed "https://github.com/Jermolene/TiddlyWiki5/commit/c0615e20ecf7d5d5e66d8a2acd28b80e8d59688d">> [[improvements to table layout|https://github.com/Jermolene/TiddlyWiki5/pull/7010]] from v5.2.5 that have proved to not be backwards compatible * <<.link-badge-removed "https://github.com/Jermolene/TiddlyWiki5/commit/c0615e20ecf7d5d5e66d8a2acd28b80e8d59688d">> [[improvements to table layout|https://github.com/Jermolene/TiddlyWiki5/pull/7010]] from v5.2.5 that have proved to not be backwards compatible
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7323">> support for `&dollar;` HTML entity
! Widget Improvements ! Widget Improvements
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/7222">> EditTextWidget to support `focusSelectFromStart` and `focusSelectFromEnd` attributes to give better control over text selection *
! Filter improvements ! Filter improvements
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/7121">> [[encodeuricomponent Operator]] to encode characters such as `*` that are illegal in Windows filenames * <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/7121">> [[encodeuricomponent Operator]] to encode characters such as `*` that are illegal in Windows filenames
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/89fd8871b6217634c9896b9402069757ca5ea189">> [[encodebase64 Operator]] and [[decodebase64 Operator]]
! Hackability Improvements ! Hackability Improvements
@@ -74,7 +41,6 @@ Improvements to the following translations:
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7118">> readability of [[tag-picker Macro]] and [[keyboard-driven-input Macro]] * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7118">> readability of [[tag-picker Macro]] and [[keyboard-driven-input Macro]]
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7129">> reliability of [[list-links-draggable Macro]] and [[list-tagged-draggable Macro]] by using the new GenesisWidget instead of textual substitution * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7129">> reliability of [[list-links-draggable Macro]] and [[list-tagged-draggable Macro]] by using the new GenesisWidget instead of textual substitution
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7210">> [[external JavaScript core support|Using the external JavaScript template]] to make it possible to save an external JS wiki as a standard single file wiki * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7210">> [[external JavaScript core support|Using the external JavaScript template]] to make it possible to save an external JS wiki as a standard single file wiki
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7007">> a warning message in the browser console when the Zoomin storyview fails due to the tiddler view template lacking a single containing element
! Bug Fixes ! Bug Fixes
@@ -84,60 +50,43 @@ Improvements to the following translations:
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7121">> (and <<.link-badge-here "https://github.com/Jermolene/TiddlyWiki5/pull/7219">>) overriding `toc-caption` macro for [[Table-of-Contents Macros]] * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7121">> (and <<.link-badge-here "https://github.com/Jermolene/TiddlyWiki5/pull/7219">>) overriding `toc-caption` macro for [[Table-of-Contents Macros]]
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7212">> rendering of $:/core/ui/MoreSideBar/Tags when viewed within the story river * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7212">> rendering of $:/core/ui/MoreSideBar/Tags when viewed within the story river
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7156">> undefined variable crash in [[reduce Operator]], [[filter Operator]] and [[sortsub Operator]] * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7156">> undefined variable crash in [[reduce Operator]], [[filter Operator]] and [[sortsub Operator]]
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/issues/7153">> GenesisWidget not to create anything if the `$type` attribute is blank or missing * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7153">> GenesisWidget not to create anything if the `$type` attribute is blank or missing
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7230">> GenesisWidget to pass `isBlock` flag to the generated widget
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7160">> crash using [[jsonget Operator]] with "fixed" as key name * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7160">> crash using [[jsonget Operator]] with "fixed" as key name
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/0b39e47ce88c7620b7a66c1553a71efaff06edb9">> importing of MP3 files to match current browser implementations * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/0b39e47ce88c7620b7a66c1553a71efaff06edb9">> importing of MP3 files to match current browser implementations
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7122">> crash when attempting to create an element with a blank tag name * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7122">> crash when attempting to create an element with a blank tag name
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7224">> layout issue with "save tiddler" button
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/3d0ec5b1bdc157f87d65b8c9b76e681c14337eb4">> (and <<.link-badge-here "https://github.com/Jermolene/TiddlyWiki5/commit/4e5c957e975459350cd7df3038e5fb3c7aea859f">>) handling of whitespace in lists to cover all Unicode whitespace characters
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7228">> test spacing of parser rule checkboxes in control panel
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/f249b79e81e51d48364ea8147fe27850df9f577f">> CSS classes assigned to edit toolbar buttons
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7247">> usage of broken CSS class `tc-storyview-zoomin-tiddler` in Zoomin story view
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7243">> usage of `importTitle` and `autoOpenOnImport` options for [[WidgetMessage: tm-import-tiddlers]]
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7276">> fixed text editor refresh when the palette is changed
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7270">> crash with LetWidget when referencing a variable that exists but has an undefined value
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7354">> unwanted double braces around tags specified in $:/config/NewTiddler/Tags when using "new here" button
! Node.js Improvements ! Node.js Improvements
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7169">> integration between the [[BrowserStorage Plugin]] and the client-server configuration to allow changes to be made while offline and then later resynchronised with the server
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7130">> duplicate fields in internal templates used in client-server configuration * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7130">> duplicate fields in internal templates used in client-server configuration
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7138">> lazy loading not triggering a sync from the server * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7138">> lazy loading not triggering a sync from the server
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/bf8e1ca5b0587787bf80692b0213bb7b038c7868">> crash on creating a new tiddler if anonymous users manage to create syncable tiddlers in a read only wiki * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/bf8e1ca5b0587787bf80692b0213bb7b038c7868">> crash on creating a new tiddler if anonymous users manage to create syncable tiddlers in a read only wiki
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/commit/95e61688397ff1bc9be04193bc4ce2e3c8c48dce">> handling of logout in the client-server configuration to avoid 404 errors * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/commit/95e61688397ff1bc9be04193bc4ce2e3c8c48dce">> handling of logout in the client-server configuration to avoid 404 errors
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7238">> problem with saving tiddlers with `_canonical_uri` field as `.tid` files
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6953">> missing meta viewport to static river template
! Performance Improvements ! Performance Improvements
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7299">> field indexer to more efficiently process lookups *
! Acknowledgements ! Acknowledgements
[[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki: [[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki:
<<.contributors """ <<.contributors """
andrigamerita
AnthonyMuscio AnthonyMuscio
BramChen BramChen
btheado btheado
cdruan cdruan
CrossEye CrossEye
cs8425 cs8425
EvidentlyCube
fkmiec fkmiec
flibbles flibbles
GameDungeon GameDungeon
hffqyd
jeffrey4l jeffrey4l
joebordes joebordes
kookma kookma
linonetwo
m42e m42e
Marxsal Marxsal
mateuszwilczek
newmedicine newmedicine
michsa
pippep pippep
pmario pmario
saqimtiaz saqimtiaz
@@ -145,4 +94,4 @@ Telumire
twMat twMat
wincentbalin wincentbalin
yaisog yaisog
""">> """>>

View File

@@ -1,83 +0,0 @@
caption: 5.3.0
created: 20230419103154368
modified: 20230419103154368
tags: ReleaseNotes
title: Release 5.3.0
type: text/vnd.tiddlywiki
//[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/master...parameterised-transclusions]]//
! About v5.3.0
This pre-release introduces a number of significant improvements and new features related to some of TiddlyWiki's most fundamental components: macros, widgets, operators and transclusion.
! Introduction to v5.3.0
The motivation of these changes is to fix one of ~TiddlyWiki 5's early design flaws: the reliance on macros using textual substitution as the primary way to modularise and reuse wikitext and filters.
Experience has shown that while macros are a good match for a small number of tasks, they are brittle and error prone for many common operations. See [[Macro Pitfalls]] for a discussion of the problems that accompany this approach. Over the years we have introduced mitigations for the worst problems but these have come at a cost of increased complexity.
The changes in this release provide powerful new ways to achieve common tasks, and unlock completely new capabilities that were previously impossible in wikitext.
* [[Procedures]], which are essentially what macros should have been; they work in exactly the same way except that parameters are exposed as simple variables (without the double underscores) and no textual substitution takes place
* [[Custom Widgets]], allowing the creation of widgets in wikitext, and the redefinition of built-in widgets
* [[Functions]], a new way to encapsulate filter expressions with named parameters, including the ability to make custom filter operators
* Parameterised [[Transclusions|Transclusion]], allowing strings and wikitext trees to be passed to transclusions
The approach taken by this release is to add new functionality by extending and augmenting the system without disturbing existing functionality. All of these changes are thus intended to be backwards compatible. While they represent a new field of opportunities for wikitext authors, it is possible for authors to ignore all these new features and continue to use ~TiddlyWiki 5 in the way that they have always done.
These changes lay the groundwork for macros and related features to be deprecated (which is the point at which users are advised not to use old features, and instead given clear pointers to the equivalent modern functionality).
The new transclusion architecture is not by itself sufficient to enable us to fully deprecate macros yet. To handle the remaining use cases we propose a new backtick quoted attribute format that allows for the substitution of variable values. See https://github.com/Jermolene/TiddlyWiki5/issues/6663 for details.
! Plugin Improvements
*
! Translation improvement
Improvements to the following translations:
*
! Accessibility Improvements
*
! Usability Improvements
*
! Widget Improvements
*
! Filter improvements
*
! Hackability Improvements
*
! Bug Fixes
*
! Developer Improvements
*
! Node.js Improvements
*
! Performance Improvements
*
! Acknowledgements
[[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki:
<<.contributors """
""">>

View File

@@ -1,6 +1,6 @@
title: $:/config/OfficialPluginLibrary title: $:/config/OfficialPluginLibrary
tags: $:/tags/PluginLibrary tags: $:/tags/PluginLibrary
url: https://tiddlywiki.com/prerelease/library/v5.2.8/index.html url: https://tiddlywiki.com/prerelease/library/v5.2.6/index.html
caption: {{$:/language/OfficialPluginLibrary}} (Prerelease) caption: {{$:/language/OfficialPluginLibrary}} (Prerelease)
The prerelease version of the official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team. The prerelease version of the official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.

View File

@@ -1,24 +0,0 @@
title: CustomOperators/NestedParameterised
description: Nested parameterised custom operator usage
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\function .dividebysomething(first:ignored,factor:0.5)
[divide[2]multiply<factor>]
\end
\function .multiplebysomething(first:ignored,factor:2)
[multiply[2].dividebysomething[],<factor>]
\end
<$text text={{{ [[123].multiplebysomething[]] }}}/>
-
<$text text={{{ [[123].multiplebysomething[x],[4]] }}}/>
+
title: ExpectedResult
<p>246-492</p>

View File

@@ -1,24 +0,0 @@
title: CustomOperators/Parameterised
description: Parameterised custom operator usage
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\function .multiplybysomething(first:ignored,factor:2)
[multiply[2]multiply<factor>]
\end
<$text text={{{ [[123].multiplybysomething[]] }}}/>
-
<$text text={{{ [[123].multiplybysomething[x],[4]] }}}/>
|
<$text text={{{ [[123]function[.multiplybysomething]] }}}/>
-
<$text text={{{ [[123]function[.multiplybysomething],[x],[4]] }}}/>
+
title: ExpectedResult
<p>492-984|492-984</p>

View File

@@ -1,21 +0,0 @@
title: CustomOperators/Simple
description: Simple custom operator usage
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\function .multiplybytwo()
[multiply[2]]
\end
<$text text={{{ [[123].multiplybytwo[]] }}}/>
|
<$text text={{{ [[123]function[.multiplybytwo]] }}}/>
+
title: ExpectedResult
<p>246|246</p>

View File

@@ -1,19 +0,0 @@
title: Filters/Base64
description: Test {encode|decode}base64 operators
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
(<$text text={{{ [[Jeremy1234]encodebase64[]] }}}/>)
(<$text text={{{ [[]encodebase64[]] }}}/>)
(<$text text={{{ [[SmVyZW15MTIzNA==]decodebase64[]] }}}/>)
(<$text text={{{ [[]decodebase64[]] }}}/>)
+
title: ExpectedResult
<p>(SmVyZW15MTIzNA==)
()
(Jeremy1234)
()</p>

View File

@@ -1,28 +0,0 @@
title: Filters/DiffMergePatch1
description: Tests for diff-merge-patch derived operators
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\define text1()
the cat sat on the mat
\end
\define text2()
the hat saw in every category
\end
<$text text={{{ [<text1>makepatches<text2>] }}}/>
+
title: ExpectedResult
<p>@@ -1,22 +1,29 @@
the
-c
+h
at sa
-t on the mat
+w in every category
</p>

View File

@@ -1,25 +0,0 @@
title: Filters/DiffMergePatch2
description: Tests for diff-merge-patch derived operators
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\define text1()
the cat sat on the mat
\end
\define text2()
the hat saw in every category
\end
<$let patches={{{ [<text1>makepatches<text2>] }}}>
<$text text={{{ [<text1>applypatches<patches>] }}}/>
</$let>
+
title: ExpectedResult
the hat saw in every category

View File

@@ -1,22 +0,0 @@
title: Filters/DiffMergePatch3
description: Tests for diff-merge-patch derived operators
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\define text1()
the cat sat on the mat
\end
\define patches()
**NOT A VALID PATCH**
\end
<$text text={{{ [<text1>applypatches<patches>] }}}/>
+
title: ExpectedResult
the cat sat on the mat

View File

@@ -1,24 +0,0 @@
title: Functions/FunctionAttributes
description: Attributes specified as function invocations
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\function .dividebysomething(factor:0.5)
[divide<factor>]
\end
\function multiplebysomething(first:ignored,factor:2)
[<factor>multiply[2].dividebysomething[0.25]]
\end
<$text text=<<multiplebysomething>>/>
|
<$text text=<<multiplebysomething "nothing" "4">>/>
+
title: ExpectedResult
<p>16|32</p>

View File

@@ -1,24 +0,0 @@
title: Functions/FunctionOperator
description: Calling a function via the function operator
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\function .dividebysomething(factor:0.5)
[divide<factor>]
\end
\function multiplebysomething(first:ignored,factor:2)
[multiply<factor>multiply[2].dividebysomething[0.25]]
\end
<$text text={{{ [[4]function[multiplebysomething]] }}}/>
|
<$text text={{{ [[6]function[multiplebysomething],[ignored],[4]] }}}/>
+
title: ExpectedResult
<p>64|192</p>

View File

@@ -1,15 +0,0 @@
title: Functions/MissingFunction
description: Calling a missing function via the function operator
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
<$text text={{{ [[23]function[missing]] }}}/>
+
title: ExpectedResult
23

View File

@@ -1,18 +0,0 @@
title: Functions/RunawayRecursiveFunctions
description: Runaway recursive functions
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\function .buffalo(p)
[.buffalo<p>]
\end
<$text text=<<.buffalo 8>>/>
+
title: ExpectedResult
/**-- Excessive filter recursion --**/

View File

@@ -1,22 +0,0 @@
title: Functions/UndefinedParameters
description: Undefined function parameters
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\function greet(who)
[[hello ]addsuffix<who>]
\end
<$text text={{{[function[greet],[world]]}}}/>
<<greet world>>
<$text text={{{[function[greet]]}}}/>
<<greet>>
+
title: ExpectedResult
hello world<p>hello world</p>hello <p>hello </p>

View File

@@ -1,36 +0,0 @@
title: Functions/WikifiedFunctions
description: Wikified functions
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\function fn-buffalo(param)
[<param>addsuffix[ with a ''buffalo'']]
\end
\procedure proc-buffalo(param)
<<param>> with a ''buffalo''
\end
\define macro-buffalo(param)
$param$ with a ''buffalo''
\end
<<fn-buffalo "Going to lunch">>
<<proc-buffalo "Going to breakfast">>
<<macro-buffalo "Going to dinner">>
<$transclude $variable="fn-buffalo" param="Going to lunch" $output="text/plain"/>
<$transclude $variable="proc-buffalo" param="Going to breakfast" $output="text/plain"/>
<$transclude $variable="macro-buffalo" param="Going to dinner" $output="text/plain"/>
+
title: ExpectedResult
<p>Going to lunch with a ''buffalo''</p><p>Going to breakfastwith a<strong>buffalo</strong></p><p>Going to dinner with a <strong>buffalo</strong></p>Going to lunch with a buffalo with a buffaloGoing to dinner with a buffalo

View File

@@ -1,30 +0,0 @@
title: Genesis/Block
description: genesis widget distinguishes between block and inline
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
<$genesis $type="$reveal" type=nomatch>
Block
</$genesis>
<$genesis $type="$reveal" type=nomatch $mode=block>
Block forced block
</$genesis>
<$genesis $type="$reveal" type=nomatch $mode=inline>
Block forced inline
</$genesis>
<$genesis $type=$reveal type=nomatch>Inline</$genesis>
<$genesis $type=$reveal type=nomatch $mode=block>Inline forced block</$genesis>
<$genesis $type=$reveal type=nomatch $mode=inline>Inline forced inline</$genesis>
+
title: ExpectedResult
<div class=" tc-reveal"><p>Block</p></div><div class=" tc-reveal"><p>Block forced block</p></div><span class=" tc-reveal"><p>Block forced inline</p></span><p><span class=" tc-reveal">Inline</span><div class=" tc-reveal">Inline forced block</div><span class=" tc-reveal">Inline forced inline</span></p>

View File

@@ -1,31 +0,0 @@
title: Genesis/RedefineLet
description: Using the genesis widget to override the let widget
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\widget $let()
\whitespace trim
<$parameters $params="@params">
<$setmultiplevariables $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>addprefix[--]addsuffix[--]]">
<$slot $name="ts-raw"/>
</$setmultiplevariables>
</$parameters>
\end
<$let
one="Elephant"
$two="Kangaroo"
$$three="Giraffe"
>
(<$text text=<<one>>/>)
(<$text text=<<$two>>/>)
(<$text text=<<$$three>>/>)
</$let>
+
title: ExpectedResult
<p>(--Elephant--)
(--Kangaroo--)
(--Giraffe--)</p>

View File

@@ -1,22 +0,0 @@
title: Macros/TrailingNewlines
description: Trailing newlines in macros must not be dropped
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\define inner()
Paragraph 1
Paragraph 2
\end
\define outer()
<$macrocall $name=inner />
\end
<<outer>>
+
title: ExpectedResult
<p>Paragraph 1</p><p>Paragraph 2</p>

View File

@@ -1,35 +0,0 @@
title: Message/tm-import-tiddlers/CustomTitle
description: tm-import-tiddlers message can import to a tiddler with a custom title
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
text: <$text text={{MyCustomTitle}}/>
plugin-type: <$text text={{MyCustomTitle!!plugin-type}}/>
~$:/StoryList: <$text text={{$:/StoryList!!list}}/>
+
title: Actions
<$navigator story="$:/StoryList">
<$action-sendmessage
$message="tm-import-tiddlers"
$param='[{"title": "Elephants"}, {"title": "Eagles"}]'
importTitle=MyCustomTitle/>
</$navigator>
+
title: ExpectedResult
<p>text: {
"tiddlers": {
"Elephants": {
"title": "Elephants"
},
"Eagles": {
"title": "Eagles"
}
}
}
plugin-type: import
$:/StoryList: MyCustomTitle</p>

View File

@@ -1,35 +0,0 @@
title: Message/tm-import-tiddlers/NoAutoOpen
description: tm-import-tiddlers can import without automatically opening the import tiddler
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
text: <$text text={{$:/Import}}/>
plugin-type: <$text text={{$:/Import!!plugin-type}}/>
~$:/StoryList: <$text text={{$:/StoryList!!list}}/>
+
title: Actions
<$navigator story="$:/StoryList">
<$action-sendmessage
$message="tm-import-tiddlers"
$param='[{"title": "Elephants"}, {"title": "Eagles"}]'
autoOpenOnImport=no/>
</$navigator>
+
title: ExpectedResult
<p>text: {
"tiddlers": {
"Elephants": {
"title": "Elephants"
},
"Eagles": {
"title": "Eagles"
}
}
}
plugin-type: import
$:/StoryList: </p>

View File

@@ -1,36 +0,0 @@
title: Message/tm-import-tiddlers/NoAutoOpenViaVar
description: tm-import-tiddlers can import and open based on tv-auto-open-on-import
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
text: <$text text={{$:/Import}}/>
plugin-type: <$text text={{$:/Import!!plugin-type}}/>
~$:/StoryList: <$text text={{$:/StoryList!!list}}/>
+
title: Actions
<$let tv-auto-open-on-import="no">
<$navigator story="$:/StoryList">
<$action-sendmessage
$message="tm-import-tiddlers"
$param='[{"title": "Elephants"}, {"title": "Eagles"}]'/>
</$navigator>
</$let>
+
title: ExpectedResult
<p>text: {
"tiddlers": {
"Elephants": {
"title": "Elephants"
},
"Eagles": {
"title": "Eagles"
}
}
}
plugin-type: import
$:/StoryList: </p>

View File

@@ -1,34 +0,0 @@
title: Message/tm-import-tiddlers/default
description: tm-import-tiddlers message by default should import to $:/Import and open the tiddler
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
text: <$text text={{$:/Import}}/>
plugin-type: <$text text={{$:/Import!!plugin-type}}/>
~$:/StoryList: <$text text={{$:/StoryList!!list}}/>
+
title: Actions
<$navigator story="$:/StoryList">
<$action-sendmessage
$message="tm-import-tiddlers"
$param='[{"title": "Elephants"}, {"title": "Eagles"}]'/>
</$navigator>
+
title: ExpectedResult
<p>text: {
"tiddlers": {
"Elephants": {
"title": "Elephants"
},
"Eagles": {
"title": "Eagles"
}
}
}
plugin-type: import
$:/StoryList: $:/Import</p>

View File

@@ -1,20 +0,0 @@
title: Procedures/Nested
description: Nested Procedures
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\procedure alpha(x)
\procedure beta(y)
<$text text=<<y>>/>
\end beta
<$transclude $variable="beta" y={{{ [<x>addprefix<x>] }}}/>
\end alpha
<<alpha "Elephant">>
+
title: ExpectedResult
<p>ElephantElephant</p>

Some files were not shown because too many files have changed in this diff Show More