mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-16 06:44:50 +00:00
Merge branch 'master' into bidi-improvements
This commit is contained in:
commit
46f448faef
@ -5,7 +5,7 @@
|
|||||||
# Default to the current version number for building the plugin library
|
# Default to the current version number for building the plugin library
|
||||||
|
|
||||||
if [ -z "$TW5_BUILD_VERSION" ]; then
|
if [ -z "$TW5_BUILD_VERSION" ]; then
|
||||||
TW5_BUILD_VERSION=v5.2.6
|
TW5_BUILD_VERSION=v5.2.8
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
||||||
@ -359,14 +359,14 @@ node $TW5_BUILD_TIDDLYWIKI \
|
|||||||
|
|
||||||
# Delete any existing static content
|
# Delete any existing static content
|
||||||
|
|
||||||
rm $TW5_BUILD_OUTPUT/languages/de-AT/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/de-AT/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/de-DE/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/de-DE/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/es-ES/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/es-ES/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/fr-FR/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/fr-FR/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/ja-JP/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/ja-JP/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/ko-KR/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/ko-KR/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/zh-Hans/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/zh-Hans/static/*
|
||||||
rm $TW5_BUILD_OUTPUT/languages/zh-Hant/static/*
|
rm -rf $TW5_BUILD_OUTPUT/languages/zh-Hant/static/*
|
||||||
|
|
||||||
# /languages/de-AT/index.html Demo wiki with de-AT language
|
# /languages/de-AT/index.html Demo wiki with de-AT language
|
||||||
# /languages/de-AT/empty.html Empty wiki with de-AT language
|
# /languages/de-AT/empty.html Empty wiki with de-AT language
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
# Remove any output files
|
# Remove any output files
|
||||||
|
|
||||||
find . -regex "^./editions/[a-z0-9\.-]*/output/.*" -delete
|
find . -regex "^./editions/.*/output/.*" -delete
|
||||||
|
@ -313,7 +313,7 @@ $tw.utils.getLocationHash = function() {
|
|||||||
var idx = href.indexOf('#');
|
var idx = href.indexOf('#');
|
||||||
if(idx === -1) {
|
if(idx === -1) {
|
||||||
return "#";
|
return "#";
|
||||||
} else if(idx < href.length-1 && href[idx+1] === '#') {
|
} else if(href.substr(idx + 1,1) === "#" || href.substr(idx + 1,3) === "%23") {
|
||||||
// Special case: ignore location hash if it itself starts with a #
|
// Special case: ignore location hash if it itself starts with a #
|
||||||
return "#";
|
return "#";
|
||||||
} else {
|
} else {
|
||||||
@ -375,7 +375,7 @@ $tw.utils.stringifyList = function(value) {
|
|||||||
var result = new Array(value.length);
|
var result = new Array(value.length);
|
||||||
for(var t=0, l=value.length; t<l; t++) {
|
for(var t=0, l=value.length; t<l; t++) {
|
||||||
var entry = value[t] || "";
|
var entry = value[t] || "";
|
||||||
if(entry.indexOf(" ") !== -1) {
|
if(entry.match(/[^\S\xA0]/mg)) {
|
||||||
result[t] = "[[" + entry + "]]";
|
result[t] = "[[" + entry + "]]";
|
||||||
} else {
|
} else {
|
||||||
result[t] = entry;
|
result[t] = entry;
|
||||||
|
12
core/images/save-button-dynamic.tid
Normal file
12
core/images/save-button-dynamic.tid
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
title: $:/core/images/save-button-dynamic
|
||||||
|
tags: $:/tags/Image
|
||||||
|
|
||||||
|
<svg width="22pt" height="22pt" class="tc-image-save-button-dynamic tc-image-button" viewBox="0 0 128 128">
|
||||||
|
<g class="tc-image-save-button-dynamic-clean">
|
||||||
|
<path fill-rule="evenodd" d="M120.783 34.33c4.641 8.862 7.266 18.948 7.266 29.646 0 35.347-28.653 64-64 64-35.346 0-64-28.653-64-64 0-35.346 28.654-64 64-64 18.808 0 35.72 8.113 47.43 21.03l2.68-2.68c3.13-3.13 8.197-3.132 11.321-.008 3.118 3.118 3.121 8.193-.007 11.32l-4.69 4.691zm-12.058 12.058a47.876 47.876 0 013.324 17.588c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48c14.39 0 27.3 6.332 36.098 16.362L58.941 73.544 41.976 56.578c-3.127-3.127-8.201-3.123-11.32-.005-3.123 3.124-3.119 8.194.006 11.319l22.617 22.617a7.992 7.992 0 005.659 2.347c2.05 0 4.101-.783 5.667-2.349l44.12-44.12z"/>
|
||||||
|
</g>
|
||||||
|
<g class="tc-image-save-button-dynamic-dirty">
|
||||||
|
<path d="M64.856912,0 C100.203136,0 128.856912,28.653776 128.856912,64 C128.856912,99.346224 100.203136,128 64.856912,128 C29.510688,128 0.856911958,99.346224 0.856911958,64 C0.856911958,28.653776 29.510688,0 64.856912,0 Z M64.856912,16 C38.347244,16 16.856912,37.490332 16.856912,64 C16.856912,90.509668 38.347244,112 64.856912,112 C91.3665799,112 112.856912,90.509668 112.856912,64 C112.856912,37.490332 91.3665799,16 64.856912,16 Z"></path>
|
||||||
|
<circle cx="65" cy="64" r="32"></circle>
|
||||||
|
</g>
|
||||||
|
</svg>
|
@ -40,6 +40,7 @@ Error/RetrievingSkinny: Error retrieving skinny tiddler list
|
|||||||
Error/SavingToTWEdit: Error saving to TWEdit
|
Error/SavingToTWEdit: Error saving to TWEdit
|
||||||
Error/WhileSaving: Error while saving
|
Error/WhileSaving: Error while saving
|
||||||
Error/XMLHttpRequest: XMLHttpRequest error code
|
Error/XMLHttpRequest: XMLHttpRequest error code
|
||||||
|
Error/ZoominTextNode: Story View Error: It appears you tried to interact with a tiddler that displays in a custom container. This is most likely caused by using `$:/tags/StoryTiddlerTemplateFilter` with a template that contains text or whitespace at the start. Please use the pragma `\whitespace trim` and ensure the whole contents of the tiddler is wrapped in a single HTML element. The text that caused this issue:
|
||||||
InternalJavaScriptError/Title: Internal JavaScript Error
|
InternalJavaScriptError/Title: Internal JavaScript Error
|
||||||
InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser
|
InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser
|
||||||
LayoutSwitcher/Description: Open the layout switcher
|
LayoutSwitcher/Description: Open the layout switcher
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
title: $:/language/Modals/SaveInstructions
|
|
||||||
subtitle: Save your work
|
|
||||||
footer: <$button message="tm-close-tiddler">Close</$button>
|
|
||||||
help: https://tiddlywiki.com/static/SavingChanges.html
|
|
||||||
|
|
||||||
Your changes to this wiki need to be saved as a ~TiddlyWiki HTML file.
|
|
||||||
|
|
||||||
!!! Desktop browsers
|
|
||||||
|
|
||||||
# Select ''Save As'' from the ''File'' menu
|
|
||||||
# Choose a filename and location
|
|
||||||
#* Some browsers also require you to explicitly specify the file saving format as ''Webpage, HTML only'' or similar
|
|
||||||
# Close this tab
|
|
||||||
|
|
||||||
!!! Smartphone browsers
|
|
||||||
|
|
||||||
# Create a bookmark to this page
|
|
||||||
#* If you've got iCloud or Google Sync set up then the bookmark will automatically sync to your desktop where you can open it and save it as above
|
|
||||||
# Close this tab
|
|
||||||
|
|
||||||
//If you open the bookmark again in Mobile Safari you will see this message again. If you want to go ahead and use the file, just click the ''close'' button below//
|
|
@ -57,7 +57,7 @@ Command.prototype.execute = function() {
|
|||||||
exportPath = path.resolve(outputPath,macroPath + extension);
|
exportPath = path.resolve(outputPath,macroPath + extension);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var finalPath = exportPath || path.resolve(pathname,encodeURIComponent(title) + extension);
|
var finalPath = exportPath || path.resolve(pathname,$tw.utils.encodeURIComponentExtended(title) + extension);
|
||||||
$tw.utils.createFileDirectories(finalPath);
|
$tw.utils.createFileDirectories(finalPath);
|
||||||
fs.writeFileSync(finalPath,text,"utf8");
|
fs.writeFileSync(finalPath,text,"utf8");
|
||||||
});
|
});
|
||||||
|
@ -65,7 +65,7 @@ Command.prototype.execute = function() {
|
|||||||
$tw.utils.each(filteredPluginList,function(title) {
|
$tw.utils.each(filteredPluginList,function(title) {
|
||||||
var tiddler = containerData.tiddlers[title];
|
var tiddler = containerData.tiddlers[title];
|
||||||
// Save each JSON file and collect the skinny data
|
// Save each JSON file and collect the skinny data
|
||||||
var pathname = path.resolve(self.commander.outputPath,basepath + encodeURIComponent(title) + ".json");
|
var pathname = path.resolve(self.commander.outputPath,basepath + $tw.utils.encodeURIComponentExtended(title) + ".json");
|
||||||
$tw.utils.createFileDirectories(pathname);
|
$tw.utils.createFileDirectories(pathname);
|
||||||
fs.writeFileSync(pathname,JSON.stringify(tiddler),"utf8");
|
fs.writeFileSync(pathname,JSON.stringify(tiddler),"utf8");
|
||||||
// Collect the skinny list data
|
// Collect the skinny list data
|
||||||
|
@ -45,7 +45,7 @@ Command.prototype.execute = function() {
|
|||||||
var tiddler = self.commander.wiki.getTiddler(title),
|
var tiddler = self.commander.wiki.getTiddler(title),
|
||||||
type = tiddler.fields.type || "text/vnd.tiddlywiki",
|
type = tiddler.fields.type || "text/vnd.tiddlywiki",
|
||||||
contentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: "utf8"},
|
contentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: "utf8"},
|
||||||
filename = path.resolve(pathname,encodeURIComponent(title));
|
filename = path.resolve(pathname,$tw.utils.encodeURIComponentExtended(title));
|
||||||
fs.writeFileSync(filename,tiddler.fields.text,contentTypeInfo.encoding);
|
fs.writeFileSync(filename,tiddler.fields.text,contentTypeInfo.encoding);
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
|
@ -30,7 +30,7 @@ exports.textPrimitives.wikiLink = exports.textPrimitives.upperLetter + "+" +
|
|||||||
exports.textPrimitives.upperLetter +
|
exports.textPrimitives.upperLetter +
|
||||||
exports.textPrimitives.anyLetter + "*";
|
exports.textPrimitives.anyLetter + "*";
|
||||||
|
|
||||||
exports.htmlEntities = {quot:34, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };
|
exports.htmlEntities = {quot:34, dollar:36, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };
|
||||||
|
|
||||||
exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",");
|
exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",");
|
||||||
|
|
||||||
|
@ -168,13 +168,13 @@ FramedEngine.prototype.fixHeight = function() {
|
|||||||
if(this.widget.editAutoHeight) {
|
if(this.widget.editAutoHeight) {
|
||||||
if(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {
|
if(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {
|
||||||
var newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);
|
var newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);
|
||||||
this.iframeNode.style.height = (newHeight + 14) + "px"; // +14 for the border on the textarea
|
this.iframeNode.style.height = newHeight + "px";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,"400px"),10);
|
var fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,"400px"),10);
|
||||||
fixedHeight = Math.max(fixedHeight,20);
|
fixedHeight = Math.max(fixedHeight,20);
|
||||||
this.domNode.style.height = fixedHeight + "px";
|
this.domNode.style.height = fixedHeight + "px";
|
||||||
this.iframeNode.style.height = (fixedHeight + 14) + "px";
|
this.iframeNode.style.height = fixedHeight + "px";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -183,9 +183,11 @@ FramedEngine.prototype.fixHeight = function() {
|
|||||||
Focus the engine node
|
Focus the engine node
|
||||||
*/
|
*/
|
||||||
FramedEngine.prototype.focus = function() {
|
FramedEngine.prototype.focus = function() {
|
||||||
if(this.domNode.focus && this.domNode.select) {
|
if(this.domNode.focus) {
|
||||||
this.domNode.focus();
|
this.domNode.focus();
|
||||||
this.domNode.select();
|
}
|
||||||
|
if(this.domNode.select) {
|
||||||
|
$tw.utils.setSelectionByPosition(this.domNode,this.widget.editFocusSelectFromStart,this.widget.editFocusSelectFromEnd);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -122,10 +122,12 @@ SimpleEngine.prototype.fixHeight = function() {
|
|||||||
/*
|
/*
|
||||||
Focus the engine node
|
Focus the engine node
|
||||||
*/
|
*/
|
||||||
SimpleEngine.prototype.focus = function() {
|
SimpleEngine.prototype.focus = function() {
|
||||||
if(this.domNode.focus && this.domNode.select) {
|
if(this.domNode.focus) {
|
||||||
this.domNode.focus();
|
this.domNode.focus();
|
||||||
this.domNode.select();
|
}
|
||||||
|
if(this.domNode.select) {
|
||||||
|
$tw.utils.setSelectionByPosition(this.domNode,this.widget.editFocusSelectFromStart,this.widget.editFocusSelectFromEnd);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -180,6 +180,8 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
|||||||
this.editMinHeight = this.getAttribute("minHeight",DEFAULT_MIN_TEXT_AREA_HEIGHT);
|
this.editMinHeight = this.getAttribute("minHeight",DEFAULT_MIN_TEXT_AREA_HEIGHT);
|
||||||
this.editFocusPopup = this.getAttribute("focusPopup");
|
this.editFocusPopup = this.getAttribute("focusPopup");
|
||||||
this.editFocus = this.getAttribute("focus");
|
this.editFocus = this.getAttribute("focus");
|
||||||
|
this.editFocusSelectFromStart = $tw.utils.parseNumber(this.getAttribute("focusSelectFromStart","0"));
|
||||||
|
this.editFocusSelectFromEnd = $tw.utils.parseNumber(this.getAttribute("focusSelectFromEnd","0"));
|
||||||
this.editTabIndex = this.getAttribute("tabindex");
|
this.editTabIndex = this.getAttribute("tabindex");
|
||||||
this.editDir = this.getAttribute("dir");
|
this.editDir = this.getAttribute("dir");
|
||||||
this.editCancelPopups = this.getAttribute("cancelPopups","") === "yes";
|
this.editCancelPopups = this.getAttribute("cancelPopups","") === "yes";
|
||||||
@ -219,7 +221,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
|||||||
EditTextWidget.prototype.refresh = function(changedTiddlers) {
|
EditTextWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var changedAttributes = this.computeAttributes();
|
var changedAttributes = this.computeAttributes();
|
||||||
// Completely rerender if any of our attributes have changed
|
// Completely rerender if any of our attributes have changed
|
||||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.dir || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedAttributes.disabled || changedAttributes.fileDrop) {
|
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.dir || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedTiddlers["$:/palette"] || changedAttributes.disabled || changedAttributes.fileDrop) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
} else if (changedTiddlers[this.editRefreshTitle]) {
|
} else if (changedTiddlers[this.editRefreshTitle]) {
|
||||||
|
@ -25,20 +25,10 @@ exports.cascade = function(operationSubFunction,options) {
|
|||||||
if(!filterFnList[index]) {
|
if(!filterFnList[index]) {
|
||||||
filterFnList[index] = options.wiki.compileFilter(filter);
|
filterFnList[index] = options.wiki.compileFilter(filter);
|
||||||
}
|
}
|
||||||
var output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),{
|
var output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": widget.getVariable("currentTiddler","")
|
||||||
opts.variables = {
|
}));
|
||||||
"currentTiddler": "" + title,
|
|
||||||
"..currentTiddler": widget.getVariable("currentTiddler")
|
|
||||||
};
|
|
||||||
if(name in opts.variables) {
|
|
||||||
return opts.variables[name];
|
|
||||||
} else {
|
|
||||||
return widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(output.length !== 0) {
|
if(output.length !== 0) {
|
||||||
result = output[0];
|
result = output[0];
|
||||||
return false;
|
return false;
|
||||||
|
@ -19,23 +19,13 @@ exports.filter = function(operationSubFunction,options) {
|
|||||||
var resultsToRemove = [],
|
var resultsToRemove = [],
|
||||||
index = 0;
|
index = 0;
|
||||||
results.each(function(title) {
|
results.each(function(title) {
|
||||||
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": widget.getVariable("currentTiddler",""),
|
||||||
opts.variables = {
|
"index": "" + index,
|
||||||
"currentTiddler": "" + title,
|
"revIndex": "" + (results.length - 1 - index),
|
||||||
"..currentTiddler": widget.getVariable("currentTiddler"),
|
"length": "" + results.length
|
||||||
"index": "" + index,
|
}));
|
||||||
"revIndex": "" + (results.length - 1 - index),
|
|
||||||
"length": "" + results.length
|
|
||||||
};
|
|
||||||
if(name in opts.variables) {
|
|
||||||
return opts.variables[name];
|
|
||||||
} else {
|
|
||||||
return widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(filtered.length === 0) {
|
if(filtered.length === 0) {
|
||||||
resultsToRemove.push(title);
|
resultsToRemove.push(title);
|
||||||
}
|
}
|
||||||
|
@ -21,23 +21,13 @@ exports.map = function(operationSubFunction,options) {
|
|||||||
flatten = (suffixes[0] && suffixes[0][0] === "flat") ? true : false;
|
flatten = (suffixes[0] && suffixes[0][0] === "flat") ? true : false;
|
||||||
results.clear();
|
results.clear();
|
||||||
$tw.utils.each(inputTitles,function(title) {
|
$tw.utils.each(inputTitles,function(title) {
|
||||||
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": widget.getVariable("currentTiddler",""),
|
||||||
opts.variables = {
|
"index": "" + index,
|
||||||
"currentTiddler": "" + title,
|
"revIndex": "" + (inputTitles.length - 1 - index),
|
||||||
"..currentTiddler": widget.getVariable("currentTiddler"),
|
"length": "" + inputTitles.length
|
||||||
"index": "" + index,
|
}));
|
||||||
"revIndex": "" + (inputTitles.length - 1 - index),
|
|
||||||
"length": "" + inputTitles.length
|
|
||||||
};
|
|
||||||
if(name in opts.variables) {
|
|
||||||
return opts.variables[name];
|
|
||||||
} else {
|
|
||||||
return widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(filtered.length && flatten) {
|
if(filtered.length && flatten) {
|
||||||
$tw.utils.each(filtered,function(value) {
|
$tw.utils.each(filtered,function(value) {
|
||||||
results.push(value);
|
results.push(value);
|
||||||
|
@ -18,24 +18,14 @@ exports.reduce = function(operationSubFunction,options) {
|
|||||||
var accumulator = "",
|
var accumulator = "",
|
||||||
index = 0;
|
index = 0;
|
||||||
results.each(function(title) {
|
results.each(function(title) {
|
||||||
var list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
var list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": widget.getVariable("currentTiddler"),
|
||||||
opts.variables = {
|
"index": "" + index,
|
||||||
"currentTiddler": "" + title,
|
"revIndex": "" + (results.length - 1 - index),
|
||||||
"..currentTiddler": widget.getVariable("currentTiddler"),
|
"length": "" + results.length,
|
||||||
"index": "" + index,
|
"accumulator": "" + accumulator
|
||||||
"revIndex": "" + (results.length - 1 - index),
|
}));
|
||||||
"length": "" + results.length,
|
|
||||||
"accumulator": "" + accumulator
|
|
||||||
};
|
|
||||||
if(name in opts.variables) {
|
|
||||||
return opts.variables[name];
|
|
||||||
} else {
|
|
||||||
return widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(list.length > 0) {
|
if(list.length > 0) {
|
||||||
accumulator = "" + list[0];
|
accumulator = "" + list[0];
|
||||||
}
|
}
|
||||||
|
@ -25,20 +25,10 @@ exports.sort = function(operationSubFunction,options) {
|
|||||||
indexes = new Array(inputTitles.length),
|
indexes = new Array(inputTitles.length),
|
||||||
compareFn;
|
compareFn;
|
||||||
results.each(function(title) {
|
results.each(function(title) {
|
||||||
var key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
var key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": widget.getVariable("currentTiddler")
|
||||||
opts.variables = {
|
}));
|
||||||
"currentTiddler": "" + title,
|
|
||||||
"..currentTiddler": widget.getVariable("currentTiddler")
|
|
||||||
};
|
|
||||||
if(name in opts.variables) {
|
|
||||||
return opts.variables[name];
|
|
||||||
} else {
|
|
||||||
return widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
sortKeys.push(key[0] || "");
|
sortKeys.push(key[0] || "");
|
||||||
});
|
});
|
||||||
results.clear();
|
results.clear();
|
||||||
|
@ -255,19 +255,21 @@ exports.compileFilter = function(filterString) {
|
|||||||
var operands = [],
|
var operands = [],
|
||||||
operatorFunction;
|
operatorFunction;
|
||||||
if(!operator.operator) {
|
if(!operator.operator) {
|
||||||
|
// Use the "title" operator if no operator is specified
|
||||||
operatorFunction = filterOperators.title;
|
operatorFunction = filterOperators.title;
|
||||||
} else if(!filterOperators[operator.operator]) {
|
} else if(!filterOperators[operator.operator]) {
|
||||||
operatorFunction = filterOperators.field;
|
// Unknown operators treated as "[unknown]" - at run time we can distinguish between a custom operator and falling back to the default "field" operator
|
||||||
|
operatorFunction = filterOperators["[unknown]"];
|
||||||
} else {
|
} else {
|
||||||
|
// Use the operator function
|
||||||
operatorFunction = filterOperators[operator.operator];
|
operatorFunction = filterOperators[operator.operator];
|
||||||
}
|
}
|
||||||
|
|
||||||
$tw.utils.each(operator.operands,function(operand) {
|
$tw.utils.each(operator.operands,function(operand) {
|
||||||
if(operand.indirect) {
|
if(operand.indirect) {
|
||||||
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
|
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
|
||||||
} else if(operand.variable) {
|
} else if(operand.variable) {
|
||||||
var varTree = $tw.utils.parseFilterVariable(operand.text);
|
var varTree = $tw.utils.parseFilterVariable(operand.text);
|
||||||
operand.value = widget.getVariable(varTree.name,{params:varTree.params,defaultValue: ""});
|
operand.value = widget.evaluateVariable(varTree.name,{params: varTree.params, source: source})[0] || "";
|
||||||
} else {
|
} else {
|
||||||
operand.value = operand.text;
|
operand.value = operand.text;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,22 @@ Filter operator for applying decodeURIComponent() to each item.
|
|||||||
Export our filter functions
|
Export our filter functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
exports.decodebase64 = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
results.push($tw.utils.base64Decode(title));
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.encodebase64 = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
results.push($tw.utils.base64Encode(title));
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
exports.decodeuricomponent = function(source,operator,options) {
|
exports.decodeuricomponent = function(source,operator,options) {
|
||||||
var results = [];
|
var results = [];
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
@ -27,7 +43,7 @@ exports.decodeuricomponent = function(source,operator,options) {
|
|||||||
exports.encodeuricomponent = function(source,operator,options) {
|
exports.encodeuricomponent = function(source,operator,options) {
|
||||||
var results = [];
|
var results = [];
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
results.push(encodeURIComponent(title));
|
results.push($tw.utils.encodeURIComponentExtended(title));
|
||||||
});
|
});
|
||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
@ -20,19 +20,10 @@ exports.filter = function(source,operator,options) {
|
|||||||
results = [],
|
results = [],
|
||||||
target = operator.prefix !== "!";
|
target = operator.prefix !== "!";
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
var list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),{
|
var list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),options.widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": options.widget.getVariable("currentTiddler","")
|
||||||
switch(name) {
|
}));
|
||||||
case "currentTiddler":
|
|
||||||
return "" + title;
|
|
||||||
case "..currentTiddler":
|
|
||||||
return options.widget.getVariable("currentTiddler");
|
|
||||||
default:
|
|
||||||
return options.widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if((list.length > 0) === target) {
|
if((list.length > 0) === target) {
|
||||||
results.push(title);
|
results.push(title);
|
||||||
}
|
}
|
||||||
|
32
core/modules/filters/function.js
Normal file
32
core/modules/filters/function.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/function.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator returning those input titles that are returned from a function
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.function = function(source,operator,options) {
|
||||||
|
var functionName = operator.operands[0],
|
||||||
|
variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(functionName);
|
||||||
|
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||||
|
return options.widget.evaluateVariable(functionName,{params: operator.operands.slice(1), source: source});
|
||||||
|
}
|
||||||
|
// Return the input list if the function wasn't found
|
||||||
|
var results = [];
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
results.push(title);
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
@ -26,27 +26,14 @@ exports.reduce = function(source,operator,options) {
|
|||||||
accumulator = operator.operands[1] || "";
|
accumulator = operator.operands[1] || "";
|
||||||
for(var index=0; index<results.length; index++) {
|
for(var index=0; index<results.length; index++) {
|
||||||
var title = results[index],
|
var title = results[index],
|
||||||
list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),{
|
list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),options.widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": options.widget.getVariable("currentTiddler"),
|
||||||
switch(name) {
|
"accumulator": "" + accumulator,
|
||||||
case "currentTiddler":
|
"index": "" + index,
|
||||||
return "" + title;
|
"revIndex": "" + (results.length - 1 - index),
|
||||||
case "..currentTiddler":
|
"length": "" + results.length
|
||||||
return options.widget.getVariable("currentTiddler");
|
}));
|
||||||
case "accumulator":
|
|
||||||
return "" + accumulator;
|
|
||||||
case "index":
|
|
||||||
return "" + index;
|
|
||||||
case "revIndex":
|
|
||||||
return "" + (results.length - 1 - index);
|
|
||||||
case "length":
|
|
||||||
return "" + results.length;
|
|
||||||
default:
|
|
||||||
return options.widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(list.length > 0) {
|
if(list.length > 0) {
|
||||||
accumulator = "" + list[0];
|
accumulator = "" + list[0];
|
||||||
}
|
}
|
||||||
|
@ -25,19 +25,10 @@ exports.sortsub = function(source,operator,options) {
|
|||||||
inputTitles.push(title);
|
inputTitles.push(title);
|
||||||
var r = filterFn.call(options.wiki,function(iterator) {
|
var r = filterFn.call(options.wiki,function(iterator) {
|
||||||
iterator(options.wiki.getTiddler(title),title);
|
iterator(options.wiki.getTiddler(title),title);
|
||||||
},{
|
},options.widget.makeFakeWidgetWithVariables({
|
||||||
getVariable: function(name,opts) {
|
"currentTiddler": "" + title,
|
||||||
opts = opts || {};
|
"..currentTiddler": options.widget.getVariable("currentTiddler")
|
||||||
switch(name) {
|
}));
|
||||||
case "currentTiddler":
|
|
||||||
return "" + title;
|
|
||||||
case "..currentTiddler":
|
|
||||||
return options.widget.getVariable("currentTiddler");
|
|
||||||
default:
|
|
||||||
return options.widget.getVariable(name,opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
sortKeys.push(r[0] || "");
|
sortKeys.push(r[0] || "");
|
||||||
});
|
});
|
||||||
// Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays
|
// Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays
|
||||||
|
@ -74,6 +74,113 @@ exports.join = makeStringReducingOperator(
|
|||||||
},null
|
},null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var dmp = require("$:/core/modules/utils/diff-match-patch/diff_match_patch.js");
|
||||||
|
|
||||||
|
exports.levenshtein = makeStringBinaryOperator(
|
||||||
|
function(a,b) {
|
||||||
|
var dmpObject = new dmp.diff_match_patch(),
|
||||||
|
diffs = dmpObject.diff_main(a,b);
|
||||||
|
return [dmpObject.diff_levenshtein(diffs) + ""];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// these two functions are adapted from https://github.com/google/diff-match-patch/wiki/Line-or-Word-Diffs
|
||||||
|
function diffLineWordMode(text1,text2,mode) {
|
||||||
|
var dmpObject = new dmp.diff_match_patch();
|
||||||
|
var a = diffPartsToChars(text1,text2,mode);
|
||||||
|
var lineText1 = a.chars1;
|
||||||
|
var lineText2 = a.chars2;
|
||||||
|
var lineArray = a.lineArray;
|
||||||
|
var diffs = dmpObject.diff_main(lineText1,lineText2,false);
|
||||||
|
dmpObject.diff_charsToLines_(diffs,lineArray);
|
||||||
|
return diffs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function diffPartsToChars(text1,text2,mode) {
|
||||||
|
var lineArray = [];
|
||||||
|
var lineHash = {};
|
||||||
|
lineArray[0] = '';
|
||||||
|
|
||||||
|
function diff_linesToPartsMunge_(text,mode) {
|
||||||
|
var chars = '';
|
||||||
|
var lineStart = 0;
|
||||||
|
var lineEnd = -1;
|
||||||
|
var lineArrayLength = lineArray.length,
|
||||||
|
regexpResult;
|
||||||
|
var searchRegexp = /\W+/g;
|
||||||
|
while(lineEnd < text.length - 1) {
|
||||||
|
if(mode === "words") {
|
||||||
|
regexpResult = searchRegexp.exec(text);
|
||||||
|
lineEnd = searchRegexp.lastIndex;
|
||||||
|
if(regexpResult === null) {
|
||||||
|
lineEnd = text.length;
|
||||||
|
}
|
||||||
|
lineEnd = --lineEnd;
|
||||||
|
} else {
|
||||||
|
lineEnd = text.indexOf('\n', lineStart);
|
||||||
|
if(lineEnd == -1) {
|
||||||
|
lineEnd = text.length - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var line = text.substring(lineStart, lineEnd + 1);
|
||||||
|
|
||||||
|
if(lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : (lineHash[line] !== undefined)) {
|
||||||
|
chars += String.fromCharCode(lineHash[line]);
|
||||||
|
} else {
|
||||||
|
if (lineArrayLength == maxLines) {
|
||||||
|
line = text.substring(lineStart);
|
||||||
|
lineEnd = text.length;
|
||||||
|
}
|
||||||
|
chars += String.fromCharCode(lineArrayLength);
|
||||||
|
lineHash[line] = lineArrayLength;
|
||||||
|
lineArray[lineArrayLength++] = line;
|
||||||
|
}
|
||||||
|
lineStart = lineEnd + 1;
|
||||||
|
}
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
var maxLines = 40000;
|
||||||
|
var chars1 = diff_linesToPartsMunge_(text1,mode);
|
||||||
|
maxLines = 65535;
|
||||||
|
var chars2 = diff_linesToPartsMunge_(text2,mode);
|
||||||
|
return {chars1: chars1, chars2: chars2, lineArray: lineArray};
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.makepatches = function(source,operator,options) {
|
||||||
|
var dmpObject = new dmp.diff_match_patch(),
|
||||||
|
suffix = operator.suffix || "",
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
var diffs, patches;
|
||||||
|
if(suffix === "lines" || suffix === "words") {
|
||||||
|
diffs = diffLineWordMode(title,operator.operand,suffix);
|
||||||
|
patches = dmpObject.patch_make(title,diffs);
|
||||||
|
} else {
|
||||||
|
patches = dmpObject.patch_make(title,operator.operand);
|
||||||
|
}
|
||||||
|
Array.prototype.push.apply(result,[dmpObject.patch_toText(patches)]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.applypatches = makeStringBinaryOperator(
|
||||||
|
function(a,b) {
|
||||||
|
var dmpObject = new dmp.diff_match_patch(),
|
||||||
|
patches;
|
||||||
|
try {
|
||||||
|
patches = dmpObject.patch_fromText(b);
|
||||||
|
} catch(e) {
|
||||||
|
}
|
||||||
|
if(patches) {
|
||||||
|
return [dmpObject.patch_apply(patches,a)[0]];
|
||||||
|
} else {
|
||||||
|
return [a];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
function makeStringBinaryOperator(fnCalc) {
|
function makeStringBinaryOperator(fnCalc) {
|
||||||
return function(source,operator,options) {
|
return function(source,operator,options) {
|
||||||
var result = [];
|
var result = [];
|
||||||
@ -184,4 +291,4 @@ exports.charcode = function(source,operator,options) {
|
|||||||
return [chars.join("")];
|
return [chars.join("")];
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
45
core/modules/filters/unknown.js
Normal file
45
core/modules/filters/unknown.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/unknown.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for handling unknown filter operators.
|
||||||
|
|
||||||
|
Not intended to be used directly by end users, hence the square brackets around the name.
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var fieldFilterOperatorFn = require("$:/core/modules/filters/field.js").field;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports["[unknown]"] = function(source,operator,options) {
|
||||||
|
// Check for a user defined filter operator
|
||||||
|
if(operator.operator.charAt(0) === ".") {
|
||||||
|
var variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(operator.operator);
|
||||||
|
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||||
|
var list = options.widget.evaluateVariable(operator.operator,{params: operator.operands, source: source});
|
||||||
|
if(operator.prefix === "!") {
|
||||||
|
var results = [];
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
if(list.indexOf(title) === -1) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
} else {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Otherwise, use the "field" operator
|
||||||
|
return fieldFilterOperatorFn(source,operator,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
@ -32,18 +32,18 @@ FieldIndexer.prototype.setMaxIndexedValueLength = function(length) {
|
|||||||
|
|
||||||
FieldIndexer.prototype.addIndexMethods = function() {
|
FieldIndexer.prototype.addIndexMethods = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
// get all tiddlers, including those overwrite shadow tiddlers
|
||||||
this.wiki.each.byField = function(name,value) {
|
this.wiki.each.byField = function(name,value) {
|
||||||
var titles = self.wiki.allTitles(),
|
var lookup = self.lookup(name,value);
|
||||||
lookup = self.lookup(name,value);
|
|
||||||
return lookup && lookup.filter(function(title) {
|
return lookup && lookup.filter(function(title) {
|
||||||
return titles.indexOf(title) !== -1;
|
return self.wiki.tiddlerExists(title)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
// get shadow tiddlers, including shadow tiddlers that is overwritten
|
||||||
this.wiki.eachShadow.byField = function(name,value) {
|
this.wiki.eachShadow.byField = function(name,value) {
|
||||||
var titles = self.wiki.allShadowTitles(),
|
var lookup = self.lookup(name,value);
|
||||||
lookup = self.lookup(name,value);
|
|
||||||
return lookup && lookup.filter(function(title) {
|
return lookup && lookup.filter(function(title) {
|
||||||
return titles.indexOf(title) !== -1;
|
return self.wiki.isShadowTiddler(title)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
this.wiki.eachTiddlerPlusShadows.byField = function(name,value) {
|
this.wiki.eachTiddlerPlusShadows.byField = function(name,value) {
|
||||||
|
@ -28,6 +28,8 @@ var AudioParser = function(type,text,options) {
|
|||||||
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
||||||
}
|
}
|
||||||
this.tree = [element];
|
this.tree = [element];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["audio/ogg"] = AudioParser;
|
exports["audio/ogg"] = AudioParser;
|
||||||
|
@ -23,7 +23,7 @@ var BinaryParser = function(type,text,options) {
|
|||||||
children: [{
|
children: [{
|
||||||
type: "transclude",
|
type: "transclude",
|
||||||
attributes: {
|
attributes: {
|
||||||
tiddler: {type: "string", value: BINARY_WARNING_MESSAGE}
|
"$tiddler": {type: "string", value: BINARY_WARNING_MESSAGE}
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
@ -38,7 +38,7 @@ var BinaryParser = function(type,text,options) {
|
|||||||
children: [{
|
children: [{
|
||||||
type: "transclude",
|
type: "transclude",
|
||||||
attributes: {
|
attributes: {
|
||||||
tiddler: {type: "string", value: EXPORT_BUTTON_IMAGE}
|
"$tiddler": {type: "string", value: EXPORT_BUTTON_IMAGE}
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
@ -64,6 +64,8 @@ var BinaryParser = function(type,text,options) {
|
|||||||
children: [warn, link]
|
children: [warn, link]
|
||||||
}
|
}
|
||||||
this.tree = [element];
|
this.tree = [element];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["application/octet-stream"] = BinaryParser;
|
exports["application/octet-stream"] = BinaryParser;
|
||||||
|
@ -52,6 +52,8 @@ var CsvParser = function(type,text,options) {
|
|||||||
tag = "td";
|
tag = "td";
|
||||||
this.tree[0].children[0].children[0].children.push(row);
|
this.tree[0].children[0].children[0].children.push(row);
|
||||||
}
|
}
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["text/csv"] = CsvParser;
|
exports["text/csv"] = CsvParser;
|
||||||
|
@ -29,6 +29,8 @@ var HtmlParser = function(type,text,options) {
|
|||||||
if($tw.wiki.getTiddlerText("$:/config/HtmlParser/DisableSandbox","no") !== "yes") {
|
if($tw.wiki.getTiddlerText("$:/config/HtmlParser/DisableSandbox","no") !== "yes") {
|
||||||
this.tree[0].attributes.sandbox = {type: "string", value: $tw.wiki.getTiddlerText("$:/config/HtmlParser/SandboxTokens","")};
|
this.tree[0].attributes.sandbox = {type: "string", value: $tw.wiki.getTiddlerText("$:/config/HtmlParser/SandboxTokens","")};
|
||||||
}
|
}
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["text/html"] = HtmlParser;
|
exports["text/html"] = HtmlParser;
|
||||||
|
@ -28,6 +28,8 @@ var ImageParser = function(type,text,options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.tree = [element];
|
this.tree = [element];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["image/svg+xml"] = ImageParser;
|
exports["image/svg+xml"] = ImageParser;
|
||||||
|
@ -123,6 +123,36 @@ exports.parseStringLiteral = function(source,pos) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns an array of {name:} with an optional "default" property. Options include:
|
||||||
|
requireParenthesis: require the parameter definition to be wrapped in parenthesis
|
||||||
|
*/
|
||||||
|
exports.parseParameterDefinition = function(paramString,options) {
|
||||||
|
options = options || {};
|
||||||
|
if(options.requireParenthesis) {
|
||||||
|
var parenMatch = /^\s*\((.*)\)\s*$/g.exec(paramString);
|
||||||
|
if(!parenMatch) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
paramString = parenMatch[1];
|
||||||
|
}
|
||||||
|
var params = [],
|
||||||
|
reParam = /\s*([^:),\s]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|([^,"'\s]+)))?/mg,
|
||||||
|
paramMatch = reParam.exec(paramString);
|
||||||
|
while(paramMatch) {
|
||||||
|
// Save the parameter details
|
||||||
|
var paramInfo = {name: paramMatch[1]},
|
||||||
|
defaultValue = paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5];
|
||||||
|
if(defaultValue !== undefined) {
|
||||||
|
paramInfo["default"] = defaultValue;
|
||||||
|
}
|
||||||
|
params.push(paramInfo);
|
||||||
|
// Look for the next parameter
|
||||||
|
paramMatch = reParam.exec(paramString);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
exports.parseMacroParameters = function(node,source,pos) {
|
exports.parseMacroParameters = function(node,source,pos) {
|
||||||
// Process parameters
|
// Process parameters
|
||||||
var parameter = $tw.utils.parseMacroParameter(source,pos);
|
var parameter = $tw.utils.parseMacroParameter(source,pos);
|
||||||
@ -175,7 +205,36 @@ exports.parseMacroParameter = function(source,pos) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Look for a macro invocation. Returns null if not found, or {type: "macrocall", name:, parameters:, start:, end:}
|
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;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Look for a macro invocation. Returns null if not found, or {type: "macrocall", name:, params:, start:, end:}
|
||||||
*/
|
*/
|
||||||
exports.parseMacroInvocation = function(source,pos) {
|
exports.parseMacroInvocation = function(source,pos) {
|
||||||
var node = {
|
var node = {
|
||||||
|
@ -15,7 +15,7 @@ The PDF parser embeds a PDF viewer
|
|||||||
var ImageParser = function(type,text,options) {
|
var ImageParser = function(type,text,options) {
|
||||||
var element = {
|
var element = {
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: "embed",
|
tag: "iframe",
|
||||||
attributes: {}
|
attributes: {}
|
||||||
},
|
},
|
||||||
src;
|
src;
|
||||||
@ -25,6 +25,8 @@ var ImageParser = function(type,text,options) {
|
|||||||
element.attributes.src = {type: "string", value: "data:application/pdf;base64," + text};
|
element.attributes.src = {type: "string", value: "data:application/pdf;base64," + text};
|
||||||
}
|
}
|
||||||
this.tree = [element];
|
this.tree = [element];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["application/pdf"] = ImageParser;
|
exports["application/pdf"] = ImageParser;
|
||||||
|
@ -20,6 +20,8 @@ var TextParser = function(type,text,options) {
|
|||||||
language: {type: "string", value: type}
|
language: {type: "string", value: type}
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["text/plain"] = TextParser;
|
exports["text/plain"] = TextParser;
|
||||||
|
@ -28,6 +28,8 @@ var VideoParser = function(type,text,options) {
|
|||||||
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
||||||
}
|
}
|
||||||
this.tree = [element];
|
this.tree = [element];
|
||||||
|
this.source = text;
|
||||||
|
this.type = type;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["video/ogg"] = VideoParser;
|
exports["video/ogg"] = VideoParser;
|
||||||
|
97
core/modules/parsers/wikiparser/rules/fnprocdef.js
Normal file
97
core/modules/parsers/wikiparser/rules/fnprocdef.js
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/parsers/wikiparser/rules/fnprocdef.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: wikirule
|
||||||
|
|
||||||
|
Wiki pragma rule for function, procedure and widget definitions
|
||||||
|
|
||||||
|
```
|
||||||
|
\function name(param:defaultvalue,param2:defaultvalue)
|
||||||
|
definition text
|
||||||
|
\end
|
||||||
|
|
||||||
|
\procedure name(param:defaultvalue,param2:defaultvalue)
|
||||||
|
definition text
|
||||||
|
\end
|
||||||
|
|
||||||
|
\widget $mywidget(param:defaultvalue,param2:defaultvalue)
|
||||||
|
definition text
|
||||||
|
\end
|
||||||
|
```
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
exports.name = "fnprocdef";
|
||||||
|
exports.types = {pragma: true};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Instantiate parse rule
|
||||||
|
*/
|
||||||
|
exports.init = function(parser) {
|
||||||
|
this.parser = parser;
|
||||||
|
// Regexp to match
|
||||||
|
this.matchRegExp = /^\\(function|procedure|widget)\s+([^(\s]+)\((\s*([^)]*))?\)(\s*\r?\n)?/mg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse the most recent match
|
||||||
|
*/
|
||||||
|
exports.parse = function() {
|
||||||
|
// Move past the macro name and parameters
|
||||||
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
// Parse the parameters
|
||||||
|
var params = [];
|
||||||
|
if(this.match[3]) {
|
||||||
|
params = $tw.utils.parseParameterDefinition(this.match[4]);
|
||||||
|
}
|
||||||
|
// Is this a multiline definition?
|
||||||
|
var reEnd;
|
||||||
|
if(this.match[5]) {
|
||||||
|
// If so, the end of the body is marked with \end
|
||||||
|
reEnd = new RegExp("(\\r?\\n\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[2]) + ")?(?:$|\\r?\\n))","mg");
|
||||||
|
} else {
|
||||||
|
// Otherwise, the end of the definition is marked by the end of the line
|
||||||
|
reEnd = /($|\r?\n)/mg;
|
||||||
|
// Move past any whitespace
|
||||||
|
this.parser.pos = $tw.utils.skipWhiteSpace(this.parser.source,this.parser.pos);
|
||||||
|
}
|
||||||
|
// Find the end of the definition
|
||||||
|
reEnd.lastIndex = this.parser.pos;
|
||||||
|
var text,
|
||||||
|
endMatch = reEnd.exec(this.parser.source);
|
||||||
|
if(endMatch) {
|
||||||
|
text = this.parser.source.substring(this.parser.pos,endMatch.index);
|
||||||
|
this.parser.pos = endMatch.index + endMatch[0].length;
|
||||||
|
} else {
|
||||||
|
// We didn't find the end of the definition, so we'll make it blank
|
||||||
|
text = "";
|
||||||
|
}
|
||||||
|
// Save the macro definition
|
||||||
|
var parseTreeNodes = [{
|
||||||
|
type: "set",
|
||||||
|
attributes: {},
|
||||||
|
children: [],
|
||||||
|
params: params
|
||||||
|
}];
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"name",this.match[2]);
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"value",text);
|
||||||
|
if(this.match[1] === "function") {
|
||||||
|
parseTreeNodes[0].isFunctionDefinition = true;
|
||||||
|
} else if(this.match[1] === "procedure") {
|
||||||
|
parseTreeNodes[0].isProcedureDefinition = true;
|
||||||
|
} else if(this.match[1] === "widget") {
|
||||||
|
parseTreeNodes[0].isWidgetDefinition = true;
|
||||||
|
}
|
||||||
|
if(this.parser.configTrimWhiteSpace) {
|
||||||
|
parseTreeNodes[0].configTrimWhiteSpace = true;
|
||||||
|
}
|
||||||
|
return parseTreeNodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
@ -93,9 +93,6 @@ exports.parseTag = function(source,pos,options) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
node.tag = token.match[1];
|
node.tag = token.match[1];
|
||||||
if(node.tag.slice(1).indexOf("$") !== -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if(node.tag.charAt(0) === "$") {
|
if(node.tag.charAt(0) === "$") {
|
||||||
node.type = node.tag.substr(1);
|
node.type = node.tag.substr(1);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ exports.findNextMatch = function(startPos) {
|
|||||||
var nextStart = startPos;
|
var nextStart = startPos;
|
||||||
// Try parsing at all possible macrocall openers until we match
|
// Try parsing at all possible macrocall openers until we match
|
||||||
while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) {
|
while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) {
|
||||||
var nextCall = $tw.utils.parseMacroInvocation(this.parser.source,nextStart);
|
var nextCall = $tw.utils.parseMacroInvocationAsTransclusion(this.parser.source,nextStart);
|
||||||
if(nextCall) {
|
if(nextCall) {
|
||||||
var c = this.parser.source.charAt(nextCall.end);
|
var c = this.parser.source.charAt(nextCall.end);
|
||||||
// Ensure EOL after parsed macro
|
// Ensure EOL after parsed macro
|
||||||
|
@ -27,7 +27,7 @@ exports.findNextMatch = function(startPos) {
|
|||||||
var nextStart = startPos;
|
var nextStart = startPos;
|
||||||
// Try parsing at all possible macrocall openers until we match
|
// Try parsing at all possible macrocall openers until we match
|
||||||
while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) {
|
while((nextStart = this.parser.source.indexOf("<<",nextStart)) >= 0) {
|
||||||
this.nextCall = $tw.utils.parseMacroInvocation(this.parser.source,nextStart);
|
this.nextCall = $tw.utils.parseMacroInvocationAsTransclusion(this.parser.source,nextStart);
|
||||||
if(this.nextCall) {
|
if(this.nextCall) {
|
||||||
return nextStart;
|
return nextStart;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ exports.parse = function() {
|
|||||||
var reEnd;
|
var reEnd;
|
||||||
if(this.match[3]) {
|
if(this.match[3]) {
|
||||||
// If so, the end of the body is marked with \end
|
// If so, the end of the body is marked with \end
|
||||||
reEnd = new RegExp("(\\r?\\n\\s*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?(?:$|\\r?\\n))","mg");
|
reEnd = new RegExp("(\\r?\\n[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?(?:$|\\r?\\n))","mg");
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, the end of the definition is marked by the end of the line
|
// Otherwise, the end of the definition is marked by the end of the line
|
||||||
reEnd = /($|\r?\n)/mg;
|
reEnd = /($|\r?\n)/mg;
|
||||||
@ -77,16 +77,16 @@ exports.parse = function() {
|
|||||||
text = "";
|
text = "";
|
||||||
}
|
}
|
||||||
// Save the macro definition
|
// Save the macro definition
|
||||||
return [{
|
var parseTreeNodes = [{
|
||||||
type: "set",
|
type: "set",
|
||||||
attributes: {
|
attributes: {},
|
||||||
name: {type: "string", value: this.match[1]},
|
|
||||||
value: {type: "string", value: text}
|
|
||||||
},
|
|
||||||
children: [],
|
children: [],
|
||||||
params: params,
|
params: params,
|
||||||
isMacroDefinition: true
|
isMacroDefinition: true
|
||||||
}];
|
}];
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"name",this.match[1]);
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"value",text);
|
||||||
|
return parseTreeNodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
60
core/modules/parsers/wikiparser/rules/parameters.js
Normal file
60
core/modules/parsers/wikiparser/rules/parameters.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/parsers/wikiparser/rules/parameters.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: wikirule
|
||||||
|
|
||||||
|
Wiki pragma rule for parameter definitions
|
||||||
|
|
||||||
|
```
|
||||||
|
\parameters(param:defaultvalue,param2:defaultvalue)
|
||||||
|
definition text
|
||||||
|
```
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
exports.name = "parameters";
|
||||||
|
exports.types = {pragma: true};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Instantiate parse rule
|
||||||
|
*/
|
||||||
|
exports.init = function(parser) {
|
||||||
|
this.parser = parser;
|
||||||
|
// Regexp to match
|
||||||
|
this.matchRegExp = /^\\parameters\s*\(([^)]*)\)\s*\r?\n/mg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse the most recent match
|
||||||
|
*/
|
||||||
|
exports.parse = function() {
|
||||||
|
// Move past the macro name and parameters
|
||||||
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
// Parse the parameters
|
||||||
|
var params = $tw.utils.parseParameterDefinition(this.match[1]);
|
||||||
|
var attributes = Object.create(null),
|
||||||
|
orderedAttributes = [];
|
||||||
|
$tw.utils.each(params,function(param) {
|
||||||
|
var name = param.name;
|
||||||
|
// Parameter names starting with dollar must be escaped to double dollars for the parameters widget
|
||||||
|
if(name.charAt(0) === "$") {
|
||||||
|
name = "$" + name;
|
||||||
|
}
|
||||||
|
var attribute = {name: name, type: "string", value: param["default"] || ""};
|
||||||
|
attributes[name] = attribute;
|
||||||
|
orderedAttributes.push(attribute);
|
||||||
|
});
|
||||||
|
// Save the macro definition
|
||||||
|
return [{
|
||||||
|
type: "parameters",
|
||||||
|
attributes: attributes,
|
||||||
|
orderedAttributes: orderedAttributes
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
@ -23,7 +23,7 @@ exports.types = {block: true};
|
|||||||
exports.init = function(parser) {
|
exports.init = function(parser) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
// Regexp to match
|
// Regexp to match
|
||||||
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?\}\}(?:\r?\n|$)/mg;
|
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}(?:\r?\n|$)/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
@ -31,13 +31,22 @@ exports.parse = function() {
|
|||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Get the match details
|
// Get the match details
|
||||||
var template = $tw.utils.trim(this.match[2]),
|
var template = $tw.utils.trim(this.match[2]),
|
||||||
textRef = $tw.utils.trim(this.match[1]);
|
textRef = $tw.utils.trim(this.match[1]),
|
||||||
|
params = this.match[3] ? this.match[3].split("|") : [];
|
||||||
// Prepare the transclude widget
|
// Prepare the transclude widget
|
||||||
var transcludeNode = {
|
var transcludeNode = {
|
||||||
type: "transclude",
|
type: "transclude",
|
||||||
attributes: {},
|
attributes: {},
|
||||||
isBlock: true
|
isBlock: true
|
||||||
};
|
};
|
||||||
|
$tw.utils.each(params,function(paramValue,index) {
|
||||||
|
var name = "" + index;
|
||||||
|
transcludeNode.attributes[name] = {
|
||||||
|
name: name,
|
||||||
|
type: "string",
|
||||||
|
value: paramValue
|
||||||
|
}
|
||||||
|
});
|
||||||
// Prepare the tiddler widget
|
// Prepare the tiddler widget
|
||||||
var tr, targetTitle, targetField, targetIndex, tiddlerNode;
|
var tr, targetTitle, targetField, targetIndex, tiddlerNode;
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
@ -48,14 +57,14 @@ exports.parse = function() {
|
|||||||
tiddlerNode = {
|
tiddlerNode = {
|
||||||
type: "tiddler",
|
type: "tiddler",
|
||||||
attributes: {
|
attributes: {
|
||||||
tiddler: {type: "string", value: targetTitle}
|
tiddler: {name: "tiddler", type: "string", value: targetTitle}
|
||||||
},
|
},
|
||||||
isBlock: true,
|
isBlock: true,
|
||||||
children: [transcludeNode]
|
children: [transcludeNode]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if(template) {
|
if(template) {
|
||||||
transcludeNode.attributes.tiddler = {type: "string", value: template};
|
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: template};
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
return [tiddlerNode];
|
return [tiddlerNode];
|
||||||
} else {
|
} else {
|
||||||
@ -63,12 +72,12 @@ exports.parse = function() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
|
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: targetTitle};
|
||||||
if(targetField) {
|
if(targetField) {
|
||||||
transcludeNode.attributes.field = {type: "string", value: targetField};
|
transcludeNode.attributes["$field"] = {name: "$field", type: "string", value: targetField};
|
||||||
}
|
}
|
||||||
if(targetIndex) {
|
if(targetIndex) {
|
||||||
transcludeNode.attributes.index = {type: "string", value: targetIndex};
|
transcludeNode.attributes["$index"] = {name: "$index", type: "string", value: targetIndex};
|
||||||
}
|
}
|
||||||
return [tiddlerNode];
|
return [tiddlerNode];
|
||||||
} else {
|
} else {
|
||||||
|
@ -23,7 +23,7 @@ exports.types = {inline: true};
|
|||||||
exports.init = function(parser) {
|
exports.init = function(parser) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
// Regexp to match
|
// Regexp to match
|
||||||
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?\}\}/mg;
|
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
@ -31,12 +31,21 @@ exports.parse = function() {
|
|||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Get the match details
|
// Get the match details
|
||||||
var template = $tw.utils.trim(this.match[2]),
|
var template = $tw.utils.trim(this.match[2]),
|
||||||
textRef = $tw.utils.trim(this.match[1]);
|
textRef = $tw.utils.trim(this.match[1]),
|
||||||
|
params = this.match[3] ? this.match[3].split("|") : [];
|
||||||
// Prepare the transclude widget
|
// Prepare the transclude widget
|
||||||
var transcludeNode = {
|
var transcludeNode = {
|
||||||
type: "transclude",
|
type: "transclude",
|
||||||
attributes: {}
|
attributes: {}
|
||||||
};
|
};
|
||||||
|
$tw.utils.each(params,function(paramValue,index) {
|
||||||
|
var name = "" + index;
|
||||||
|
transcludeNode.attributes[name] = {
|
||||||
|
name: name,
|
||||||
|
type: "string",
|
||||||
|
value: paramValue
|
||||||
|
}
|
||||||
|
});
|
||||||
// Prepare the tiddler widget
|
// Prepare the tiddler widget
|
||||||
var tr, targetTitle, targetField, targetIndex, tiddlerNode;
|
var tr, targetTitle, targetField, targetIndex, tiddlerNode;
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
@ -47,13 +56,13 @@ exports.parse = function() {
|
|||||||
tiddlerNode = {
|
tiddlerNode = {
|
||||||
type: "tiddler",
|
type: "tiddler",
|
||||||
attributes: {
|
attributes: {
|
||||||
tiddler: {type: "string", value: targetTitle}
|
tiddler: {name: "tiddler", type: "string", value: targetTitle}
|
||||||
},
|
},
|
||||||
children: [transcludeNode]
|
children: [transcludeNode]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if(template) {
|
if(template) {
|
||||||
transcludeNode.attributes.tiddler = {type: "string", value: template};
|
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: template};
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
return [tiddlerNode];
|
return [tiddlerNode];
|
||||||
} else {
|
} else {
|
||||||
@ -61,12 +70,12 @@ exports.parse = function() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(textRef) {
|
if(textRef) {
|
||||||
transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
|
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: targetTitle};
|
||||||
if(targetField) {
|
if(targetField) {
|
||||||
transcludeNode.attributes.field = {type: "string", value: targetField};
|
transcludeNode.attributes["$field"] = {name: "$field", type: "string", value: targetField};
|
||||||
}
|
}
|
||||||
if(targetIndex) {
|
if(targetIndex) {
|
||||||
transcludeNode.attributes.index = {type: "string", value: targetIndex};
|
transcludeNode.attributes["$index"] = {name: "$index", type: "string", value: targetIndex};
|
||||||
}
|
}
|
||||||
return [tiddlerNode];
|
return [tiddlerNode];
|
||||||
} else {
|
} else {
|
||||||
|
@ -32,6 +32,7 @@ options: see below:
|
|||||||
parseAsInline: true to parse text as inline instead of block
|
parseAsInline: true to parse text as inline instead of block
|
||||||
wiki: reference to wiki to use
|
wiki: reference to wiki to use
|
||||||
_canonical_uri: optional URI of content if text is missing or empty
|
_canonical_uri: optional URI of content if text is missing or empty
|
||||||
|
configTrimWhiteSpace: true to trim whitespace
|
||||||
*/
|
*/
|
||||||
var WikiParser = function(type,text,options) {
|
var WikiParser = function(type,text,options) {
|
||||||
this.wiki = options.wiki;
|
this.wiki = options.wiki;
|
||||||
@ -47,7 +48,7 @@ var WikiParser = function(type,text,options) {
|
|||||||
this.source = text || "";
|
this.source = text || "";
|
||||||
this.sourceLength = this.source.length;
|
this.sourceLength = this.source.length;
|
||||||
// Flag for ignoring whitespace
|
// Flag for ignoring whitespace
|
||||||
this.configTrimWhiteSpace = false;
|
this.configTrimWhiteSpace = options.configTrimWhiteSpace !== undefined ? options.configTrimWhiteSpace : false;
|
||||||
// Parser mode
|
// Parser mode
|
||||||
this.parseAsInline = options.parseAsInline;
|
this.parseAsInline = options.parseAsInline;
|
||||||
// Set current parse position
|
// Set current parse position
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/core/modules/savers/beaker.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: saver
|
|
||||||
|
|
||||||
Saves files using the Beaker browser's (https://beakerbrowser.com) Dat protocol (https://datproject.org/)
|
|
||||||
Compatible with beaker >= V0.7.2
|
|
||||||
|
|
||||||
\*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
|
||||||
/*global $tw: false */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/*
|
|
||||||
Set up the saver
|
|
||||||
*/
|
|
||||||
var BeakerSaver = function(wiki) {
|
|
||||||
this.wiki = wiki;
|
|
||||||
};
|
|
||||||
|
|
||||||
BeakerSaver.prototype.save = function(text,method,callback) {
|
|
||||||
var dat = new DatArchive("" + window.location),
|
|
||||||
pathname = ("" + window.location.pathname).split("#")[0];
|
|
||||||
dat.stat(pathname).then(function(value) {
|
|
||||||
if(value.isDirectory()) {
|
|
||||||
pathname = pathname + "/index.html";
|
|
||||||
}
|
|
||||||
dat.writeFile(pathname,text,"utf8").then(function(value) {
|
|
||||||
callback(null);
|
|
||||||
},function(reason) {
|
|
||||||
callback("Beaker Saver Write Error: " + reason);
|
|
||||||
});
|
|
||||||
},function(reason) {
|
|
||||||
callback("Beaker Saver Stat Error: " + reason);
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Information about this saver
|
|
||||||
*/
|
|
||||||
BeakerSaver.prototype.info = {
|
|
||||||
name: "beaker",
|
|
||||||
priority: 3000,
|
|
||||||
capabilities: ["save", "autosave"]
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Static method that returns true if this saver is capable of working
|
|
||||||
*/
|
|
||||||
exports.canSave = function(wiki) {
|
|
||||||
return !!window.DatArchive && location.protocol==="dat:";
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Create an instance of this saver
|
|
||||||
*/
|
|
||||||
exports.create = function(wiki) {
|
|
||||||
return new BeakerSaver(wiki);
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@ -1,64 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/core/modules/savers/hyperdrive.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: saver
|
|
||||||
|
|
||||||
Saves files using the Hyperdrive Protocol (https://hypercore-protocol.org/#hyperdrive) Beaker browser beta-1.0 and later (https://beakerbrowser.com)
|
|
||||||
Compatible with beaker >= V1.0.0
|
|
||||||
|
|
||||||
\*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
|
||||||
/*global $tw: false */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/*
|
|
||||||
Set up the saver
|
|
||||||
*/
|
|
||||||
var HyperdriveSaver = function(wiki) {
|
|
||||||
this.wiki = wiki;
|
|
||||||
};
|
|
||||||
|
|
||||||
HyperdriveSaver.prototype.save = function(text,method,callback) {
|
|
||||||
var dat = beaker.hyperdrive.drive("" + window.location),
|
|
||||||
pathname = ("" + window.location.pathname).split("#")[0];
|
|
||||||
dat.stat(pathname).then(function(value) {
|
|
||||||
if(value.isDirectory()) {
|
|
||||||
pathname = pathname + "/index.html";
|
|
||||||
}
|
|
||||||
dat.writeFile(pathname,text,"utf8").then(function(value) {
|
|
||||||
callback(null);
|
|
||||||
},function(reason) {
|
|
||||||
callback("Hyperdrive Saver Write Error: " + reason);
|
|
||||||
});
|
|
||||||
},function(reason) {
|
|
||||||
callback("Hyperdrive Saver Stat Error: " + reason);
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Information about this saver
|
|
||||||
*/
|
|
||||||
HyperdriveSaver.prototype.info = {
|
|
||||||
name: "beaker-1.x",
|
|
||||||
priority: 3000,
|
|
||||||
capabilities: ["save", "autosave"]
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Static method that returns true if this saver is capable of working
|
|
||||||
*/
|
|
||||||
exports.canSave = function(wiki) {
|
|
||||||
return !!window.beaker && !!beaker.hyperdrive && location.protocol==="hyper:";
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Create an instance of this saver
|
|
||||||
*/
|
|
||||||
exports.create = function(wiki) {
|
|
||||||
return new HyperdriveSaver(wiki);
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@ -87,13 +87,6 @@ exports.startup = function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// If we're being viewed on a data: URI then give instructions for how to save
|
|
||||||
if(document.location.protocol === "data:") {
|
|
||||||
$tw.rootWidget.dispatchEvent({
|
|
||||||
type: "tm-modal",
|
|
||||||
param: "$:/language/Modals/SaveInstructions"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -17,6 +17,10 @@ var easing = "cubic-bezier(0.645, 0.045, 0.355, 1)"; // From http://easings.net/
|
|||||||
var ZoominListView = function(listWidget) {
|
var ZoominListView = function(listWidget) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.listWidget = listWidget;
|
this.listWidget = listWidget;
|
||||||
|
this.textNodeLogger = new $tw.utils.Logger("zoomin story river view", {
|
||||||
|
enable: true,
|
||||||
|
colour: 'red'
|
||||||
|
});
|
||||||
// Get the index of the tiddler that is at the top of the history
|
// Get the index of the tiddler that is at the top of the history
|
||||||
var history = this.listWidget.wiki.getTiddlerDataCached(this.listWidget.historyTitle,[]),
|
var history = this.listWidget.wiki.getTiddlerDataCached(this.listWidget.historyTitle,[]),
|
||||||
targetTiddler;
|
targetTiddler;
|
||||||
@ -48,7 +52,10 @@ ZoominListView.prototype.navigateTo = function(historyInfo) {
|
|||||||
var listItemWidget = this.listWidget.children[listElementIndex],
|
var listItemWidget = this.listWidget.children[listElementIndex],
|
||||||
targetElement = listItemWidget.findFirstDomNode();
|
targetElement = listItemWidget.findFirstDomNode();
|
||||||
// Abandon if the list entry isn't a DOM element (it might be a text node)
|
// Abandon if the list entry isn't a DOM element (it might be a text node)
|
||||||
if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
|
if(!targetElement) {
|
||||||
|
return;
|
||||||
|
} else if (targetElement.nodeType === Node.TEXT_NODE) {
|
||||||
|
this.logTextNodeRoot(targetElement);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Make the new tiddler be position absolute and visible so that we can measure it
|
// Make the new tiddler be position absolute and visible so that we can measure it
|
||||||
@ -130,7 +137,10 @@ function findTitleDomNode(widget,targetClass) {
|
|||||||
ZoominListView.prototype.insert = function(widget) {
|
ZoominListView.prototype.insert = function(widget) {
|
||||||
var targetElement = widget.findFirstDomNode();
|
var targetElement = widget.findFirstDomNode();
|
||||||
// Abandon if the list entry isn't a DOM element (it might be a text node)
|
// Abandon if the list entry isn't a DOM element (it might be a text node)
|
||||||
if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
|
if(!targetElement) {
|
||||||
|
return;
|
||||||
|
} else if (targetElement.nodeType === Node.TEXT_NODE) {
|
||||||
|
this.logTextNodeRoot(targetElement);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Make the newly inserted node position absolute and hidden
|
// Make the newly inserted node position absolute and hidden
|
||||||
@ -173,16 +183,21 @@ ZoominListView.prototype.remove = function(widget) {
|
|||||||
var toWidgetDomNode = toWidget && toWidget.findFirstDomNode();
|
var toWidgetDomNode = toWidget && toWidget.findFirstDomNode();
|
||||||
// Set up the tiddler we're moving back in
|
// Set up the tiddler we're moving back in
|
||||||
if(toWidgetDomNode) {
|
if(toWidgetDomNode) {
|
||||||
$tw.utils.addClass(toWidgetDomNode,"tc-storyview-zoomin-tiddler");
|
if (toWidgetDomNode.nodeType === Node.TEXT_NODE) {
|
||||||
$tw.utils.setStyle(toWidgetDomNode,[
|
this.logTextNodeRoot(toWidgetDomNode);
|
||||||
{display: "block"},
|
toWidgetDomNode = null;
|
||||||
{transformOrigin: "50% 50%"},
|
} else {
|
||||||
{transform: "translateX(0px) translateY(0px) scale(10)"},
|
$tw.utils.addClass(toWidgetDomNode,"tc-storyview-zoomin-tiddler");
|
||||||
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms " + easing + ", opacity " + duration + "ms " + easing},
|
$tw.utils.setStyle(toWidgetDomNode,[
|
||||||
{opacity: "0"},
|
{display: "block"},
|
||||||
{zIndex: "500"}
|
{transformOrigin: "50% 50%"},
|
||||||
]);
|
{transform: "translateX(0px) translateY(0px) scale(10)"},
|
||||||
this.currentTiddlerDomNode = toWidgetDomNode;
|
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms " + easing + ", opacity " + duration + "ms " + easing},
|
||||||
|
{opacity: "0"},
|
||||||
|
{zIndex: "500"}
|
||||||
|
]);
|
||||||
|
this.currentTiddlerDomNode = toWidgetDomNode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Animate them both
|
// Animate them both
|
||||||
// Force layout
|
// Force layout
|
||||||
@ -206,6 +221,10 @@ ZoominListView.prototype.remove = function(widget) {
|
|||||||
return true; // Indicate that we'll delete the DOM node
|
return true; // Indicate that we'll delete the DOM node
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ZoominListView.prototype.logTextNodeRoot = function(node) {
|
||||||
|
this.textNodeLogger.log($tw.language.getString("Error/ZoominTextNode") + " " + node.textContent);
|
||||||
|
};
|
||||||
|
|
||||||
exports.zoomin = ZoominListView;
|
exports.zoomin = ZoominListView;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -28,6 +28,24 @@ exports.domMatchesSelector = function(node,selector) {
|
|||||||
return node.matches ? node.matches(selector) : node.msMatchesSelector(selector);
|
return node.matches ? node.matches(selector) : node.msMatchesSelector(selector);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Select text in a an input or textarea (setSelectionRange crashes on certain input types)
|
||||||
|
*/
|
||||||
|
exports.setSelectionRangeSafe = function(node,start,end,direction) {
|
||||||
|
try {
|
||||||
|
node.setSelectionRange(start,end,direction);
|
||||||
|
} catch(e) {
|
||||||
|
node.select();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Select the text in an input or textarea by position
|
||||||
|
*/
|
||||||
|
exports.setSelectionByPosition = function(node,selectFromStart,selectFromEnd) {
|
||||||
|
$tw.utils.setSelectionRangeSafe(node,selectFromStart,node.value.length - selectFromEnd);
|
||||||
|
};
|
||||||
|
|
||||||
exports.removeChildren = function(node) {
|
exports.removeChildren = function(node) {
|
||||||
while(node.hasChildNodes()) {
|
while(node.hasChildNodes()) {
|
||||||
node.removeChild(node.firstChild);
|
node.removeChild(node.firstChild);
|
||||||
|
@ -228,7 +228,7 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
|
|||||||
hasUnsafeFields = hasUnsafeFields || /[\x00-\x1F]/mg.test(value);
|
hasUnsafeFields = hasUnsafeFields || /[\x00-\x1F]/mg.test(value);
|
||||||
hasUnsafeFields = hasUnsafeFields || ($tw.utils.trim(value) !== value);
|
hasUnsafeFields = hasUnsafeFields || ($tw.utils.trim(value) !== value);
|
||||||
}
|
}
|
||||||
hasUnsafeFields = hasUnsafeFields || /:/mg.test(fieldName);
|
hasUnsafeFields = hasUnsafeFields || /:|#/mg.test(fieldName);
|
||||||
});
|
});
|
||||||
// Check for field values
|
// Check for field values
|
||||||
if(hasUnsafeFields) {
|
if(hasUnsafeFields) {
|
||||||
@ -238,7 +238,7 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
|
|||||||
} else {
|
} else {
|
||||||
// Save as a .tid or a text/binary file plus a .meta file
|
// Save as a .tid or a text/binary file plus a .meta file
|
||||||
var tiddlerType = tiddler.fields.type || "text/vnd.tiddlywiki";
|
var tiddlerType = tiddler.fields.type || "text/vnd.tiddlywiki";
|
||||||
if(tiddlerType === "text/vnd.tiddlywiki") {
|
if(tiddlerType === "text/vnd.tiddlywiki" || tiddler.hasField("_canonical_uri")) {
|
||||||
// Save as a .tid file
|
// Save as a .tid file
|
||||||
fileInfo.type = "application/x-tiddler";
|
fileInfo.type = "application/x-tiddler";
|
||||||
fileInfo.hasMetaFile = false;
|
fileInfo.hasMetaFile = false;
|
||||||
@ -393,7 +393,7 @@ exports.generateTiddlerFilepath = function(title,options) {
|
|||||||
} while(fs.existsSync(fullPath));
|
} while(fs.existsSync(fullPath));
|
||||||
// If the last write failed with an error, or if path does not start with:
|
// If the last write failed with an error, or if path does not start with:
|
||||||
// the resolved options.directory, the resolved wikiPath directory, the wikiTiddlersPath directory,
|
// the resolved options.directory, the resolved wikiPath directory, the wikiTiddlersPath directory,
|
||||||
// or the 'originalpath' directory, then encodeURIComponent() and resolve to tiddler directory.
|
// or the 'originalpath' directory, then $tw.utils.encodeURIComponentExtended() and resolve to tiddler directory.
|
||||||
var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath,fullPath),
|
var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath,fullPath),
|
||||||
encode = (options.fileInfo || {writeError: false}).writeError == true;
|
encode = (options.fileInfo || {writeError: false}).writeError == true;
|
||||||
if(!encode) {
|
if(!encode) {
|
||||||
@ -403,7 +403,7 @@ exports.generateTiddlerFilepath = function(title,options) {
|
|||||||
writePath.indexOf(path.resolve($tw.boot.wikiTiddlersPath,originalpath)) == 0 );
|
writePath.indexOf(path.resolve($tw.boot.wikiTiddlersPath,originalpath)) == 0 );
|
||||||
}
|
}
|
||||||
if(encode) {
|
if(encode) {
|
||||||
writePath = path.resolve(directory,encodeURIComponent(fullPath));
|
writePath = path.resolve(directory,$tw.utils.encodeURIComponentExtended(fullPath));
|
||||||
}
|
}
|
||||||
// Return the full path to the file
|
// Return the full path to the file
|
||||||
return writePath;
|
return writePath;
|
||||||
|
@ -685,6 +685,16 @@ exports.escapeRegExp = function(s) {
|
|||||||
return s.replace(/[\-\/\\\^\$\*\+\?\.\(\)\|\[\]\{\}]/g, '\\$&');
|
return s.replace(/[\-\/\\\^\$\*\+\?\.\(\)\|\[\]\{\}]/g, '\\$&');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Extended version of encodeURIComponent that encodes additional characters including
|
||||||
|
those that are illegal within filepaths on various platforms including Windows
|
||||||
|
*/
|
||||||
|
exports.encodeURIComponentExtended = function(s) {
|
||||||
|
return encodeURIComponent(s).replace(/[!'()*]/g,function(c) {
|
||||||
|
return "%" + c.charCodeAt(0).toString(16).toUpperCase();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Checks whether a link target is external, i.e. not a tiddler title
|
// Checks whether a link target is external, i.e. not a tiddler title
|
||||||
exports.isLinkExternal = function(to) {
|
exports.isLinkExternal = function(to) {
|
||||||
var externalRegExp = /^(?:file|http|https|mailto|ftp|irc|news|obsidian|data|skype):[^\s<>{}\[\]`|"\\^]+(?:\/|\b)/i;
|
var externalRegExp = /^(?:file|http|https|mailto|ftp|irc|news|obsidian|data|skype):[^\s<>{}\[\]`|"\\^]+(?:\/|\b)/i;
|
||||||
|
@ -232,12 +232,34 @@ DropZoneWidget.prototype.handleDropEvent = function(event) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DropZoneWidget.prototype.handlePasteEvent = function(event) {
|
DropZoneWidget.prototype.handlePasteEvent = function(event) {
|
||||||
var self = this,
|
var self = this;
|
||||||
readFileCallback = function(tiddlerFieldsArray) {
|
var readFileCallback = function(tiddlerFieldsArray) {
|
||||||
self.readFileCallback(tiddlerFieldsArray);
|
self.readFileCallback(tiddlerFieldsArray);
|
||||||
};
|
};
|
||||||
|
var getItem = function(type) {
|
||||||
|
type = type || "text/plain";
|
||||||
|
return function(str) {
|
||||||
|
// Use the deserializer specified if any
|
||||||
|
if(self.dropzoneDeserializer) {
|
||||||
|
tiddlerFields = self.wiki.deserializeTiddlers(null,str,{title: self.wiki.generateNewTitle("Untitled " + type)},{deserializer:self.dropzoneDeserializer});
|
||||||
|
if(tiddlerFields && tiddlerFields.length) {
|
||||||
|
readFileCallback(tiddlerFields);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tiddlerFields = {
|
||||||
|
title: self.wiki.generateNewTitle("Untitled " + type),
|
||||||
|
text: str,
|
||||||
|
type: type
|
||||||
|
};
|
||||||
|
if($tw.log.IMPORT) {
|
||||||
|
console.log("Importing string '" + str + "', type: '" + type + "'");
|
||||||
|
}
|
||||||
|
readFileCallback([tiddlerFields]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
// Let the browser handle it if we're in a textarea or input box
|
// Let the browser handle it if we're in a textarea or input box
|
||||||
if(["TEXTAREA","INPUT"].indexOf(event.target.tagName) == -1 && !event.target.isContentEditable) {
|
if(["TEXTAREA","INPUT"].indexOf(event.target.tagName) == -1 && !event.target.isContentEditable && !event.twEditor) {
|
||||||
var self = this,
|
var self = this,
|
||||||
items = event.clipboardData.items;
|
items = event.clipboardData.items;
|
||||||
// Enumerate the clipboard items
|
// Enumerate the clipboard items
|
||||||
@ -251,27 +273,10 @@ DropZoneWidget.prototype.handlePasteEvent = function(event) {
|
|||||||
});
|
});
|
||||||
} else if(item.kind === "string") {
|
} else if(item.kind === "string") {
|
||||||
// Create tiddlers from string items
|
// Create tiddlers from string items
|
||||||
var tiddlerFields,
|
var tiddlerFields;
|
||||||
type = item.type;
|
// It's important to give getAsString a closure with the right type
|
||||||
item.getAsString(function(str) {
|
// So it can be added to the import queue
|
||||||
// Use the deserializer specified if any
|
item.getAsString(getItem(item.type));
|
||||||
if(self.dropzoneDeserializer) {
|
|
||||||
tiddlerFields = self.wiki.deserializeTiddlers(null,str,{title: self.wiki.generateNewTitle("Untitled")},{deserializer:self.dropzoneDeserializer});
|
|
||||||
if(tiddlerFields && tiddlerFields.length) {
|
|
||||||
readFileCallback(tiddlerFields);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tiddlerFields = {
|
|
||||||
title: self.wiki.generateNewTitle("Untitled"),
|
|
||||||
text: str,
|
|
||||||
type: type
|
|
||||||
};
|
|
||||||
if($tw.log.IMPORT) {
|
|
||||||
console.log("Importing string '" + str + "', type: '" + type + "'");
|
|
||||||
}
|
|
||||||
readFileCallback([tiddlerFields]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Tell the browser that we've handled the paste
|
// Tell the browser that we've handled the paste
|
||||||
|
30
core/modules/widgets/fill.js
Normal file
30
core/modules/widgets/fill.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/widgets/fill.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
Sub-widget used by the transclude widget for specifying values for slots within transcluded content. It doesn't do anything by itself because the transclude widget only ever deals with the parse tree nodes, and doesn't instantiate the widget itself
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||||
|
|
||||||
|
var FillWidget = function(parseTreeNode,options) {
|
||||||
|
// Initialise
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inherit from the base widget class
|
||||||
|
*/
|
||||||
|
FillWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
exports.fill = FillWidget;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
@ -46,6 +46,7 @@ GenesisWidget.prototype.execute = function() {
|
|||||||
this.genesisRemappable = this.getAttribute("$remappable","yes") === "yes";
|
this.genesisRemappable = this.getAttribute("$remappable","yes") === "yes";
|
||||||
this.genesisNames = this.getAttribute("$names","");
|
this.genesisNames = this.getAttribute("$names","");
|
||||||
this.genesisValues = this.getAttribute("$values","");
|
this.genesisValues = this.getAttribute("$values","");
|
||||||
|
this.genesisIsBlock = this.getAttribute("$mode",this.parseTreeNode.isBlock && "block") === "block";
|
||||||
// Do not create a child widget if the $type attribute is missing or blank
|
// Do not create a child widget if the $type attribute is missing or blank
|
||||||
if(!this.genesisType) {
|
if(!this.genesisType) {
|
||||||
this.makeChildWidgets(this.parseTreeNode.children);
|
this.makeChildWidgets(this.parseTreeNode.children);
|
||||||
@ -60,6 +61,7 @@ GenesisWidget.prototype.execute = function() {
|
|||||||
tag: nodeTag,
|
tag: nodeTag,
|
||||||
attributes: {},
|
attributes: {},
|
||||||
orderedAttributes: [],
|
orderedAttributes: [],
|
||||||
|
isBlock: this.genesisIsBlock,
|
||||||
children: this.parseTreeNode.children || [],
|
children: this.parseTreeNode.children || [],
|
||||||
isNotRemappable: !this.genesisRemappable
|
isNotRemappable: !this.genesisRemappable
|
||||||
}];
|
}];
|
||||||
|
@ -52,38 +52,44 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
|
|||||||
var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true});
|
var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true});
|
||||||
if(parser) {
|
if(parser) {
|
||||||
var parseTreeNode = parser.tree[0];
|
var parseTreeNode = parser.tree[0];
|
||||||
while(parseTreeNode && parseTreeNode.type === "set") {
|
while(parseTreeNode && ["setvariable","set","parameters"].indexOf(parseTreeNode.type) !== -1) {
|
||||||
var node = {
|
var node = {
|
||||||
type: "set",
|
type: "set",
|
||||||
attributes: parseTreeNode.attributes,
|
attributes: parseTreeNode.attributes,
|
||||||
params: parseTreeNode.params,
|
params: parseTreeNode.params,
|
||||||
isMacroDefinition: parseTreeNode.isMacroDefinition
|
isMacroDefinition: parseTreeNode.isMacroDefinition,
|
||||||
|
isFunctionDefinition: parseTreeNode.isFunctionDefinition,
|
||||||
|
isProcedureDefinition: parseTreeNode.isProcedureDefinition,
|
||||||
|
isWidgetDefinition: parseTreeNode.isWidgetDefinition,
|
||||||
|
configTrimWhiteSpace: parseTreeNode.configTrimWhiteSpace
|
||||||
};
|
};
|
||||||
if (parseTreeNode.isMacroDefinition) {
|
if(parseTreeNode.type === "set" || parseTreeNode.type === "setvariable") {
|
||||||
// Macro definitions can be folded into
|
if(parseTreeNode.isMacroDefinition || parseTreeNode.isProcedureDefinition || parseTreeNode.isWidgetDefinition || parseTreeNode.isFunctionDefinition) {
|
||||||
// current widget instead of adding
|
// Macro definitions can be folded into
|
||||||
// another link to the chain.
|
// current widget instead of adding
|
||||||
var widget = widgetPointer.makeChildWidget(node);
|
// another link to the chain.
|
||||||
widget.computeAttributes();
|
var widget = widgetPointer.makeChildWidget(node);
|
||||||
widget.execute();
|
widget.computeAttributes();
|
||||||
// We SHALLOW copy over all variables
|
widget.execute();
|
||||||
// in widget. We can't use
|
// We SHALLOW copy over all variables
|
||||||
// $tw.utils.assign, because that copies
|
// in widget. We can't use
|
||||||
// up the prototype chain, which we
|
// $tw.utils.assign, because that copies
|
||||||
// don't want.
|
// up the prototype chain, which we
|
||||||
$tw.utils.each(Object.keys(widget.variables), function(key) {
|
// don't want.
|
||||||
widgetPointer.variables[key] = widget.variables[key];
|
$tw.utils.each(Object.keys(widget.variables), function(key) {
|
||||||
});
|
widgetPointer.variables[key] = widget.variables[key];
|
||||||
} else {
|
});
|
||||||
widgetPointer.children = [widgetPointer.makeChildWidget(node)];
|
} else {
|
||||||
// No more regenerating children for
|
widgetPointer.children = [widgetPointer.makeChildWidget(node)];
|
||||||
// this widget. If it needs to refresh,
|
// No more regenerating children for
|
||||||
// it'll do so along with the the whole
|
// this widget. If it needs to refresh,
|
||||||
// importvariable tree.
|
// it'll do so along with the the whole
|
||||||
if (widgetPointer != this) {
|
// importvariable tree.
|
||||||
widgetPointer.makeChildWidgets = function(){};
|
if (widgetPointer != this) {
|
||||||
|
widgetPointer.makeChildWidgets = function(){};
|
||||||
|
}
|
||||||
|
widgetPointer = widgetPointer.children[0];
|
||||||
}
|
}
|
||||||
widgetPointer = widgetPointer.children[0];
|
|
||||||
}
|
}
|
||||||
parseTreeNode = parseTreeNode.children && parseTreeNode.children[0];
|
parseTreeNode = parseTreeNode.children && parseTreeNode.children[0];
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,9 @@ LetWidget.prototype.computeAttributes = function() {
|
|||||||
name = attribute.name;
|
name = attribute.name;
|
||||||
// Now that it's prepped, we're allowed to look this variable up
|
// Now that it's prepped, we're allowed to look this variable up
|
||||||
// when defining later variables
|
// when defining later variables
|
||||||
self.currentValueFor[name] = value;
|
if(value !== undefined) {
|
||||||
|
self.currentValueFor[name] = value;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// Run through again, setting variables and looking for differences
|
// Run through again, setting variables and looking for differences
|
||||||
$tw.utils.each(this.currentValueFor,function(value,name) {
|
$tw.utils.each(this.currentValueFor,function(value,name) {
|
||||||
|
@ -97,8 +97,8 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||||||
// Expand the tv-wikilink-template variable to construct the href
|
// Expand the tv-wikilink-template variable to construct the href
|
||||||
var wikiLinkTemplateMacro = this.getVariable("tv-wikilink-template"),
|
var wikiLinkTemplateMacro = this.getVariable("tv-wikilink-template"),
|
||||||
wikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.trim() : "#$uri_encoded$";
|
wikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.trim() : "#$uri_encoded$";
|
||||||
wikiLinkText = $tw.utils.replaceString(wikiLinkTemplate,"$uri_encoded$",encodeURIComponent(this.to));
|
wikiLinkText = $tw.utils.replaceString(wikiLinkTemplate,"$uri_encoded$",$tw.utils.encodeURIComponentExtended(this.to));
|
||||||
wikiLinkText = $tw.utils.replaceString(wikiLinkText,"$uri_doubleencoded$",encodeURIComponent(encodeURIComponent(this.to)));
|
wikiLinkText = $tw.utils.replaceString(wikiLinkText,"$uri_doubleencoded$",$tw.utils.encodeURIComponentExtended($tw.utils.encodeURIComponentExtended(this.to)));
|
||||||
}
|
}
|
||||||
// Override with the value of tv-get-export-link if defined
|
// Override with the value of tv-get-export-link if defined
|
||||||
wikiLinkText = this.getVariable("tv-get-export-link",{params: [{name: "to",value: this.to}],defaultValue: wikiLinkText});
|
wikiLinkText = this.getVariable("tv-get-export-link",{params: [{name: "to",value: this.to}],defaultValue: wikiLinkText});
|
||||||
|
@ -37,7 +37,7 @@ MacroCallWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
Compute the internal state of the widget
|
Compute the internal state of the widget
|
||||||
*/
|
*/
|
||||||
MacroCallWidget.prototype.execute = function() {
|
MacroCallWidget.prototype.execute = function() {
|
||||||
// Get the parse type if specified
|
this.macroName = this.parseTreeNode.name || this.getAttribute("$name"),
|
||||||
this.parseType = this.getAttribute("$type","text/vnd.tiddlywiki");
|
this.parseType = this.getAttribute("$type","text/vnd.tiddlywiki");
|
||||||
this.renderOutput = this.getAttribute("$output","text/html");
|
this.renderOutput = this.getAttribute("$output","text/html");
|
||||||
// Merge together the parameters specified in the parse tree with the specified attributes
|
// Merge together the parameters specified in the parse tree with the specified attributes
|
||||||
@ -47,49 +47,26 @@ MacroCallWidget.prototype.execute = function() {
|
|||||||
params.push({name: name, value: attribute});
|
params.push({name: name, value: attribute});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Get the macro value
|
// Make a transclude widget
|
||||||
var macroName = this.parseTreeNode.name || this.getAttribute("$name"),
|
var positionalName = 0,
|
||||||
variableInfo = this.getVariableInfo(macroName,{params: params}),
|
|
||||||
text = variableInfo.text,
|
|
||||||
parseTreeNodes;
|
|
||||||
// Are we rendering to HTML?
|
|
||||||
if(this.renderOutput === "text/html") {
|
|
||||||
// If so we'll return the parsed macro
|
|
||||||
// Check if we've already cached parsing this macro
|
|
||||||
var mode = this.parseTreeNode.isBlock ? "blockParser" : "inlineParser",
|
|
||||||
parser;
|
|
||||||
if(variableInfo.srcVariable && variableInfo.srcVariable[mode]) {
|
|
||||||
parser = variableInfo.srcVariable[mode];
|
|
||||||
} else {
|
|
||||||
parser = this.wiki.parseText(this.parseType,text,
|
|
||||||
{parseAsInline: !this.parseTreeNode.isBlock});
|
|
||||||
if(variableInfo.isCacheable && variableInfo.srcVariable) {
|
|
||||||
variableInfo.srcVariable[mode] = parser;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var parseTreeNodes = parser ? parser.tree : [];
|
|
||||||
// Wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
|
||||||
var attributes = {};
|
|
||||||
$tw.utils.each(variableInfo.params,function(param) {
|
|
||||||
var name = "__" + param.name + "__";
|
|
||||||
attributes[name] = {
|
|
||||||
name: name,
|
|
||||||
type: "string",
|
|
||||||
value: param.value
|
|
||||||
};
|
|
||||||
});
|
|
||||||
parseTreeNodes = [{
|
parseTreeNodes = [{
|
||||||
type: "vars",
|
type: "transclude",
|
||||||
attributes: attributes,
|
isBlock: this.parseTreeNode.isBlock
|
||||||
children: parseTreeNodes
|
|
||||||
}];
|
}];
|
||||||
} else if(this.renderOutput === "text/raw") {
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$variable",this.macroName);
|
||||||
parseTreeNodes = [{type: "text", text: text}];
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$type",this.parseType);
|
||||||
} else {
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"$output",this.renderOutput);
|
||||||
// Otherwise, we'll render the text
|
$tw.utils.each(params,function(param) {
|
||||||
var plainText = this.wiki.renderText("text/plain",this.parseType,text,{parentWidget: this});
|
var name = param.name;
|
||||||
parseTreeNodes = [{type: "text", text: plainText}];
|
if(name) {
|
||||||
}
|
if(name.charAt(0) === "$") {
|
||||||
|
name = "$" + name;
|
||||||
|
}
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],name,param.value);
|
||||||
|
} else {
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],(positionalName++) + "",param.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
// Construct the child widgets
|
// Construct the child widgets
|
||||||
this.makeChildWidgets(parseTreeNodes);
|
this.makeChildWidgets(parseTreeNodes);
|
||||||
};
|
};
|
||||||
|
@ -82,7 +82,7 @@ MessageCatcherWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Render children
|
// Render children
|
||||||
this.renderChildren(parent,null);
|
this.renderChildren(parent,nextSibling);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -227,10 +227,7 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
|
|||||||
originalTitle = tiddler ? tiddler.fields["draft.of"] : "",
|
originalTitle = tiddler ? tiddler.fields["draft.of"] : "",
|
||||||
originalTiddler = originalTitle ? this.wiki.getTiddler(originalTitle) : undefined,
|
originalTiddler = originalTitle ? this.wiki.getTiddler(originalTitle) : undefined,
|
||||||
confirmationTitle,
|
confirmationTitle,
|
||||||
win = event.event && event.event.view ? event.event.view : window;
|
win = event.event && event.event.view ? event.event.view : window;
|
||||||
if(!tiddler) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Check if the tiddler we're deleting is in draft mode
|
// Check if the tiddler we're deleting is in draft mode
|
||||||
if(originalTitle) {
|
if(originalTitle) {
|
||||||
// If so, we'll prompt for confirmation referencing the original tiddler
|
// If so, we'll prompt for confirmation referencing the original tiddler
|
||||||
@ -240,7 +237,7 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
|
|||||||
confirmationTitle = title;
|
confirmationTitle = title;
|
||||||
}
|
}
|
||||||
// Seek confirmation
|
// Seek confirmation
|
||||||
if((this.wiki.getTiddler(originalTitle) || (tiddler.fields.text || "") !== "") && !win.confirm($tw.language.getString(
|
if(((originalTitle && this.wiki.getTiddler(originalTitle)) || (tiddler && ((tiddler.fields.text || "") !== ""))) && !win.confirm($tw.language.getString(
|
||||||
"ConfirmDeleteTiddler",
|
"ConfirmDeleteTiddler",
|
||||||
{variables:
|
{variables:
|
||||||
{title: confirmationTitle}
|
{title: confirmationTitle}
|
||||||
@ -257,8 +254,10 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
|
|||||||
this.removeTitleFromStory(storyList,originalTitle);
|
this.removeTitleFromStory(storyList,originalTitle);
|
||||||
}
|
}
|
||||||
// Invoke the hook function and delete this tiddler
|
// Invoke the hook function and delete this tiddler
|
||||||
$tw.hooks.invokeHook("th-deleting-tiddler",tiddler);
|
if(tiddler) {
|
||||||
this.wiki.deleteTiddler(title);
|
$tw.hooks.invokeHook("th-deleting-tiddler",tiddler);
|
||||||
|
this.wiki.deleteTiddler(title);
|
||||||
|
}
|
||||||
// Remove the closed tiddler from the story
|
// Remove the closed tiddler from the story
|
||||||
this.removeTitleFromStory(storyList,title);
|
this.removeTitleFromStory(storyList,title);
|
||||||
this.saveStoryList(storyList);
|
this.saveStoryList(storyList);
|
||||||
@ -500,7 +499,8 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
|
|||||||
// Get the tiddlers
|
// Get the tiddlers
|
||||||
var tiddlers = $tw.utils.parseJSONSafe(event.param,[]);
|
var tiddlers = $tw.utils.parseJSONSafe(event.param,[]);
|
||||||
// Get the current $:/Import tiddler
|
// Get the current $:/Import tiddler
|
||||||
var importTitle = event.importTitle ? event.importTitle : IMPORT_TITLE,
|
var paramObject = event.paramObject || {},
|
||||||
|
importTitle = event.importTitle || paramObject.importTitle || IMPORT_TITLE,
|
||||||
importTiddler = this.wiki.getTiddler(importTitle),
|
importTiddler = this.wiki.getTiddler(importTitle),
|
||||||
importData = this.wiki.getTiddlerData(importTitle,{}),
|
importData = this.wiki.getTiddlerData(importTitle,{}),
|
||||||
newFields = new Object({
|
newFields = new Object({
|
||||||
@ -541,7 +541,7 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
|
|||||||
newFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces);
|
newFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces);
|
||||||
this.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields));
|
this.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields));
|
||||||
// Update the story and history details
|
// Update the story and history details
|
||||||
var autoOpenOnImport = event.autoOpenOnImport ? event.autoOpenOnImport : this.getVariable("tv-auto-open-on-import");
|
var autoOpenOnImport = event.autoOpenOnImport || paramObject.autoOpenOnImport || this.getVariable("tv-auto-open-on-import");
|
||||||
if(autoOpenOnImport !== "no") {
|
if(autoOpenOnImport !== "no") {
|
||||||
var storyList = this.getStoryList(),
|
var storyList = this.getStoryList(),
|
||||||
history = [];
|
history = [];
|
||||||
|
96
core/modules/widgets/parameters.js
Normal file
96
core/modules/widgets/parameters.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/widgets/parameters.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
Widget for definition of transclusion parameters
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Widget = require("$:/core/modules/widgets/widget.js").widget,
|
||||||
|
TranscludeWidget = require("$:/core/modules/widgets/transclude.js").transclude;
|
||||||
|
|
||||||
|
var ParametersWidget = function(parseTreeNode,options) {
|
||||||
|
// Initialise
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inherit from the base widget class
|
||||||
|
*/
|
||||||
|
ParametersWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Render this widget into the DOM
|
||||||
|
*/
|
||||||
|
ParametersWidget.prototype.render = function(parent,nextSibling) {
|
||||||
|
// Call the constructor
|
||||||
|
Widget.call(this);
|
||||||
|
this.parentDomNode = parent;
|
||||||
|
this.computeAttributes();
|
||||||
|
this.execute();
|
||||||
|
this.renderChildren(parent,nextSibling);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compute the internal state of the widget
|
||||||
|
*/
|
||||||
|
ParametersWidget.prototype.execute = function() {
|
||||||
|
var self = this;
|
||||||
|
this.parametersDepth = Math.max(parseInt(this.getAttribute("$depth","1"),10) || 1,1);
|
||||||
|
// Find the parent transclusions
|
||||||
|
var pointer = this.parentWidget,
|
||||||
|
depth = this.parametersDepth;
|
||||||
|
while(pointer) {
|
||||||
|
if(pointer instanceof TranscludeWidget) {
|
||||||
|
depth--;
|
||||||
|
if(depth <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pointer = pointer.parentWidget;
|
||||||
|
}
|
||||||
|
// Process each parameter
|
||||||
|
if(pointer instanceof TranscludeWidget) {
|
||||||
|
// Get the value for each defined parameter
|
||||||
|
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(self.parseTreeNode),function(attr,index) {
|
||||||
|
var name = attr.name;
|
||||||
|
// If the attribute name starts with $$ then reduce to a single dollar
|
||||||
|
if(name.substr(0,2) === "$$") {
|
||||||
|
name = name.substr(1);
|
||||||
|
}
|
||||||
|
var value = pointer.getTransclusionParameter(name,index,self.getAttribute(attr.name,""));
|
||||||
|
self.setVariable(name,value);
|
||||||
|
});
|
||||||
|
// Assign any metaparameters
|
||||||
|
$tw.utils.each(pointer.getTransclusionMetaParameters(),function(getValue,name) {
|
||||||
|
var variableName = self.getAttribute("$" + name);
|
||||||
|
if(variableName) {
|
||||||
|
self.setVariable(variableName,getValue(name));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Construct the child widgets
|
||||||
|
this.makeChildWidgets();
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Refresh the widget by ensuring our attributes are up to date
|
||||||
|
*/
|
||||||
|
ParametersWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
|
var changedAttributes = this.computeAttributes();
|
||||||
|
if(Object.keys(changedAttributes).length) {
|
||||||
|
this.refreshSelf();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return this.refreshChildren(changedTiddlers);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.parameters = ParametersWidget;
|
||||||
|
|
||||||
|
})();
|
@ -48,7 +48,17 @@ SetWidget.prototype.execute = function() {
|
|||||||
this.setValue = this.getAttribute("value");
|
this.setValue = this.getAttribute("value");
|
||||||
this.setEmptyValue = this.getAttribute("emptyValue");
|
this.setEmptyValue = this.getAttribute("emptyValue");
|
||||||
// Set context variable
|
// Set context variable
|
||||||
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,!!this.parseTreeNode.isMacroDefinition);
|
if(this.parseTreeNode.isMacroDefinition) {
|
||||||
|
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,true);
|
||||||
|
} else if(this.parseTreeNode.isFunctionDefinition) {
|
||||||
|
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isFunctionDefinition: true});
|
||||||
|
} else if(this.parseTreeNode.isProcedureDefinition) {
|
||||||
|
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isProcedureDefinition: true, configTrimWhiteSpace: this.parseTreeNode.configTrimWhiteSpace});
|
||||||
|
} else if(this.parseTreeNode.isWidgetDefinition) {
|
||||||
|
this.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,undefined,{isWidgetDefinition: true, configTrimWhiteSpace: this.parseTreeNode.configTrimWhiteSpace});
|
||||||
|
} else {
|
||||||
|
this.setVariable(this.setName,this.getValue());
|
||||||
|
}
|
||||||
// Construct the child widgets
|
// Construct the child widgets
|
||||||
this.makeChildWidgets();
|
this.makeChildWidgets();
|
||||||
};
|
};
|
||||||
|
82
core/modules/widgets/slot.js
Normal file
82
core/modules/widgets/slot.js
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/widgets/slot.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
Widget for definition of slots within transcluded content. The values provided by the translusion are passed to the slot.
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Widget = require("$:/core/modules/widgets/widget.js").widget,
|
||||||
|
TranscludeWidget = require("$:/core/modules/widgets/transclude.js").transclude;
|
||||||
|
|
||||||
|
var SlotWidget = function(parseTreeNode,options) {
|
||||||
|
// Initialise
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inherit from the base widget class
|
||||||
|
*/
|
||||||
|
SlotWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Render this widget into the DOM
|
||||||
|
*/
|
||||||
|
SlotWidget.prototype.render = function(parent,nextSibling) {
|
||||||
|
// Call the constructor
|
||||||
|
Widget.call(this);
|
||||||
|
this.parentDomNode = parent;
|
||||||
|
this.computeAttributes();
|
||||||
|
this.execute();
|
||||||
|
this.renderChildren(parent,nextSibling);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compute the internal state of the widget
|
||||||
|
*/
|
||||||
|
SlotWidget.prototype.execute = function() {
|
||||||
|
var self = this;
|
||||||
|
this.slotName = this.getAttribute("$name");
|
||||||
|
this.slotDepth = parseInt(this.getAttribute("$depth","1"),10) || 1;
|
||||||
|
// Find the parent transclusions
|
||||||
|
var pointer = this.parentWidget,
|
||||||
|
depth = this.slotDepth;
|
||||||
|
while(pointer) {
|
||||||
|
if(pointer instanceof TranscludeWidget) {
|
||||||
|
depth--;
|
||||||
|
if(depth <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pointer = pointer.parentWidget;
|
||||||
|
}
|
||||||
|
var parseTreeNodes = [{type: "text", attributes: {text: {type: "string", value: "Missing slot reference!"}}}];
|
||||||
|
if(pointer instanceof TranscludeWidget) {
|
||||||
|
// Get the parse tree nodes comprising the slot contents
|
||||||
|
parseTreeNodes = pointer.getTransclusionSlotFill(this.slotName,this.parseTreeNode.children);
|
||||||
|
}
|
||||||
|
// Construct the child widgets
|
||||||
|
this.makeChildWidgets(parseTreeNodes);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Refresh the widget by ensuring our attributes are up to date
|
||||||
|
*/
|
||||||
|
SlotWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
|
var changedAttributes = this.computeAttributes();
|
||||||
|
if(changedAttributes["$name"] || changedAttributes["$depth"]) {
|
||||||
|
this.refreshSelf();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return this.refreshChildren(changedTiddlers);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.slot = SlotWidget;
|
||||||
|
|
||||||
|
})();
|
@ -37,46 +37,347 @@ TranscludeWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
Compute the internal state of the widget
|
Compute the internal state of the widget
|
||||||
*/
|
*/
|
||||||
TranscludeWidget.prototype.execute = function() {
|
TranscludeWidget.prototype.execute = function() {
|
||||||
// Get our parameters
|
// Get our attributes, string parameters, and slot values into properties of the widget object
|
||||||
this.transcludeTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
|
this.collectAttributes();
|
||||||
this.transcludeSubTiddler = this.getAttribute("subtiddler");
|
this.collectStringParameters();
|
||||||
this.transcludeField = this.getAttribute("field");
|
this.collectSlotFillParameters();
|
||||||
this.transcludeIndex = this.getAttribute("index");
|
// Get the parse tree nodes that we are transcluding
|
||||||
this.transcludeMode = this.getAttribute("mode");
|
var target = this.getTransclusionTarget(),
|
||||||
this.recursionMarker = this.getAttribute("recursionMarker","yes");
|
parseTreeNodes = target.parseTreeNodes;
|
||||||
// Parse the text reference
|
this.sourceText = target.text;
|
||||||
|
this.sourceType = target.type;
|
||||||
|
this.parseAsInline = target.parseAsInline;
|
||||||
|
// Process the transclusion according to the output type
|
||||||
|
switch(this.transcludeOutput || "text/html") {
|
||||||
|
case "text/html":
|
||||||
|
// No further processing required
|
||||||
|
break;
|
||||||
|
case "text/raw":
|
||||||
|
// Just return the raw text
|
||||||
|
parseTreeNodes = [{type: "text", text: this.sourceText}];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// text/plain
|
||||||
|
var plainText = this.wiki.renderText("text/plain",this.sourceType,this.sourceText,{parentWidget: this});
|
||||||
|
parseTreeNodes = [{type: "text", text: plainText}];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Set the legacy transclusion context variables only if we're not transcluding a variable
|
||||||
|
if(!this.transcludeVariable) {
|
||||||
|
var recursionMarker = this.makeRecursionMarker();
|
||||||
|
this.setVariable("transclusion",recursionMarker);
|
||||||
|
}
|
||||||
|
// Construct the child widgets
|
||||||
|
this.makeChildWidgets(parseTreeNodes);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Collect the attributes we need, in the process determining whether we're being used in legacy mode
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.collectAttributes = function() {
|
||||||
|
var self = this;
|
||||||
|
// Detect legacy mode
|
||||||
|
this.legacyMode = true;
|
||||||
|
$tw.utils.each(this.attributes,function(value,name) {
|
||||||
|
if(name.charAt(0) === "$") {
|
||||||
|
self.legacyMode = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Get the attributes for the appropriate mode
|
||||||
|
if(this.legacyMode) {
|
||||||
|
this.transcludeTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
|
||||||
|
this.transcludeSubTiddler = this.getAttribute("subtiddler");
|
||||||
|
this.transcludeField = this.getAttribute("field");
|
||||||
|
this.transcludeIndex = this.getAttribute("index");
|
||||||
|
this.transcludeMode = this.getAttribute("mode");
|
||||||
|
this.recursionMarker = this.getAttribute("recursionMarker","yes");
|
||||||
|
} else {
|
||||||
|
this.transcludeVariable = this.getAttribute("$variable");
|
||||||
|
this.transcludeType = this.getAttribute("$type");
|
||||||
|
this.transcludeOutput = this.getAttribute("$output","text/html");
|
||||||
|
this.transcludeTitle = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
|
||||||
|
this.transcludeSubTiddler = this.getAttribute("$subtiddler");
|
||||||
|
this.transcludeField = this.getAttribute("$field");
|
||||||
|
this.transcludeIndex = this.getAttribute("$index");
|
||||||
|
this.transcludeMode = this.getAttribute("$mode");
|
||||||
|
this.recursionMarker = this.getAttribute("$recursionMarker","yes");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Collect string parameters
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.collectStringParameters = function() {
|
||||||
|
var self = this;
|
||||||
|
this.stringParametersByName = Object.create(null);
|
||||||
|
if(!this.legacyMode) {
|
||||||
|
$tw.utils.each(this.attributes,function(value,name) {
|
||||||
|
if(name.charAt(0) === "$") {
|
||||||
|
if(name.charAt(1) === "$") {
|
||||||
|
// Attributes starting $$ represent parameters starting with a single $
|
||||||
|
name = name.slice(1);
|
||||||
|
} else {
|
||||||
|
// Attributes starting with a single $ are reserved for the widget
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.stringParametersByName[name] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Collect slot value parameters
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.collectSlotFillParameters = function() {
|
||||||
|
var self = this;
|
||||||
|
this.slotFillParseTrees = Object.create(null);
|
||||||
|
if(this.legacyMode) {
|
||||||
|
this.slotFillParseTrees["ts-missing"] = this.parseTreeNode.children;
|
||||||
|
} else {
|
||||||
|
this.slotFillParseTrees["ts-raw"] = this.parseTreeNode.children;
|
||||||
|
var noFillWidgetsFound = true,
|
||||||
|
searchParseTreeNodes = function(nodes) {
|
||||||
|
$tw.utils.each(nodes,function(node) {
|
||||||
|
if(node.type === "fill") {
|
||||||
|
if(node.attributes["$name"] && node.attributes["$name"].type === "string") {
|
||||||
|
var slotValueName = node.attributes["$name"].value;
|
||||||
|
self.slotFillParseTrees[slotValueName] = node.children || [];
|
||||||
|
}
|
||||||
|
noFillWidgetsFound = false;
|
||||||
|
} else {
|
||||||
|
searchParseTreeNodes(node.children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
searchParseTreeNodes(this.parseTreeNode.children);
|
||||||
|
if(noFillWidgetsFound) {
|
||||||
|
this.slotFillParseTrees["ts-missing"] = this.parseTreeNode.children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get transcluded parse tree nodes as an object {parser:,text:,type:}
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||||
|
var self = this;
|
||||||
|
// Determine whether we're being used in inline or block mode
|
||||||
var parseAsInline = !this.parseTreeNode.isBlock;
|
var parseAsInline = !this.parseTreeNode.isBlock;
|
||||||
if(this.transcludeMode === "inline") {
|
if(this.transcludeMode === "inline") {
|
||||||
parseAsInline = true;
|
parseAsInline = true;
|
||||||
} else if(this.transcludeMode === "block") {
|
} else if(this.transcludeMode === "block") {
|
||||||
parseAsInline = false;
|
parseAsInline = false;
|
||||||
}
|
}
|
||||||
var parser = this.wiki.parseTextReference(
|
var parser;
|
||||||
|
// Get the parse tree
|
||||||
|
if(this.transcludeVariable) {
|
||||||
|
// Transcluding a variable
|
||||||
|
var variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()}),
|
||||||
|
srcVariable = variableInfo && variableInfo.srcVariable;
|
||||||
|
if(srcVariable) {
|
||||||
|
if(srcVariable.isFunctionDefinition) {
|
||||||
|
// Function to return parameters by name or position
|
||||||
|
var fnGetParam = function(name,index) {
|
||||||
|
// Parameter names starting with dollar must be escaped to double dollars
|
||||||
|
if(name.charAt(0) === "$") {
|
||||||
|
name = "$" + name;
|
||||||
|
}
|
||||||
|
// Look for the parameter by name
|
||||||
|
if(self.hasAttribute(name)) {
|
||||||
|
return self.getAttribute(name);
|
||||||
|
// Look for the parameter by index
|
||||||
|
} else if(self.hasAttribute(index + "")) {
|
||||||
|
return self.getAttribute(index + "");
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
result = this.evaluateVariable(this.transcludeVariable,{params: fnGetParam})[0] || "";
|
||||||
|
parser = {
|
||||||
|
tree: [{
|
||||||
|
type: "text",
|
||||||
|
text: result
|
||||||
|
}],
|
||||||
|
source: result,
|
||||||
|
type: "text/vnd.tiddlywiki"
|
||||||
|
};
|
||||||
|
if(parseAsInline) {
|
||||||
|
parser.tree[0] = {
|
||||||
|
type: "text",
|
||||||
|
text: result
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
parser.tree[0] = {
|
||||||
|
type: "element",
|
||||||
|
tag: "p",
|
||||||
|
children: [{
|
||||||
|
type: "text",
|
||||||
|
text: result
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var cacheKey = (parseAsInline ? "inlineParser" : "blockParser") + (this.transcludeType || "");
|
||||||
|
if(variableInfo.isCacheable && srcVariable[cacheKey]) {
|
||||||
|
parser = srcVariable[cacheKey];
|
||||||
|
} else {
|
||||||
|
parser = this.wiki.parseText(this.transcludeType,variableInfo.text || "",{parseAsInline: parseAsInline, configTrimWhiteSpace: srcVariable.configTrimWhiteSpace});
|
||||||
|
if(variableInfo.isCacheable) {
|
||||||
|
srcVariable[cacheKey] = parser;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(parser) {
|
||||||
|
// Add parameters widget for procedures and custom widgets
|
||||||
|
if(srcVariable.isProcedureDefinition || srcVariable.isWidgetDefinition) {
|
||||||
|
parser = {
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
type: "parameters",
|
||||||
|
children: parser.tree
|
||||||
|
}
|
||||||
|
],
|
||||||
|
source: parser.source,
|
||||||
|
type: parser.type
|
||||||
|
}
|
||||||
|
$tw.utils.each(srcVariable.params,function(param) {
|
||||||
|
var name = param.name;
|
||||||
|
// Parameter names starting with dollar must be escaped to double dollars
|
||||||
|
if(name.charAt(0) === "$") {
|
||||||
|
name = "$" + name;
|
||||||
|
}
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],name,param["default"])
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// For macros and ordinary variables, wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
||||||
|
parser = {
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
type: "vars",
|
||||||
|
children: parser.tree
|
||||||
|
}
|
||||||
|
],
|
||||||
|
source: parser.source,
|
||||||
|
type: parser.type
|
||||||
|
}
|
||||||
|
$tw.utils.each(variableInfo.params,function(param) {
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],"__" + param.name + "__",param.value)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Transcluding a text reference
|
||||||
|
parser = this.wiki.parseTextReference(
|
||||||
this.transcludeTitle,
|
this.transcludeTitle,
|
||||||
this.transcludeField,
|
this.transcludeField,
|
||||||
this.transcludeIndex,
|
this.transcludeIndex,
|
||||||
{
|
{
|
||||||
parseAsInline: parseAsInline,
|
parseAsInline: parseAsInline,
|
||||||
subTiddler: this.transcludeSubTiddler
|
subTiddler: this.transcludeSubTiddler,
|
||||||
}),
|
defaultType: this.transcludeType
|
||||||
parseTreeNodes = parser ? parser.tree : this.parseTreeNode.children;
|
});
|
||||||
this.sourceText = parser ? parser.source : null;
|
|
||||||
this.parserType = parser? parser.type : null;
|
|
||||||
// Set context variables for recursion detection
|
|
||||||
var recursionMarker = this.makeRecursionMarker();
|
|
||||||
if(this.recursionMarker === "yes") {
|
|
||||||
this.setVariable("transclusion",recursionMarker);
|
|
||||||
}
|
}
|
||||||
// Check for recursion
|
// Return the parse tree
|
||||||
if(parser) {
|
if(parser) {
|
||||||
if(this.parentWidget && this.parentWidget.hasVariable("transclusion",recursionMarker)) {
|
return {
|
||||||
parseTreeNodes = [{type: "error", attributes: {
|
parser: parser,
|
||||||
"$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")}
|
parseTreeNodes: parser.tree,
|
||||||
}}];
|
parseAsInline: parseAsInline,
|
||||||
|
text: parser.source,
|
||||||
|
type: parser.type
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// If there's no parse tree then return the missing slot value
|
||||||
|
return {
|
||||||
|
parser: null,
|
||||||
|
parseTreeNodes: (this.slotFillParseTrees["ts-missing"] || []),
|
||||||
|
parseAsInline: parseAsInline,
|
||||||
|
text: null,
|
||||||
|
type: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fetch all the string parameters as an ordered array of {name:, value:} where the name is optional
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.getOrderedTransclusionParameters = function() {
|
||||||
|
var result = [];
|
||||||
|
// Collect the parameters
|
||||||
|
for(var name in this.stringParametersByName) {
|
||||||
|
var value = this.stringParametersByName[name];
|
||||||
|
result.push({name: name, value: value});
|
||||||
|
}
|
||||||
|
// Sort numerical parameter names first
|
||||||
|
result.sort(function(a,b) {
|
||||||
|
var aIsNumeric = !isNaN(a.name),
|
||||||
|
bIsNumeric = !isNaN(b.name);
|
||||||
|
if(aIsNumeric && bIsNumeric) {
|
||||||
|
return a.name - b.name;
|
||||||
|
} else if(aIsNumeric) {
|
||||||
|
return -1;
|
||||||
|
} else if(bIsNumeric) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return a.name === b.name ? 0 : (a.name < b.name ? -1 : 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Remove names from numerical parameters
|
||||||
|
$tw.utils.each(result,function(param,index) {
|
||||||
|
if(!isNaN(param.name)) {
|
||||||
|
delete param.name;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fetch the value of a parameter
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.getTransclusionParameter = function(name,index,defaultValue) {
|
||||||
|
if(name in this.stringParametersByName) {
|
||||||
|
return this.stringParametersByName[name];
|
||||||
|
} else {
|
||||||
|
var name = "" + index;
|
||||||
|
if(name in this.stringParametersByName) {
|
||||||
|
return this.stringParametersByName[name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Construct the child widgets
|
return defaultValue;
|
||||||
this.makeChildWidgets(parseTreeNodes);
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get one of the special parameters to be provided by the parameters widget
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.getTransclusionMetaParameters = function() {
|
||||||
|
var self = this;
|
||||||
|
return {
|
||||||
|
"parseMode": function() {
|
||||||
|
return self.parseAsInline ? "inline" : "block";
|
||||||
|
},
|
||||||
|
"parseTreeNodes": function() {
|
||||||
|
return JSON.stringify(self.parseTreeNode.children || []);
|
||||||
|
},
|
||||||
|
"slotFillParseTreeNodes": function() {
|
||||||
|
return JSON.stringify(self.slotFillParseTrees);
|
||||||
|
},
|
||||||
|
"params": function() {
|
||||||
|
return JSON.stringify(self.stringParametersByName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fetch the value of a slot
|
||||||
|
*/
|
||||||
|
TranscludeWidget.prototype.getTransclusionSlotFill = function(name,defaultParseTreeNodes) {
|
||||||
|
if(name && this.slotFillParseTrees[name] && this.slotFillParseTrees[name].length > 0) {
|
||||||
|
return this.slotFillParseTrees[name];
|
||||||
|
} else {
|
||||||
|
return defaultParseTreeNodes || [];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -99,6 +400,7 @@ TranscludeWidget.prototype.makeRecursionMarker = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TranscludeWidget.prototype.parserNeedsRefresh = function() {
|
TranscludeWidget.prototype.parserNeedsRefresh = function() {
|
||||||
|
// Doesn't need to consider transcluded variables because a parent variable can't change once a widget has been created
|
||||||
var parserInfo = this.wiki.getTextReferenceParserInfo(this.transcludeTitle,this.transcludeField,this.transcludeIndex,{subTiddler:this.transcludeSubTiddler});
|
var parserInfo = this.wiki.getTextReferenceParserInfo(this.transcludeTitle,this.transcludeField,this.transcludeIndex,{subTiddler:this.transcludeSubTiddler});
|
||||||
return (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType)
|
return (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType)
|
||||||
};
|
};
|
||||||
@ -108,7 +410,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
|
|||||||
*/
|
*/
|
||||||
TranscludeWidget.prototype.refresh = function(changedTiddlers) {
|
TranscludeWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var changedAttributes = this.computeAttributes();
|
var changedAttributes = this.computeAttributes();
|
||||||
if(($tw.utils.count(changedAttributes) > 0) || (changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) {
|
if(($tw.utils.count(changedAttributes) > 0) || (!this.transcludeVariable && changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -168,11 +168,11 @@ ViewWidget.prototype.getValueAsHtmlTextEncoded = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ViewWidget.prototype.getValueAsUrlEncoded = function() {
|
ViewWidget.prototype.getValueAsUrlEncoded = function() {
|
||||||
return encodeURIComponent(this.getValueAsText());
|
return $tw.utils.encodeURIComponentExtended(this.getValueAsText());
|
||||||
};
|
};
|
||||||
|
|
||||||
ViewWidget.prototype.getValueAsDoubleUrlEncoded = function() {
|
ViewWidget.prototype.getValueAsDoubleUrlEncoded = function() {
|
||||||
return encodeURIComponent(encodeURIComponent(this.getValueAsText()));
|
return $tw.utils.encodeURIComponentExtended($tw.utils.encodeURIComponentExtended(this.getValueAsText()));
|
||||||
};
|
};
|
||||||
|
|
||||||
ViewWidget.prototype.getValueAsDate = function(format) {
|
ViewWidget.prototype.getValueAsDate = function(format) {
|
||||||
|
@ -41,10 +41,7 @@ Widget.prototype.initialise = function(parseTreeNode,options) {
|
|||||||
this.parseTreeNode = parseTreeNode;
|
this.parseTreeNode = parseTreeNode;
|
||||||
this.wiki = options.wiki;
|
this.wiki = options.wiki;
|
||||||
this.parentWidget = options.parentWidget;
|
this.parentWidget = options.parentWidget;
|
||||||
this.variables = Object.create(null);
|
this.variables = Object.create(this.parentWidget ? this.parentWidget.variables : null);
|
||||||
if(this.parentWidget) {
|
|
||||||
Object.setPrototypeOf(this.variables,this.parentWidget.variables);
|
|
||||||
}
|
|
||||||
this.document = options.document;
|
this.document = options.document;
|
||||||
this.attributes = {};
|
this.attributes = {};
|
||||||
this.children = [];
|
this.children = [];
|
||||||
@ -92,9 +89,22 @@ name: name of the variable
|
|||||||
value: value of the variable
|
value: value of the variable
|
||||||
params: array of {name:, default:} for each parameter
|
params: array of {name:, default:} for each parameter
|
||||||
isMacroDefinition: true if the variable is set via a \define macro pragma (and hence should have variable substitution performed)
|
isMacroDefinition: true if the variable is set via a \define macro pragma (and hence should have variable substitution performed)
|
||||||
|
options includes:
|
||||||
|
isProcedureDefinition: true if the variable is set via a \procedure pragma (and hence should not have variable substitution performed)
|
||||||
|
isFunctionDefinition: true if the variable is set via a \function pragma (and hence should not have variable substitution performed)
|
||||||
|
isWidgetDefinition: true if the variable is set via a \widget pragma (and hence should not have variable substitution performed)
|
||||||
*/
|
*/
|
||||||
Widget.prototype.setVariable = function(name,value,params,isMacroDefinition) {
|
Widget.prototype.setVariable = function(name,value,params,isMacroDefinition,options) {
|
||||||
this.variables[name] = {value: value, params: params, isMacroDefinition: !!isMacroDefinition};
|
options = options || {};
|
||||||
|
this.variables[name] = {
|
||||||
|
value: value,
|
||||||
|
params: params,
|
||||||
|
isMacroDefinition: !!isMacroDefinition,
|
||||||
|
isFunctionDefinition: !!options.isFunctionDefinition,
|
||||||
|
isProcedureDefinition: !!options.isProcedureDefinition,
|
||||||
|
isWidgetDefinition: !!options.isWidgetDefinition,
|
||||||
|
configTrimWhiteSpace: !!options.configTrimWhiteSpace
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -104,6 +114,7 @@ options: see below
|
|||||||
Options include
|
Options include
|
||||||
params: array of {name:, value:} for each parameter
|
params: array of {name:, value:} for each parameter
|
||||||
defaultValue: default value if the variable is not defined
|
defaultValue: default value if the variable is not defined
|
||||||
|
allowSelfAssigned: if true, includes the current widget in the context chain instead of just the parent
|
||||||
|
|
||||||
Returns an object with the following fields:
|
Returns an object with the following fields:
|
||||||
|
|
||||||
@ -112,21 +123,27 @@ text: text of variable, with parameters properly substituted
|
|||||||
*/
|
*/
|
||||||
Widget.prototype.getVariableInfo = function(name,options) {
|
Widget.prototype.getVariableInfo = function(name,options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var actualParams = options.params || [],
|
var self = this,
|
||||||
parentWidget = this.parentWidget;
|
actualParams = options.params || [],
|
||||||
|
variable;
|
||||||
|
if(options.allowSelfAssigned) {
|
||||||
|
variable = this.variables[name];
|
||||||
|
} else {
|
||||||
|
variable = this.parentWidget && this.parentWidget.variables[name];
|
||||||
|
}
|
||||||
// Check for the variable defined in the parent widget (or an ancestor in the prototype chain)
|
// Check for the variable defined in the parent widget (or an ancestor in the prototype chain)
|
||||||
if(parentWidget && name in parentWidget.variables) {
|
if(variable) {
|
||||||
var variable = parentWidget.variables[name],
|
var originalValue = variable.value,
|
||||||
originalValue = variable.value,
|
|
||||||
value = originalValue,
|
value = originalValue,
|
||||||
params = this.resolveVariableParameters(variable.params,actualParams);
|
params = [];
|
||||||
// Substitute any parameters specified in the definition
|
// Only substitute parameter and variable references if this variable was defined with the \define pragma
|
||||||
$tw.utils.each(params,function(param) {
|
|
||||||
value = $tw.utils.replaceString(value,new RegExp("\\$" + $tw.utils.escapeRegExp(param.name) + "\\$","mg"),param.value);
|
|
||||||
});
|
|
||||||
// Only substitute variable references if this variable was defined with the \define pragma
|
|
||||||
if(variable.isMacroDefinition) {
|
if(variable.isMacroDefinition) {
|
||||||
value = this.substituteVariableReferences(value,options);
|
params = self.resolveVariableParameters(variable.params,actualParams);
|
||||||
|
// Substitute any parameters specified in the definition
|
||||||
|
$tw.utils.each(params,function(param) {
|
||||||
|
value = $tw.utils.replaceString(value,new RegExp("\\$" + $tw.utils.escapeRegExp(param.name) + "\\$","mg"),param.value);
|
||||||
|
});
|
||||||
|
value = self.substituteVariableReferences(value,options);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
text: value,
|
text: value,
|
||||||
@ -136,8 +153,13 @@ Widget.prototype.getVariableInfo = function(name,options) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
// If the variable doesn't exist in the parent widget then look for a macro module
|
// If the variable doesn't exist in the parent widget then look for a macro module
|
||||||
|
var text = this.evaluateMacroModule(name,actualParams);
|
||||||
|
if(text === undefined) {
|
||||||
|
text = options.defaultValue;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
text: this.evaluateMacroModule(name,actualParams,options.defaultValue)
|
text: text,
|
||||||
|
srcVariable: {}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -148,6 +170,11 @@ Widget.prototype.getVariable = function(name,options) {
|
|||||||
return this.getVariableInfo(name,options).text;
|
return this.getVariableInfo(name,options).text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Maps actual parameters onto formal parameters, returning an array of {name:,value:} objects
|
||||||
|
formalParams - Array of {name:,default:} (default value is optional)
|
||||||
|
actualParams - Array of string values or {name:,value:} (name is optional)
|
||||||
|
*/
|
||||||
Widget.prototype.resolveVariableParameters = function(formalParams,actualParams) {
|
Widget.prototype.resolveVariableParameters = function(formalParams,actualParams) {
|
||||||
formalParams = formalParams || [];
|
formalParams = formalParams || [];
|
||||||
actualParams = actualParams || [];
|
actualParams = actualParams || [];
|
||||||
@ -160,7 +187,7 @@ Widget.prototype.resolveVariableParameters = function(formalParams,actualParams)
|
|||||||
paramInfo = formalParams[p];
|
paramInfo = formalParams[p];
|
||||||
paramValue = undefined;
|
paramValue = undefined;
|
||||||
for(var m=0; m<actualParams.length; m++) {
|
for(var m=0; m<actualParams.length; m++) {
|
||||||
if(actualParams[m].name === paramInfo.name) {
|
if(typeof actualParams[m] !== "string" && actualParams[m].name === paramInfo.name) {
|
||||||
paramValue = actualParams[m].value;
|
paramValue = actualParams[m].value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,7 +196,8 @@ Widget.prototype.resolveVariableParameters = function(formalParams,actualParams)
|
|||||||
nextAnonParameter++;
|
nextAnonParameter++;
|
||||||
}
|
}
|
||||||
if(paramValue === undefined && nextAnonParameter < actualParams.length) {
|
if(paramValue === undefined && nextAnonParameter < actualParams.length) {
|
||||||
paramValue = actualParams[nextAnonParameter++].value;
|
var param = actualParams[nextAnonParameter++];
|
||||||
|
paramValue = typeof param === "string" ? param : param.value;
|
||||||
}
|
}
|
||||||
// If we've still not got a value, use the default, if any
|
// If we've still not got a value, use the default, if any
|
||||||
paramValue = paramValue || paramInfo["default"] || "";
|
paramValue = paramValue || paramInfo["default"] || "";
|
||||||
@ -263,12 +291,103 @@ Widget.prototype.getStateQualifier = function(name) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Compute the current values of the attributes of the widget. Returns a hashmap of the names of the attributes that have changed
|
Make a fake widget with specified variables, suitable for variable lookup in filters
|
||||||
*/
|
*/
|
||||||
Widget.prototype.computeAttributes = function() {
|
Widget.prototype.makeFakeWidgetWithVariables = function(variables) {
|
||||||
|
var self = this;
|
||||||
|
return {
|
||||||
|
getVariable: function(name,opts) {
|
||||||
|
if($tw.utils.hop(variables,name)) {
|
||||||
|
return variables[name];
|
||||||
|
} else {
|
||||||
|
opts = opts || {};
|
||||||
|
opts.variables = variables;
|
||||||
|
return self.getVariable(name,opts);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getVariableInfo: function(name,opts) {
|
||||||
|
if($tw.utils.hop(variables,name)) {
|
||||||
|
return {
|
||||||
|
text: variables[name]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
opts = opts || {};
|
||||||
|
opts.variables = variables;
|
||||||
|
return self.getVariableInfo(name,opts);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
makeFakeWidgetWithVariables: self.makeFakeWidgetWithVariables,
|
||||||
|
evaluateVariable: self.evaluateVariable,
|
||||||
|
resolveVariableParameters: self.resolveVariableParameters,
|
||||||
|
wiki: self.wiki
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Evaluate a variable and associated actual parameters and result the resulting array.
|
||||||
|
The way that the variable is evaluated depends upon its type:
|
||||||
|
* Functions are evaluated as parameterised filter strings
|
||||||
|
* Macros are returned as plain text with substitution of parameters
|
||||||
|
* Procedures and widgets are returned as plain text
|
||||||
|
|
||||||
|
Options are:
|
||||||
|
params - the actual parameters – may be one of:
|
||||||
|
* an array of values that may be an anonymous string value, or a {name:, value:} pair
|
||||||
|
* a hashmap of {name: value} pairs
|
||||||
|
* a function invoked with parameters (name,index) that returns a parameter value by name or position
|
||||||
|
source - iterator for source tiddlers
|
||||||
|
*/
|
||||||
|
Widget.prototype.evaluateVariable = function(name,options) {
|
||||||
|
options = options || {};
|
||||||
|
var params = options.params || [];
|
||||||
|
// Get the details of the variable (includes processing text substitution for macros
|
||||||
|
var variableInfo = this.getVariableInfo(name,{params: params,defaultValue: ""});
|
||||||
|
// Process function parameters
|
||||||
|
var variables = Object.create(null);
|
||||||
|
if(variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||||
|
// Apply default parameter values
|
||||||
|
$tw.utils.each(variableInfo.srcVariable.params,function(param,index) {
|
||||||
|
if(param["default"]) {
|
||||||
|
variables[param.name] = param["default"];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if($tw.utils.isArray(params)) {
|
||||||
|
// Parameters are an array of values or {name:, value:} pairs
|
||||||
|
$tw.utils.each(this.resolveVariableParameters(variableInfo.srcVariable.params,params),function(param) {
|
||||||
|
variables[param.name] = param.value;
|
||||||
|
});
|
||||||
|
} else if(typeof params === "function") {
|
||||||
|
// Parameters are passed via a function
|
||||||
|
$tw.utils.each(variableInfo.srcVariable.params,function(param,index) {
|
||||||
|
variables[param.name] = params(param.name,index) || param["default"] || "";
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Parameters are a hashmap
|
||||||
|
$tw.utils.each(params,function(value,name) {
|
||||||
|
variables[name] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return this.wiki.filterTiddlers(variableInfo.text,this.makeFakeWidgetWithVariables(variables),options.source);
|
||||||
|
} else {
|
||||||
|
return [variableInfo.text];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compute the current values of the attributes of the widget. Returns a hashmap of the names of the attributes that have changed.
|
||||||
|
Options include:
|
||||||
|
filterFn: only include attributes where filterFn(name) returns true
|
||||||
|
*/
|
||||||
|
Widget.prototype.computeAttributes = function(options) {
|
||||||
|
options = options || {};
|
||||||
var changedAttributes = {},
|
var changedAttributes = {},
|
||||||
self = this;
|
self = this;
|
||||||
$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {
|
$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {
|
||||||
|
if(options.filterFn) {
|
||||||
|
if(!options.filterFn(name)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
var value = self.computeAttribute(attribute);
|
var value = self.computeAttribute(attribute);
|
||||||
if(self.attributes[name] !== value) {
|
if(self.attributes[name] !== value) {
|
||||||
self.attributes[name] = value;
|
self.attributes[name] = value;
|
||||||
@ -279,13 +398,21 @@ Widget.prototype.computeAttributes = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Widget.prototype.computeAttribute = function(attribute) {
|
Widget.prototype.computeAttribute = function(attribute) {
|
||||||
var value;
|
var self = this,
|
||||||
|
value;
|
||||||
if(attribute.type === "filtered") {
|
if(attribute.type === "filtered") {
|
||||||
value = this.wiki.filterTiddlers(attribute.filter,this)[0] || "";
|
value = this.wiki.filterTiddlers(attribute.filter,this)[0] || "";
|
||||||
} else if(attribute.type === "indirect") {
|
} else if(attribute.type === "indirect") {
|
||||||
value = this.wiki.getTextReference(attribute.textReference,"",this.getVariable("currentTiddler"));
|
value = this.wiki.getTextReference(attribute.textReference,"",this.getVariable("currentTiddler"));
|
||||||
} else if(attribute.type === "macro") {
|
} else if(attribute.type === "macro") {
|
||||||
value = this.getVariable(attribute.value.name,{params: attribute.value.params});
|
var variableInfo = this.getVariableInfo(attribute.value.name,{params: attribute.value.params});
|
||||||
|
if(variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||||
|
// It is a function definition. Go through each of the defined parameters, and make a variable with the value of the corresponding provided parameter
|
||||||
|
var paramArray = this.resolveVariableParameters(variableInfo.srcVariable.params,attribute.value.params);
|
||||||
|
value = this.evaluateVariable(attribute.value.name,{params: paramArray})[0] || "";
|
||||||
|
} else {
|
||||||
|
value = variableInfo.text;
|
||||||
|
}
|
||||||
} else { // String attribute
|
} else { // String attribute
|
||||||
value = attribute.value;
|
value = attribute.value;
|
||||||
}
|
}
|
||||||
@ -413,7 +540,34 @@ options include:
|
|||||||
variables: optional hashmap of variables to wrap around the widget
|
variables: optional hashmap of variables to wrap around the widget
|
||||||
*/
|
*/
|
||||||
Widget.prototype.makeChildWidget = function(parseTreeNode,options) {
|
Widget.prototype.makeChildWidget = function(parseTreeNode,options) {
|
||||||
|
var self = this;
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
// Check whether this node type is defined by a custom widget definition
|
||||||
|
var variableDefinitionName = "$" + parseTreeNode.type;
|
||||||
|
if(this.variables[variableDefinitionName]) {
|
||||||
|
var isOverrideable = function() {
|
||||||
|
// Widget is overrideable if it has a double dollar user defined name, or if it is an existing JS widget and we're not in safe mode
|
||||||
|
return parseTreeNode.type.charAt(0) === "$" || (!!self.widgetClasses[parseTreeNode.type] && !$tw.safeMode);
|
||||||
|
};
|
||||||
|
if(!parseTreeNode.isNotRemappable && isOverrideable()) {
|
||||||
|
var variableInfo = this.getVariableInfo(variableDefinitionName,{allowSelfAssigned: true});
|
||||||
|
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.value && variableInfo.srcVariable.isWidgetDefinition) {
|
||||||
|
var newParseTreeNode = {
|
||||||
|
type: "transclude",
|
||||||
|
children: parseTreeNode.children,
|
||||||
|
isBlock: parseTreeNode.isBlock
|
||||||
|
};
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(newParseTreeNode,"$variable",variableDefinitionName);
|
||||||
|
$tw.utils.each(parseTreeNode.attributes,function(attr,name) {
|
||||||
|
// If the attribute starts with a dollar then add an extra dollar so that it doesn't clash with the $xxx attributes of transclude
|
||||||
|
name = name.charAt(0) === "$" ? "$" + name : name;
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(newParseTreeNode,$tw.utils.extend({},attr,{name: name}));
|
||||||
|
});
|
||||||
|
parseTreeNode = newParseTreeNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get the widget class for this node type
|
||||||
var WidgetClass = this.widgetClasses[parseTreeNode.type];
|
var WidgetClass = this.widgetClasses[parseTreeNode.type];
|
||||||
if(!WidgetClass) {
|
if(!WidgetClass) {
|
||||||
WidgetClass = this.widgetClasses.text;
|
WidgetClass = this.widgetClasses.text;
|
||||||
|
@ -988,7 +988,8 @@ exports.parseText = function(type,text,options) {
|
|||||||
return new Parser(type,text,{
|
return new Parser(type,text,{
|
||||||
parseAsInline: options.parseAsInline,
|
parseAsInline: options.parseAsInline,
|
||||||
wiki: this,
|
wiki: this,
|
||||||
_canonical_uri: options._canonical_uri
|
_canonical_uri: options._canonical_uri,
|
||||||
|
configTrimWhiteSpace: options.configTrimWhiteSpace
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1028,10 +1029,11 @@ exports.parseTextReference = function(title,field,index,options) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
exports.getTextReferenceParserInfo = function(title,field,index,options) {
|
exports.getTextReferenceParserInfo = function(title,field,index,options) {
|
||||||
var tiddler,
|
var defaultType = options.defaultType || "text/vnd.tiddlywiki",
|
||||||
|
tiddler,
|
||||||
parserInfo = {
|
parserInfo = {
|
||||||
sourceText : null,
|
sourceText : null,
|
||||||
parserType : "text/vnd.tiddlywiki"
|
parserType : defaultType
|
||||||
};
|
};
|
||||||
if(options.subTiddler) {
|
if(options.subTiddler) {
|
||||||
tiddler = this.getSubTiddler(title,options.subTiddler);
|
tiddler = this.getSubTiddler(title,options.subTiddler);
|
||||||
@ -1077,19 +1079,20 @@ exports.makeWidget = function(parser,options) {
|
|||||||
children: []
|
children: []
|
||||||
},
|
},
|
||||||
currWidgetNode = widgetNode;
|
currWidgetNode = widgetNode;
|
||||||
// Create set variable widgets for each variable
|
// Create let variable widget for variables
|
||||||
$tw.utils.each(options.variables,function(value,name) {
|
if($tw.utils.count(options.variables) > 0) {
|
||||||
var setVariableWidget = {
|
var letVariableWidget = {
|
||||||
type: "set",
|
type: "let",
|
||||||
attributes: {
|
attributes: {
|
||||||
name: {type: "string", value: name},
|
|
||||||
value: {type: "string", value: value}
|
|
||||||
},
|
},
|
||||||
children: []
|
children: []
|
||||||
};
|
};
|
||||||
currWidgetNode.children = [setVariableWidget];
|
$tw.utils.each(options.variables,function(value,name) {
|
||||||
currWidgetNode = setVariableWidget;
|
$tw.utils.addAttributeToParseTreeNode(letVariableWidget,name,"" + value);
|
||||||
});
|
});
|
||||||
|
currWidgetNode.children = [letVariableWidget];
|
||||||
|
currWidgetNode = letVariableWidget;
|
||||||
|
}
|
||||||
// Add in the supplied parse tree nodes
|
// Add in the supplied parse tree nodes
|
||||||
currWidgetNode.children = parser ? parser.tree : [];
|
currWidgetNode.children = parser ? parser.tree : [];
|
||||||
// Create the widget
|
// Create the widget
|
||||||
|
@ -14,6 +14,7 @@ extension: .html
|
|||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||||
<meta name="generator" content="TiddlyWiki" />
|
<meta name="generator" content="TiddlyWiki" />
|
||||||
<meta name="tiddlywiki-version" content="{{$:/core/templates/version}}" />
|
<meta name="tiddlywiki-version" content="{{$:/core/templates/version}}" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="format-detection" content="telephone=no">
|
<meta name="format-detection" content="telephone=no">
|
||||||
<link id="faviconLink" rel="shortcut icon" href="favicon.ico">
|
<link id="faviconLink" rel="shortcut icon" href="favicon.ico">
|
||||||
<title>{{$:/core/wiki/title}}</title>
|
<title>{{$:/core/wiki/title}}</title>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
title: $:/core/save/all-external-js
|
title: $:/core/save/all-external-js
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||||
\define saveTiddlerFilter()
|
\define saveTiddlerFilter()
|
||||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
title: $:/core/save/offline-external-js
|
title: $:/core/save/offline-external-js
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||||
\define saveTiddlerFilter()
|
\define saveTiddlerFilter()
|
||||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
||||||
|
3
core/templates/external-js/tiddlywiki.js.load.tid
Normal file
3
core/templates/external-js/tiddlywiki.js.load.tid
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
title: $:/core/templates/tiddlywiki.js/load-tiddler
|
||||||
|
|
||||||
|
_load(window,<$macrocall $name="jsontiddler" $output="text/raw"/>);
|
@ -1,15 +1,48 @@
|
|||||||
|
|
||||||
title: $:/core/templates/tiddlywiki5.js
|
title: $:/core/templates/tiddlywiki5.js
|
||||||
|
|
||||||
\rules only filteredtranscludeinline transcludeinline codeinline
|
\rules only filteredtranscludeinline transcludeinline codeinline
|
||||||
|
|
||||||
/*
|
`/*
|
||||||
{{ $:/core/copyright.txt ||$:/core/templates/plain-text-tiddler}}
|
`{{ $:/core/copyright.txt ||$:/core/templates/plain-text-tiddler}}`
|
||||||
`*/
|
*/
|
||||||
`<!--~~ Library modules ~~-->
|
|
||||||
{{{ [is[system]type[application/javascript]library[yes]] ||$:/core/templates/plain-text-tiddler}}}
|
$tw = (typeof $tw === 'undefined') ? Object.create(null) : $tw;
|
||||||
<!--~~ Boot prefix ~~-->
|
|
||||||
{{ $:/boot/bootprefix.js ||$:/core/templates/plain-text-tiddler}}
|
$tw.preloadTiddlers = $tw.preloadTiddlers || [];
|
||||||
<!--~~ Core plugin ~~-->
|
|
||||||
{{$:/core/templates/tiddlywiki5.js/tiddlers}}
|
_load = function(window,tiddler) {
|
||||||
<!--~~ Boot kernel ~~-->
|
"use strict";
|
||||||
{{ $:/boot/boot.js ||$:/core/templates/plain-text-tiddler}}
|
var f;
|
||||||
|
$tw.preloadTiddlers.push(tiddler);
|
||||||
|
if(tiddler.library === "yes") {
|
||||||
|
var module = { exports:{} };
|
||||||
|
var moduleName = function moduleName(path) {
|
||||||
|
var word = path.split("/").pop();
|
||||||
|
word = word.substring(0,word.indexOf(".")) || word;
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
f = new Function("module",tiddler.text);
|
||||||
|
f(module);
|
||||||
|
window[moduleName(tiddler.title)] = module.exports;
|
||||||
|
} else {
|
||||||
|
f = new Function("window",tiddler.text);
|
||||||
|
f(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ~~ Library modules ~~ */
|
||||||
|
|
||||||
|
`{{{ [is[system]type[application/javascript]library[yes]] ||$:/core/templates/tiddlywiki.js/load-tiddler}}}`
|
||||||
|
|
||||||
|
/* ~~ Boot kernel prologue ~~ */
|
||||||
|
|
||||||
|
`{{ $:/boot/bootprefix.js ||$:/core/templates/tiddlywiki.js/load-tiddler}}`
|
||||||
|
|
||||||
|
/* ~~ Core tiddlers ~~ */
|
||||||
|
|
||||||
|
`{{$:/core/templates/tiddlywiki5.js/tiddlers}}`
|
||||||
|
|
||||||
|
/* ~~ Boot kernel ~~ */
|
||||||
|
|
||||||
|
`{{ $:/boot/boot.js ||$:/core/templates/tiddlywiki.js/load-tiddler}}`
|
||||||
|
@ -1,48 +1,50 @@
|
|||||||
title: $:/core/templates/tiddlywiki5-external-js.html
|
title: $:/core/templates/tiddlywiki5-external-js.html
|
||||||
|
|
||||||
\rules only filteredtranscludeinline transcludeinline
|
<$set name="saveTiddlerAndShadowsFilter" filter="[subfilter<saveTiddlerFilter>] [subfilter<saveTiddlerFilter>plugintiddlers[]]">
|
||||||
<!doctype html>
|
`<!doctype html>
|
||||||
{{$:/core/templates/MOTW.html}}<html lang="{{{ [{$:/language}get[name]] }}}">
|
`{{$:/core/templates/MOTW.html}}`<html lang="`<$text text={{{ [{$:/language}get[name]] }}}/>`">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||||
<!--~~ Raw markup for the top of the head section ~~-->
|
<!--~~ Raw markup for the top of the head section ~~-->
|
||||||
{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}
|
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
|
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
|
||||||
<meta name="application-name" content="TiddlyWiki" />
|
<meta name="application-name" content="TiddlyWiki" />
|
||||||
<meta name="generator" content="TiddlyWiki" />
|
<meta name="generator" content="TiddlyWiki" />
|
||||||
<meta name="tiddlywiki-version" content="{{$:/core/templates/version}}" />
|
<meta name="tiddlywiki-version" content="`{{$:/core/templates/version}}`" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
<meta name="mobile-web-app-capable" content="yes"/>
|
<meta name="mobile-web-app-capable" content="yes"/>
|
||||||
<meta name="format-detection" content="telephone=no" />
|
<meta name="format-detection" content="telephone=no" />
|
||||||
<meta name="copyright" content="{{$:/core/copyright.txt}}" />
|
<meta name="copyright" content="`{{$:/core/copyright.txt}}`" />
|
||||||
<link id="faviconLink" rel="shortcut icon" href="favicon.ico">
|
<link id="faviconLink" rel="shortcut icon" href="favicon.ico">
|
||||||
<title>{{$:/core/wiki/title}}</title>
|
<title>`{{$:/core/wiki/title}}`</title>
|
||||||
<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->
|
<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->
|
||||||
|
|
||||||
<!--~~ Raw markup ~~-->
|
<!--~~ Raw markup ~~-->
|
||||||
{{{ [all[shadows+tiddlers]tag[$:/core/wiki/rawmarkup]] [all[shadows+tiddlers]tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}
|
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/core/wiki/rawmarkup]] ||$:/core/templates/plain-text-tiddler}}}`
|
||||||
{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}
|
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}`
|
||||||
|
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}`
|
||||||
</head>
|
</head>
|
||||||
<body class="tc-body">
|
<body class="tc-body">
|
||||||
<!--~~ Raw markup for the top of the body section ~~-->
|
<!--~~ Raw markup for the top of the body section ~~-->
|
||||||
{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}
|
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}`
|
||||||
<!--~~ Static styles ~~-->
|
<!--~~ Static styles ~~-->
|
||||||
<div id="styleArea">
|
<div id="styleArea">
|
||||||
{{$:/boot/boot.css||$:/core/templates/css-tiddler}}
|
`{{$:/boot/boot.css||$:/core/templates/css-tiddler}}`
|
||||||
</div>
|
</div>
|
||||||
<!--~~ Static content for Google and browsers without JavaScript ~~-->
|
<!--~~ Static content for Google and browsers without JavaScript ~~-->
|
||||||
<noscript>
|
<noscript>
|
||||||
<div id="splashArea">
|
<div id="splashArea">
|
||||||
{{$:/core/templates/static.area}}
|
`{{$:/core/templates/static.area}}`
|
||||||
</div>
|
</div>
|
||||||
</noscript>
|
</noscript>
|
||||||
<!--~~ Ordinary tiddlers ~~-->
|
<!--~~ Ordinary tiddlers ~~-->
|
||||||
{{$:/core/templates/store.area.template.html}}
|
`{{$:/core/templates/store.area.template.html}}`
|
||||||
<!--~~ Raw markup for the bottom of the body section ~~-->
|
<!--~~ Raw markup for the bottom of the body section ~~-->
|
||||||
{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}
|
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}`
|
||||||
|
<!--~~ Load external JavaScripts ~~-->
|
||||||
|
<script src="`{{{ [<coreURL>] }}}`" onerror="alert('Error: Cannot load `{{{ [<coreURL>] }}}`');"></script>
|
||||||
</body>
|
</body>
|
||||||
<!--~~ Load external JS ~~-->
|
</html>`
|
||||||
<script src="{{{ [<coreURL>] }}}" onerror="alert('Error: Cannot load {{{ [<coreURL>] }}}');"></script>
|
</$set>
|
||||||
</html>
|
|
48
core/ui/Components/VisibleTransclude.tid
Normal file
48
core/ui/Components/VisibleTransclude.tid
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
title: $:/core/ui/VisibleTransclude
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Import this component to make all the child transclusions visible.
|
||||||
|
|
||||||
|
Block transclusions are shown in red, and inline transclusions are shown in green.
|
||||||
|
-->
|
||||||
|
\widget $transclude()
|
||||||
|
<!-- Use a parameters widget so that we can access the `$params` data -->
|
||||||
|
<$parameters tiddler="" $$tiddler="" mode="" $$mode="" $parseMode="@parseMode" $params="@params">
|
||||||
|
<!-- Replicate the logic of the transclude widget to determine the output mode, and hence the tag and colour to use for output -->
|
||||||
|
<$let
|
||||||
|
mode={{{ [[$mode]is[variable]then<$mode>!is[blank]] :else[[mode]is[variable]then<mode>!is[blank]] :else[<@parseMode>] }}}
|
||||||
|
outputTag={{{ [<mode>match[inline]then[span]else[div]] }}}
|
||||||
|
outputColour={{{ [<mode>match[inline]then[green]else[red]] }}}
|
||||||
|
>
|
||||||
|
<!-- Use divs or spans according to the mode -->
|
||||||
|
<$genesis $type=<<outputTag>> style="color:white;padding:4px;" style.background=<<outputColour>>>
|
||||||
|
<$genesis $type=<<outputTag>> style="display: inline-block;">
|
||||||
|
<div style="background:white;color:black;font-size: 12px;line-height:1.2;text-align:left;font-weight:normal;padding:4px;margin:4px;">
|
||||||
|
<!-- Render the parameters to the transclusion -->
|
||||||
|
<$list filter="[<@params>jsonindexes[]]" emptyMessage="(none)">
|
||||||
|
<div>
|
||||||
|
<$text text=<<currentTiddler>>/><$text text=": "/><$text text={{{ [<@params>jsonget<currentTiddler>] }}}/>
|
||||||
|
</div>
|
||||||
|
</$list>
|
||||||
|
</div>
|
||||||
|
</$genesis>
|
||||||
|
<$genesis $type=<<outputTag>> style="background:white;color:black;padding:4px;">
|
||||||
|
<!-- Look for a parameter starting with $ to determine if we are in legacy mode -->
|
||||||
|
<$list filter="[<@params>jsonindexes[]] :filter[<currentTiddler>prefix[$]] +[limit[1]]" variable="ignore" emptyMessage="""
|
||||||
|
<!-- Legacy mode: we render the transclusion without a dollar sign for recursionMarker and mode -->
|
||||||
|
<$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" recursionMarker="no" mode=<<mode>>>
|
||||||
|
<!-- Reach back up to the grandparent transclusion to get the correct slot value -->
|
||||||
|
<$slot $name="ts-raw" $depth="2"/>
|
||||||
|
</$genesis>
|
||||||
|
""">
|
||||||
|
<!-- Non-legacy mode: we use dollar signs for the recursionMarker and mode -->
|
||||||
|
<$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" $$recursionMarker="no" $$mode=<<mode>>>
|
||||||
|
<!-- Reach back up to the grandparent transclusion to get the correct slot fill value -->
|
||||||
|
<$slot $name="ts-raw" $depth="2"/>
|
||||||
|
</$genesis>
|
||||||
|
</$list>
|
||||||
|
</$genesis>
|
||||||
|
</$genesis>
|
||||||
|
</$let>
|
||||||
|
</$parameters>
|
||||||
|
\end
|
@ -12,7 +12,7 @@ field="text"
|
|||||||
checked="enable"
|
checked="enable"
|
||||||
unchecked="disable"
|
unchecked="disable"
|
||||||
default="enable">
|
default="enable">
|
||||||
<<rule>>
|
<span class="tc-small-gap-left"><<rule>></span>
|
||||||
</$checkbox>
|
</$checkbox>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
18
core/ui/DownloadFullWiki.tid
Normal file
18
core/ui/DownloadFullWiki.tid
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
title: $:/core/ui/DownloadFullWiki
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
\rules except wikilink
|
||||||
|
|
||||||
|
To download the standard single-file version of your wiki:
|
||||||
|
|
||||||
|
<$wikify name="site-title" text={{$:/config/SaveWikiButton/Filename}}>
|
||||||
|
<$let publishFilter="""-[[$:/config/SaveWikiButton/Template]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]]""">
|
||||||
|
<$button tooltip="Download fully standalone wiki" aria-label="download full wiki" class="tc-btn-big-green">
|
||||||
|
<$action-sendmessage $message="tm-download-file" $param="$:/core/save/all" publishFilter=<<publishFilter>> filename=<<site-title>>/>
|
||||||
|
{{$:/core/images/download-button}}
|
||||||
|
<span class="tc-tiny-gap-left">
|
||||||
|
Download full wiki
|
||||||
|
</span>
|
||||||
|
</$button>
|
||||||
|
</$let>
|
||||||
|
</$wikify>
|
@ -47,9 +47,7 @@ title: $:/core/ui/EditTemplate
|
|||||||
<$keyboard key="((cancel-edit-tiddler))" actions=<<cancel-delete-tiddler-actions "cancel">> tag="div">
|
<$keyboard key="((cancel-edit-tiddler))" actions=<<cancel-delete-tiddler-actions "cancel">> tag="div">
|
||||||
<$keyboard key="((save-tiddler))" actions=<<save-tiddler-actions>> tag="div">
|
<$keyboard key="((save-tiddler))" actions=<<save-tiddler-actions>> tag="div">
|
||||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]" variable="listItem">
|
<$list filter="[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]" variable="listItem">
|
||||||
<$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]">
|
|
||||||
<$transclude tiddler=<<listItem>>/>
|
<$transclude tiddler=<<listItem>>/>
|
||||||
</$set>
|
|
||||||
</$list>
|
</$list>
|
||||||
</$keyboard>
|
</$keyboard>
|
||||||
</$keyboard>
|
</$keyboard>
|
||||||
|
@ -6,6 +6,6 @@ $:/config/EditToolbarButtons/Visibility/$(listItem)$
|
|||||||
\end
|
\end
|
||||||
<div class="tc-tiddler-title tc-tiddler-edit-title" dir={{$:/config/DefaultTextDirection}}>
|
<div class="tc-tiddler-title tc-tiddler-edit-title" dir={{$:/config/DefaultTextDirection}}>
|
||||||
<$view field="title"/>
|
<$view field="title"/>
|
||||||
<span class="tc-tiddler-controls tc-titlebar"><$list filter="[all[shadows+tiddlers]tag[$:/tags/EditToolbar]!has[draft.of]]" variable="listItem"><$reveal type="nomatch" state=<<config-title>> text="hide"><$transclude tiddler=<<listItem>>/></$reveal></$list></span>
|
<span class="tc-tiddler-controls tc-titlebar"><$list filter="[all[shadows+tiddlers]tag[$:/tags/EditToolbar]!has[draft.of]]" variable="listItem"><$let tv-config-toolbar-class={{{ [enlist<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]] +[join[ ]]}}}><$reveal type="nomatch" state=<<config-title>> text="hide"><$transclude tiddler=<<listItem>>/></$reveal></$let></$list></span>
|
||||||
<div style="clear: both;"></div>
|
<div style="clear: both;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,16 +3,23 @@ tags: $:/tags/EditToolbar
|
|||||||
caption: {{$:/core/images/done-button}} {{$:/language/Buttons/Save/Caption}}
|
caption: {{$:/core/images/done-button}} {{$:/language/Buttons/Save/Caption}}
|
||||||
description: {{$:/language/Buttons/Save/Hint}}
|
description: {{$:/language/Buttons/Save/Hint}}
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
\define save-tiddler-button()
|
\define save-tiddler-button()
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$fieldmangler><$button tooltip={{$:/language/Buttons/Save/Hint}} aria-label={{$:/language/Buttons/Save/Caption}} class=<<tv-config-toolbar-class>>>
|
<$fieldmangler>
|
||||||
<<save-tiddler-actions>>
|
<$button
|
||||||
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
|
tooltip={{$:/language/Buttons/Save/Hint}}
|
||||||
{{$:/core/images/done-button}}
|
aria-label={{$:/language/Buttons/Save/Caption}}
|
||||||
</$list>
|
class=<<tv-config-toolbar-class>>
|
||||||
<$list filter="[<tv-config-toolbar-text>match[yes]]">
|
>
|
||||||
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Save/Caption}}/></span>
|
<<save-tiddler-actions>>
|
||||||
</$list>
|
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
|
||||||
</$button></$fieldmangler>
|
{{$:/core/images/done-button}}
|
||||||
|
</$list>
|
||||||
|
<$list filter="[<tv-config-toolbar-text>match[yes]]">
|
||||||
|
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Save/Caption}}/></span>
|
||||||
|
</$list>
|
||||||
|
</$button>
|
||||||
|
</$fieldmangler>
|
||||||
\end
|
\end
|
||||||
<<save-tiddler-button>>
|
<<save-tiddler-button>>
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
title: $:/core/ui/ExportTiddlyWikiCore
|
title: $:/core/ui/ExportTiddlyWikiCore
|
||||||
|
|
||||||
\define jsFileName() tiddlywikicore-$(version)$.js
|
\define jsFileName() tiddlywikicore-$(version)$.js
|
||||||
\define noExportMsg()
|
|
||||||
It appears that you have a wiki with an external ~TiddlyWiki core. The export action cannot be performed.
|
|
||||||
<p>You will need to view the page source in your browser. Then go to the very bottom the the source, find the last `<script>`
|
|
||||||
element, and right-click its `src` URI. Save the link as ''$(jsFileName)$''</p>
|
|
||||||
\end
|
|
||||||
\rules except wikilink
|
\rules except wikilink
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
|
||||||
@ -17,16 +12,11 @@ Export the TiddlyWiki core JavaScript code for running with external JavaScript:
|
|||||||
tooltip="Export the TiddlyWiki core code for running with external JavaScript"
|
tooltip="Export the TiddlyWiki core code for running with external JavaScript"
|
||||||
aria-label="export TiddlyWiki core"
|
aria-label="export TiddlyWiki core"
|
||||||
class="tc-btn-big-green">
|
class="tc-btn-big-green">
|
||||||
<$list
|
<$action-sendmessage $message='tm-download-file' $param='$:/core/templates/tiddlywiki5.js' filename=<<jsFileName>>/>
|
||||||
filter="[[$:/boot/boot.js]is[missing]]"
|
|
||||||
variable="ignore"
|
|
||||||
emptyMessage="<$action-sendmessage $message='tm-download-file' $param='$:/core/templates/tiddlywiki5.js' filename=<<jsFileName>>/>" >
|
|
||||||
<$action-setfield $tiddler=<<qualify "$:/temp/alert">> text=<<noExportMsg>> subtitle="Export ~TiddllyWiki Core"/>
|
|
||||||
<$action-sendmessage $message="tm-modal" $param=<<qualify "$:/temp/alert">>/>
|
|
||||||
</$list>
|
|
||||||
{{$:/core/images/download-button}}
|
{{$:/core/images/download-button}}
|
||||||
 
|
<span class="tc-tiny-gap-left">
|
||||||
Download TiddlyWiki core
|
Download TiddlyWiki core
|
||||||
|
</span>
|
||||||
</$button>
|
</$button>
|
||||||
|
|
||||||
[[Further information|https://tiddlywiki.com/#Using%20the%20external%20JavaScript%20template]]
|
[[Further information|https://tiddlywiki.com/#Using%20the%20external%20JavaScript%20template]]
|
||||||
|
@ -13,13 +13,13 @@ caption: {{$:/language/ControlPanel/LayoutSwitcher/Caption}}
|
|||||||
<$set name="cls" filter="[all[current]field:title{$:/layout}]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
|
<$set name="cls" filter="[all[current]field:title{$:/layout}]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
|
||||||
<div class=<<cls>>>
|
<div class=<<cls>>>
|
||||||
<$link to={{!!title}}>
|
<$link to={{!!title}}>
|
||||||
''<$transclude field="name"/>'' - <$transclude field="description"/>
|
''<$transclude tiddler={{{ [<currentTiddler>get[icon]] }}}/><$transclude field="name"/>'' - <$transclude field="description"/>
|
||||||
</$link></div></$set>
|
</$link></div></$set>
|
||||||
""">
|
""">
|
||||||
<$set name="cls" filter="[all[current]field:title[$:/core/ui/PageTemplate]]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
|
<$set name="cls" filter="[all[current]field:title[$:/core/ui/PageTemplate]]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
|
||||||
<div class=<<cls>>>
|
<div class=<<cls>>>
|
||||||
<$link to={{!!title}}>
|
<$link to={{!!title}}>
|
||||||
''<$transclude field="name"/>'' - <$transclude field="description"/>
|
''<$transclude tiddler={{{ [<currentTiddler>get[icon]] }}}/><$transclude field="name"/>'' - <$transclude field="description"/>
|
||||||
</$link>
|
</$link>
|
||||||
</div>
|
</div>
|
||||||
</$set>
|
</$set>
|
||||||
|
@ -2,26 +2,17 @@ title: $:/core/ui/MoreSideBar/Tags
|
|||||||
tags: $:/tags/MoreSideBar
|
tags: $:/tags/MoreSideBar
|
||||||
caption: {{$:/language/SideBar/Tags/Caption}}
|
caption: {{$:/language/SideBar/Tags/Caption}}
|
||||||
|
|
||||||
<$set name="tv-config-toolbar-icons" value="yes">
|
\whitespace trim
|
||||||
|
|
||||||
<$set name="tv-config-toolbar-text" value="yes">
|
|
||||||
|
|
||||||
<$set name="tv-config-toolbar-class" value="">
|
|
||||||
|
|
||||||
{{$:/core/ui/Buttons/tag-manager}}
|
|
||||||
|
|
||||||
</$set>
|
|
||||||
|
|
||||||
</$set>
|
|
||||||
|
|
||||||
</$set>
|
|
||||||
|
|
||||||
|
<$let tv-config-toolbar-icons="yes" tv-config-toolbar-text="yes" tv-config-toolbar-class="">
|
||||||
|
<div class="tc-tiny-v-gap-bottom">
|
||||||
|
{{$:/core/ui/Buttons/tag-manager}}
|
||||||
|
</div>
|
||||||
|
</$let>
|
||||||
<$list filter={{$:/core/Filters/AllTags!!filter}}>
|
<$list filter={{$:/core/Filters/AllTags!!filter}}>
|
||||||
|
<div class="tc-tiny-v-gap-bottom">
|
||||||
<$transclude tiddler="$:/core/ui/TagTemplate"/>
|
<$transclude tiddler="$:/core/ui/TagTemplate"/>
|
||||||
|
</div>
|
||||||
</$list>
|
</$list>
|
||||||
|
|
||||||
<hr class="tc-untagged-separator">
|
<hr class="tc-untagged-separator">
|
||||||
|
|
||||||
{{$:/core/ui/UntaggedTemplate}}
|
{{$:/core/ui/UntaggedTemplate}}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
title: $:/core/ui/Buttons/save-wiki
|
title: $:/core/ui/Buttons/save-wiki
|
||||||
tags: $:/tags/PageControls
|
tags: $:/tags/PageControls
|
||||||
caption: {{$:/core/images/save-button}} {{$:/language/Buttons/SaveWiki/Caption}}
|
caption: {{$:/core/images/save-button-dynamic}} {{$:/language/Buttons/SaveWiki/Caption}}
|
||||||
description: {{$:/language/Buttons/SaveWiki/Hint}}
|
description: {{$:/language/Buttons/SaveWiki/Hint}}
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
@ -10,7 +10,7 @@ description: {{$:/language/Buttons/SaveWiki/Hint}}
|
|||||||
</$wikify>
|
</$wikify>
|
||||||
<span class="tc-dirty-indicator">
|
<span class="tc-dirty-indicator">
|
||||||
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
|
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
|
||||||
{{$:/core/images/save-button}}
|
{{$:/core/images/save-button-dynamic}}
|
||||||
</$list>
|
</$list>
|
||||||
<$list filter="[<tv-config-toolbar-text>match[yes]]">
|
<$list filter="[<tv-config-toolbar-text>match[yes]]">
|
||||||
<span class="tc-btn-text">
|
<span class="tc-btn-text">
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
title: $:/core/ui/PageTemplate
|
title: $:/core/ui/PageTemplate
|
||||||
name: {{$:/language/PageTemplate/Name}}
|
name: {{$:/language/PageTemplate/Name}}
|
||||||
description: {{$:/language/PageTemplate/Description}}
|
description: {{$:/language/PageTemplate/Description}}
|
||||||
|
icon: $:/core/images/layout-button
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||||
|
@ -3,10 +3,8 @@ title: $:/core/ui/UntaggedTemplate
|
|||||||
\define lingo-base() $:/language/SideBar/
|
\define lingo-base() $:/language/SideBar/
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$button popup=<<qualify "$:/state/popup/tag">> class="tc-btn-invisible tc-untagged-label tc-tag-label">
|
<$button popup=<<qualify "$:/state/popup/tag">> class="tc-btn-invisible tc-untagged-label tc-tag-label">
|
||||||
<<lingo Tags/Untagged/Caption>>
|
<<lingo Tags/Untagged/Caption>>
|
||||||
</$button>
|
</$button>
|
||||||
<$reveal state=<<qualify "$:/state/popup/tag">> type="popup" position="below">
|
<$reveal class="tc-drop-down" tag="div" state=<<qualify "$:/state/popup/tag">> type="popup" position="below">
|
||||||
<div class="tc-drop-down">
|
<$list filter="[untagged[]!is[system]] -[tags[]] +[sort[title]]" template="$:/core/ui/ListItemTemplate"/>
|
||||||
<$list filter="[untagged[]!is[system]] -[tags[]] +[sort[title]]" template="$:/core/ui/ListItemTemplate"/>
|
|
||||||
</div>
|
|
||||||
</$reveal>
|
</$reveal>
|
||||||
|
@ -6,7 +6,7 @@ description: {{$:/language/Buttons/NewHere/Hint}}
|
|||||||
\whitespace trim
|
\whitespace trim
|
||||||
\define newHereActions()
|
\define newHereActions()
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$set name="tags" filter="[<currentTiddler>] [{$:/config/NewTiddler/Tags}]">
|
<$set name="tags" filter="[<currentTiddler>] [enlist{$:/config/NewTiddler/Tags}]">
|
||||||
<$action-sendmessage $message="tm-new-tiddler" tags=<<tags>>/>
|
<$action-sendmessage $message="tm-new-tiddler" tags=<<tags>>/>
|
||||||
</$set>
|
</$set>
|
||||||
\end
|
\end
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
title: $:/config/OfficialPluginLibrary
|
title: $:/config/OfficialPluginLibrary
|
||||||
tags: $:/tags/PluginLibrary
|
tags: $:/tags/PluginLibrary
|
||||||
url: https://tiddlywiki.com/library/v5.2.6/index.html
|
url: https://tiddlywiki.com/library/v5.2.8/index.html
|
||||||
caption: {{$:/language/OfficialPluginLibrary}}
|
caption: {{$:/language/OfficialPluginLibrary}}
|
||||||
|
|
||||||
{{$:/language/OfficialPluginLibrary/Hint}}
|
{{$:/language/OfficialPluginLibrary/Hint}}
|
||||||
|
@ -4,5 +4,5 @@ title: $:/snippets/download-wiki-button
|
|||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$button class="tc-btn-big-green">
|
<$button class="tc-btn-big-green">
|
||||||
<$action-sendmessage $message="tm-download-file" $param="$:/core/save/all" filename="index.html"/>
|
<$action-sendmessage $message="tm-download-file" $param="$:/core/save/all" filename="index.html"/>
|
||||||
<<lingo Full/Caption>> {{$:/core/images/save-button}}
|
<<lingo Full/Caption>> {{$:/core/images/save-button-dynamic}}
|
||||||
</$button>
|
</$button>
|
@ -4,76 +4,85 @@ tags: $:/tags/Macro
|
|||||||
\define change-input-tab(stateTitle,tag,beforeafter,defaultState,actions)
|
\define change-input-tab(stateTitle,tag,beforeafter,defaultState,actions)
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$set name="tabsList" filter="[all[shadows+tiddlers]tag<__tag__>!has[draft.of]]">
|
<$set name="tabsList" filter="[all[shadows+tiddlers]tag<__tag__>!has[draft.of]]">
|
||||||
<$let
|
<$let
|
||||||
currentState={{{ [<__stateTitle__>!is[missing]get[text]] ~[<__defaultState__>] }}}
|
currentState={{{ [<__stateTitle__>!is[missing]get[text]] ~[<__defaultState__>] }}}
|
||||||
firstTab={{{ [enlist<tabsList>nth[1]] }}}
|
firstTab={{{ [enlist<tabsList>nth[1]] }}}
|
||||||
lastTab={{{ [enlist<tabsList>last[]] }}}
|
lastTab={{{ [enlist<tabsList>last[]] }}}
|
||||||
nextTab={{{ [all[shadows+tiddlers]tag<__tag__>!has[draft.of]$beforeafter$<currentState>] ~[[$beforeafter$]removeprefix[after]suffix[]addprefix<firstTab>] ~[[$beforeafter$]removeprefix[before]suffix[]addprefix<lastTab>] }}}>
|
nextTab={{{ [all[shadows+tiddlers]tag<__tag__>!has[draft.of]$beforeafter$<currentState>] ~[[$beforeafter$]removeprefix[after]suffix[]addprefix<firstTab>] ~[[$beforeafter$]removeprefix[before]suffix[]addprefix<lastTab>] }}}
|
||||||
<$action-setfield $tiddler=<<__stateTitle__>> text=<<nextTab>>/>
|
>
|
||||||
$actions$
|
<$action-setfield $tiddler=<<__stateTitle__>> text=<<nextTab>>/>
|
||||||
</$let>
|
$actions$
|
||||||
|
</$let>
|
||||||
</$set>
|
</$set>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define keyboard-input-actions()
|
\define keyboard-input-actions()
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$list filter="[<__index__>match[]]">
|
<$list filter="[<__index__>match[]]">
|
||||||
<$action-setfield $tiddler=<<__storeTitle__>> text={{{ [<__tiddler__>get<__field__>] }}}/>
|
<$action-setfield $tiddler=<<__storeTitle__>> text={{{ [<__tiddler__>get<__field__>] }}}/>
|
||||||
</$list>
|
</$list>
|
||||||
<$list filter="[<__index__>!match[]]">
|
<$list filter="[<__index__>!match[]]">
|
||||||
<$action-setfield $tiddler=<<__storeTitle__>> text={{{ [<__tiddler__>getindex<__index__>] }}}/>
|
<$action-setfield $tiddler=<<__storeTitle__>> text={{{ [<__tiddler__>getindex<__index__>] }}}/>
|
||||||
</$list>
|
</$list>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define input-next-actions-inner()
|
\define input-next-actions-inner()
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$list filter="[<nextItem>minlength[1]]" variable="ignore">
|
<$list filter="[<nextItem>minlength[1]]" variable="ignore">
|
||||||
<$action-setfield $tiddler=<<__selectionStateTitle__>> text=<<nextItem>>/>
|
<$action-setfield $tiddler=<<__selectionStateTitle__>> text=<<nextItem>>/>
|
||||||
<$list filter="[<__index__>match[]]">
|
<$list filter="[<__index__>match[]]">
|
||||||
<$action-setfield $tiddler=<<__tiddler__>> $field=<<__field__>> $value={{{ [<nextItem>] +[splitregexp[(?:.(?!-))+$]] }}}/>
|
<$action-setfield $tiddler=<<__tiddler__>> $field=<<__field__>> $value={{{ [<nextItem>] +[splitregexp[(?:.(?!-))+$]] }}}/>
|
||||||
</$list>
|
</$list>
|
||||||
<$list filter="[<__index__>!match[]]">
|
<$list filter="[<__index__>!match[]]">
|
||||||
<$action-setfield $tiddler=<<__tiddler__>> $index=<<__index__>> $value={{{ [<nextItem>] +[splitregexp[(?:.(?!-))+$]] }}}/>
|
<$action-setfield $tiddler=<<__tiddler__>> $index=<<__index__>> $value={{{ [<nextItem>] +[splitregexp[(?:.(?!-))+$]] }}}/>
|
||||||
</$list>
|
</$list>
|
||||||
<$action-setfield $tiddler=<<__refreshTitle__>> text="yes"/>
|
<$action-setfield $tiddler=<<__refreshTitle__>> text="yes"/>
|
||||||
</$list>
|
</$list>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define input-next-actions(afterOrBefore:"after",reverse:"")
|
\define input-next-actions(afterOrBefore:"after",reverse:"")
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$list filter="[<__storeTitle__>get[text]minlength<__filterMinLength__>] [<__filterMinLength__>match[0]] +[limit[1]]" variable="ignore">
|
<$list
|
||||||
<$let
|
filter="[<__storeTitle__>get[text]minlength<__filterMinLength__>] [<__filterMinLength__>match[0]] +[limit[1]]"
|
||||||
userInput={{{ [<__storeTitle__>get[text]] }}}
|
variable="ignore"
|
||||||
selectedItem={{{ [<__selectionStateTitle__>get[text]] }}}
|
>
|
||||||
configTiddler={{{ [subfilter<__configTiddlerFilter__>] }}}
|
<$let
|
||||||
primaryListFilter={{{ [<configTiddler>get<__firstSearchFilterField__>] }}}
|
userInput={{{ [<__storeTitle__>get[text]] }}}
|
||||||
secondaryListFilter={{{ [<configTiddler>get<__secondSearchFilterField__>] }}}>
|
selectedItem={{{ [<__selectionStateTitle__>get[text]] }}}
|
||||||
<$set name="filteredList" filter="[subfilter<primaryListFilter>addsuffix[-primaryList]] =[subfilter<secondaryListFilter>addsuffix[-secondaryList]]">
|
configTiddler={{{ [subfilter<__configTiddlerFilter__>] }}}
|
||||||
<$let
|
primaryListFilter={{{ [<configTiddler>get<__firstSearchFilterField__>] }}}
|
||||||
nextItem={{{ [enlist<filteredList>$afterOrBefore$<selectedItem>] ~[enlist<filteredList>$reverse$nth[1]] }}}
|
secondaryListFilter={{{ [<configTiddler>get<__secondSearchFilterField__>] }}}
|
||||||
firstItem={{{ [enlist<filteredList>nth[1]] }}}
|
>
|
||||||
lastItem={{{ [enlist<filteredList>last[]] }}}>
|
<$set
|
||||||
<$list filter="[<selectedItem>match<firstItem>!match<lastItem>]" variable="ignore">
|
name="filteredList"
|
||||||
<$set name="nextItem" value={{{ [[$afterOrBefore$]match[before]then<userInput>addsuffix[-userInput]] ~[<nextItem>] }}}>
|
filter="[subfilter<primaryListFilter>addsuffix[-primaryList]] =[subfilter<secondaryListFilter>addsuffix[-secondaryList]]"
|
||||||
<<input-next-actions-inner>>
|
>
|
||||||
</$set>
|
<$let
|
||||||
</$list>
|
nextItem={{{ [enlist<filteredList>$afterOrBefore$<selectedItem>] ~[enlist<filteredList>$reverse$nth[1]] }}}
|
||||||
<$list filter="[<selectedItem>match<lastItem>!match<firstItem>]" variable="ignore">
|
firstItem={{{ [enlist<filteredList>nth[1]] }}}
|
||||||
<$set name="nextItem" value={{{ [[$afterOrBefore$]match[after]then<userInput>addsuffix[-userInput]] ~[<nextItem>] }}}>
|
lastItem={{{ [enlist<filteredList>last[]] }}}
|
||||||
<<input-next-actions-inner>>
|
>
|
||||||
</$set>
|
<$list filter="[<selectedItem>match<firstItem>!match<lastItem>]" variable="ignore">
|
||||||
</$list>
|
<$set name="nextItem" value={{{ [[$afterOrBefore$]match[before]then<userInput>addsuffix[-userInput]] ~[<nextItem>] }}}>
|
||||||
<$list filter="[<selectedItem>match<firstItem>match<lastItem>]" variable="ignore">
|
<<input-next-actions-inner>>
|
||||||
<$set name="nextItem" value={{{ [<userInput>addsuffix[-userInput]] }}}>
|
</$set>
|
||||||
<<input-next-actions-inner>>
|
</$list>
|
||||||
</$set>
|
<$list filter="[<selectedItem>match<lastItem>!match<firstItem>]" variable="ignore">
|
||||||
</$list>
|
<$set name="nextItem" value={{{ [[$afterOrBefore$]match[after]then<userInput>addsuffix[-userInput]] ~[<nextItem>] }}}>
|
||||||
<$list filter="[<selectedItem>!match<firstItem>!match<lastItem>]" variable="ignore">
|
<<input-next-actions-inner>>
|
||||||
<<input-next-actions-inner>>
|
</$set>
|
||||||
</$list>
|
</$list>
|
||||||
</$let>
|
<$list filter="[<selectedItem>match<firstItem>match<lastItem>]" variable="ignore">
|
||||||
</$set>
|
<$set name="nextItem" value={{{ [<userInput>addsuffix[-userInput]] }}}>
|
||||||
</$let>
|
<<input-next-actions-inner>>
|
||||||
|
</$set>
|
||||||
|
</$list>
|
||||||
|
<$list filter="[<selectedItem>!match<firstItem>!match<lastItem>]" variable="ignore">
|
||||||
|
<<input-next-actions-inner>>
|
||||||
|
</$list>
|
||||||
|
</$let>
|
||||||
|
</$set>
|
||||||
|
</$let>
|
||||||
</$list>
|
</$list>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
@ -84,12 +93,14 @@ $actions$
|
|||||||
<$keyboard key="((input-up))" actions=<<input-next-actions "before" "reverse[]">>>
|
<$keyboard key="((input-up))" actions=<<input-next-actions "before" "reverse[]">>>
|
||||||
<$keyboard key="((input-down))" actions=<<input-next-actions>>>
|
<$keyboard key="((input-down))" actions=<<input-next-actions>>>
|
||||||
<$keyboard key="((input-cancel))" actions=<<__inputCancelActions__>>>
|
<$keyboard key="((input-cancel))" actions=<<__inputCancelActions__>>>
|
||||||
<$edit-text tiddler=<<__tiddler__>> field=<<__field__>> index=<<__index__>>
|
<$edit-text
|
||||||
inputActions=<<keyboard-input-actions>> tag=<<__tag__>> class=<<__class__>>
|
tiddler=<<__tiddler__>> field=<<__field__>> index=<<__index__>>
|
||||||
placeholder=<<__placeholder__>> default=<<__default__>> focusPopup=<<__focusPopup__>>
|
inputActions=<<keyboard-input-actions>> tag=<<__tag__>> class=<<__class__>>
|
||||||
focus=<<__focus__>> type=<<__type__>> rows=<<__rows__>> minHeight=<<__minHeight__>>
|
placeholder=<<__placeholder__>> default=<<__default__>> focusPopup=<<__focusPopup__>>
|
||||||
tabindex=<<__tabindex__>> size=<<__size__>> autoHeight=<<__autoHeight__>>
|
focus=<<__focus__>> type=<<__type__>> rows=<<__rows__>> minHeight=<<__minHeight__>>
|
||||||
refreshTitle=<<__refreshTitle__>> cancelPopups=<<__cancelPopups__>>/>
|
tabindex=<<__tabindex__>> size=<<__size__>> autoHeight=<<__autoHeight__>>
|
||||||
|
refreshTitle=<<__refreshTitle__>> cancelPopups=<<__cancelPopups__>>
|
||||||
|
/>
|
||||||
</$keyboard>
|
</$keyboard>
|
||||||
</$keyboard>
|
</$keyboard>
|
||||||
</$keyboard>
|
</$keyboard>
|
||||||
|
@ -26,7 +26,7 @@ tags: $:/tags/Macro
|
|||||||
\whitespace trim
|
\whitespace trim
|
||||||
<span class="tc-links-draggable-list">
|
<span class="tc-links-draggable-list">
|
||||||
<$vars targetTiddler="""$tiddler$""" targetField="""$field$""">
|
<$vars targetTiddler="""$tiddler$""" targetField="""$field$""">
|
||||||
<$type$ class="$class$">
|
<$genesis $type=<<__type__>> class="$class$">
|
||||||
<$list filter="[list[$tiddler$!!$field$]]" emptyMessage=<<__emptyMessage__>>>
|
<$list filter="[list[$tiddler$!!$field$]]" emptyMessage=<<__emptyMessage__>>>
|
||||||
<$droppable actions=<<list-links-draggable-drop-actions>> tag="""$subtype$""" enable=<<tv-enable-drag-and-drop>>>
|
<$droppable actions=<<list-links-draggable-drop-actions>> tag="""$subtype$""" enable=<<tv-enable-drag-and-drop>>>
|
||||||
<div class="tc-droppable-placeholder"/>
|
<div class="tc-droppable-placeholder"/>
|
||||||
@ -51,7 +51,7 @@ tags: $:/tags/Macro
|
|||||||
<div style="height:0.5em;"/>
|
<div style="height:0.5em;"/>
|
||||||
</$droppable>
|
</$droppable>
|
||||||
</$tiddler>
|
</$tiddler>
|
||||||
</$type$>
|
</$genesis>
|
||||||
</$vars>
|
</$vars>
|
||||||
</span>
|
</span>
|
||||||
\end
|
\end
|
||||||
@ -84,24 +84,24 @@ tags: $:/tags/Macro
|
|||||||
<span class="tc-tagged-draggable-list">
|
<span class="tc-tagged-draggable-list">
|
||||||
<$set name="tag" value=<<__tag__>>>
|
<$set name="tag" value=<<__tag__>>>
|
||||||
<$list filter="[<__tag__>tagging[]$subFilter$]" emptyMessage=<<__emptyMessage__>> storyview=<<__storyview__>>>
|
<$list filter="[<__tag__>tagging[]$subFilter$]" emptyMessage=<<__emptyMessage__>> storyview=<<__storyview__>>>
|
||||||
<$elementTag$ class="tc-menu-list-item">
|
<$genesis $type=<<__elementTag__>> class="tc-menu-list-item">
|
||||||
<$droppable actions="""<$macrocall $name="list-tagged-draggable-drop-actions" tag=<<__tag__>>/>""" enable=<<tv-enable-drag-and-drop>>>
|
<$droppable actions="""<$macrocall $name="list-tagged-draggable-drop-actions" tag=<<__tag__>>/>""" enable=<<tv-enable-drag-and-drop>>>
|
||||||
<$elementTag$ class="tc-droppable-placeholder"/>
|
<$genesis $type=<<__elementTag__>> class="tc-droppable-placeholder"/>
|
||||||
<$elementTag$>
|
<$genesis $type=<<__elementTag__>>>
|
||||||
<$transclude tiddler="""$itemTemplate$""">
|
<$transclude tiddler="""$itemTemplate$""">
|
||||||
<$link to={{!!title}}>
|
<$link to={{!!title}}>
|
||||||
<$view field="title"/>
|
<$view field="title"/>
|
||||||
</$link>
|
</$link>
|
||||||
</$transclude>
|
</$transclude>
|
||||||
</$elementTag$>
|
</$genesis>
|
||||||
</$droppable>
|
</$droppable>
|
||||||
</$elementTag$>
|
</$genesis>
|
||||||
</$list>
|
</$list>
|
||||||
<$tiddler tiddler="">
|
<$tiddler tiddler="">
|
||||||
<$droppable actions="""<$macrocall $name="list-tagged-draggable-drop-actions" tag=<<__tag__>>/>""" enable=<<tv-enable-drag-and-drop>>>
|
<$droppable actions="""<$macrocall $name="list-tagged-draggable-drop-actions" tag=<<__tag__>>/>""" enable=<<tv-enable-drag-and-drop>>>
|
||||||
<$elementTag$ class="tc-droppable-placeholder"/>
|
<$genesis $type=<<__elementTag__>> class="tc-droppable-placeholder"/>
|
||||||
<$elementTag$ style="height:0.5em;">
|
<$genesis $type=<<__elementTag__>> style="height:0.5em;">
|
||||||
</$elementTag$>
|
</$genesis>
|
||||||
</$droppable>
|
</$droppable>
|
||||||
</$tiddler>
|
</$tiddler>
|
||||||
</$set>
|
</$set>
|
||||||
|
@ -60,4 +60,4 @@ code-body: yes
|
|||||||
</div>
|
</div>
|
||||||
</$let>
|
</$let>
|
||||||
</$qualify>
|
</$qualify>
|
||||||
\end
|
\end
|
@ -10,10 +10,14 @@ second-search-filter: [tags[]is[system]search:title<userInput>sort[]]
|
|||||||
\define add-tag-actions(actions,tagField:"tags")
|
\define add-tag-actions(actions,tagField:"tags")
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$set name="tag" value={{{ [<__tiddler__>get[text]] }}}>
|
<$set name="tag" value={{{ [<__tiddler__>get[text]] }}}>
|
||||||
<$list filter="[<saveTiddler>!contains:$tagField$<tag>!match[]]" variable="ignore" emptyMessage="<$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter='-[<tag>]'/>">
|
<$list
|
||||||
<$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter="[<tag>trim[]]"/>
|
filter="[<saveTiddler>!contains:$tagField$<tag>!match[]]"
|
||||||
$actions$
|
variable="ignore"
|
||||||
</$list>
|
emptyMessage="<$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter='-[<tag>]'/>"
|
||||||
|
>
|
||||||
|
<$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter="[<tag>trim[]]"/>
|
||||||
|
$actions$
|
||||||
|
</$list>
|
||||||
</$set>
|
</$set>
|
||||||
<<delete-tag-state-tiddlers>>
|
<<delete-tag-state-tiddlers>>
|
||||||
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||||
@ -21,80 +25,153 @@ $actions$
|
|||||||
|
|
||||||
\define clear-tags-actions-inner()
|
\define clear-tags-actions-inner()
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$list filter="[<storeTitle>has[text]] [<newTagNameTiddler>has[text]]" variable="ignore" emptyMessage="<<cancel-delete-tiddler-actions 'cancel'>>">
|
<$list
|
||||||
<<delete-tag-state-tiddlers>>
|
filter="[<storeTitle>has[text]] [<newTagNameTiddler>has[text]]"
|
||||||
|
variable="ignore"
|
||||||
|
emptyMessage="<<cancel-delete-tiddler-actions 'cancel'>>"
|
||||||
|
>
|
||||||
|
<<delete-tag-state-tiddlers>>
|
||||||
</$list>
|
</$list>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define clear-tags-actions()
|
\define clear-tags-actions()
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$set name="userInput" value={{{ [<storeTitle>get[text]] }}}>
|
<$set name="userInput" value={{{ [<storeTitle>get[text]] }}}>
|
||||||
<$list filter="[<newTagNameTiddler>get[text]!match<userInput>]" emptyMessage="<<clear-tags-actions-inner>>">
|
<$list filter="[<newTagNameTiddler>get[text]!match<userInput>]" emptyMessage="<<clear-tags-actions-inner>>">
|
||||||
<$action-setfield $tiddler=<<newTagNameTiddler>> text=<<userInput>>/><$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
<$action-setfield $tiddler=<<newTagNameTiddler>> text=<<userInput>>/><$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||||
</$list>
|
</$list>
|
||||||
</$set>
|
</$set>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define tag-picker-inner(actions,tagField:"tags")
|
\define tag-picker-inner(actions,tagField:"tags")
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$vars newTagNameInputTiddlerQualified=<<qualify "$:/temp/NewTagName/input">> newTagNameSelectionTiddlerQualified=<<qualify "$:/temp/NewTagName/selected-item">> fallbackTarget={{$(palette)$##tag-background}} colourA={{$(palette)$##foreground}} colourB={{$(palette)$##background}}>
|
<$vars
|
||||||
<$vars storeTitle={{{ [<newTagNameInputTiddler>!match[]] ~[<newTagNameInputTiddlerQualified>] }}} tagSelectionState={{{ [<newTagNameSelectionTiddler>!match[]] ~[<newTagNameSelectionTiddlerQualified>] }}}>
|
newTagNameInputTiddlerQualified=<<qualify "$:/temp/NewTagName/input">>
|
||||||
<$vars refreshTitle=<<qualify "$:/temp/NewTagName/refresh">> nonSystemTagsFilter="[tags[]!is[system]search:title<userInput>sort[]]" systemTagsFilter="[tags[]is[system]search:title<userInput>sort[]]">
|
newTagNameSelectionTiddlerQualified=<<qualify "$:/temp/NewTagName/selected-item">>
|
||||||
<div class="tc-edit-add-tag">
|
fallbackTarget={{$(palette)$##tag-background}}
|
||||||
<div>
|
colourA={{$(palette)$##foreground}}
|
||||||
<span class="tc-add-tag-name tc-small-gap-right">
|
colourB={{$(palette)$##background}}
|
||||||
<$macrocall $name="keyboard-driven-input" tiddler=<<newTagNameTiddler>> storeTitle=<<storeTitle>> refreshTitle=<<refreshTitle>>
|
>
|
||||||
selectionStateTitle=<<tagSelectionState>> inputAcceptActions="<$macrocall $name='add-tag-actions' actions=<<__actions__>> tagField=<<__tagField__>>/>"
|
<$vars
|
||||||
inputCancelActions=<<clear-tags-actions>> tag="input" placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}}
|
storeTitle={{{ [<newTagNameInputTiddler>!match[]] ~[<newTagNameInputTiddlerQualified>] }}}
|
||||||
focusPopup=<<qualify "$:/state/popup/tags-auto-complete">> class="tc-edit-texteditor tc-popup-handle" tabindex=<<tabIndex>>
|
tagSelectionState={{{ [<newTagNameSelectionTiddler>!match[]] ~[<newTagNameSelectionTiddlerQualified>] }}}
|
||||||
focus={{{ [{$:/config/AutoFocus}match[tags]then[true]] ~[[false]] }}} filterMinLength={{$:/config/Tags/MinLength}}
|
>
|
||||||
cancelPopups=<<cancelPopups>> configTiddlerFilter="[[$:/core/macros/tag-picker]]"/>
|
<$vars
|
||||||
</span><$button popup=<<qualify "$:/state/popup/tags-auto-complete">> class="tc-btn-invisible tc-btn-dropdown" tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button><$reveal state=<<storeTitle>> type="nomatch" text=""><$button class="tc-btn-invisible tc-small-gap tc-btn-dropdown" tooltip={{$:/language/EditTemplate/Tags/ClearInput/Hint}} aria-label={{$:/language/EditTemplate/Tags/ClearInput/Caption}}>{{$:/core/images/close-button}}<<delete-tag-state-tiddlers>></$button></$reveal><span class="tc-add-tag-button tc-small-gap-left">
|
refreshTitle=<<qualify "$:/temp/NewTagName/refresh">>
|
||||||
<$set name="tag" value={{{ [<newTagNameTiddler>get[text]] }}}>
|
nonSystemTagsFilter="[tags[]!is[system]search:title<userInput>sort[]]"
|
||||||
<$button set=<<newTagNameTiddler>> setTo="" class="">
|
systemTagsFilter="[tags[]is[system]search:title<userInput>sort[]]"
|
||||||
<$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter="[<tag>trim[]]"/>
|
>
|
||||||
$actions$
|
<div class="tc-edit-add-tag">
|
||||||
<$set name="currentTiddlerCSSEscaped" value={{{ [<saveTiddler>escapecss[]] }}}>
|
<div>
|
||||||
<<delete-tag-state-tiddlers>><$action-sendmessage $message="tm-focus-selector" $param=<<get-tagpicker-focus-selector>>/>
|
<span class="tc-add-tag-name tc-small-gap-right">
|
||||||
</$set>
|
<$macrocall
|
||||||
{{$:/language/EditTemplate/Tags/Add/Button}}
|
$name="keyboard-driven-input"
|
||||||
</$button>
|
tiddler=<<newTagNameTiddler>>
|
||||||
</$set>
|
storeTitle=<<storeTitle>>
|
||||||
</span>
|
refreshTitle=<<refreshTitle>>
|
||||||
</div>
|
selectionStateTitle=<<tagSelectionState>>
|
||||||
<div class="tc-block-dropdown-wrapper">
|
inputAcceptActions="<$macrocall $name='add-tag-actions' actions=<<__actions__>> tagField=<<__tagField__>>/>"
|
||||||
<$reveal state=<<qualify "$:/state/popup/tags-auto-complete">> type="nomatch" text="" default="">
|
inputCancelActions=<<clear-tags-actions>>
|
||||||
<div class="tc-block-dropdown tc-block-tags-dropdown">
|
tag="input"
|
||||||
<$set name="userInput" value={{{ [<storeTitle>get[text]] }}}>
|
placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}}
|
||||||
<$list filter="[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]" emptyMessage="<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>" variable="listItem">
|
focusPopup=<<qualify "$:/state/popup/tags-auto-complete">>
|
||||||
<$list filter=<<nonSystemTagsFilter>> variable="tag">
|
class="tc-edit-texteditor tc-popup-handle"
|
||||||
<$list filter="[<tag>addsuffix[-primaryList]] -[<tagSelectionState>get[text]]" emptyMessage="<$vars button-classes='tc-btn-invisible tc-tag-button-selected' actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<<tag>>>{{||$:/core/ui/TagPickerTagTemplate}}</$vars>">
|
tabindex=<<tabIndex>>
|
||||||
<$vars button-classes="tc-btn-invisible" actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<<tag>>>{{||$:/core/ui/TagPickerTagTemplate}}</$vars>
|
focus={{{ [{$:/config/AutoFocus}match[tags]then[true]] ~[[false]] }}}
|
||||||
</$list>
|
filterMinLength={{$:/config/Tags/MinLength}}
|
||||||
</$list></$list>
|
cancelPopups=<<cancelPopups>>
|
||||||
<hr>
|
configTiddlerFilter="[[$:/core/macros/tag-picker]]"
|
||||||
<$list filter="[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]" emptyMessage="<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>" variable="listItem">
|
/>
|
||||||
<$list filter=<<systemTagsFilter>> variable="tag">
|
</span>
|
||||||
<$list filter="[<tag>addsuffix[-secondaryList]] -[<tagSelectionState>get[text]]" emptyMessage="<$vars button-classes='tc-btn-invisible tc-tag-button-selected' actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<<tag>>>{{||$:/core/ui/TagPickerTagTemplate}}</$vars>">
|
<$button popup=<<qualify "$:/state/popup/tags-auto-complete">>
|
||||||
<$vars button-classes="tc-btn-invisible" actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<<tag>>>{{||$:/core/ui/TagPickerTagTemplate}}</$vars>
|
class="tc-btn-invisible tc-btn-dropdown"
|
||||||
</$list>
|
tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}}
|
||||||
</$list></$list>
|
aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}
|
||||||
</$set>
|
>
|
||||||
</div>
|
{{$:/core/images/down-arrow}}
|
||||||
</$reveal>
|
</$button>
|
||||||
</div>
|
<$reveal state=<<storeTitle>> type="nomatch" text="">
|
||||||
</div>
|
<$button class="tc-btn-invisible tc-small-gap tc-btn-dropdown"
|
||||||
</$vars>
|
tooltip={{$:/language/EditTemplate/Tags/ClearInput/Hint}}
|
||||||
</$vars>
|
aria-label={{$:/language/EditTemplate/Tags/ClearInput/Caption}}
|
||||||
|
>
|
||||||
|
{{$:/core/images/close-button}}<<delete-tag-state-tiddlers>>
|
||||||
|
</$button>
|
||||||
|
</$reveal>
|
||||||
|
<span class="tc-add-tag-button tc-small-gap-left">
|
||||||
|
<$set name="tag" value={{{ [<newTagNameTiddler>get[text]] }}}>
|
||||||
|
<$button set=<<newTagNameTiddler>> setTo="" class="">
|
||||||
|
<$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter="[<tag>trim[]]"/>
|
||||||
|
$actions$
|
||||||
|
<$set name="currentTiddlerCSSEscaped" value={{{ [<saveTiddler>escapecss[]] }}}>
|
||||||
|
<<delete-tag-state-tiddlers>><$action-sendmessage $message="tm-focus-selector" $param=<<get-tagpicker-focus-selector>>/>
|
||||||
|
</$set>
|
||||||
|
{{$:/language/EditTemplate/Tags/Add/Button}}
|
||||||
|
</$button>
|
||||||
|
</$set>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="tc-block-dropdown-wrapper">
|
||||||
|
<$reveal state=<<qualify "$:/state/popup/tags-auto-complete">> type="nomatch" text="" default="">
|
||||||
|
<div class="tc-block-dropdown tc-block-tags-dropdown">
|
||||||
|
<$set name="userInput" value={{{ [<storeTitle>get[text]] }}}>
|
||||||
|
<$list
|
||||||
|
filter="[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]"
|
||||||
|
emptyMessage="<div class='tc-search-results'
|
||||||
|
>
|
||||||
|
{{$:/language/Search/Search/TooShort}}</div>" variable="listItem">
|
||||||
|
<$list filter=<<nonSystemTagsFilter>> variable="tag">
|
||||||
|
<$list
|
||||||
|
filter="[<tag>addsuffix[-primaryList]] -[<tagSelectionState>get[text]]"
|
||||||
|
emptyMessage="<$vars button-classes='tc-btn-invisible tc-tag-button-selected' actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<<tag>>>{{||$:/core/ui/TagPickerTagTemplate}}</$vars>"
|
||||||
|
>
|
||||||
|
<$vars button-classes="tc-btn-invisible"
|
||||||
|
actions=<<__actions__>>
|
||||||
|
tagField=<<__tagField__>>
|
||||||
|
currentTiddler=<<tag>>
|
||||||
|
>
|
||||||
|
{{||$:/core/ui/TagPickerTagTemplate}}
|
||||||
|
</$vars>
|
||||||
|
</$list>
|
||||||
|
</$list>
|
||||||
|
</$list>
|
||||||
|
<hr>
|
||||||
|
<$list filter="[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]" emptyMessage="<div class='tc-search-results'>
|
||||||
|
{{$:/language/Search/Search/TooShort}}</div>" variable="listItem">
|
||||||
|
<$list filter=<<systemTagsFilter>> variable="tag">
|
||||||
|
<$list filter="[<tag>addsuffix[-secondaryList]] -[<tagSelectionState>get[text]]"
|
||||||
|
emptyMessage="<$vars button-classes='tc-btn-invisible tc-tag-button-selected' actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<<tag>>>{{||$:/core/ui/TagPickerTagTemplate}}</$vars>"
|
||||||
|
>
|
||||||
|
<$vars button-classes="tc-btn-invisible"
|
||||||
|
actions=<<__actions__>>
|
||||||
|
tagField=<<__tagField__>>
|
||||||
|
currentTiddler=<<tag>>
|
||||||
|
>
|
||||||
|
{{||$:/core/ui/TagPickerTagTemplate}}
|
||||||
|
</$vars>
|
||||||
|
</$list>
|
||||||
|
</$list>
|
||||||
|
</$list>
|
||||||
|
</$set>
|
||||||
|
</div>
|
||||||
|
</$reveal>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</$vars>
|
||||||
|
</$vars>
|
||||||
</$vars>
|
</$vars>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define tag-picker(actions,tagField:"tags")
|
\define tag-picker(actions,tagField:"tags")
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$vars saveTiddler=<<currentTiddler>> palette={{$:/palette}}>
|
<$vars saveTiddler=<<currentTiddler>> palette={{$:/palette}}>
|
||||||
<$list filter="[<newTagNameTiddler>match[]]" emptyMessage="<$macrocall $name='tag-picker-inner' actions=<<__actions__>> tagField=<<__tagField__>>/>">
|
<$list
|
||||||
<$set name="newTagNameTiddler" value=<<qualify "$:/temp/NewTagName">>>
|
filter="[<newTagNameTiddler>match[]]"
|
||||||
<$macrocall $name="tag-picker-inner" actions=<<__actions__>> tagField=<<__tagField__>>/>
|
emptyMessage="<$macrocall $name='tag-picker-inner' actions=<<__actions__>> tagField=<<__tagField__>>/>"
|
||||||
</$set>
|
>
|
||||||
</$list>
|
<$set name="newTagNameTiddler" value=<<qualify "$:/temp/NewTagName">>>
|
||||||
|
<$macrocall $name="tag-picker-inner" actions=<<__actions__>> tagField=<<__tagField__>>/>
|
||||||
|
</$set>
|
||||||
|
</$list>
|
||||||
</$vars>
|
</$vars>
|
||||||
\end
|
\end
|
||||||
|
@ -7,7 +7,7 @@ tags: $:/tags/Macro
|
|||||||
|
|
||||||
\define toc-caption()
|
\define toc-caption()
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<span class="tc-toc-caption tc-tiny-gap-left">
|
<span class="tc-toc-caption">
|
||||||
<$set name="tv-wikilinks" value="no">
|
<$set name="tv-wikilinks" value="no">
|
||||||
<$transclude field="caption">
|
<$transclude field="caption">
|
||||||
<$view field="title"/>
|
<$view field="title"/>
|
||||||
@ -24,7 +24,7 @@ tags: $:/tags/Macro
|
|||||||
<$set name="excluded" filter="""[enlist<__exclude__>] [<__tag__>]""">
|
<$set name="excluded" filter="""[enlist<__exclude__>] [<__tag__>]""">
|
||||||
<$set name="toc-item-class" filter=<<__itemClassFilter__>> emptyValue="toc-item-selected" value="toc-item">
|
<$set name="toc-item-class" filter=<<__itemClassFilter__>> emptyValue="toc-item-selected" value="toc-item">
|
||||||
<li class=<<toc-item-class>>>
|
<li class=<<toc-item-class>>>
|
||||||
<$list filter="[all[current]toc-link[no]]" emptyMessage="<$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}><$view field='caption'><$view field='title'/></$view></$link>">
|
<$list filter="[all[current]toc-link[no]]" emptyMessage="<$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}><<toc-caption>></$link>">
|
||||||
<<toc-caption>>
|
<<toc-caption>>
|
||||||
</$list>
|
</$list>
|
||||||
<$macrocall $name="toc-body" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>
|
<$macrocall $name="toc-body" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
title: HelloThere
|
title: HelloThere
|
||||||
|
|
||||||
This is a demo of TiddlyWiki5 incorporating a plugin for the [[D3.js]] visualization library.
|
This is a demo of TiddlyWiki5 incorporating a plugin for the [[D3.js]] visualisation library.
|
||||||
|
|
||||||
! Word Cloud
|
! Word Cloud
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
created: 20140923173639039
|
created: 20140923173639039
|
||||||
creator: pmario
|
creator: pmario
|
||||||
modified: 20140924155046340
|
modified: 20230307080008193
|
||||||
modifier: pmario
|
modifier: pmario
|
||||||
title: TaskManagement
|
title: TaskManagement
|
||||||
type: text/vnd.tiddlywiki
|
type: text/vnd.tiddlywiki
|
||||||
|
|
||||||
In dieser Edition sind folgende Task Management Varianten beschreiben:
|
In dieser Edition sind folgende Task Management Varianten beschrieben:
|
||||||
|
|
||||||
<<list-links filter:"[tag[TaskManagement]]">>
|
<<list-links filter:"[tag[TaskManagement]]">>
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ color: #37d011
|
|||||||
created: 20140923104300415
|
created: 20140923104300415
|
||||||
creator: pmario
|
creator: pmario
|
||||||
icon: $:/core/images/done-button
|
icon: $:/core/images/done-button
|
||||||
modified: 20140923105208878
|
modified: 20230307080039831
|
||||||
modifier: ChrisK
|
modifier: ChrisK
|
||||||
tags: done
|
tags: done
|
||||||
title: done
|
title: done
|
||||||
@ -12,5 +12,5 @@ Diese Tag wird verwendet um "Tasks" als erledigt zu markieren.
|
|||||||
|
|
||||||
Siehe auch:
|
Siehe auch:
|
||||||
|
|
||||||
* [[Task Management]] .. Beispiel
|
* [[Task Management|TaskManagement]] .. Beispiel
|
||||||
* [[Tag Manager|$:/TagManager]] .. Zuweisung der Farben und Symbole
|
* [[Tag Manager|$:/TagManager]] .. Zuweisung der Farben und Symbole
|
@ -0,0 +1,6 @@
|
|||||||
|
created: 20230307080413903
|
||||||
|
modified: 20230307080417122
|
||||||
|
title: Importieren von Tiddlern
|
||||||
|
type: text/vnd.tiddlywiki
|
||||||
|
|
||||||
|
https://tiddlywiki.com/#Importing%20Tiddlers
|
@ -1,11 +1,11 @@
|
|||||||
created: 20140918094051245
|
created: 20140918094051245
|
||||||
creator: pmario
|
creator: pmario
|
||||||
modified: 20140918094948642
|
modified: 20230307080301079
|
||||||
modifier: pmario
|
modifier: pmario
|
||||||
tags: Referenz
|
tags: Referenz
|
||||||
title: Liste aller HowTo's
|
title: Liste aller HowTo's
|
||||||
type: text/vnd.tiddlywiki
|
type: text/vnd.tiddlywiki
|
||||||
|
|
||||||
Hier finden Sie eine Auflistung aller HowTo's
|
Hier finden Sie eine Auflistung aller ~HowTo's
|
||||||
|
|
||||||
<<list-links "[tag[howto]]">>
|
<<list-links "[tag[howto]]">>
|
6
editions/de-AT/tiddlers/konzept/Tagging.tid
Normal file
6
editions/de-AT/tiddlers/konzept/Tagging.tid
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
created: 20230307081437974
|
||||||
|
modified: 20230307081439303
|
||||||
|
title: Tagging
|
||||||
|
type: text/vnd.tiddlywiki
|
||||||
|
|
||||||
|
https://tiddlywiki.com/#Tagging
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user