mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-02-05 17:50:25 +00:00
Compare commits
27 Commits
element-ma
...
revert-949
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
092b745a8c | ||
|
|
bf7c0b575c | ||
|
|
b236373064 | ||
|
|
d15398fc09 | ||
|
|
6bc77cf3e2 | ||
|
|
dc764b3a4a | ||
|
|
9c09841eda | ||
|
|
9d5be2e9f8 | ||
|
|
486d3bd326 | ||
|
|
196683915c | ||
|
|
42a3928960 | ||
|
|
2e76cc08a1 | ||
|
|
891e4fcb2b | ||
|
|
f6fd5ff261 | ||
|
|
526aaa3db8 | ||
|
|
455f1be3fb | ||
|
|
bffa0bb95a | ||
|
|
a1ef2ef6d4 | ||
|
|
75edd9b488 | ||
|
|
cde9c931c8 | ||
|
|
d07fe25cdb | ||
|
|
a40ce29451 | ||
|
|
75647eb623 | ||
|
|
70b4557738 | ||
|
|
efe58e41bc | ||
|
|
79e3d14698 | ||
|
|
763d717a13 |
23
boot/boot.js
23
boot/boot.js
@@ -316,8 +316,25 @@ $tw.utils.htmlDecode = function(s) {
|
||||
return s.toString().replace(/</mg,"<").replace(/ /mg,"\xA0").replace(/>/mg,">").replace(/"/mg,"\"").replace(/&/mg,"&");
|
||||
};
|
||||
|
||||
/** @deprecated Use window.location.hash instead. */
|
||||
$tw.utils.getLocationHash = () => window.location.hash;
|
||||
/*
|
||||
Get the browser location.hash. We don't use location.hash because of the way that Firefox auto-urldecodes it (see http://stackoverflow.com/questions/1703552/encoding-of-window-location-hash)
|
||||
*/
|
||||
$tw.utils.getLocationHash = function() {
|
||||
const href = window.location.href,
|
||||
idx = href.indexOf("#");
|
||||
|
||||
if(idx === -1) {
|
||||
return "#";
|
||||
}
|
||||
|
||||
const afterHash = href.substring(idx + 1);
|
||||
if(afterHash.startsWith("#") || afterHash.startsWith("%23")) {
|
||||
// Special case: ignore location hash if it itself starts with a #
|
||||
return "#";
|
||||
}
|
||||
return href.substring(idx);
|
||||
};
|
||||
|
||||
|
||||
/** @deprecated Pad a string to a given length with "0"s. Length defaults to 2 */
|
||||
$tw.utils.pad = function(value,length = 2) {
|
||||
@@ -596,7 +613,7 @@ $tw.utils.evalGlobal = function(code,context,filename,sandbox,allowGlobals) {
|
||||
// Compile the code into a function
|
||||
var fn;
|
||||
if($tw.browser) {
|
||||
fn = window["eval"](code + "\n\n//# sourceURL=" + filename); // eslint-disable-line no-eval -- See https://github.com/TiddlyWiki/TiddlyWiki5/issues/6839
|
||||
fn = Function("return " + code + "\n\n//# sourceURL=" + filename)(); // See https://github.com/TiddlyWiki/TiddlyWiki5/issues/6839
|
||||
} else {
|
||||
if(sandbox){
|
||||
fn = vm.runInContext(code,sandbox,filename)
|
||||
|
||||
@@ -33,8 +33,8 @@ exports.handler = function(request,response,state) {
|
||||
}
|
||||
var text = state.wiki.renderTiddler(renderType,renderTemplate,{parseAsInline: true, variables: {currentTiddler: title}});
|
||||
|
||||
// Naughty not to set a content-type, but it's the easiest way to ensure the browser will see HTML pages as HTML, and accept plain text tiddlers as CSS or JS
|
||||
state.sendResponse(200,{},text,"utf8");
|
||||
var headers = {"Content-Type": renderType};
|
||||
state.sendResponse(200,headers,text,"utf8");
|
||||
} else {
|
||||
response.writeHead(404);
|
||||
response.end();
|
||||
|
||||
@@ -42,6 +42,8 @@ function Server(options) {
|
||||
}
|
||||
// Setup the default required plugins
|
||||
this.requiredPlugins = this.get("required-plugins").split(',');
|
||||
// Initialise CORS
|
||||
this.corsEnable = this.get("cors-enable") === "yes";
|
||||
// Initialise CSRF
|
||||
this.csrfDisable = this.get("csrf-disable") === "yes";
|
||||
// Initialize Gzip compression
|
||||
@@ -261,6 +263,13 @@ Server.prototype.requestHandler = function(request,response,options) {
|
||||
state.urlInfo = url.parse(request.url);
|
||||
state.queryParameters = querystring.parse(state.urlInfo.query);
|
||||
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
|
||||
// Enable CORS
|
||||
if(this.corsEnable) {
|
||||
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||
response.setHeader("Access-Control-Allow-Headers", "*");
|
||||
response.setHeader("Access-Control-Allow-Methods", "*");
|
||||
response.setHeader("Access-Control-Expose-Headers", "*");
|
||||
}
|
||||
state.sendResponse = sendResponse.bind(self,request,response);
|
||||
// Get the principals authorized to access this resource
|
||||
state.authorizationType = options.authorizationType || this.methodMappings[request.method] || "readers";
|
||||
@@ -285,6 +294,12 @@ Server.prototype.requestHandler = function(request,response,options) {
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
// Reply to OPTIONS
|
||||
if(this.corsEnable && request.method === "OPTIONS") {
|
||||
response.writeHead(204);
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
// Find the route that matches this path
|
||||
var route = self.findMatchingRoute(request,state);
|
||||
// Optionally output debug info
|
||||
|
||||
4
core/language/en-GB/Draft.multids
Normal file
4
core/language/en-GB/Draft.multids
Normal file
@@ -0,0 +1,4 @@
|
||||
title: $:/language/Draft/
|
||||
|
||||
Attribution: Draft of '<<draft-title>>' by {{$:/status/UserName}}
|
||||
Title: Draft of '<<draft-title>>'
|
||||
@@ -48,8 +48,8 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
||||
this.toolbarNode = this.document.createElement("div");
|
||||
this.toolbarNode.className = "tc-editor-toolbar";
|
||||
parent.insertBefore(this.toolbarNode,nextSibling);
|
||||
this.renderChildren(this.toolbarNode,null);
|
||||
this.domNodes.push(this.toolbarNode);
|
||||
this.renderChildren(this.toolbarNode,null);
|
||||
}
|
||||
// Create our element
|
||||
var editInfo = this.getEditInfo(),
|
||||
|
||||
@@ -88,8 +88,8 @@ function parseFilterOperation(operators,filterString,p) {
|
||||
rexMatch = rex.exec(filterString.substring(p));
|
||||
if(rexMatch) {
|
||||
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
|
||||
// DEPRECATION WARNING
|
||||
console.log("WARNING: Filter",operator.operator,"has a deprecated regexp operand",operator.regexp);
|
||||
// DEPRECATION WARNING
|
||||
console.log("WARNING: Filter",operator.operator,"has a deprecated regexp operand",operator.regexp);
|
||||
nextBracketPos = p + rex.lastIndex - 1;
|
||||
}
|
||||
else {
|
||||
@@ -232,12 +232,7 @@ exports.getFilterRunPrefixes = function() {
|
||||
|
||||
exports.filterTiddlers = function(filterString,widget,source) {
|
||||
var fn = this.compileFilter(filterString);
|
||||
try {
|
||||
const fnResult = fn.call(this,source,widget);
|
||||
return fnResult;
|
||||
} catch(e) {
|
||||
return [`${$tw.language.getString("Error/Filter")}: ${e}`];
|
||||
}
|
||||
return fn.call(this,source,widget);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -319,19 +314,19 @@ exports.compileFilter = function(filterString) {
|
||||
|
||||
// Invoke the appropriate filteroperator module
|
||||
results = operatorFunction(accumulator,{
|
||||
operator: operator.operator,
|
||||
operand: operands.length > 0 ? operands[0] : undefined,
|
||||
operands: operands,
|
||||
multiValueOperands: multiValueOperands,
|
||||
isMultiValueOperand: isMultiValueOperand,
|
||||
prefix: operator.prefix,
|
||||
suffix: operator.suffix,
|
||||
suffixes: operator.suffixes,
|
||||
regexp: operator.regexp
|
||||
},{
|
||||
wiki: self,
|
||||
widget: widget
|
||||
});
|
||||
operator: operator.operator,
|
||||
operand: operands.length > 0 ? operands[0] : undefined,
|
||||
operands: operands,
|
||||
multiValueOperands: multiValueOperands,
|
||||
isMultiValueOperand: isMultiValueOperand,
|
||||
prefix: operator.prefix,
|
||||
suffix: operator.suffix,
|
||||
suffixes: operator.suffixes,
|
||||
regexp: operator.regexp
|
||||
},{
|
||||
wiki: self,
|
||||
widget: widget
|
||||
});
|
||||
if($tw.utils.isArray(results)) {
|
||||
accumulator = self.makeTiddlerIterator(results);
|
||||
} else {
|
||||
|
||||
@@ -107,13 +107,14 @@ exports.parseStringLiteral = function(source,pos) {
|
||||
type: "string",
|
||||
start: pos
|
||||
};
|
||||
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')/g;
|
||||
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')|\[\[((?:[^\]]|\](?!\]))*)\]\]/g;
|
||||
reString.lastIndex = pos;
|
||||
var match = reString.exec(source);
|
||||
if(match && match.index === pos) {
|
||||
node.value = match[1] !== undefined ? match[1] :(
|
||||
match[2] !== undefined ? match[2] : match[3]
|
||||
);
|
||||
match[2] !== undefined ? match[2] : (
|
||||
match[3] !== undefined ? match[3] : match[4]
|
||||
));
|
||||
node.end = pos + match[0].length;
|
||||
return node;
|
||||
} else {
|
||||
@@ -173,7 +174,7 @@ exports.parseMacroParameter = function(source,pos) {
|
||||
start: pos
|
||||
};
|
||||
// Define our regexp
|
||||
const reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|((?:(?:>(?!>))|[^\s>"'])+)))/y;
|
||||
const reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[((?:[^\]]|\](?!\]))*)\]\]|((?:(?:>(?!>))|[^\s>"'])+)))/y;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for the parameter
|
||||
@@ -206,28 +207,152 @@ exports.parseMacroParameter = function(source,pos) {
|
||||
Look for a macro invocation. Returns null if not found, or {type: "transclude", attributes:, 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;
|
||||
var node = {
|
||||
type: "transclude",
|
||||
start: pos,
|
||||
attributes: {},
|
||||
orderedAttributes: []
|
||||
};
|
||||
// Define our regexps
|
||||
var reVarName = /([^\s>"'=:]+)/g;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a double opening angle bracket
|
||||
var token = $tw.utils.parseTokenString(source,pos,"<<");
|
||||
if(!token) {
|
||||
return null;
|
||||
}
|
||||
pos = token.end;
|
||||
// Get the variable name for the macro
|
||||
token = $tw.utils.parseTokenRegExp(source,pos,reVarName);
|
||||
if(!token) {
|
||||
return null;
|
||||
}
|
||||
$tw.utils.addAttributeToParseTreeNode(node,"$variable",token.match[1]);
|
||||
pos = token.end;
|
||||
// Check that the tag is terminated by a space or >>
|
||||
if(!$tw.utils.parseWhiteSpace(source,pos) && !(source.charAt(pos) === ">" && source.charAt(pos + 1) === ">") ) {
|
||||
return null;
|
||||
}
|
||||
// Process attributes
|
||||
pos = $tw.utils.parseMacroParametersAsAttributes(node,source,pos);
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a double closing angle bracket
|
||||
token = $tw.utils.parseTokenString(source,pos,">>");
|
||||
if(!token) {
|
||||
return null;
|
||||
}
|
||||
node.end = token.end;
|
||||
return node;
|
||||
};
|
||||
|
||||
/*
|
||||
Parse macro parameters as attributes. Returns the position after the last attribute
|
||||
*/
|
||||
exports.parseMacroParametersAsAttributes = function(node,source,pos) {
|
||||
var position = 0,
|
||||
attribute = $tw.utils.parseMacroParameterAsAttribute(source,pos);
|
||||
while(attribute) {
|
||||
if(!attribute.name) {
|
||||
attribute.name = (position++) + "";
|
||||
attribute.isPositional = true;
|
||||
}
|
||||
node.orderedAttributes.push(attribute);
|
||||
node.attributes[attribute.name] = attribute;
|
||||
pos = attribute.end;
|
||||
// Get the next attribute
|
||||
attribute = $tw.utils.parseMacroParameterAsAttribute(source,pos);
|
||||
}
|
||||
node.end = pos;
|
||||
return pos;
|
||||
};
|
||||
|
||||
/*
|
||||
Parse a macro parameter as an attribute. Returns null if not found, otherwise returns {name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}, with the name being optional
|
||||
*/
|
||||
exports.parseMacroParameterAsAttribute = function(source,pos) {
|
||||
var node = {
|
||||
start: pos
|
||||
};
|
||||
// Define our regexps
|
||||
var reAttributeName = /([^\/\s>"'`=:]+)/g,
|
||||
reUnquotedAttribute = /((?:(?:>(?!>))|[^\s>"'])+)/g,
|
||||
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/g,
|
||||
reIndirectValue = /\{\{([^\}]+)\}\}/g,
|
||||
reSubstitutedValue = /(?:```([\s\S]*?)```|`([^`]|[\S\s]*?)`)/g;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Get the attribute name and the separator token
|
||||
var nameToken = $tw.utils.parseTokenRegExp(source,pos,reAttributeName),
|
||||
namePos = nameToken && $tw.utils.skipWhiteSpace(source,nameToken.end),
|
||||
separatorToken = nameToken && $tw.utils.parseTokenRegExp(source,namePos,/=|:/g),
|
||||
isNewStyleSeparator = false; // If there is no separator then we don't allow new style values
|
||||
// If we have a name and a separator then we have a named attribute
|
||||
if(nameToken && separatorToken) {
|
||||
node.name = nameToken.match[1];
|
||||
// key value separator is `=` or `:`
|
||||
node.assignmentOperator = separatorToken.match[0];
|
||||
pos = separatorToken.end;
|
||||
isNewStyleSeparator = (node.assignmentOperator === "=");
|
||||
}
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a string literal
|
||||
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
|
||||
if(stringLiteral) {
|
||||
pos = stringLiteral.end;
|
||||
node.type = "string";
|
||||
node.value = stringLiteral.value;
|
||||
// Mark the value as having been quoted in the source
|
||||
node.quoted = true;
|
||||
} else {
|
||||
// Look for a filtered value
|
||||
var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);
|
||||
if(filteredValue && isNewStyleSeparator) {
|
||||
pos = filteredValue.end;
|
||||
node.type = "filtered";
|
||||
node.filter = filteredValue.match[1];
|
||||
} else {
|
||||
// Look for an indirect value
|
||||
var indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);
|
||||
if(indirectValue && isNewStyleSeparator) {
|
||||
pos = indirectValue.end;
|
||||
node.type = "indirect";
|
||||
node.textReference = indirectValue.match[1];
|
||||
} else {
|
||||
// Look for a unquoted value
|
||||
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
|
||||
if(unquotedValue) {
|
||||
pos = unquotedValue.end;
|
||||
node.type = "string";
|
||||
node.value = unquotedValue.match[1];
|
||||
} else {
|
||||
// Look for a macro invocation value
|
||||
var macroInvocation = $tw.utils.parseMacroInvocationAsTransclusion(source,pos);
|
||||
if(macroInvocation && isNewStyleSeparator) {
|
||||
pos = macroInvocation.end;
|
||||
node.type = "macro";
|
||||
node.value = macroInvocation;
|
||||
} else {
|
||||
var substitutedValue = $tw.utils.parseTokenRegExp(source,pos,reSubstitutedValue);
|
||||
if(substitutedValue && isNewStyleSeparator) {
|
||||
pos = substitutedValue.end;
|
||||
node.type = "substituted";
|
||||
node.rawValue = substitutedValue.match[1] || substitutedValue.match[2];
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Bail if we don't have a value
|
||||
if(!node.type) {
|
||||
return null;
|
||||
}
|
||||
// Update the end position
|
||||
node.end = pos;
|
||||
return node;
|
||||
};
|
||||
|
||||
@@ -296,7 +421,7 @@ exports.parseFilterVariable = function(source) {
|
||||
};
|
||||
|
||||
/*
|
||||
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}
|
||||
Look for an HTML attribute definition. Returns null if not found, otherwise returns {name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}
|
||||
*/
|
||||
exports.parseAttribute = function(source,pos) {
|
||||
var node = {
|
||||
@@ -354,7 +479,7 @@ exports.parseAttribute = function(source,pos) {
|
||||
node.value = unquotedValue.match[1];
|
||||
} else {
|
||||
// Look for a macro invocation value
|
||||
var macroInvocation = $tw.utils.parseMacroInvocation(source,pos);
|
||||
var macroInvocation = $tw.utils.parseMacroInvocationAsTransclusion(source,pos);
|
||||
if(macroInvocation) {
|
||||
pos = macroInvocation.end;
|
||||
node.type = "macro";
|
||||
@@ -375,6 +500,7 @@ exports.parseAttribute = function(source,pos) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If there is no equals sign or colon, then this is an attribute with no value, defaulting to "true"
|
||||
node.type = "string";
|
||||
node.value = "true";
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ exports.parse = function() {
|
||||
var paramString = this.match[2],
|
||||
params = [];
|
||||
if(paramString !== "") {
|
||||
var reParam = /\s*([A-Za-z0-9\-_]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|([^"'\s]+)))?/mg,
|
||||
var reParam = /\s*([A-Za-z0-9\-_]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[((?:[^\]]|\](?!\]))*)\]\]|([^"'\s]+)))?/mg,
|
||||
paramMatch = reParam.exec(paramString);
|
||||
while(paramMatch) {
|
||||
// Save the parameter details
|
||||
|
||||
@@ -23,27 +23,6 @@ exports.init = function(parser) {
|
||||
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}(?:\r?\n|$)/mg;
|
||||
};
|
||||
|
||||
/*
|
||||
Reject the match if we don't have a template or text reference
|
||||
*/
|
||||
exports.findNextMatch = function(startPos) {
|
||||
this.matchRegExp.lastIndex = startPos;
|
||||
this.match = this.matchRegExp.exec(this.parser.source);
|
||||
if(this.match) {
|
||||
var template = $tw.utils.trim(this.match[2]),
|
||||
textRef = $tw.utils.trim(this.match[1]);
|
||||
// Bail if we don't have a template or text reference
|
||||
if(!template && !textRef) {
|
||||
return undefined;
|
||||
} else {
|
||||
return this.match.index;
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
return this.match ? this.match.index : undefined;
|
||||
};
|
||||
|
||||
exports.parse = function() {
|
||||
// Move past the match
|
||||
this.parser.pos = this.matchRegExp.lastIndex;
|
||||
|
||||
@@ -23,27 +23,6 @@ exports.init = function(parser) {
|
||||
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}/mg;
|
||||
};
|
||||
|
||||
/*
|
||||
Reject the match if we don't have a template or text reference
|
||||
*/
|
||||
exports.findNextMatch = function(startPos) {
|
||||
this.matchRegExp.lastIndex = startPos;
|
||||
this.match = this.matchRegExp.exec(this.parser.source);
|
||||
if(this.match) {
|
||||
var template = $tw.utils.trim(this.match[2]),
|
||||
textRef = $tw.utils.trim(this.match[1]);
|
||||
// Bail if we don't have a template or text reference
|
||||
if(!template && !textRef) {
|
||||
return undefined;
|
||||
} else {
|
||||
return this.match.index;
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
return this.match ? this.match.index : undefined;
|
||||
};
|
||||
|
||||
exports.parse = function() {
|
||||
// Move past the match
|
||||
this.parser.pos = this.matchRegExp.lastIndex;
|
||||
|
||||
@@ -6,6 +6,7 @@ module-type: utils
|
||||
Custom errors for TiddlyWiki.
|
||||
|
||||
\*/
|
||||
|
||||
function TranscludeRecursionError() {
|
||||
Error.apply(this,arguments);
|
||||
this.signatures = Object.create(null);
|
||||
|
||||
@@ -37,6 +37,7 @@ Object.defineProperty(TW_Node.prototype, 'TEXT_NODE', {
|
||||
var TW_TextNode = function(text) {
|
||||
bumpSequenceNumber(this);
|
||||
this.textContent = text + "";
|
||||
this.children = [];
|
||||
};
|
||||
|
||||
Object.setPrototypeOf(TW_TextNode.prototype,TW_Node.prototype);
|
||||
|
||||
@@ -80,8 +80,8 @@ BrowseWidget.prototype.render = function(parent,nextSibling) {
|
||||
});
|
||||
// Insert element
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -135,8 +135,8 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
|
||||
}
|
||||
// Insert element
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -64,8 +64,8 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) {
|
||||
]);
|
||||
// Insert the label into the DOM and render any children
|
||||
parent.insertBefore(this.labelDomNode,nextSibling);
|
||||
this.renderChildren(this.spanDomNode,null);
|
||||
this.domNodes.push(this.labelDomNode);
|
||||
this.renderChildren(this.spanDomNode,null);
|
||||
};
|
||||
|
||||
CheckboxWidget.prototype.getValue = function() {
|
||||
|
||||
@@ -59,6 +59,8 @@ DiffTextWidget.prototype.render = function(parent,nextSibling) {
|
||||
var domContainer = this.document.createElement("div"),
|
||||
domDiff = this.createDiffDom(diffs);
|
||||
parent.insertBefore(domContainer,nextSibling);
|
||||
// Save our container
|
||||
this.domNodes.push(domContainer);
|
||||
// Set variables
|
||||
this.setVariable("diff-count",diffs.reduce(function(acc,diff) {
|
||||
if(diff[0] !== dmp.DIFF_EQUAL) {
|
||||
@@ -70,8 +72,6 @@ DiffTextWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.renderChildren(domContainer,null);
|
||||
// Render the diff
|
||||
domContainer.appendChild(domDiff);
|
||||
// Save our container
|
||||
this.domNodes.push(domContainer);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -56,6 +56,7 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
|
||||
});
|
||||
// Insert the node into the DOM and render any children
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
// Add event handlers
|
||||
if(this.dragEnable) {
|
||||
@@ -70,7 +71,6 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
|
||||
selector: self.dragHandleSelector
|
||||
});
|
||||
}
|
||||
this.domNodes.push(domNode);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -57,8 +57,8 @@ DroppableWidget.prototype.render = function(parent,nextSibling) {
|
||||
}
|
||||
// Insert element
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
// Stack of outstanding enter/leave events
|
||||
this.currentlyEntered = [];
|
||||
};
|
||||
|
||||
@@ -77,8 +77,8 @@ ElementWidget.prototype.render = function(parent,nextSibling) {
|
||||
// Allow hooks to manipulate the DOM node. Eg: Add debug info
|
||||
$tw.hooks.invokeHook("th-dom-rendering-element", domNode, this);
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -106,8 +106,8 @@ EventWidget.prototype.render = function(parent,nextSibling) {
|
||||
});
|
||||
// Insert element
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -45,7 +45,7 @@ ImageWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.execute();
|
||||
// Create element
|
||||
// Determine what type of image it is
|
||||
var tag = "img", src = "",
|
||||
var tag = "img", src = "", self = this,
|
||||
tiddler = this.wiki.getTiddler(this.imageSource);
|
||||
if(!tiddler) {
|
||||
// The source isn't the title of a tiddler, so we'll assume it's a URL
|
||||
@@ -115,11 +115,21 @@ ImageWidget.prototype.render = function(parent,nextSibling) {
|
||||
if(this.lazyLoading && tag === "img") {
|
||||
domNode.setAttribute("loading",this.lazyLoading);
|
||||
}
|
||||
this.assignAttributes(domNode,{
|
||||
sourcePrefix: "data-",
|
||||
destPrefix: "data-"
|
||||
});
|
||||
// Add classes when the image loads or fails
|
||||
$tw.utils.addClass(domNode,"tc-image-loading");
|
||||
domNode.addEventListener("load",function() {
|
||||
domNode.addEventListener("load",function(event) {
|
||||
$tw.utils.removeClass(domNode,"tc-image-loading");
|
||||
$tw.utils.addClass(domNode,"tc-image-loaded");
|
||||
if(self.loadedActions) {
|
||||
var variables = $tw.utils.collectDOMVariables(domNode,null,event);
|
||||
variables["img-natural-width"] = domNode.naturalWidth.toString();
|
||||
variables["img-natural-height"] = domNode.naturalHeight.toString();
|
||||
self.invokeActionString(self.loadedActions,self,event,variables);
|
||||
}
|
||||
},false);
|
||||
domNode.addEventListener("error",function() {
|
||||
$tw.utils.removeClass(domNode,"tc-image-loading");
|
||||
@@ -143,17 +153,31 @@ ImageWidget.prototype.execute = function() {
|
||||
this.imageTooltip = this.getAttribute("tooltip");
|
||||
this.imageAlt = this.getAttribute("alt");
|
||||
this.lazyLoading = this.getAttribute("loading");
|
||||
this.loadedActions = this.getAttribute("loadActions");
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
ImageWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(changedAttributes.source || changedAttributes.width || changedAttributes.height || changedAttributes["class"] || changedAttributes.usemap || changedAttributes.tooltip || changedTiddlers[this.imageSource]) {
|
||||
var changedAttributes = this.computeAttributes(),
|
||||
hasChangedAttributes = $tw.utils.count(changedAttributes) > 0;
|
||||
if(changedAttributes.source || changedAttributes["class"] || changedAttributes.usemap || changedAttributes.tooltip || changedTiddlers[this.imageSource] ||changedAttributes.loadActions) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else {
|
||||
} else if(hasChangedAttributes) {
|
||||
this.assignAttributes(this.domNodes[0],{
|
||||
sourcePrefix: "data-",
|
||||
destPrefix: "data-"
|
||||
});
|
||||
if(changedAttributes.width) {
|
||||
this.domNodes[0].setAttribute("width",this.getAttribute("width"));
|
||||
}
|
||||
if(changedAttributes.height) {
|
||||
this.domNodes[0].setAttribute("height",this.getAttribute("height"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -45,8 +45,8 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) {
|
||||
]);
|
||||
// Insert element
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
};
|
||||
|
||||
KeyboardWidget.prototype.handleChangeEvent = function(event) {
|
||||
|
||||
@@ -50,8 +50,8 @@ LinkWidget.prototype.render = function(parent,nextSibling) {
|
||||
destPrefix: "aria-"
|
||||
});
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -157,8 +157,8 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
||||
});
|
||||
// Insert the link into the DOM and render any children
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
};
|
||||
|
||||
LinkWidget.prototype.handleClickEvent = function(event) {
|
||||
|
||||
@@ -42,8 +42,8 @@ PasswordWidget.prototype.render = function(parent,nextSibling) {
|
||||
]);
|
||||
// Insert the label into the DOM and render any children
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
};
|
||||
|
||||
PasswordWidget.prototype.handleChangeEvent = function(event) {
|
||||
|
||||
@@ -59,8 +59,8 @@ RadioWidget.prototype.render = function(parent,nextSibling) {
|
||||
]);
|
||||
// Insert the label into the DOM and render any children
|
||||
parent.insertBefore(this.labelDomNode,nextSibling);
|
||||
this.renderChildren(this.spanDomNode,null);
|
||||
this.domNodes.push(this.labelDomNode);
|
||||
this.renderChildren(this.spanDomNode,null);
|
||||
};
|
||||
|
||||
RadioWidget.prototype.getValue = function() {
|
||||
|
||||
@@ -40,6 +40,7 @@ RevealWidget.prototype.render = function(parent,nextSibling) {
|
||||
domNode.setAttribute("style",this.style);
|
||||
}
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
if(!domNode.isTiddlyWikiFakeDom && this.type === "popup" && this.isOpen) {
|
||||
this.positionPopup(domNode);
|
||||
@@ -48,7 +49,6 @@ RevealWidget.prototype.render = function(parent,nextSibling) {
|
||||
if(!this.isOpen) {
|
||||
domNode.setAttribute("hidden","true");
|
||||
}
|
||||
this.domNodes.push(domNode);
|
||||
};
|
||||
|
||||
RevealWidget.prototype.positionPopup = function(domNode) {
|
||||
|
||||
@@ -168,8 +168,8 @@ ScrollableWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.outerDomNode.className = this["class"] || "";
|
||||
// Insert element
|
||||
parent.insertBefore(this.outerDomNode,nextSibling);
|
||||
this.renderChildren(this.innerDomNode,null);
|
||||
this.domNodes.push(this.outerDomNode);
|
||||
this.renderChildren(this.innerDomNode,null);
|
||||
// If the scroll position is bound to a tiddler
|
||||
if(this.scrollableBind) {
|
||||
// After a delay for rendering, scroll to the bound position
|
||||
|
||||
@@ -63,8 +63,8 @@ SelectWidget.prototype.render = function(parent,nextSibling) {
|
||||
domNode.setAttribute("title",this.selectTooltip);
|
||||
}
|
||||
this.parentDomNode.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
this.domNodes.push(domNode);
|
||||
this.renderChildren(domNode,null);
|
||||
this.setSelectValue();
|
||||
if(this.selectFocus == "yes") {
|
||||
this.getSelectDomNode().focus();
|
||||
@@ -82,8 +82,8 @@ SelectWidget.prototype.handleChangeEvent = function(event) {
|
||||
if(this.selectMultiple == false) {
|
||||
var value = this.getSelectDomNode().value;
|
||||
} else {
|
||||
var value = this.getSelectValues()
|
||||
value = $tw.utils.stringifyList(value);
|
||||
var value = this.getSelectValues();
|
||||
value = $tw.utils.stringifyList(value);
|
||||
}
|
||||
this.wiki.setText(this.selectTitle,this.selectField,this.selectIndex,value);
|
||||
// Trigger actions
|
||||
@@ -118,12 +118,21 @@ SelectWidget.prototype.setSelectValue = function() {
|
||||
}
|
||||
}
|
||||
// Assign it to the select element if it's different than the current value
|
||||
if (this.selectMultiple) {
|
||||
if(this.selectMultiple) {
|
||||
value = value === undefined ? "" : value;
|
||||
var select = this.getSelectDomNode();
|
||||
var values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);
|
||||
var child,
|
||||
values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);
|
||||
for(var i=0; i < select.children.length; i++){
|
||||
select.children[i].selected = values.indexOf(select.children[i].value) !== -1
|
||||
child=select.children[i];
|
||||
if(child.children.length === 0){
|
||||
child.selected = values.indexOf(child.value) !== -1;
|
||||
} else {
|
||||
// grouped options
|
||||
for(var y=0; y < child.children.length; y++){
|
||||
child.children[y].selected = values.indexOf(child.children[y].value) !== -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var domNode = this.getSelectDomNode();
|
||||
@@ -147,14 +156,14 @@ SelectWidget.prototype.getSelectValues = function() {
|
||||
select = this.getSelectDomNode();
|
||||
result = [];
|
||||
options = select && select.options;
|
||||
for (var i=0; i<options.length; i++) {
|
||||
for(var i=0; i<options.length; i++) {
|
||||
opt = options[i];
|
||||
if (opt.selected) {
|
||||
if(opt.selected) {
|
||||
result.push(opt.value || opt.text);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Compute the internal state of the widget
|
||||
@@ -183,7 +192,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
|
||||
SelectWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
// If we're using a different tiddler/field/index then completely refresh ourselves
|
||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tooltip || changedAttributes.tabindex || changedAttributes.disabled) {
|
||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tooltip || changedAttributes.default || changedAttributes.tabindex || changedAttributes.disabled) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@@ -32,16 +32,26 @@ TranscludeWidget.prototype.render = function(parent,nextSibling) {
|
||||
} catch(error) {
|
||||
if(error instanceof $tw.utils.TranscludeRecursionError) {
|
||||
// We were infinite looping.
|
||||
// We need to try and abort as much of the loop as we can, so we will keep "throwing" upward until we find a transclusion that has a different signature.
|
||||
// Hopefully that will land us just outside where the loop began. That's where we want to issue an error.
|
||||
// Rendering widgets beneath this point may result in a freezing browser if they explode exponentially.
|
||||
// We need to try and abort as much of the loop as we
|
||||
// can, so we will keep "throwing" upward until we find
|
||||
// a transclusion that has a different signature.
|
||||
// Hopefully that will land us just outside where the
|
||||
// loop began. That's where we want to issue an error.
|
||||
// Rendering widgets beneath this point may result in a
|
||||
// freezing browser if they explode exponentially.
|
||||
var transcludeSignature = this.getVariable("transclusion");
|
||||
if(this.getAncestorCount() > $tw.utils.TranscludeRecursionError.MAX_WIDGET_TREE_DEPTH - 50) {
|
||||
// For the first fifty transcludes we climb up, we simply collect signatures.
|
||||
// We're assuming that those first 50 will likely include all transcludes involved in the loop.
|
||||
// For the first fifty transcludes we climb up,
|
||||
// we simply collect signatures.
|
||||
// We're assuming those first 50 will likely
|
||||
// include all transcludes involved in the loop.
|
||||
error.signatures[transcludeSignature] = true;
|
||||
} else if(!error.signatures[transcludeSignature]) {
|
||||
// Now that we're past the first 50, let's look for the first signature that wasn't in the loop. That'll be where we print the error and resume rendering.
|
||||
// Now that we're past the first 50, look for
|
||||
// the first signature that wasn't in that loop.
|
||||
// That's where we print the error and resume
|
||||
// rendering.
|
||||
this.removeChildDomNodes();
|
||||
this.children = [this.makeChildWidget({type: "error", attributes: {
|
||||
"$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")}
|
||||
}})];
|
||||
|
||||
@@ -160,7 +160,7 @@ Widget.prototype.getVariableInfo = function(name,options) {
|
||||
});
|
||||
// Parameters are an array of {name:, value:, multivalue:} pairs (name and multivalue are optional)
|
||||
$tw.utils.each(params,function(param) {
|
||||
if(param.multiValue) {
|
||||
if(param.multiValue && param.multiValue.length) {
|
||||
variables[param.name] = param.multiValue;
|
||||
} else {
|
||||
variables[param.name] = param.value || "";
|
||||
@@ -233,8 +233,10 @@ Widget.prototype.resolveVariableParameters = function(formalParams,actualParams)
|
||||
paramMultiValue = typeof param === "string" ? [param] : (param.multiValue || [paramValue]);
|
||||
}
|
||||
// If we've still not got a value, use the default, if any
|
||||
paramValue = paramValue || paramInfo["default"] || "";
|
||||
paramMultiValue = paramMultiValue || [paramValue];
|
||||
if(!paramValue) {
|
||||
paramValue = paramInfo["default"] || "";
|
||||
paramMultiValue = [paramValue];
|
||||
}
|
||||
// Store the parameter name and value
|
||||
results.push({name: paramInfo.name, value: paramValue, multiValue: paramMultiValue});
|
||||
}
|
||||
@@ -414,7 +416,21 @@ Widget.prototype.computeAttribute = function(attribute,options) {
|
||||
value = [value];
|
||||
}
|
||||
} else if(attribute.type === "macro") {
|
||||
var variableInfo = this.getVariableInfo(attribute.value.name,{params: attribute.value.params});
|
||||
// Get the macro name
|
||||
var macroName = attribute.value.attributes["$variable"].value;
|
||||
// Collect macro parameters
|
||||
var params = [];
|
||||
$tw.utils.each(attribute.value.orderedAttributes,function(attr) {
|
||||
var param = {
|
||||
value: self.computeAttribute(attr)
|
||||
};
|
||||
if(attr.name && !attr.isPositional) {
|
||||
param.name = attr.name;
|
||||
}
|
||||
params.push(param);
|
||||
});
|
||||
// Invoke the macro
|
||||
var variableInfo = this.getVariableInfo(macroName,{params: params});
|
||||
if(options.asList) {
|
||||
value = variableInfo.resultList;
|
||||
} else {
|
||||
|
||||
@@ -1122,15 +1122,16 @@ Parse a block of text of a specified MIME type
|
||||
Options include:
|
||||
substitutions: an optional array of substitutions
|
||||
*/
|
||||
exports.getSubstitutedText = function(text,widget,options) {
|
||||
exports.getSubstitutedText = function(text,thisWidget,options) {
|
||||
options = options || {};
|
||||
text = text || "";
|
||||
var self = this,
|
||||
widgetClass = widget.widget,
|
||||
substitutions = options.substitutions || [],
|
||||
output;
|
||||
// Evaluate embedded filters and substitute with first result
|
||||
output = text.replace(/\$\{([\S\s]+?)\}\$/g, function(match,filter) {
|
||||
return self.filterTiddlers(filter,widget)[0] || "";
|
||||
return self.filterTiddlers(filter,thisWidget)[0] || "";
|
||||
});
|
||||
// Process any substitutions provided in options
|
||||
$tw.utils.each(substitutions,function(substitute) {
|
||||
@@ -1138,7 +1139,7 @@ exports.getSubstitutedText = function(text,widget,options) {
|
||||
});
|
||||
// Substitute any variable references with their values
|
||||
return output.replace(/\$\((.+?)\)\$/g, function(match,varname) {
|
||||
return widget.getVariable(varname,{defaultValue: ""});
|
||||
return widgetClass.evaluateVariable(thisWidget,varname, {defaultValue: ""})[0];
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1663,12 +1664,14 @@ exports.addToStory = function(title,fromTitle,storyTitle,options) {
|
||||
Generate a title for the draft of a given tiddler
|
||||
*/
|
||||
exports.generateDraftTitle = function(title) {
|
||||
var c = 0,
|
||||
draftTitle,
|
||||
username = this.getTiddlerText("$:/status/UserName"),
|
||||
attribution = username ? " by " + username : "";
|
||||
let c = 0,
|
||||
draftTitle;
|
||||
const username = this.getTiddlerText("$:/status/UserName");
|
||||
do {
|
||||
draftTitle = "Draft " + (c ? (c + 1) + " " : "") + "of '" + title + "'" + attribution;
|
||||
draftTitle = username ? $tw.language.getString("Draft/Attribution", {variables: {"draft-title": title}}) : $tw.language.getString("Draft/Title", {variables: {"draft-title": title}});
|
||||
if(c) {
|
||||
draftTitle = draftTitle.concat(" ", (c + 1).toString());
|
||||
}
|
||||
c++;
|
||||
} while(this.tiddlerExists(draftTitle));
|
||||
return draftTitle;
|
||||
|
||||
30
core/stylesheets/custom-properties.tid
Normal file
30
core/stylesheets/custom-properties.tid
Normal file
@@ -0,0 +1,30 @@
|
||||
title: $:/core/stylesheets/custom-properties
|
||||
|
||||
\rules only transcludeinline macrocallinline html transcludeblock
|
||||
|
||||
/* Tiddlywiki's CSS properties */
|
||||
|
||||
:root {
|
||||
<$list filter="[[$:/palettes/Vanilla]indexes[]]">
|
||||
--tpc-<<currentTiddler>>: <$transclude $variable="colour" $mode="inline" name=<<currentTiddler>>/>;
|
||||
</$list>
|
||||
|
||||
/* CSS settings */
|
||||
--tp-code-wrapping: {{$:/themes/tiddlywiki/vanilla/options/codewrapping}};
|
||||
--tp-font-family: {{$:/themes/tiddlywiki/vanilla/settings/fontfamily}};
|
||||
--tp-code-font-family: {{$:/themes/tiddlywiki/vanilla/settings/codefontfamily}};
|
||||
--tp-editor-font-family: {{$:/themes/tiddlywiki/vanilla/settings/editorfontfamily}};
|
||||
--tp-font-size: {{$:/themes/tiddlywiki/vanilla/metrics/fontsize}};
|
||||
--tp-line-height: {{$:/themes/tiddlywiki/vanilla/metrics/lineheight}};
|
||||
--tp-body-font-size: {{$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize}};
|
||||
--tp-body-line-height: {{$:/themes/tiddlywiki/vanilla/metrics/bodylineheight}};
|
||||
--tp-story-left: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};
|
||||
--tp-story-top: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};
|
||||
--tp-story-right: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};
|
||||
--tp-story-width: {{$:/themes/tiddlywiki/vanilla/metrics/storyrwidth}};
|
||||
--tp-tiddler-width: {{$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth}};
|
||||
--tp-sidebar-breakpoint: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}};
|
||||
--tp-sidebar-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};
|
||||
|
||||
--tp-animation-duration: {{{ [{$:/config/AnimationDuration}addsuffix[ms]] }}};
|
||||
}
|
||||
@@ -1,157 +1,181 @@
|
||||
title: $:/core/ui/EditTemplate/fields
|
||||
tags: $:/tags/EditTemplate
|
||||
|
||||
\procedure lingo-base() $:/language/EditTemplate/
|
||||
\function tf.config-title() [[$:/config/EditTemplateFields/Visibility/]addsuffix[$(currentField)$]substitute[]get[text]]
|
||||
|
||||
\function tf.config-filter() [[hide]] :except[title<tf.config-title>]
|
||||
|
||||
<!-- Beware this is duplicated from EditTemplate.tid. For details see bug #7054 -->
|
||||
\procedure get-field-value-tiddler-filter() [subfilter<get-field-editor-filter>sha256[16]addprefix[/]addprefix<newFieldValueTiddlerPrefix>]
|
||||
\procedure get-field-editor-filter() [<newFieldNameTiddler>get[text]else[]] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]
|
||||
|
||||
\procedure prefix.bracket() [
|
||||
\procedure suffix.bracket() ]
|
||||
|
||||
\function tf.current-tiddler-new-field-selector() [[data-tiddler-title=]addprefix[$(prefix.bracket)$]substitute[]addsuffix<currentTiddlerCSSescaped>addsuffix[$(suffix.bracket)$]substitute[]] .tc-edit-field-add-name-wrapper input :and[join[ ]]
|
||||
|
||||
\procedure new-field-actions()
|
||||
\whitespace trim
|
||||
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldNameTiddler>get[text]] :map[subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
|
||||
<$set name="safeNewFieldValueTiddlerPrefix" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify "$:/temp/NewFieldValue">> >
|
||||
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix[$:/temp/NewFieldValue]prefix<safeNewFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]"/>
|
||||
</$set>
|
||||
<$action-sendmessage $message="tm-focus-selector" $param=<<tf.current-tiddler-new-field-selector>>/>
|
||||
\end
|
||||
|
||||
\procedure lingo-base() $:/language/EditTemplate/
|
||||
|
||||
\procedure delete-state-tiddlers() <$action-deletetiddler $filter="[<newFieldNameTiddler>] [<storeTitle>] [<searchListState>]"/>
|
||||
|
||||
\procedure cancel-search-actions-inner()
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[<storeTitle>has[text]] [<newFieldNameTiddler>has[text]]"
|
||||
variable="ignore"
|
||||
emptyMessage="<<cancel-delete-tiddler-actions 'cancel'>>">
|
||||
<<delete-state-tiddlers>>
|
||||
</$list>
|
||||
\procedure focus-new-field-input() <$action-sendmessage $message="tm-focus-selector" $param=`[data-tiddler-title="$(storyTiddler)$"] .tc-edit-field-add-name-wrapper input` />
|
||||
|
||||
\procedure new-field-actions()
|
||||
<$action-setfield $tiddler=<<storyTiddler>> $field={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldValueTiddler>get[text]] }}} />
|
||||
<$action-deletetiddler $filter="[prefix[$:/temp/NewFieldValue]prefix<newFieldValueTiddlerPrefix>]"/>
|
||||
<<delete-state-tiddlers>>
|
||||
<<focus-new-field-input>>
|
||||
\end
|
||||
|
||||
\procedure delete-field-actions()
|
||||
<$action-deletefield $field=<<currentField>>/>
|
||||
<<focus-new-field-input>>
|
||||
\end
|
||||
|
||||
\procedure cancel-search-actions()
|
||||
\whitespace trim
|
||||
<$set name="userInput" value={{{ [<storeTitle>get[text]] }}}>
|
||||
<$list
|
||||
filter="[<newFieldNameTiddler>get[text]!match<userInput>]"
|
||||
emptyMessage="<<cancel-search-actions-inner>>">
|
||||
<$action-setfield $tiddler=<<newFieldNameTiddler>> text=<<userInput>>/><$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||
</$list>
|
||||
</$set>
|
||||
<$let userInput={{{ [<storeTitle>get[text]] }}}>
|
||||
<%if [<newFieldNameTiddler>get[text]!match<userInput>] %>
|
||||
<$action-setfield $tiddler=<<newFieldNameTiddler>> text=<<userInput>>/>
|
||||
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||
<%else%>
|
||||
<%if [<storeTitle>has[text]] [<newFieldNameTiddler>has[text]] %>
|
||||
<<delete-state-tiddlers>>
|
||||
<%else%>
|
||||
<<cancel-delete-tiddler-actions 'cancel'>>
|
||||
<%endif%>
|
||||
<%endif%>
|
||||
</$let>
|
||||
\end
|
||||
|
||||
\procedure new-field()
|
||||
\whitespace trim
|
||||
<$vars name={{{ [<newFieldNameTiddler>get[text]] }}}>
|
||||
<$reveal type="nomatch" text="" default=<<name>>>
|
||||
<$button tooltip={{$:/language/EditTemplate/Fields/Add/Button/Hint}}>
|
||||
<$action-sendmessage $message="tm-add-field"
|
||||
$name=<<name>>
|
||||
$value={{{ [subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
|
||||
<$set name="safeNewFieldValueTiddlerPrefix" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify "$:/temp/NewFieldValue">> >
|
||||
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix[$:/temp/NewFieldValue]prefix<safeNewFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]"/>
|
||||
</$set>
|
||||
<<lingo Fields/Add/Button>>
|
||||
</$button>
|
||||
</$reveal>
|
||||
<$reveal type="match" text="" default=<<name>>>
|
||||
<$button>
|
||||
<<lingo Fields/Add/Button>>
|
||||
</$button>
|
||||
</$reveal>
|
||||
</$vars>
|
||||
<%if [<newFieldNameTiddler>get[text]!is[blank]] %>
|
||||
<$button actions="<<new-field-actions>>" tooltip={{$:/language/EditTemplate/Fields/Add/Button/Hint}}>
|
||||
<<lingo Fields/Add/Button>>
|
||||
</$button>
|
||||
<%else%>
|
||||
<$button>
|
||||
<<lingo Fields/Add/Button>>
|
||||
</$button>
|
||||
<%endif%>
|
||||
\end
|
||||
\whitespace trim
|
||||
|
||||
<$set name="newFieldValueTiddlerPrefix" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify "$:/temp/NewFieldValue">> >
|
||||
<div class="tc-edit-fields">
|
||||
<table class={{{ [all[current]fields[]] :filter[lookup[$:/config/EditTemplateFields/Visibility/]!match[hide]] :and[count[]!match[0]] :and[then[tc-edit-fields]] :else[[tc-edit-fields tc-edit-fields-small]] }}}>
|
||||
<tbody>
|
||||
<$list filter="[all[current]fields[]] :and[sort[title]]" variable="currentField" storyview="pop">
|
||||
<$list filter=<<tf.config-filter>> variable="temp">
|
||||
<tr class="tc-edit-field">
|
||||
<td class="tc-edit-field-name">
|
||||
<$text text=<<currentField>>/>:</td>
|
||||
<td class="tc-edit-field-value">
|
||||
<$keyboard key="((delete-field))" actions="""<$action-deletefield $field=<<currentField>>/><$set name="currentTiddlerCSSescaped" value={{{ [<currentTiddler>escapecss[]] }}}><$action-sendmessage $message="tm-focus-selector" $param=<<tf.current-tiddler-new-field-selector>>/></$set>""">
|
||||
<$transclude tiddler={{{ [<currentField>] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}] }}} />
|
||||
</$keyboard>
|
||||
</td>
|
||||
<td class="tc-edit-field-remove">
|
||||
<$button class="tc-btn-invisible" tooltip={{$:/language/EditTemplate/Field/Remove/Hint}} aria-label={{$:/language/EditTemplate/Field/Remove/Caption}}>
|
||||
<$action-deletefield $field=<<currentField>>/>
|
||||
{{$:/core/images/delete-button}}
|
||||
</$button>
|
||||
</td>
|
||||
</tr>
|
||||
</$list>
|
||||
</$list>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
\function tf.config-filter() [lookup:show[$:/config/EditTemplateFields/Visibility/]!match[hide]]
|
||||
|
||||
<$fieldmangler>
|
||||
<div class="tc-edit-field-add">
|
||||
<em class="tc-edit tc-small-gap-right">
|
||||
<<lingo Fields/Add/Prompt>>
|
||||
</em>
|
||||
<$vars refreshTitle=<<qualify "$:/temp/fieldname/refresh">> storeTitle=<<newFieldNameInputTiddler>> searchListState=<<newFieldNameSelectionTiddler>>>
|
||||
<div class="tc-edit-field-add-name-wrapper">
|
||||
<$transclude $variable="keyboard-driven-input" tiddler=<<newFieldNameTiddler>> storeTitle=<<storeTitle>> refreshTitle=<<refreshTitle>>
|
||||
selectionStateTitle=<<searchListState>> tag="input" default="" placeholder={{$:/language/EditTemplate/Fields/Add/Name/Placeholder}}
|
||||
focusPopup=<<qualify "$:/state/popup/field-dropdown">> class="tc-edit-texteditor tc-popup-handle" tabindex={{$:/config/EditTabIndex}}
|
||||
focus={{{ [{$:/config/AutoFocus}match[fields]then[true]] :else[[false]] }}} cancelPopups="yes"
|
||||
configTiddlerFilter="[[$:/config/EditMode/fieldname-filter]]" inputCancelActions=<<cancel-search-actions>> />
|
||||
<$button popup=<<qualify "$:/state/popup/field-dropdown">> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Field/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Field/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button>
|
||||
<$reveal state=<<qualify "$:/state/popup/field-dropdown">> type="nomatch" text="" default="">
|
||||
<div class="tc-block-dropdown tc-edit-type-dropdown">
|
||||
<$set name="tv-show-missing-links" value="yes">
|
||||
<$linkcatcher to=<<newFieldNameTiddler>>>
|
||||
<div class="tc-dropdown-item">
|
||||
<<lingo Fields/Add/Dropdown/User>>
|
||||
</div>
|
||||
<$set name="newFieldName" value={{{ [<storeTitle>get[text]] }}}>
|
||||
<$list filter="[!is[shadow]!is[system]fields[]search:title<newFieldName>sort[]] :except[[created]] :except[[creator]] :except[[draft.of]] :except[[draft.title]] :except[[modified]] :except[[modifier]] :except[[tags]] :except[[text]] :except[[title]] :except[[type]]" variable="currentField">
|
||||
<$list filter="[<currentField>addsuffix[-primaryList]] :except[<searchListState>get[text]]" emptyMessage="""<$link to=<<currentField>> class="tc-list-item-selected"><$text text=<<currentField>>/></$link>""">
|
||||
<$link to=<<currentField>>>
|
||||
<$text text=<<currentField>>/>
|
||||
</$link>
|
||||
</$list>
|
||||
</$list>
|
||||
<div class="tc-dropdown-item">
|
||||
<<lingo Fields/Add/Dropdown/System>>
|
||||
</div>
|
||||
<$list filter="[fields[]search:title<newFieldName>sort[]] :except[!is[shadow]!is[system]fields[]]" variable="currentField">
|
||||
<$list filter="[<currentField>addsuffix[-secondaryList]] :except[<searchListState>get[text]]" emptyMessage="""<$link to=<<currentField>> class="tc-list-item-selected"><$text text=<<currentField>>/></$link>""">
|
||||
<$link to=<<currentField>>>
|
||||
<$text text=<<currentField>>/>
|
||||
</$link>
|
||||
</$list>
|
||||
</$list>
|
||||
</$set>
|
||||
</$linkcatcher>
|
||||
</$set>
|
||||
</div>
|
||||
</$reveal>
|
||||
</div>
|
||||
<$let currentTiddlerCSSescaped={{{ [<currentTiddler>escapecss[]] }}} currentTiddler={{{ [subfilter<get-field-value-tiddler-filter>] }}} currentField="text" currentFieldName={{{ [<newFieldNameTiddler>get[text]] }}}>
|
||||
<span class="tc-edit-field-add-value tc-small-gap-right">
|
||||
<$keyboard key="((add-field))" actions=<<new-field-actions>>>
|
||||
<$transclude tiddler={{{ [subfilter<get-field-editor-filter>] }}} />
|
||||
</$keyboard>
|
||||
</span>
|
||||
<span class="tc-edit-field-add-button">
|
||||
<$transclude $variable="new-field"/>
|
||||
</span>
|
||||
</$let>
|
||||
</$vars>
|
||||
</div>
|
||||
</$fieldmangler>
|
||||
</$set>
|
||||
\function tf.field-cascade()
|
||||
[<currentField>]
|
||||
:cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]]
|
||||
:and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]
|
||||
\end
|
||||
|
||||
\function tf.get-field-editor()
|
||||
[<newFieldNameTiddler>get[text]else[]]
|
||||
:cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]]
|
||||
:and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]
|
||||
\end
|
||||
|
||||
\function tf.primary-list-exceptions() created creator draft.of draft.title modified modifier tags text title type
|
||||
|
||||
\function tf.list-selection-class(listSuffix) [<searchListState>get[text]removesuffix<listSuffix>match<currentField>then[tc-list-item-selected]]
|
||||
|
||||
|
||||
<$let newFieldValueTiddlerPrefix={{{ [<newFieldValueTiddlerPrefix>!is[blank]else<qualify "$:/temp/NewFieldValue">] }}} >
|
||||
<div class="tc-edit-fields">
|
||||
<!-- table of user fields of the current tiddler -->
|
||||
<table class=`tc-edit-fields ${ [all[current]fields[]] :filter[tf.config-filter[]] :and[count[]match[0]then[tc-edit-fields-small]] }$`>
|
||||
<tbody>
|
||||
<$list filter="[all[current]fields[]] :and[sort[title]]" variable="currentField" storyview="pop">
|
||||
<%if [<currentField>tf.config-filter[]] %>
|
||||
<tr class="tc-edit-field">
|
||||
<td class="tc-edit-field-name">
|
||||
<$text text=<<currentField>>/>:
|
||||
</td>
|
||||
<td class="tc-edit-field-value">
|
||||
<$keyboard key="((delete-field))" actions="<<delete-field-actions>>">
|
||||
<$transclude tiddler=<<tf.field-cascade>> />
|
||||
</$keyboard>
|
||||
</td>
|
||||
<td class="tc-edit-field-remove">
|
||||
<$button actions="<<delete-field-actions>>"
|
||||
aria-label={{$:/language/EditTemplate/Field/Remove/Caption}}
|
||||
class="tc-btn-invisible"
|
||||
tooltip={{$:/language/EditTemplate/Field/Remove/Hint}}
|
||||
>
|
||||
{{$:/core/images/delete-button}}
|
||||
</$button>
|
||||
</td>
|
||||
</tr>
|
||||
<%endif%>
|
||||
</$list>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- input control for new field name with selection dropdown -->
|
||||
<div class="tc-edit-field-add">
|
||||
<em class="tc-edit tc-small-gap-right">
|
||||
<<lingo Fields/Add/Prompt>>
|
||||
</em>
|
||||
<$let refreshTitle=<<qualify "$:/temp/fieldname/refresh">>
|
||||
storeTitle=<<newFieldNameInputTiddler>>
|
||||
searchListState=<<newFieldNameSelectionTiddler>>
|
||||
>
|
||||
<div class="tc-edit-field-add-name-wrapper">
|
||||
<$transclude $variable="keyboard-driven-input"
|
||||
cancelPopups="yes"
|
||||
class=`tc-edit-texteditor tc-popup-handle ${ [<newFieldNameTiddler>get[text]] :intersection[<storyTiddler>fields[]] :then[[tc-edit-field-exists]] }$`
|
||||
configTiddlerFilter="[[$:/config/EditMode/fieldname-filter]]"
|
||||
default=""
|
||||
focus={{{ [{$:/config/AutoFocus}match[fields]then[true]] :else[[false]] }}}
|
||||
focusPopup=<<qualify "$:/state/popup/field-dropdown">>
|
||||
inputAcceptVariantActions=<<save-tiddler-actions>>
|
||||
inputCancelActions=<<cancel-search-actions>>
|
||||
placeholder={{$:/language/EditTemplate/Fields/Add/Name/Placeholder}}
|
||||
refreshTitle=<<refreshTitle>>
|
||||
selectionStateTitle=<<searchListState>>
|
||||
storeTitle=<<storeTitle>>
|
||||
tag="input"
|
||||
tabindex={{$:/config/EditTabIndex}}
|
||||
tiddler=<<newFieldNameTiddler>>
|
||||
/>
|
||||
<$button aria-label={{$:/language/EditTemplate/Field/Dropdown/Caption}}
|
||||
class="tc-btn-invisible tc-btn-dropdown tc-small-gap"
|
||||
popup=<<qualify "$:/state/popup/field-dropdown">>
|
||||
tooltip={{$:/language/EditTemplate/Field/Dropdown/Hint}}
|
||||
>
|
||||
{{$:/core/images/down-arrow}}
|
||||
</$button>
|
||||
<$reveal state=<<qualify "$:/state/popup/field-dropdown">> type="nomatch" text="" default="" tag="div" class="tc-block-dropdown tc-edit-type-dropdown">
|
||||
<$let tv-show-missing-links="yes">
|
||||
<$linkcatcher to=<<newFieldNameTiddler>>>
|
||||
<div class="tc-dropdown-item">
|
||||
<<lingo Fields/Add/Dropdown/User>>
|
||||
</div>
|
||||
<$let newFieldName={{{ [<storeTitle>get[text]] }}}
|
||||
primaryListFields={{{ [!is[shadow]!is[system]fields[]format:titlelist[]join[ ]] }}}
|
||||
>
|
||||
<$list filter="[enlist<primaryListFields>search:title<newFieldName>sort[]] :except[tf.primary-list-exceptions[]]" variable="currentField">
|
||||
<$link to=<<currentField>> class=<<tf.list-selection-class "-primaryList">> >
|
||||
<$text text=<<currentField>>/>
|
||||
</$link>
|
||||
</$list>
|
||||
<div class="tc-dropdown-item">
|
||||
<<lingo Fields/Add/Dropdown/System>>
|
||||
</div>
|
||||
<$list filter="[fields[]search:title<newFieldName>!enlist<primaryListFields>sort[]]" variable="currentField">
|
||||
<$link to=<<currentField>> class=<<tf.list-selection-class "-secondaryList">>>
|
||||
<$text text=<<currentField>>/>
|
||||
</$link>
|
||||
</$list>
|
||||
</$let>
|
||||
</$linkcatcher>
|
||||
</$let>
|
||||
</$reveal>
|
||||
</div>
|
||||
|
||||
<!-- input control for new field content -->
|
||||
<$let currentFieldName={{{ [<newFieldNameTiddler>get[text]] }}}
|
||||
fieldEditor=<<tf.get-field-editor>>
|
||||
newFieldValueTiddler={{{ [<newFieldValueTiddlerPrefix>] [[/]] [<fieldEditor>sha256[16]] :and[join[]] }}}
|
||||
currentTiddler=<<newFieldValueTiddler>>
|
||||
>
|
||||
<span class="tc-edit-field-add-value tc-small-gap-right">
|
||||
<$keyboard key="((add-field))" actions="<<new-field-actions>>">
|
||||
<$transclude $tiddler=<<fieldEditor>> />
|
||||
</$keyboard>
|
||||
</span>
|
||||
<span class="tc-edit-field-add-button">
|
||||
<$transclude $variable="new-field"/>
|
||||
</span>
|
||||
</$let>
|
||||
</$let>
|
||||
</div>
|
||||
</$let>
|
||||
@@ -17,7 +17,7 @@ tags: $:/tags/EditTemplate
|
||||
<$let backgroundColor=<<colour>> >
|
||||
<span class="tc-tag-label tc-tag-list-item tc-small-gap-right"
|
||||
data-tag-title=<<currentTiddler>>
|
||||
style=`color:$(foregroundColor)$; background-color:$(backgroundColor)$;`
|
||||
style=`color:$(foregroundColor)$; background-color:$(backgroundColor)$; --tp-remove-tag-button-color:$(foregroundColor)$`
|
||||
>
|
||||
<$transclude tiddler=<<icon>>/>
|
||||
<$view field="title" format="text"/>
|
||||
|
||||
@@ -8,6 +8,8 @@ code-body: yes
|
||||
|
||||
<$set name="languageTitle" value={{!!name}}>
|
||||
|
||||
<$transclude $tiddler="$:/core/stylesheets/custom-properties" $mode="block"/>
|
||||
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]">
|
||||
<$transclude mode="block"/>
|
||||
</$list>
|
||||
|
||||
@@ -15,7 +15,18 @@ tags: $:/tags/Macro
|
||||
</span>
|
||||
\end
|
||||
|
||||
\define toc-body(tag,sort:"",itemClassFilter,exclude,path)
|
||||
\define toc-level-indicator()
|
||||
\whitespace trim
|
||||
<%if [<__level__>compare:number:gt[0]]%>
|
||||
<%if [<currentTiddler>tagging[]] %>
|
||||
<span class="tc-tiny-gap-left">{{$:/core/images/new-button}}</span>
|
||||
<%else%>
|
||||
<span class="tc-tiny-gap-left">{{$:/core/images/blank}}</span>
|
||||
<%endif%>
|
||||
<% endif %>
|
||||
\end
|
||||
|
||||
\define toc-body(tag,sort:"",itemClassFilter,exclude,path,level)
|
||||
\whitespace trim
|
||||
<ol class="tc-toc">
|
||||
<$list filter="""[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[subfilter<__exclude__>]""">
|
||||
@@ -23,10 +34,26 @@ tags: $:/tags/Macro
|
||||
<$set name="excluded" filter="[subfilter<__exclude__>] [<__tag__>]">
|
||||
<$set name="toc-item-class" filter=<<__itemClassFilter__>> emptyValue="toc-item-selected" value="toc-item">
|
||||
<li class=<<toc-item-class>>>
|
||||
<$list filter="[all[current]toc-link[no]]" emptyMessage="<$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}><<toc-caption>></$link>">
|
||||
<$list filter="[all[current]toc-link[no]]" >
|
||||
<$list-empty>
|
||||
<!-- link to target-field or currentTiddler -->
|
||||
<$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}>
|
||||
<<toc-level-indicator>>
|
||||
<<toc-caption>>
|
||||
</$link>
|
||||
</$list-empty>
|
||||
<!-- toc-link = no -->
|
||||
<<toc-level-indicator>>
|
||||
<<toc-caption>>
|
||||
</$list>
|
||||
<$macrocall $name="toc-body" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>
|
||||
<$let _level={{{ [<__level__>subtract[1]] }}}>
|
||||
<%if [<_level>compare:number:gt[0]]%>
|
||||
<$macrocall $name="toc-body" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>> level=<<_level>>/>
|
||||
<%elseif [<_level>match[-1]]%>
|
||||
<!-- show full toc, no level defined -->
|
||||
<$macrocall $name="toc-body" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>
|
||||
<%endif%>
|
||||
</$let>
|
||||
</li>
|
||||
</$set>
|
||||
</$set>
|
||||
@@ -35,10 +62,10 @@ tags: $:/tags/Macro
|
||||
</ol>
|
||||
\end
|
||||
|
||||
\define toc(tag,sort:"",itemClassFilter:"", exclude)
|
||||
\define toc(tag,sort:"",itemClassFilter:"",exclude,level)
|
||||
\whitespace trim
|
||||
<$let __tag__={{{ [<__tag__>is[blank]then<currentTiddler>else<__tag__>] }}} >
|
||||
<$macrocall $name="toc-body" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>>/>
|
||||
<$macrocall $name="toc-body" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> level=<<__level__>>/>
|
||||
</$let>
|
||||
\end
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
created: 20150220191009000
|
||||
modified: 20150602092431500
|
||||
title: $:/editions/tw5.com/railroad/macro-parameter-value
|
||||
title: $:/editions/tw5.com/railroad/call-parameter-value
|
||||
type: text/vnd.tiddlywiki.railroad
|
||||
|
||||
( '"""' [:{/'tout sauf """'/}] '"""'
|
||||
| '"' [:{/'tout sauf "'/}] '"'
|
||||
| "'" [:{/"tout sauf '"/}] "'"
|
||||
| "[[" [:{/"tout sauf ]"/}] "]]"
|
||||
| "`" [:{/"tout sauf `"/}] "`"
|
||||
| "```" [:{/"tout sauf ```"/}] "```"
|
||||
| {/"""tout sauf ' " ou espacevierge"""/}
|
||||
)
|
||||
|
||||
@@ -25,4 +25,4 @@ The <<.place param-nom>> is a sequence of letters (`A`--`Z`, `a`--`z`), digits (
|
||||
|
||||
The <<.place valeur>> is specified as follows<<dp>>
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
||||
|
||||
@@ -33,7 +33,7 @@ parametre.nom [: [:espace] ":" [:espace] defaut ]
|
||||
|
||||
La valeur par <<.place défaut>> d'un paramètre est spécifiée comme suit<<:>>
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
||||
|
||||
La définition de la <<.place suite>> se fait comme suit<<:>>
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
title: Functions/FunctionDefaultValues
|
||||
description: Use defaults for missing parameters in functions in filters
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
\function .test(prefix:Default) [[ Content]addprefix<prefix>]
|
||||
|
||||
<$text text={{{ [.test[Special]] }}}/>,<$text text={{{ [.test[]] }}}/>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>Special Content,Default Content</p>
|
||||
@@ -0,0 +1,38 @@
|
||||
title: Functions/FunctionResolutionInSubstitute
|
||||
description: Functions should resolve correctly in the substitute operator
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
|
||||
\function getIndex() [<index>add[1]]
|
||||
|
||||
\procedure template-with-var() $(getIndex)$
|
||||
|
||||
\procedure template-with-filteredexpression() ${ [<getIndex>] }$
|
||||
|
||||
\function test-with-substitute-variable()
|
||||
[[abc]split[]] :map[<template-with-var>substitute[]] :and[join[ / ]]
|
||||
\end
|
||||
|
||||
\function test-with-substitute-filteredexpression()
|
||||
[[abc]split[]] :map[<template-with-filteredexpression>substitute[]] :and[join[ / ]]
|
||||
\end
|
||||
|
||||
\function test-with-function()
|
||||
[[abc]split[]] :map[function[getIndex]substitute[]] :and[join[ / ]]
|
||||
\end
|
||||
|
||||
|
||||
|
||||
<<test-with-substitute-variable>>|
|
||||
<<test-with-substitute-filteredexpression>>|
|
||||
<<test-with-function>>
|
||||
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>1 / 2 / 3|1 / 2 / 3|1 / 2 / 3</p>
|
||||
@@ -0,0 +1,26 @@
|
||||
title: Macros/Dynamic/Attribute
|
||||
description: Attribute macrocall with dynamic paramters
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\define mamacromamacro(param:"red")
|
||||
It is $param$
|
||||
\end
|
||||
|
||||
<$text text=<<mamacromamacro>>/>
|
||||
-
|
||||
<$text text=<<mamacromamacro param={{{ [[a]addprefix[b]] }}}>>/>
|
||||
-
|
||||
<$text text=<<mamacromamacro param>>/>
|
||||
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>It is red
|
||||
-
|
||||
It is ba
|
||||
-
|
||||
It is param
|
||||
</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
title: Macros/Dynamic/Standalone
|
||||
description: Standalone macrocall with dynamic paramters
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
|
||||
\define mamacro(one:"red",two:"green")
|
||||
It is $one$ and $two$ or <<__one__>> and <<__two__>>.
|
||||
\end
|
||||
|
||||
<<mamacro>>
|
||||
|
||||
<<mamacro one={{{ [[b]addprefix[a]] }}}>>
|
||||
|
||||
|
||||
<<mamacro one>>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>It is red and green or red and green.</p><p>It is ab and green or ab and green.</p><p>It is one and green or one and green.</p>
|
||||
@@ -0,0 +1,9 @@
|
||||
tags: $:/tags/wikitext-serialize-test-spec
|
||||
title: Serialize/DynamicMacroMixed
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<mymacro static:"value" dynamic={{reference}} filter={{{ [tag[test]] }}}>>
|
||||
|
||||
<$macrocall $name="mymacro" static="value" dynamic=<<inner>>/>
|
||||
|
||||
<<mymacro `substituted $(var)$`>>
|
||||
@@ -0,0 +1,9 @@
|
||||
tags: $:/tags/wikitext-serialize-test-spec
|
||||
title: Serialize/DynamicMacroParams
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<mymacro param={{Something}}>>
|
||||
|
||||
<<mymacro param={{{ [<myvar>addprefix[https:]] }}}>>
|
||||
|
||||
<$macrocall $name="outermacro" inner=<<innermacro arg="value">>/>
|
||||
@@ -0,0 +1,7 @@
|
||||
tags: $:/tags/wikitext-serialize-test-spec
|
||||
title: Serialize/DynamicWidgetAttribute
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<div class=<<mymacro param={{Something}}>>>content</div>
|
||||
|
||||
<$button actions=<<myactions target={{!!title}}>>/>
|
||||
@@ -7,3 +7,7 @@ type: text/vnd.tiddlywiki
|
||||
<<.def "macro calls">>
|
||||
|
||||
<<alert "primary" "primary alert" width:"60%">>
|
||||
|
||||
<<john one:val1 two:val2 three:"quoted value">>
|
||||
|
||||
<<test unquoted:value quoted:"value" number:123>>
|
||||
|
||||
@@ -3,3 +3,5 @@ title: Serialize/MacroCallInline
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
These are macro calls in a line: <<name "value" "value2">> and <<.def "macro calls">> <<alert "primary" "primary alert" width:"60%">>
|
||||
|
||||
Testing unquoted parameters: <<john one:val1 two:val2>> and <<test param:value other:"quoted">>.
|
||||
|
||||
@@ -235,11 +235,307 @@ describe("HTML tag new parser tests", function() {
|
||||
expect(parser.parseTag("< $mytag attrib1='something' attrib2=else thing>",0)).toEqual(
|
||||
null
|
||||
);
|
||||
expect(parser.parseTag("<$mytag attrib3=<<myMacro one:two three:'four and five'>>>",0)).toEqual(
|
||||
{ type : "mytag", start : 0, attributes : { attrib3 : { type : "macro", start : 7, name : "attrib3", value : { type : "macrocall", start : 16, params : [ { type : "macro-parameter", start : 25, value : "two", name : "one", end : 33 }, { type : "macro-parameter", start : 33, value : "four and five", name : "three", end : 55 } ], name : "myMacro", end : 57 }, end : 57 } }, orderedAttributes: [ { type : "macro", start : 7, name : "attrib3", value : { type : "macrocall", start : 16, params : [ { type : "macro-parameter", start : 25, value : "two", name : "one", end : 33 }, { type : "macro-parameter", start : 33, value : "four and five", name : "three", end : 55 } ], name : "myMacro", end : 57 }, end : 57 } ], tag : "$mytag", end : 58 }
|
||||
expect(parser.parseTag("<$mytag attrib3=<<myMacro one:two three:'four and five'>>>", 0)).toEqual(
|
||||
{
|
||||
"type": "mytag",
|
||||
"start": 0,
|
||||
"attributes": {
|
||||
"attrib3": {
|
||||
"start": 7,
|
||||
"name": "attrib3",
|
||||
"type": "macro",
|
||||
"value": {
|
||||
"type": "transclude",
|
||||
"start": 16,
|
||||
"attributes": {
|
||||
"$variable": {
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
"one": {
|
||||
"start": 25,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 33
|
||||
},
|
||||
"three": {
|
||||
"start": 33,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 55
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
{
|
||||
"start": 25,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 33
|
||||
},
|
||||
{
|
||||
"start": 33,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 55
|
||||
}
|
||||
],
|
||||
"end": 57
|
||||
},
|
||||
"end": 57
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"start": 7,
|
||||
"name": "attrib3",
|
||||
"type": "macro",
|
||||
"value": {
|
||||
"type": "transclude",
|
||||
"start": 16,
|
||||
"attributes": {
|
||||
"$variable": {
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
"one": {
|
||||
"start": 25,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 33
|
||||
},
|
||||
"three": {
|
||||
"start": 33,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 55
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
{
|
||||
"start": 25,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 33
|
||||
},
|
||||
{
|
||||
"start": 33,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 55
|
||||
}
|
||||
],
|
||||
"end": 57
|
||||
},
|
||||
"end": 57
|
||||
}
|
||||
],
|
||||
"tag": "$mytag",
|
||||
"end": 58
|
||||
}
|
||||
);
|
||||
expect(parser.parseTag("<$mytag attrib1='something' attrib2=else thing attrib3=<<myMacro one:two three:'four and five'>>>",0)).toEqual(
|
||||
{ type : "mytag", start : 0, attributes : { attrib1 : { type : "string", start : 7, name : "attrib1", value : "something", end : 27 }, attrib2 : { type : "string", start : 27, name : "attrib2", value : "else", end : 40 }, thing : { type : "string", start : 40, name : "thing", value : "true", end : 47 }, attrib3 : { type : "macro", start : 47, name : "attrib3", value : { type : "macrocall", start : 55, params : [ { type : "macro-parameter", start : 64, value : "two", name : "one", end : 72 }, { type : "macro-parameter", start : 72, value : "four and five", name : "three", end : 94 } ], name : "myMacro", end : 96 }, end : 96 } }, orderedAttributes: [ { type : "string", start : 7, name : "attrib1", value : "something", end : 27 }, { type : "string", start : 27, name : "attrib2", value : "else", end : 40 }, { type : "string", start : 40, name : "thing", value : "true", end : 47 }, { type : "macro", start : 47, name : "attrib3", value : { type : "macrocall", start : 55, params : [ { type : "macro-parameter", start : 64, value : "two", name : "one", end : 72 }, { type : "macro-parameter", start : 72, value : "four and five", name : "three", end : 94 } ], name : "myMacro", end : 96 }, end : 96 } ], tag : "$mytag", end : 97 }
|
||||
{
|
||||
"type": "mytag",
|
||||
"start": 0,
|
||||
"attributes": {
|
||||
"attrib1": {
|
||||
"start": 7,
|
||||
"name": "attrib1",
|
||||
"type": "string",
|
||||
"value": "something",
|
||||
"end": 27
|
||||
},
|
||||
"attrib2": {
|
||||
"start": 27,
|
||||
"name": "attrib2",
|
||||
"type": "string",
|
||||
"value": "else",
|
||||
"end": 40
|
||||
},
|
||||
"thing": {
|
||||
"start": 40,
|
||||
"name": "thing",
|
||||
"type": "string",
|
||||
"value": "true",
|
||||
"end": 47
|
||||
},
|
||||
"attrib3": {
|
||||
"start": 47,
|
||||
"name": "attrib3",
|
||||
"type": "macro",
|
||||
"value": {
|
||||
"type": "transclude",
|
||||
"start": 55,
|
||||
"attributes": {
|
||||
"$variable": {
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
"one": {
|
||||
"start": 64,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 72
|
||||
},
|
||||
"three": {
|
||||
"start": 72,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 94
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
{
|
||||
"start": 64,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 72
|
||||
},
|
||||
{
|
||||
"start": 72,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 94
|
||||
}
|
||||
],
|
||||
"end": 96
|
||||
},
|
||||
"end": 96
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"start": 7,
|
||||
"name": "attrib1",
|
||||
"type": "string",
|
||||
"value": "something",
|
||||
"end": 27
|
||||
},
|
||||
{
|
||||
"start": 27,
|
||||
"name": "attrib2",
|
||||
"type": "string",
|
||||
"value": "else",
|
||||
"end": 40
|
||||
},
|
||||
{
|
||||
"start": 40,
|
||||
"name": "thing",
|
||||
"type": "string",
|
||||
"value": "true",
|
||||
"end": 47
|
||||
},
|
||||
{
|
||||
"start": 47,
|
||||
"name": "attrib3",
|
||||
"type": "macro",
|
||||
"value": {
|
||||
"type": "transclude",
|
||||
"start": 55,
|
||||
"attributes": {
|
||||
"$variable": {
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
"one": {
|
||||
"start": 64,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 72
|
||||
},
|
||||
"three": {
|
||||
"start": 72,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 94
|
||||
}
|
||||
},
|
||||
"orderedAttributes": [
|
||||
{
|
||||
"name": "$variable",
|
||||
"type": "string",
|
||||
"value": "myMacro"
|
||||
},
|
||||
{
|
||||
"start": 64,
|
||||
"name": "one",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "two",
|
||||
"end": 72
|
||||
},
|
||||
{
|
||||
"start": 72,
|
||||
"name": "three",
|
||||
"assignmentOperator": ":",
|
||||
"type": "string",
|
||||
"value": "four and five",
|
||||
"quoted": true,
|
||||
"end": 94
|
||||
}
|
||||
],
|
||||
"end": 96
|
||||
},
|
||||
"end": 96
|
||||
}
|
||||
],
|
||||
"tag": "$mytag",
|
||||
"end": 97
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -177,6 +177,32 @@ describe("Widget module", function() {
|
||||
expect(wrapper.innerHTML).toBe("<span class=\"tc-error\">Recursive transclusion error in transclude widget</span> <span class=\"tc-error\">Recursive transclusion error in transclude widget</span>");
|
||||
});
|
||||
|
||||
// Do NOT use a for-of or for-in here. Each jasmine test must be
|
||||
// defined in its own function context, or the `tag` variable will
|
||||
// end up being the same value for all iterations of the test.
|
||||
$tw.utils.each(["div","$button","$checkbox","$diff-text","$draggable","$droppable","dropzone","$eventcatcher","$keyboard","$link","$list filter=x variable=x","$radio","$reveal type=nomatch","$scrollable","$select","$view field=x"],function(tag) {
|
||||
it(`${tag} cleans itself up if children rendering fails`, function() {
|
||||
var wiki = new $tw.Wiki();
|
||||
wiki.addTiddler({title: "TiddlerOne", text: `<$tiddler tiddler='TiddlerOne'><${tag}><$transclude />`});
|
||||
var parseTreeNode = {type: "widget", children: [
|
||||
{type: "transclude", attributes: {
|
||||
"tiddler": {type: "string", value: "TiddlerOne"}
|
||||
}}
|
||||
]};
|
||||
// Construct the widget node
|
||||
var widgetNode = createWidgetNode(parseTreeNode,wiki);
|
||||
// Render the widget node to the DOM
|
||||
var wrapper = renderWidgetNode(widgetNode);
|
||||
// We don't actually care exactly what the HTML contains,
|
||||
// only that it's reasonably sized. If it's super large,
|
||||
// that means the widget containing the bad transclusion
|
||||
// didn't figure out how to clean itself up, and it cloned a bunch.
|
||||
var html = wrapper.innerHTML;
|
||||
expect(html).toContain("Recursive transclusion error in transclude widget");
|
||||
expect(html.length).toBeLessThan(256, "CONTENTS: " + html);
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle many-tiddler recursion with branching nodes", function() {
|
||||
var wiki = new $tw.Wiki();
|
||||
// Add a tiddler
|
||||
|
||||
@@ -261,7 +261,7 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
expect(parse("text <<john one:val1 two: 'val \"2\"' three: \"val '3'\" four: \"\"\"val 4\"5'\"\"\" five: [[val 5]] >>")).toEqual(
|
||||
|
||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":92,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","type":"string","value":"val1","start":11,"end":20},"two":{"name":"two","type":"string","value":"val \"2\"","start":20,"end":35},"three":{"name":"three","type":"string","value":"val '3'","start":35,"end":52},"four":{"name":"four","type":"string","value":"val 4\"5'","start":52,"end":73},"five":{"name":"five","type":"string","value":"val 5","start":73,"end":89}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","type":"string","value":"val1","start":11,"end":20},{"name":"two","type":"string","value":"val \"2\"","start":20,"end":35},{"name":"three","type":"string","value":"val '3'","start":35,"end":52},{"name":"four","type":"string","value":"val 4\"5'","start":52,"end":73},{"name":"five","type":"string","value":"val 5","start":73,"end":89}]}],"start":0,"end":92}]
|
||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":92,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":11,"end":20},"two":{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":20,"end":35},"three":{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":35,"end":52},"four":{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":52,"end":73},"five":{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":73,"end":89}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":11,"end":20},{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":20,"end":35},{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":35,"end":52},{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":52,"end":73},{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":73,"end":89}]}],"start":0,"end":92}]
|
||||
|
||||
);
|
||||
expect(parse("ignored << carrots <<john>>")).toEqual(
|
||||
@@ -287,7 +287,7 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
expect(parse("text <<outie one:'my <<innie>>' >>")).toEqual(
|
||||
|
||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":34,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"outie"},"one":{"name":"one","type":"string","value":"my <<innie>>","start":12,"end":31}},"orderedAttributes":[{"name":"$variable","type":"string","value":"outie"},{"name":"one","type":"string","value":"my <<innie>>","start":12,"end":31}]}],"start":0,"end":34}]
|
||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":34,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"outie"},"one":{"name":"one","assignmentOperator":":","type":"string","value":"my <<innie>>","quoted":true,"start":12,"end":31}},"orderedAttributes":[{"name":"$variable","type":"string","value":"outie"},{"name":"one","assignmentOperator":":","type":"string","value":"my <<innie>>","quoted":true,"start":12,"end":31}]}],"start":0,"end":34}]
|
||||
|
||||
);
|
||||
|
||||
@@ -301,7 +301,7 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
expect(parse("<<john one:val1 two: 'val \"2\"' three: \"val '3'\" four: \"\"\"val 4\"5'\"\"\" five: [[val 5]] >>")).toEqual(
|
||||
|
||||
[{"type":"transclude","start":0,"end":87,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","type":"string","value":"val1","start":6,"end":15},"two":{"name":"two","type":"string","value":"val \"2\"","start":15,"end":30},"three":{"name":"three","type":"string","value":"val '3'","start":30,"end":47},"four":{"name":"four","type":"string","value":"val 4\"5'","start":47,"end":68},"five":{"name":"five","type":"string","value":"val 5","start":68,"end":84}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","type":"string","value":"val1","start":6,"end":15},{"name":"two","type":"string","value":"val \"2\"","start":15,"end":30},{"name":"three","type":"string","value":"val '3'","start":30,"end":47},{"name":"four","type":"string","value":"val 4\"5'","start":47,"end":68},{"name":"five","type":"string","value":"val 5","start":68,"end":84}],"isBlock":true}]
|
||||
[{"type":"transclude","start":0,"end":87,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":6,"end":15},"two":{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":15,"end":30},"three":{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":30,"end":47},"four":{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":47,"end":68},"five":{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":68,"end":84}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":6,"end":15},{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":15,"end":30},{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":30,"end":47},{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":47,"end":68},{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":68,"end":84}],"isBlock":true}]
|
||||
|
||||
);
|
||||
expect(parse("<< carrots\n\n<<john>>")).toEqual(
|
||||
@@ -321,12 +321,12 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
expect(parse("<<multiline arg:\"\"\"\n\nwikitext\n\"\"\" >>")).toEqual(
|
||||
|
||||
[{"type":"transclude","start":0,"end":36,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"multiline"},"arg":{"name":"arg","type":"string","value":"\n\nwikitext\n","start":11,"end":33}},"orderedAttributes":[{"name":"$variable","type":"string","value":"multiline"},{"name":"arg","type":"string","value":"\n\nwikitext\n","start":11,"end":33}],"isBlock":true}]
|
||||
[{"type":"transclude","start":0,"end":36,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"multiline"},"arg":{"name":"arg","assignmentOperator":":","type":"string","value":"\n\nwikitext\n","quoted":true,"start":11,"end":33}},"orderedAttributes":[{"name":"$variable","type":"string","value":"multiline"},{"name":"arg","assignmentOperator":":","type":"string","value":"\n\nwikitext\n","quoted":true,"start":11,"end":33}],"isBlock":true}]
|
||||
|
||||
);
|
||||
expect(parse("<<outie one:'my <<innie>>' >>")).toEqual(
|
||||
|
||||
[ { type: "transclude", start: 0, rule: "macrocallblock", attributes: { $variable: {name: "$variable", type:"string", value: "outie"}, one: {name: "one", type:"string", value: "my <<innie>>", start: 7, end: 26} }, orderedAttributes: [ {name: "$variable", type:"string", value: "outie"}, {name: "one", type:"string", value: "my <<innie>>", start: 7, end: 26} ], end: 29, isBlock: true } ]
|
||||
[ { type: "transclude", start: 0, rule: "macrocallblock", attributes: { $variable: {name: "$variable", type:"string", value: "outie"}, one: {name: "one", assignmentOperator: ":", type:"string", value: "my <<innie>>", quoted: true, start: 7, end: 26} }, orderedAttributes: [ {name: "$variable", type:"string", value: "outie"}, {name: "one", assignmentOperator: ":", type:"string", value: "my <<innie>>", quoted: true, start: 7, end: 26} ], end: 29, isBlock: true } ]
|
||||
|
||||
);
|
||||
});
|
||||
@@ -334,23 +334,23 @@ describe("WikiText parser tests", function() {
|
||||
it("should parse tricky macrocall parameters", function() {
|
||||
expect(parse("<<john pa>am>>")).toEqual(
|
||||
|
||||
[{"type":"transclude","start":0,"end":14,"attributes":{"0":{"name":"0","type":"string","value":"pa>am","start":6,"end":12},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"pa>am","start":6,"end":12}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
[{"type":"transclude","start":0,"end":14,"attributes":{"0":{"name":"0","type":"string","value":"pa>am","start":6,"end":12,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"pa>am","start":6,"end":12,"isPositional":true}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
|
||||
);
|
||||
expect(parse("<<john param> >>")).toEqual(
|
||||
|
||||
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"param>","start":6,"end":13},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param>","start":6,"end":13}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"param>","start":6,"end":13,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param>","start":6,"end":13,"isPositional":true}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
|
||||
);
|
||||
expect(parse("<<john param>>>")).toEqual(
|
||||
|
||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"transclude","start":0,"end":14,"rule":"macrocallinline","attributes":{"0":{"name":"0","type":"string","value":"param","start":6,"end":12},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param","start":6,"end":12}]},{"type":"text","text":">","start":14,"end":15}],"start":0,"end":15}]
|
||||
[{"type":"element","rule":"parseblock","tag":"p","children":[{"type":"transclude","start":0,"end":14,"rule":"macrocallinline","attributes":{"0":{"name":"0","type":"string","value":"param","start":6,"end":12,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param","start":6,"end":12,"isPositional":true}]},{"type":"text","text":">","start":14,"end":15}],"start":0,"end":15}]
|
||||
|
||||
);
|
||||
// equals signs should be allowed
|
||||
expect(parse("<<john var>=4 >>")).toEqual(
|
||||
|
||||
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"var>=4","start":6,"end":13},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"var>=4","start":6,"end":13}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"var>=4","start":6,"end":13,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"var>=4","start":6,"end":13,"isPositional":true}],"isBlock":true,"rule":"macrocallblock"}]
|
||||
|
||||
);
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ Prioritise the groups to translate first. A translation can be useful without be
|
||||
* Buttons
|
||||
* Control Panel
|
||||
* Date
|
||||
* Draft
|
||||
* Edit Template
|
||||
* Getting Started
|
||||
* Import
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
title: $:/status/UserName
|
||||
|
||||
Jermolene
|
||||
@@ -51,6 +51,7 @@
|
||||
"--render","$:/plugins/tiddlywiki/translators/templates/ControlPanel.multids","language/ControlPanel.multids","text/plain",
|
||||
"--render","$:/plugins/tiddlywiki/translators/templates/CoreReadMe.tid","language/CoreReadMe.tid","text/plain",
|
||||
"--render","$:/plugins/tiddlywiki/translators/templates/Dates.multids","language/Dates.multids","text/plain",
|
||||
"--render","$:/plugins/tiddlywiki/translators/templates/Draft.multids","language/Draft.multids","text/plain",
|
||||
"--render","$:/plugins/tiddlywiki/translators/templates/EditTemplate.multids","language/EditTemplate.multids","text/plain",
|
||||
"--render","$:/plugins/tiddlywiki/translators/templates/Exporters.multids","language/Exporters.multids","text/plain",
|
||||
"--render","$:/plugins/tiddlywiki/translators/templates/Fields.multids","language/Fields.multids","text/plain",
|
||||
|
||||
11
editions/tw5.com/tiddlers/Core CSS Variables.tid
Normal file
11
editions/tw5.com/tiddlers/Core CSS Variables.tid
Normal file
@@ -0,0 +1,11 @@
|
||||
created: 20251108075028089
|
||||
modified: 20260130070027124
|
||||
tags: Reference
|
||||
title: Core CSS Variables
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version 5.4.0>> Tiddlywiki CSS variable definitions starts with `--tp-*` and `--tpc-*`. They are mainly used to [[Write stylesheets in vanilla CSS|Writing stylesheets in vanilla CSS]]. These prefixes ''are reserved'' for Tiddlywiki, so it should not be used for user defined CSS variables. It is also not recommended to override these core CSS variables.
|
||||
|
||||
Core CSS variables are defined in [[$:/core/stylesheets/custom-properties]].
|
||||
|
||||
<<list-links "[tag[Core CSS Variables]]" class:"multi-columns">>
|
||||
@@ -0,0 +1,69 @@
|
||||
created: 20251108075645447
|
||||
modified: 20260201043953311
|
||||
title: Writing stylesheets in vanilla CSS
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version 5.4.0>> Before v5.4.0, theme developers have to mix wikitext syntax with CSS syntax when writing stylesheets to intergrate Tiddlywiki color palettes and theme settings. With the introduction of [[Core CSS Variables]] in v5.4.0, theme developers can intergrate most Tiddlywiki palettes with vanilla CSS.
|
||||
|
||||
! Getting Tiddlywiki palette colors
|
||||
Tiddlywiki's custom properties for colors are prefixed `--tpc-`. Before v5.4.0, theme developers have to use the following wikitext to get a color value of a palette:
|
||||
|
||||
```
|
||||
.tag {
|
||||
background: <<colour tag-background>>;
|
||||
}
|
||||
```
|
||||
|
||||
Since v5.4.0, theme developers can use the following CSS to get the palette color:
|
||||
|
||||
```css
|
||||
.tag {
|
||||
background: var(--tp-color-tag-background);
|
||||
}
|
||||
```
|
||||
|
||||
! Getting and processing Tiddlywiki CSS settings
|
||||
See [[Core CSS Variables]] for the available CSS variables. Before v5.4.0, theme developers have to use macros with filters to get and process theme settings:
|
||||
|
||||
```
|
||||
.tc-sidebar-header {
|
||||
padding: 14px;
|
||||
min-height: 32px;
|
||||
margin-top: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};
|
||||
transition: min-height {{$:/config/AnimationDuration}}ms ease-in-out, padding-top {{$:/config/AnimationDuration}}ms ease-in-out, padding-bottom {{$:/config/AnimationDuration}}ms ease-in-out;
|
||||
}
|
||||
```
|
||||
|
||||
Since v5.4.0, the theme settings are also available as the CSS variables, so theme developers can use the following code:
|
||||
|
||||
```css
|
||||
.tc-sidebar-header {
|
||||
padding: 14px;
|
||||
min-height: 32px;
|
||||
margin-top: var(--tp-story-top);
|
||||
transition: min-height var(--tp-animation-duration) ease-in-out, padding-top var(--tp-animation-duration) ease-in-out, padding-bottom var(--tp-animation-duration) ease-in-out;
|
||||
}
|
||||
```
|
||||
|
||||
! Limits
|
||||
CSS variables can only be used in rules, while wikitext can be used everywhere. See this example:
|
||||
|
||||
Old way of using wikitext in media query definitions:
|
||||
|
||||
```
|
||||
\define sidebarbreakpoint()
|
||||
<$text text={{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}/>
|
||||
\end
|
||||
|
||||
@media (min-width: <<sidebarbreakpoint>>) {
|
||||
/* CSS rules */
|
||||
}
|
||||
```
|
||||
|
||||
While using CSS variables in media quert definitions doesn't work at all:
|
||||
|
||||
```css
|
||||
@media (min-width: var(--tp-sidebar-breakpoint)) {
|
||||
/* Doesn't work */
|
||||
}
|
||||
```
|
||||
@@ -193,11 +193,11 @@ tr.doc-table-subheading {
|
||||
}
|
||||
|
||||
.doc-block-icon .tc-image-tip {
|
||||
fill: <<colour primary>>;
|
||||
color: <<colour primary>>;
|
||||
}
|
||||
|
||||
.doc-block-icon .tc-image-warning {
|
||||
fill: <<colour alert-highlight>>;
|
||||
color: <<colour alert-highlight>>;
|
||||
}
|
||||
|
||||
a.doc-from-version {
|
||||
@@ -215,7 +215,6 @@ a.doc-from-version.doc-from-version-new {
|
||||
}
|
||||
|
||||
a.doc-from-version svg {
|
||||
fill: currentColor;
|
||||
vertical-align: sub;
|
||||
}
|
||||
|
||||
@@ -224,7 +223,6 @@ a.doc-deprecated-version.tc-tiddlylink {
|
||||
border-radius: 1em;
|
||||
background: red;
|
||||
color: <<colour background>>;
|
||||
fill: <<colour background>>;
|
||||
padding: 0 0.4em;
|
||||
font-size: 0.7em;
|
||||
text-transform: uppercase;
|
||||
|
||||
@@ -36,7 +36,6 @@ type: text/vnd.tiddlywiki
|
||||
border-radius: 6px;
|
||||
padding: 0.5em;
|
||||
color: <<colour background>>;
|
||||
fill: <<colour background>>;
|
||||
}
|
||||
|
||||
.tc-cards.tc-action-card .tc-card-button svg {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-animation-duration
|
||||
created: 20260130075755351
|
||||
modified: 20260130075855780
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-animation-duration CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-animation-duration` CSS variable represents the "Animation duration" setting in the control panel. The `ms` suffix is added.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-body-font-size
|
||||
created: 20260122111308483
|
||||
modified: 20260130045633904
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-body-font-size CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-body-font-size` CSS variable represents the "Font size for tiddler body" setting in Theme Tweaks.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-body-line-height
|
||||
created: 20260122111249446
|
||||
modified: 20260130045720240
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-body-line-height CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-body-line-height` CSS variable represents the "Line height for tiddler body" setting in Theme Tweaks.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-code-font-family
|
||||
created: 20260122110850673
|
||||
modified: 20260130045333134
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-code-font-family CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-code-font-family` CSS variable represents the "Code font family" setting in Theme Tweaks.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-code-wrapping
|
||||
created: 20260122110618231
|
||||
modified: 20260130045345387
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-code-wrapping CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-code-wrapping` CSS variable represents the "Wrap long lines in code blocks" setting in Theme Tweaks. Its value is `pre` when the setting is set to "No", and `pre-wrap` when set to "Yes".
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-editor-font-family
|
||||
created: 20260122110858791
|
||||
modified: 20260130045422071
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-editor-font-family CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-editor-font-family` CSS variable represents the "Editor font family" setting in Theme Tweaks.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-font-family
|
||||
created: 20260122110741282
|
||||
modified: 20260130045301357
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-font-family CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-font-family` CSS variable represents the "Font family" setting in Theme Tweaks.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-font-size
|
||||
created: 20260122110956954
|
||||
modified: 20260130045455466
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-font-size CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-font-size` CSS variable represents the "Font size" setting in Theme Tweaks.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-line-height
|
||||
created: 20260122111115266
|
||||
modified: 20260130045757204
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-line-height CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-line-height` CSS variable represents the "Line height" setting in Theme Tweaks.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-sidebar-breakpoint
|
||||
created: 20260130065756457
|
||||
modified: 20260130065841355
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-sidebar-breakpoint CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-sidebar-breakpoint` CSS variable represents the minimum page width at which the story river and sidebar will appear side by side.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-sidebar-width
|
||||
created: 20260130065850825
|
||||
modified: 20260130065925595
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-sidebar-width CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-sidebar-width` CSS variable represents the width of the sidebar in fluid-fixed layout.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-story-left
|
||||
created: 20260130065252380
|
||||
modified: 20260130065342364
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-story-left CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-story-left` CSS variable represents how far the left margin of the story river (tiddler area) is from the left of the page.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-story-right
|
||||
created: 20260130065417448
|
||||
modified: 20260130065457358
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-story-right CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-story-right` CSS variable represents how far the left margin of the sidebar is from the left of the page.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-story-top
|
||||
created: 20260130065351753
|
||||
modified: 20260130065451132
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-story-top CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-story-top` CSS variable represents how far the top margin of the story river is from the top of the page.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-story-width
|
||||
created: 20260130065510314
|
||||
modified: 20260130065552027
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-story-width CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-story-width` CSS variable represents the overall width of the story river.
|
||||
@@ -0,0 +1,8 @@
|
||||
caption: --tp-tiddler-width
|
||||
created: 20260130065558913
|
||||
modified: 20260130065746707
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tp-tiddler-width CSS Variable
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The `--tp-tiddler-width` CSS variable represents the tiddler width within the story river.
|
||||
@@ -0,0 +1,16 @@
|
||||
caption: --tpc-*
|
||||
created: 20260122104142525
|
||||
modified: 20260122104847331
|
||||
tags: [[Core CSS Variables]]
|
||||
title: --tpc-* CSS Variables
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
`--tpc-*` variables are CSS variables of palette colors. They can be accessed via appending the palette color names to the bottom. For example:
|
||||
|
||||
```css
|
||||
.code {
|
||||
background-color: var(--tpc-code-background);
|
||||
color: var(--tpc-code-foreground);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,11 +1,43 @@
|
||||
created: 20150221201838000
|
||||
modified: 20150221203742000
|
||||
title: Example Table of Contents: Simple
|
||||
caption: Simple
|
||||
tags: table-of-contents-example
|
||||
created: 20150221201838000
|
||||
modified: 20260124125915331
|
||||
order: 1
|
||||
tags: table-of-contents-example
|
||||
title: Example Table of Contents: Simple
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<$macrocall $name=".example" n="1"
|
||||
eg="""<div class="tc-table-of-contents">
|
||||
<<toc "Contents">>
|
||||
</div>"""/>
|
||||
|
||||
---
|
||||
|
||||
<<.tip"""If you use several parameters in a macro call, it is advised to use ''named parameters'' for all of them""">>
|
||||
|
||||
<$macrocall $name=".example" n="2"
|
||||
eg="""<div class="tc-table-of-contents">
|
||||
<<toc tag:"Contents" level:"1">>
|
||||
</div>"""/>
|
||||
|
||||
<$macrocall $name=".example" n="3"
|
||||
eg="""<div class="tc-table-of-contents">
|
||||
<<toc tag:"Contents" level:"2">>
|
||||
</div>"""/>
|
||||
|
||||
<$macrocall $name=".example" n="4"
|
||||
eg="""<div class="tc-table-of-contents">
|
||||
<<toc tag:"Contents" level:"4">>
|
||||
</div>"""/>
|
||||
|
||||
* If you want to ''change'' or ''remove'' the indicator, you can locally overwrite the `toc-level-indicator` macro.
|
||||
* It is globally defined at: $:/core/macros/toc tiddler. Eg:
|
||||
|
||||
<$macrocall $name=".example" n="5"
|
||||
eg="""\define toc-level-indicator()
|
||||
<!-- remove the indicator -->
|
||||
\end
|
||||
|
||||
<div class="tc-table-of-contents">
|
||||
<<toc tag:"Contents" level:"1">>
|
||||
</div>"""/>
|
||||
|
||||
@@ -4,22 +4,22 @@ tags: Learning
|
||||
title: TaskManagementExample
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
TiddlyWiki5 can be used as a simple task management system without further customisation. The idea is that tasks be tagged `task`, with those that are completed also tagged `done`. In this way it is straightforward to generate task lists.
|
||||
TiddlyWiki5 can be used as a simple task management system without further customisation.<br>The idea is that tasks be tagged `task`, with those that are completed also tagged `done`. In this way it is straightforward to generate task lists.
|
||||
|
||||
<<.tip """There is [[an enhanced version of this demo|TaskManagementExample (Draggable)]] that adds the ability to drag and drop the tasks to re-order them.""">>
|
||||
|
||||
! Outstanding tasks
|
||||
|
||||
<$list filter="[!has[draft.of]tag[task]!tag[done]sort[created]]">
|
||||
|
||||
<$checkbox tag="done"> <$link/></$checkbox>
|
||||
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src="""<$list filter="[!has[draft.of]tag[task]!tag[done]sort[created]]">
|
||||
<$checkbox tag="done"> <$link/></$checkbox><br>
|
||||
</$list>
|
||||
"""/>
|
||||
|
||||
! Completed tasks
|
||||
|
||||
<$list filter="[!has[draft.of]tag[task]tag[done]sort[created]]">
|
||||
|
||||
<$checkbox tag="done"> ~~<$link/>~~</$checkbox>
|
||||
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src="""<$list filter="[!has[draft.of]tag[task]tag[done]sort[created]]">
|
||||
<$checkbox tag="done"> ~~<$link/>~~</$checkbox><br>
|
||||
</$list>
|
||||
"""/>
|
||||
|
||||
@@ -4,20 +4,24 @@ tags: Learning
|
||||
title: TaskManagementExample (Draggable)
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
This is a version of the TaskManagementExample enhanced with the ability to drag and drop the task list to re-order them.
|
||||
This is a version of the TaskManagementExample enhanced with the ability to drag and drop the task list to re-order them.<br>The list uses a the itemTemplate [[TaskManagementExampleDraggableTemplate]] tiddler, which you will also need to experiment yourself.
|
||||
|
||||
! Outstanding tasks
|
||||
|
||||
//Drag the tasks to re-order them//
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src="""//Drag the tasks to re-order them//
|
||||
|
||||
<<list-tagged-draggable tag:"task" subFilter:"!has[draft.of]!tag[done]" itemTemplate:"TaskManagementExampleDraggableTemplate" emptyMessage:"You don't have any active tasks">>
|
||||
"""/>
|
||||
|
||||
! Completed tasks
|
||||
|
||||
//(Listed in reverse order of completion)//
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src="""//(Listed in reverse order of completion)//
|
||||
|
||||
<$list filter="[!has[draft.of]tag[task]tag[done]sort[modified]]">
|
||||
<div>
|
||||
<$checkbox tag="done"> ~~<$link/>~~</$checkbox>
|
||||
</div>
|
||||
</$list>
|
||||
"""/>
|
||||
|
||||
@@ -37,5 +37,5 @@ Some icons take further parameters to customise how they are rendered. For examp
|
||||
|
||||
The core icons are implemented as embedded [[SVG elements|Using SVG]], and not as full-blown SVG images. This means that they can be styled using CSS. For example, the CSS property `fill` can be used to change the colour of the icons. For example:
|
||||
|
||||
<<wikitext-example-without-html """<span style="fill: red;">{{$:/core/images/opacity}}</span>
|
||||
<<wikitext-example-without-html """<span style="color: red;">{{$:/core/images/opacity}}</span>
|
||||
""">>
|
||||
|
||||
@@ -4,35 +4,36 @@ tags: Features
|
||||
title: DateFormat
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The default representation of dates is a compact string such as <<.value 20211002153802059>>. The associated template is `[UTC]YYYY0MM0DD0hh0mm0ss0XXX`. For example, the <<.field created>> and <<.field modified>> fields are stored like this.
|
||||
The default representation of dates is a compact string such as <<.value "<$view field='modified' format='text'/>">>. The associated template is `[UTC]YYYY0MM0DD0hh0mm0ss0XXX`. For example, the <<.field created>> and <<.field modified>> fields are stored like this.
|
||||
|
||||
The display format for this string can be controlled with a template. For example, transcluding the <<.field modified>> field automatically applies a template to display the date as <<.value "Sat Oct 02 2021 17:40:50 GMT+0200 (Central European Summer Time)">>. A few widgets and filter operators allow you to manually specify a template, for example the ViewWidget:
|
||||
The display format for this string can be controlled with a template. For example, transcluding the <<.field modified>> field automatically applies a template to display the date as "{{!!modified}}". A few widgets and filter operators allow you to manually specify a template, for example the ViewWidget:
|
||||
|
||||
`<$view field=modified format=date template="DDth mmm YYYY 0hh:0mm:0ss" />`
|
||||
|
||||
The date string is processed with the following substitutions:
|
||||
|
||||
|!Token |!Substituted Value |
|
||||
|`[UTC]`|Time-shift the represented date to UTC. Must be at very start of format string |
|
||||
|`YYYY` |Full year |
|
||||
|`YY` |Two-digit year |
|
||||
|`wYYYY` |Full year with respect to week number |
|
||||
|`aYYYY` |<<.from-version "5.1.23">> Full year but negative dates are displayed as positive |
|
||||
|`wYY` |Two digit year with respect to week number |
|
||||
|`{era:BCE||CE}` |<<.from-version "5.1.23">> Displays a different string for years that are negative, zero or positive (see below) |
|
||||
|`MMM` |Month in full (e.g. "July") |
|
||||
|`mmm` |Short month (e.g. "Jul") |
|
||||
|`MM` |Month number |
|
||||
|`0MM` |Adds leading zero |
|
||||
|`ddddd` |<<.from-version "5.2.0">> Day of year (1 to 365, or 366 for leap years) |
|
||||
|`0ddddd` |<<.from-version "5.2.0">> Zero padded day of year (001 to 365, or 366 for leap years) |
|
||||
|`DDD` |Day of week in full (eg, "Monday") |
|
||||
|`ddd` |Short day of week (eg, "Mon") |
|
||||
|`DDD` |Day of week in full (e.g. "Monday") |
|
||||
|`ddd` |Short day of week (e.g. "Mon") |
|
||||
|`dddd` |<<.from-version "5.2.0">> Weekday number from 1 through 7, beginning with Monday and ending with Sunday |
|
||||
|`DD` |Day of month |
|
||||
|`0DD` |Adds a leading zero |
|
||||
|`DDth` |Adds a suffix |
|
||||
|`WW` |ISO-8601 week number of year |
|
||||
|`0WW` |Adds a leading zero |
|
||||
|`MMM` |Month in full (eg, "July") |
|
||||
|`mmm` |Short month (eg, "Jul") |
|
||||
|`MM` |Month number |
|
||||
|`0MM` |Adds leading zero |
|
||||
|`YYYY` |Full year |
|
||||
|`YY` |Two digit year |
|
||||
|`wYYYY` |Full year with respect to week number |
|
||||
|`aYYYY` |<<.from-version "5.1.23">> Full year but negative dates are displayed as positive |
|
||||
|`wYY` |Two digit year with respect to week number |
|
||||
|`{era:BCE||CE}` |<<.from-version "5.1.23">> Displays a different string for years that are negative, zero or positive (see below) |
|
||||
|`hh` |Hours |
|
||||
|`0hh` |Adds a leading zero |
|
||||
|`hh12` |Hours in 12 hour clock |
|
||||
@@ -43,12 +44,12 @@ The date string is processed with the following substitutions:
|
||||
|`0ss` |Seconds with leading zero |
|
||||
|`XXX` |Milliseconds |
|
||||
|`0XXX` |Milliseconds with leading zero |
|
||||
|`am` or `pm` |Lower case AM/PM indicator |
|
||||
|`am` or `pm` |Lower case am/pm indicator |
|
||||
|`AM` or `PM` |Upper case AM/PM indicator |
|
||||
|`TZD` |Timezone offset |
|
||||
|`TZD` |Timezone offset from UTC (e.g. "+01:00", "-05:00"…) |
|
||||
|`TIMESTAMP` |<<.from-version "5.2.4">> Number of milliseconds since the [[ECMAScript epoch|https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#the_ecmascript_epoch_and_timestamps]], 1 January 1970. |
|
||||
|`\x` |Used to escape a character that would otherwise have special meaning |
|
||||
|`[UTC]`|Time-shift the represented date to UTC. Must be at very start of format string|
|
||||
|
||||
|
||||
Note that other text is passed through unchanged, allowing commas, colons or other separators to be used.
|
||||
|
||||
|
||||
@@ -6,15 +6,13 @@ type: text/vnd.tiddlywiki
|
||||
<<.operator-example 2 "[!days:created[-800]]" "tiddlers created more than 800 days ago">>
|
||||
The filter can be used to highlight new items in a list. For example:
|
||||
<$macrocall
|
||||
$name="wikitext-example-without-html" src=
|
||||
"""
|
||||
<ul>
|
||||
$name="wikitext-example-without-html"
|
||||
src="""<ul>
|
||||
<$list filter="[tag[ReleaseNotes]!<currentTiddler>!sort[modified]]">
|
||||
<li>
|
||||
<$link><$view field="title"/></$link>
|
||||
<$list filter="[<currentTiddler>days[-180]]"> @@color:red;^^new^^@@</$list>
|
||||
<$list filter="[<currentTiddler>days[-500]!days[-180]]"> @@color:black;^^recent^^@@</$list>
|
||||
<$list filter="[<currentTiddler>days[-180]]"> @@color:red;^^new^^@@</$list>
|
||||
<$list filter="[<currentTiddler>days[-500]!days[-180]]"> @@color:black;^^recent^^@@</$list>
|
||||
</li>
|
||||
</$list>
|
||||
</ul>
|
||||
"""/>
|
||||
</ul>"""/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
caption: function
|
||||
created: 20220909111836951
|
||||
modified: 20230419103154328
|
||||
modified: 20260130210336084
|
||||
op-input: a [[selection of titles|Title Selection]] passed as input to the function <<.place F>>
|
||||
op-output: the [[selection of titles|Title Selection]] returned from the function <<.place F>>
|
||||
op-parameter: first parameter is the [[function name|Functions]], subsequent parameters are passed to the function by position
|
||||
@@ -10,7 +10,7 @@ tags: [[Filter Operators]]
|
||||
title: function Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version "5.3.0">> The <<.op function>> operator applies a named [[function|Functions]] to the input titles, and returns the results from the function. The function is invoked once with all of the input titles (in contrast, the [[filter Operator]] invokes its function separately for each input title).
|
||||
<<.from-version "5.3.0">> The <<.op function>> operator applies a named [[function|Functions]] to the input titles, and returns the results from the function. The function is called once with all of the input titles (in contrast, the [[filter Operator]] calls its function separately for each input title).
|
||||
|
||||
The first parameter of the <<.op function>> operator specifies the name of the function to be called. Subsequent parameters are passed to the function.
|
||||
|
||||
|
||||
@@ -16,12 +16,13 @@ Functions are usually defined with the [[Pragma: \function]]:
|
||||
\end
|
||||
```
|
||||
|
||||
Functions can be invoked in several ways:
|
||||
Functions can be called in several ways:
|
||||
|
||||
* Directly transclude functions with the syntax `<<myfun param:"value">>`
|
||||
* Assign functions to widget attributes with the syntax `<div class=<<myfun param:"value">>>`
|
||||
* Invoke functions via the [[function Operator]] with the syntax `[function[myfun],[value],...]`
|
||||
* Directly invoke functions whose names contain a period as custom filter operators with the syntax `[my.fun[value]]` or `[.myfun[value]]`
|
||||
* Using the [[Calls]] syntax:
|
||||
** Directly transclude functions with the syntax `<<myfun param:"value">>`
|
||||
** Assign functions to widget attributes with the syntax `<div class=<<myfun param:"value">>>`
|
||||
* Call functions via the [[function Operator]] with the syntax `[function[myfun],[value],...]`
|
||||
* Directly call functions whose names contain a period as custom filter operators with the syntax `[my.fun[value]]` or `[.myfun[value]]`
|
||||
|
||||
!! How Functions Work
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ type: text/vnd.tiddlywiki
|
||||
}
|
||||
|
||||
[data-tiddler-title="Hire the founder of TiddlyWiki"] .tc-btn-big-green svg {
|
||||
fill: #cece86;
|
||||
color: #cece86;
|
||||
}
|
||||
|
||||
.yellow-note-sidebar-wrapper {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20140919155729620
|
||||
modified: 20240624102502089
|
||||
modified: 20260124130054271
|
||||
tags: Macros [[Core Macros]]
|
||||
title: Table-of-Contents Macros
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -74,6 +74,9 @@ These two parameters are combined into a single [[filter expression|Filter Expre
|
||||
; exclude <<.from-version "5.3.0">>
|
||||
: This optional parameter can be used to exclude tiddlers from the TOC list. It allows a [[Title List]] or a <<.olink subfilter>>. Eg: `exclude:"HelloThere [[Title with spaces]]"` or `exclude:"[has[excludeTOC]]"`. Where the former will exclude two tiddlers and the later would exclude every tiddler that has a field <<.field excludeTOC>> independent of its value.<br>''Be aware'' that eg: `[prefix[H]]` is a shortcut for `[all[tiddlers]prefix[H]]`, which can have a performance impact, if used carelessly. So use $:/AdvancedSearch -> ''Filters'' tab to test the <<.param exclude>> parameter
|
||||
|
||||
; level <<.from-version "5.4.0">>
|
||||
: This optional parameter can be used to define how many toc levels are shown by the toc-macro. By default all levels are shown.
|
||||
|
||||
!! Custom Icons
|
||||
|
||||
<<.from-version "5.2.4">>
|
||||
|
||||
@@ -32,7 +32,7 @@ The <<.def list-links-draggable>> [[macro|Macros]] renders the ListField of a ti
|
||||
: Optional title of a tiddler to use as the template for rendering list items
|
||||
|
||||
;displayField
|
||||
: Optional name of the field to display when the list is rendered. Defaults to the "caption" field; if "caption" is not present, the "title" field is used instead
|
||||
: <<.from-version 5.4.0>> Optional name of the field to display when the list is rendered. Defaults to the "caption" field; if "caption" is not present, the "title" field is used instead
|
||||
|
||||
|
||||
If the `itemTemplate` parameter is not provided then the list items are rendered as simple links. Within the `itemTemplate`, the [[currentTiddler Variable]] refers to the current list item.
|
||||
|
||||
@@ -17,9 +17,9 @@ The <<.def list-tagged-draggable>> [[macro|Macros]] renders the tiddlers with a
|
||||
: Optional title of a tiddler to use as the template for rendering list items
|
||||
;emptyMessage
|
||||
: Optional wikitext to display if there are no tiddlers with the specified tag
|
||||
Here’s a corrected and polished version of your sentence in clear, standard English:
|
||||
|
||||
;displayField
|
||||
: Optional name of the field to display when the list is rendered. Defaults to `title` field.
|
||||
: <<.from-version 5.4.0>> Optional name of the field to display when the list is rendered. Defaults to `title` field.
|
||||
|
||||
Note that the [[ordering|Order of Tagged Tiddlers]] is accomplished by assigning a new list to the `list` field of the tag tiddler. Any `list-before` or `list-after` fields on any of the other tiddlers carrying the tag are also removed to ensure the `list` field is respected.
|
||||
|
||||
|
||||
43
editions/tw5.com/tiddlers/macros/syntax/Call Syntax.tid
Normal file
43
editions/tw5.com/tiddlers/macros/syntax/Call Syntax.tid
Normal file
@@ -0,0 +1,43 @@
|
||||
created: 20240310165023000
|
||||
modified: 20260125212303316
|
||||
tags: [[Call Syntax]]
|
||||
title: Call Syntax
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.preamble """What follows is a formal presentation of the syntax of the WikiText syntax for procedure/function/macro calls, using [[railroad diagrams|Railroad Diagrams]].""">>
|
||||
|
||||
!! callee-name
|
||||
|
||||
<$railroad text="""
|
||||
"<<" [[ callee-name |Calls]] [: [[whitespace|"Filter Whitespace"]] [:{param-value}] ]">>"
|
||||
"""/>
|
||||
|
||||
* The <<.place callee-name>> is a sequence of non-whitespace characters other than `(` or `>`.
|
||||
|
||||
* <<.place whitespace>> denotes a sequence of [[whitespace characters|Filter Whitespace]].
|
||||
|
||||
!!! param-value
|
||||
|
||||
Each ''individual'' <<.place param-value>> has the following syntax:
|
||||
|
||||
<$railroad text="""
|
||||
\start none
|
||||
\end none
|
||||
(
|
||||
value
|
||||
|
|
||||
param-name [:space] (
|
||||
":" [:space] value [: space]
|
||||
|
|
||||
"=" [:space] new-value [: space]
|
||||
)
|
||||
)
|
||||
"""/>
|
||||
|
||||
* The <<.place param-name>> is a sequence of letters (`A`--`Z`, `a`--`z`), digits (`0`--`9`), hyphens (`-`) and underscores (`_`).
|
||||
|
||||
* The <<.place value>> is specified as follows:
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
||||
|
||||
* <<.from-version 5.4.0>> The <<.place new-value>> can either be a plain <<.place value>> or a full <<.place callee-name>> call, allowing for dynamic parameter values.
|
||||
@@ -1,11 +1,13 @@
|
||||
created: 20150220191009000
|
||||
modified: 20150221111554000
|
||||
title: $:/editions/tw5.com/railroad/macro-parameter-value
|
||||
modified: 20260125212303316
|
||||
title: $:/editions/tw5.com/railroad/call-parameter-value
|
||||
type: text/vnd.tiddlywiki.railroad
|
||||
|
||||
( '"""' [:{/'anything but """'/}] '"""'
|
||||
| '"' [:{/'anything but "'/}] '"'
|
||||
| "'" [:{/"anything but '"/}] "'"
|
||||
| "[[" [:{/"anything but ]"/}] "]]"
|
||||
| "`" [:{/"anything but `"/}] "`"
|
||||
| "```" [:{/"anything but ```"/}] "```"
|
||||
| {/"""anything but ' " or whitespace"""/}
|
||||
)
|
||||
@@ -1,31 +1,7 @@
|
||||
created: 20150221105732000
|
||||
modified: 20150221222352000
|
||||
tags: [[Macro Syntax]] $:/deprecated
|
||||
modified: 20260125212303316
|
||||
tags: $:/deprecated
|
||||
title: Macro Call Syntax
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.deprecated-since "5.3.0" "Procedure Call Syntax">>
|
||||
|
||||
----------
|
||||
|
||||
<<.preamble """What follows is a formal presentation of the syntax of the WikiText syntax for macro calls, using [[railroad diagrams|Railroad Diagrams]]. A [[simpler overview|Macro Calls in WikiText]] is also available.""">>
|
||||
|
||||
<$railroad text="""
|
||||
"<<" name [: space [:{param-value}] ]">>"
|
||||
"""/>
|
||||
|
||||
<<.place space>> denotes a sequence of [[whitespace characters|Filter Whitespace]].
|
||||
|
||||
The [[macro|Macros]]'s <<.place name>> is a sequence of non-whitespace characters other than `(` or `>`.
|
||||
|
||||
Each individual <<.place param-value>> has the following syntax:
|
||||
|
||||
<$railroad text="""
|
||||
[: param-name [:space] ":" [:space] ] value [: space]
|
||||
"""/>
|
||||
|
||||
The <<.place param-name>> is a sequence of letters (`A`--`Z`, `a`--`z`), digits (`0`--`9`), hyphens (`-`) and underscores (`_`).
|
||||
|
||||
The <<.place value>> is specified as follows:
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<<.deprecated-since "5.3.0" "Call Syntax">>
|
||||
|
||||
@@ -37,7 +37,7 @@ param-name [: [:space] ":" [:space] default ]
|
||||
|
||||
The optional <<.place default>> value of a parameter is specified as follows:
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
||||
|
||||
The <<.place rest>> of the definition has the following syntax:
|
||||
|
||||
|
||||
@@ -1,33 +1,6 @@
|
||||
created: 20240310165023000
|
||||
modified: 20240310172648116
|
||||
tags: [[Procedure Syntax]]
|
||||
modified: 20260125212303316
|
||||
title: Procedure Call Syntax
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.preamble """What follows is a formal presentation of the syntax of the WikiText syntax for procedure calls, using [[railroad diagrams|Railroad Diagrams]].""">>
|
||||
|
||||
!! procedure-name
|
||||
|
||||
<$railroad text="""
|
||||
"<<" [[ procedure-name |Procedures]] [: [[whitespace|"Filter Whitespace"]] [:{param-value}] ]">>"
|
||||
"""/>
|
||||
|
||||
* The [[procedure's|Procedures]] <<.place procedure-name>> is a sequence of non-whitespace characters other than `(` or `>`.
|
||||
|
||||
* <<.place whitespace>> denotes a sequence of [[whitespace characters|Filter Whitespace]].
|
||||
|
||||
!!! param-value
|
||||
|
||||
Each ''individual'' <<.place param-value>> has the following syntax:
|
||||
|
||||
<$railroad text="""
|
||||
\start none
|
||||
\end none
|
||||
[: param-name [:[[whitespace|"Filter Whitespace"]]] ":" [:[[whitespace|"Filter Whitespace"]]] ] value [: [[whitespace|"Filter Whitespace"]] ]
|
||||
"""/>
|
||||
|
||||
* The <<.place param-name>> is a sequence of letters (`A`--`Z`, `a`--`z`), digits (`0`--`9`), hyphens (`-`) and underscores (`_`).
|
||||
|
||||
* The <<.place value>> is specified as follows:
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<<.deprecated-since "5.4.0" "Call Syntax">>
|
||||
@@ -1,6 +1,6 @@
|
||||
created: 20240310165023000
|
||||
modified: 20240310175033730
|
||||
tags: [[Procedure Syntax]]
|
||||
tags: [[Call Syntax]]
|
||||
title: Procedure Definition Syntax
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
@@ -73,7 +73,7 @@ Each ''individual'' <<.place parameter>> has the following syntax:
|
||||
|
||||
* <<.place default>> is an optional value of a parameter is specified as follows:
|
||||
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
||||
|
||||
!! body
|
||||
|
||||
|
||||
@@ -6,6 +6,6 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
Plain text description can be found at [[Procedures]]
|
||||
|
||||
<<list-links filter:"[tag[Procedure Syntax]]">>
|
||||
<<list-links filter:"[tag[Call Syntax]]">>
|
||||
|
||||
<<.tip "The railroad boxes in the linked tiddlers can be used to navigate.">>
|
||||
|
||||
@@ -1,56 +1,7 @@
|
||||
caption: Procedure Calls
|
||||
created: 20221007130006705
|
||||
modified: 20230419103154329
|
||||
tags: WikiText Procedures
|
||||
modified: 20260125212303316
|
||||
title: Procedure Calls
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
!! Introduction
|
||||
|
||||
This tiddler describes the different ways in which [[procedure|Procedures]] can be called.
|
||||
|
||||
!! Procedure Call Transclusion Shortcut
|
||||
|
||||
To call a [[procedure|Procedures]], place `<<`double angle brackets`>>` around the name and any parameter values.
|
||||
|
||||
```
|
||||
<<my-procedure param:"This is the parameter value">>
|
||||
```
|
||||
|
||||
By default, parameters are listed in the same order as in the procedure definition. A parameter can be labelled with its name and a colon to allow them to be listed in a different order.
|
||||
|
||||
If no value is specified for a parameter, the default value given for that parameter in the [[procedure definition|Procedure Definitions]] is used instead. (If no default value was defined, the parameter is blank).
|
||||
|
||||
Each parameter value can be enclosed in `'`single quotes`'`, `"`double quotes`"`, `"""`triple double quotes`"""` or `[[`double square brackets`]]`. Triple double quotes allow a value to contain almost anything. If a value contains no spaces or single or double quotes, it requires no delimiters.
|
||||
|
||||
See the discussion about [[parser modes|WikiText parser mode: macro examples]]
|
||||
|
||||
!! Procedure Calls with <<.wlink TranscludeWidget>> Widget
|
||||
|
||||
The shortcut syntax expands to the <<.wlink TranscludeWidget>> widget with the `$variable` attribute specifying the name of the procedure to transclude.
|
||||
|
||||
```
|
||||
<$transclude $variable="my-procedure" param="This is the parameter value"/>
|
||||
```
|
||||
|
||||
The widget itself offers greater flexibility than the shortcut syntax, including the ability to specify dynamic parameter values.
|
||||
|
||||
!! Assigning Procedure Calls to Attribute Values
|
||||
|
||||
The text of a procedure can be directly assigned to an attribute of a widget or HTML element. The result of the procedure is not wikified, which means that [[parameter handling|Procedure Parameter Handling]] does not take place.
|
||||
|
||||
```
|
||||
<div class=<<myclasses>>>
|
||||
...
|
||||
</div>
|
||||
```
|
||||
|
||||
!! Using Procedure Calls in Filters
|
||||
|
||||
Procedure calls can be used in filters. The text is not wikified which again means that the parameters will be ignored.
|
||||
|
||||
```
|
||||
<$list filter="[<my-procedure>]">
|
||||
...
|
||||
</$list>
|
||||
```
|
||||
<<.deprecated-since "5.4.0" "Calls">>
|
||||
@@ -33,6 +33,6 @@ Procedures are implemented as a special kind of [[variable|Variables]]. The only
|
||||
!! Using Procedures
|
||||
|
||||
* [[Procedure Definitions]] describes how to create procedures
|
||||
* [[Procedure Calls]] describes how to use procedures
|
||||
* [[Calls]] describes how to use procedures
|
||||
* [[Procedure Parameter Handling]] describes how procedure parameters work
|
||||
* [[Procedure Syntax]] is a formal syntax description using railroad diagrams
|
||||
* [[Call Syntax]] is a formal syntax description using railroad diagrams
|
||||
|
||||
56
editions/tw5.com/tiddlers/procedures/calls/Calls.tid
Normal file
56
editions/tw5.com/tiddlers/procedures/calls/Calls.tid
Normal file
@@ -0,0 +1,56 @@
|
||||
caption: Calls
|
||||
created: 20221007130006705
|
||||
modified: 20260125212303316
|
||||
tags: WikiText Procedures Functions Macros
|
||||
title: Calls
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
!! Introduction
|
||||
|
||||
This tiddler describes the different ways in which [[procedures|Procedures]], [[functions|Functions]] and [[macros|Macros]] can be called. See [[Call Syntax]] for a formal description of the syntax.
|
||||
|
||||
!! Call Transclusion Shortcut
|
||||
|
||||
To perform a call, place `<<`double angle brackets`>>` around the callee name and any parameter values.
|
||||
|
||||
```
|
||||
<<my-procedure param="This is the parameter value">>
|
||||
```
|
||||
|
||||
By default, parameters are interpreted as being in the same order as in the definition. A parameter value can be labelled with its name and an equals sign to allow them to be listed in a different order.
|
||||
|
||||
If no value is specified for a parameter, the default value given for that parameter in the [[procedure definition|Procedure Definitions]], [[function definition|Function Definitions]] or [[macro definition|Macro Definitions]] is used instead. (If no default value was defined, the parameter is blank).
|
||||
|
||||
Each parameter value can be enclosed in `'`single quotes`'`, `"`double quotes`"`, `"""`triple double quotes`"""` or `[[`double square brackets`]]`. Triple double quotes allow a value to contain almost anything. If a value contains no spaces or single or double quotes, it requires no delimiters. [[Substituted Attribute Values]] enclosed in single or triple back quotes are also supported.
|
||||
|
||||
See the discussion about [[parser modes|WikiText parser mode: macro examples]]
|
||||
|
||||
!! Calls with <<.wlink TranscludeWidget>> Widget
|
||||
|
||||
The shortcut syntax expands to the <<.wlink TranscludeWidget>> widget with the `$variable` attribute specifying the name of the procedure to transclude.
|
||||
|
||||
```
|
||||
<$transclude $variable="my-procedure" param="This is the parameter value"/>
|
||||
```
|
||||
|
||||
The widget itself offers greater flexibility than the shortcut syntax, including the ability to override it with a custom widget.
|
||||
|
||||
!! Assigning Results of Calls to Attribute Values
|
||||
|
||||
The text returned from a call can be directly assigned to an attribute of a widget or HTML element. The result of the call is not wikified, which means that [[parameter handling|Procedure Parameter Handling]] does not take place.
|
||||
|
||||
```
|
||||
<div class=<<myclasses>>>
|
||||
...
|
||||
</div>
|
||||
```
|
||||
|
||||
!! Using Calls in Filters
|
||||
|
||||
Calls can be used in filters. The text is not wikified which again means that the parameters will be ignored.
|
||||
|
||||
```
|
||||
<$list filter="[<my-procedure>]">
|
||||
...
|
||||
</$list>
|
||||
```
|
||||
10
editions/tw5.com/tiddlers/releasenotes/5.4.0/#8093.tid
Normal file
10
editions/tw5.com/tiddlers/releasenotes/5.4.0/#8093.tid
Normal file
@@ -0,0 +1,10 @@
|
||||
title: $:/changenotes/5.4.0/#8093
|
||||
description: Fixes SelectWidget does not work with multiple options organised into group - issue #8092
|
||||
release: 5.4.0
|
||||
tags: $:/tags/ChangeNote
|
||||
change-type: bugfix
|
||||
change-category: widget
|
||||
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/issues/8093 https://github.com/TiddlyWiki/TiddlyWiki5/pull/9616
|
||||
github-contributors: buggyj saqimtiaz
|
||||
|
||||
Fixed SelectWidget does not work with multiple options organised into group.
|
||||
@@ -4,8 +4,8 @@ release: 5.4.0
|
||||
tags: $:/tags/ChangeNote
|
||||
change-type: enhancement
|
||||
change-category: hackability
|
||||
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/pull/8972
|
||||
github-contributors: Jermolene
|
||||
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/pull/8972 https://github.com/TiddlyWiki/TiddlyWiki5/pull/9614
|
||||
github-contributors: Jermolene saqimtiaz
|
||||
|
||||
This PR introduces a new filter run prefix `:let` that assigns the result of the filter run to a variable that is made available for the remaining filter runs of the filter expression. It solves the problem that previously it was impossible to compute values for filter operator parameters; parameters could only be a literal string, text reference or variable reference.
|
||||
|
||||
|
||||
13
editions/tw5.com/tiddlers/releasenotes/5.4.0/#9050.tid
Normal file
13
editions/tw5.com/tiddlers/releasenotes/5.4.0/#9050.tid
Normal file
@@ -0,0 +1,13 @@
|
||||
change-category: widget
|
||||
change-type: enhancement
|
||||
created: 20260126112805413
|
||||
description: Allow actions to be invoked when an image is loaded
|
||||
github-contributors: saqimtiaz
|
||||
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/pull/9050
|
||||
modified: 20260126113146914
|
||||
release: 5.4.0
|
||||
tags: $:/tags/ChangeNote
|
||||
title: $:/changenotes/5.4.0/#9050
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
Adds support to the image widget for optional actions that are invoked when an image has completed loading.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user