diff --git a/boot/boot.js b/boot/boot.js index 9b742120c..c065cfb61 100644 --- a/boot/boot.js +++ b/boot/boot.js @@ -305,13 +305,21 @@ $tw.utils.stringifyDate = function(value) { // Parse a date from a UTC YYYYMMDDHHMMSSmmm format string $tw.utils.parseDate = function(value) { if(typeof value === "string") { - return new Date(Date.UTC(parseInt(value.substr(0,4),10), + var negative = 1; + if(value.charAt(0) === "-") { + negative = -1; + value = value.substr(1); + } + var year = parseInt(value.substr(0,4),10) * negative, + d = new Date(Date.UTC(year, parseInt(value.substr(4,2),10)-1, parseInt(value.substr(6,2),10), parseInt(value.substr(8,2)||"00",10), parseInt(value.substr(10,2)||"00",10), parseInt(value.substr(12,2)||"00",10), parseInt(value.substr(14,3)||"000",10))); + d.setUTCFullYear(year); // See https://stackoverflow.com/a/5870822 + return d; } else if($tw.utils.isDate(value)) { return value; } else { @@ -1886,7 +1894,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) { }); }); if(isEditableFile) { - tiddlers.push({filepath: pathname, hasMetaFile: !!metadata && !isTiddlerFile, tiddlers: fileTiddlers}); + tiddlers.push({filepath: pathname, hasMetaFile: !!metadata && !isTiddlerFile, isEditableFile: true, tiddlers: fileTiddlers}); } else { tiddlers.push({tiddlers: fileTiddlers}); } @@ -1912,15 +1920,21 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) { } } else { // Process directory specifier - var dirPath = path.resolve(filepath,dirSpec.path), - files = fs.readdirSync(dirPath), - fileRegExp = new RegExp(dirSpec.filesRegExp || "^.*$"), - metaRegExp = /^.*\.meta$/; - for(var t=0; t 0){ + $tw.wiki.addTiddler({title: "$:/config/OriginalTiddlerPaths", type: "application/json", text: JSON.stringify(output)}); } - $tw.wiki.addTiddler({title: "$:/config/OriginalTiddlerPaths", type: "application/json", text: JSON.stringify(output)}); } - // Save the path to the tiddlers folder for the filesystemadaptor - $tw.boot.wikiTiddlersPath = path.resolve($tw.boot.wikiPath,config["default-tiddler-location"] || $tw.config.wikiTiddlersSubDir); // Load any plugins within the wiki folder var wikiPluginsPath = path.resolve(wikiPath,$tw.config.wikiPluginsSubDir); if(fs.existsSync(wikiPluginsPath)) { @@ -2160,7 +2182,7 @@ $tw.loadTiddlersNode = function() { // Load any extra plugins $tw.utils.each($tw.boot.extraPlugins,function(name) { if(name.charAt(0) === "+") { // Relative path to plugin - var pluginFields = $tw.loadPluginFolder(name.substring(1));; + var pluginFields = $tw.loadPluginFolder(name.substring(1)); if(pluginFields) { $tw.wiki.addTiddler(pluginFields); } diff --git a/core/language/en-GB/ControlPanel.multids b/core/language/en-GB/ControlPanel.multids index c75aa5679..54f0d4050 100644 --- a/core/language/en-GB/ControlPanel.multids +++ b/core/language/en-GB/ControlPanel.multids @@ -17,6 +17,8 @@ Basics/NewJournal/Tags/Prompt: Tags for new journal tiddlers Basics/NewTiddler/Title/Prompt: Title of new tiddlers Basics/NewTiddler/Tags/Prompt: Tags for new tiddlers Basics/OverriddenShadowTiddlers/Prompt: Number of overridden shadow tiddlers +Basics/RemoveTags: Update to current format +Basics/RemoveTags/Hint: Update the tags configuration to the latest format Basics/ShadowTiddlers/Prompt: Number of shadow tiddlers Basics/Subtitle/Prompt: Subtitle Basics/SystemTiddlers/Prompt: Number of system tiddlers @@ -44,6 +46,7 @@ KeyboardShortcuts/Platform/Linux: Linux platform only KeyboardShortcuts/Platform/NonLinux: Non-Linux platforms only KeyboardShortcuts/Platform/Windows: Windows platform only KeyboardShortcuts/Platform/NonWindows: Non-Windows platforms only +LayoutSwitcher/Caption: Layout LoadedModules/Caption: Loaded Modules LoadedModules/Hint: These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process. Palette/Caption: Palette @@ -125,6 +128,7 @@ Saving/TiddlySpot/Filename: Upload Filename Saving/TiddlySpot/Heading: ~TiddlySpot Saving/TiddlySpot/Hint: //The server URL defaults to `http://.tiddlyspot.com/store.cgi` and can be changed to use a custom server address, e.g. `http://example.com/store.php`.// Saving/TiddlySpot/Password: Password +Saving/TiddlySpot/ReadOnly: ~TiddlySpot service may currently be available as read only. Please see http://tiddlyspot.com/ for details Saving/TiddlySpot/ServerURL: Server URL Saving/TiddlySpot/UploadDir: Upload Directory Saving/TiddlySpot/UserName: Wiki Name diff --git a/core/language/en-GB/Import.multids b/core/language/en-GB/Import.multids index cc2c6c143..3b3308ad5 100644 --- a/core/language/en-GB/Import.multids +++ b/core/language/en-GB/Import.multids @@ -18,11 +18,11 @@ Listing/Rename/Prompt: Rename to: Listing/Rename/ConfirmRename: Rename tiddler Listing/Rename/CancelRename: Cancel Listing/Rename/OverwriteWarning: A tiddler with this title already exists. -Upgrader/Plugins/Suppressed/Incompatible: Blocked incompatible or obsolete plugin -Upgrader/Plugins/Suppressed/Version: Blocked plugin (due to incoming <> being older than existing <>) -Upgrader/Plugins/Upgraded: Upgraded plugin from <> to <> -Upgrader/State/Suppressed: Blocked temporary state tiddler -Upgrader/System/Suppressed: Blocked system tiddler -Upgrader/System/Warning: Core module tiddler -Upgrader/System/Alert: You are about to import a tiddler that will overwrite a core module tiddler. This is not recommended as it may make the system unstable -Upgrader/ThemeTweaks/Created: Migrated theme tweak from <$text text=<>/> +Upgrader/Plugins/Suppressed/Incompatible: Blocked incompatible or obsolete plugin. +Upgrader/Plugins/Suppressed/Version: Blocked plugin (due to incoming <> not being newer than existing <>). +Upgrader/Plugins/Upgraded: Upgraded plugin from <> to <>. +Upgrader/State/Suppressed: Blocked temporary state tiddler. +Upgrader/System/Suppressed: Blocked system tiddler. +Upgrader/System/Warning: Core module tiddler. +Upgrader/System/Alert: You are about to import a tiddler that will overwrite a core module tiddler. This is not recommended as it may make the system unstable. +Upgrader/ThemeTweaks/Created: Migrated theme tweak from <$text text=<>/>. diff --git a/core/language/en-GB/Misc.multids b/core/language/en-GB/Misc.multids index a6655709d..81c5758cc 100644 --- a/core/language/en-GB/Misc.multids +++ b/core/language/en-GB/Misc.multids @@ -40,6 +40,7 @@ Error/XMLHttpRequest: XMLHttpRequest error code InternalJavaScriptError/Title: Internal JavaScript Error InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser InvalidFieldName: Illegal characters in field name "<$text text=<>/>". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`) +LayoutSwitcher/Description: Open the layout switcher LazyLoadingWarning:

Trying to load external content from ''<$text text={{!!_canonical_uri}}/>''

If this message doesn't disappear, either the tiddler content type doesn't match the type of the external content, or you may be using a browser that doesn't support external content for wikis loaded as standalone files. See https://tiddlywiki.com/#ExternalText

LoginToTiddlySpace: Login to TiddlySpace Manager/Controls/FilterByTag/None: (none) @@ -63,6 +64,8 @@ MissingTiddler/Hint: Missing tiddler "<$text text=<>/>" -- click No: No OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library OfficialPluginLibrary/Hint: The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team. +PageTemplate/Description: the default ~TiddlyWiki layout +PageTemplate/Name: Default ~PageTemplate PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect RecentChanges/DateFormat: DDth MMM YYYY Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field @@ -74,6 +77,10 @@ Shortcuts/Input/Tab-Left/Hint: Select the previous Tab Shortcuts/Input/Tab-Right/Hint: Select the next Tab Shortcuts/Input/Up/Hint: Select the previous item Shortcuts/SidebarLayout/Hint: Change the sidebar layout +Switcher/Subtitle/theme: Switch Theme +Switcher/Subtitle/layout: Switch Layout +Switcher/Subtitle/language: Switch Language +Switcher/Subtitle/palette: Switch Palette SystemTiddler/Tooltip: This is a system tiddler SystemTiddlers/Include/Prompt: Include system tiddlers TagManager/Colour/Heading: Colour diff --git a/core/language/en-GB/TiddlerInfo.multids b/core/language/en-GB/TiddlerInfo.multids index a395ce19b..0899320c6 100644 --- a/core/language/en-GB/TiddlerInfo.multids +++ b/core/language/en-GB/TiddlerInfo.multids @@ -14,7 +14,7 @@ List/Caption: List List/Empty: This tiddler does not have a list Listed/Caption: Listed Listed/Empty: This tiddler is not listed by any others -References/Caption: References +References/Caption: Backlinks References/Empty: No tiddlers link to this one Tagging/Caption: Tagging Tagging/Empty: No tiddlers are tagged with this one diff --git a/core/modules/editor/engines/framed.js b/core/modules/editor/engines/framed.js index 4d6113fae..c70167f6c 100644 --- a/core/modules/editor/engines/framed.js +++ b/core/modules/editor/engines/framed.js @@ -42,7 +42,6 @@ function FramedEngine(options) { this.iframeNode.style.border = "none"; this.iframeNode.style.padding = "0"; this.iframeNode.style.resize = "none"; - this.iframeNode.style["background-color"] = this.widget.wiki.extractTiddlerDataItem(this.widget.wiki.getTiddlerText("$:/palette"),"tiddler-editor-background"); this.iframeDoc.body.style.margin = "0"; this.iframeDoc.body.style.padding = "0"; this.widget.domNodes.push(this.iframeNode); @@ -74,6 +73,9 @@ function FramedEngine(options) { if(this.widget.editTabIndex) { this.iframeNode.setAttribute("tabindex",this.widget.editTabIndex); } + if(this.widget.editAutoComplete) { + this.domNode.setAttribute("autocomplete",this.widget.editAutoComplete); + } if(this.widget.isDisabled === "yes") { this.domNode.setAttribute("disabled",true); } @@ -100,7 +102,6 @@ FramedEngine.prototype.copyStyles = function() { this.domNode.style.display = "block"; this.domNode.style.width = "100%"; this.domNode.style.margin = "0"; - this.domNode.style["background-color"] = this.widget.wiki.extractTiddlerDataItem(this.widget.wiki.getTiddlerText("$:/palette"),"tiddler-editor-background"); // In Chrome setting -webkit-text-fill-color overrides the placeholder text colour this.domNode.style["-webkit-text-fill-color"] = "currentcolor"; }; diff --git a/core/modules/editor/engines/simple.js b/core/modules/editor/engines/simple.js index 0f65e7ceb..fe65d1fd9 100644 --- a/core/modules/editor/engines/simple.js +++ b/core/modules/editor/engines/simple.js @@ -52,6 +52,9 @@ function SimpleEngine(options) { if(this.widget.editTabIndex) { this.domNode.setAttribute("tabindex",this.widget.editTabIndex); } + if(this.widget.editAutoComplete) { + this.domNode.setAttribute("autocomplete",this.widget.editAutoComplete); + } if(this.widget.isDisabled === "yes") { this.domNode.setAttribute("disabled",true); } diff --git a/core/modules/editor/factory.js b/core/modules/editor/factory.js index 933c2eb42..3cf595371 100644 --- a/core/modules/editor/factory.js +++ b/core/modules/editor/factory.js @@ -180,6 +180,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) { this.editCancelPopups = this.getAttribute("cancelPopups","") === "yes"; this.editInputActions = this.getAttribute("inputActions"); this.editRefreshTitle = this.getAttribute("refreshTitle"); + this.editAutoComplete = this.getAttribute("autocomplete"); this.isDisabled = this.getAttribute("disabled","no"); // Get the default editor element tag and type var tag,type; @@ -212,7 +213,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) { EditTextWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); // Completely rerender if any of our attributes have changed - if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedAttributes.disabled) { + if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedAttributes.disabled) { this.refreshSelf(); return true; } else if (changedTiddlers[this.editRefreshTitle]) { diff --git a/core/modules/filterrunprefixes/and.js b/core/modules/filterrunprefixes/and.js index 29ccf1619..ad41c049c 100644 --- a/core/modules/filterrunprefixes/and.js +++ b/core/modules/filterrunprefixes/and.js @@ -16,10 +16,10 @@ Equivalent to + filter run prefix. /* Export our filter prefix function */ -exports.and = function(operationSubFunction) { +exports.and = function(operationSubFunction,options) { return function(results,source,widget) { // This replaces all the elements of the array, but keeps the actual array so that references to it are preserved - source = $tw.wiki.makeTiddlerIterator(results); + source = options.wiki.makeTiddlerIterator(results); results.splice(0,results.length); $tw.utils.pushTop(results,operationSubFunction(source,widget)); }; diff --git a/core/modules/filterrunprefixes/reduce.js b/core/modules/filterrunprefixes/reduce.js new file mode 100644 index 000000000..4dcef4bc7 --- /dev/null +++ b/core/modules/filterrunprefixes/reduce.js @@ -0,0 +1,49 @@ +/*\ +title: $:/core/modules/filterrunprefixes/reduce.js +type: application/javascript +module-type: filterrunprefix +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +/* +Export our filter prefix function +*/ +exports.reduce = function(operationSubFunction,options) { + return function(results,source,widget) { + if(results.length > 0) { + var accumulator = ""; + for(var index=0; index 0) { + accumulator = "" + list[0]; + } + } + results.splice(0,results.length); + results.push(accumulator); + } + } +}; + +})(); diff --git a/core/modules/filters.js b/core/modules/filters.js index 9a18eb2af..0fc0a3dc9 100644 --- a/core/modules/filters.js +++ b/core/modules/filters.js @@ -188,7 +188,7 @@ exports.getFilterOperators = function() { }; exports.getFilterRunPrefixes = function() { - if(!this.filterPrefixes) { + if(!this.filterRunPrefixes) { $tw.Wiki.prototype.filterRunPrefixes = {}; $tw.modules.applyMethods("filterrunprefix",this.filterRunPrefixes); } @@ -280,20 +280,21 @@ exports.compileFilter = function(filterString) { var filterRunPrefixes = self.getFilterRunPrefixes(); // Wrap the operator functions in a wrapper function that depends on the prefix operationFunctions.push((function() { + var options = {wiki: self}; switch(operation.prefix || "") { case "": // No prefix means that the operation is unioned into the result - return filterRunPrefixes["or"](operationSubFunction); + return filterRunPrefixes["or"](operationSubFunction, options); case "=": // The results of the operation are pushed into the result without deduplication - return filterRunPrefixes["all"](operationSubFunction); + return filterRunPrefixes["all"](operationSubFunction, options); case "-": // The results of this operation are removed from the main result - return filterRunPrefixes["except"](operationSubFunction); + return filterRunPrefixes["except"](operationSubFunction, options); case "+": // This operation is applied to the main results so far - return filterRunPrefixes["and"](operationSubFunction); + return filterRunPrefixes["and"](operationSubFunction, options); case "~": // This operation is unioned into the result only if the main result so far is empty - return filterRunPrefixes["else"](operationSubFunction); + return filterRunPrefixes["else"](operationSubFunction, options); default: if(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) { - return filterRunPrefixes[operation.namedPrefix](operationSubFunction); + return filterRunPrefixes[operation.namedPrefix](operationSubFunction, options); } else { return function(results,source,widget) { results.splice(0,results.length); diff --git a/core/modules/filters/encodings.js b/core/modules/filters/encodings.js index f41350791..557599c1a 100644 --- a/core/modules/filters/encodings.js +++ b/core/modules/filters/encodings.js @@ -77,7 +77,7 @@ exports.encodehtml = function(source,operator,options) { exports.stringify = function(source,operator,options) { var results = []; source(function(tiddler,title) { - results.push($tw.utils.stringify(title)); + results.push($tw.utils.stringify(title,(operator.suffix === "rawunicode"))); }); return results; }; @@ -85,7 +85,7 @@ exports.stringify = function(source,operator,options) { exports.jsonstringify = function(source,operator,options) { var results = []; source(function(tiddler,title) { - results.push($tw.utils.jsonStringify(title)); + results.push($tw.utils.jsonStringify(title,(operator.suffix === "rawunicode"))); }); return results; }; diff --git a/core/modules/filters/lookup.js b/core/modules/filters/lookup.js index 3ab7f42e6..49c8e205a 100644 --- a/core/modules/filters/lookup.js +++ b/core/modules/filters/lookup.js @@ -22,7 +22,7 @@ Export our filter function exports.lookup = function(source,operator,options) { var results = []; source(function(tiddler,title) { - results.push(options.wiki.getTiddlerText(operator.operand + title) || options.wiki.getTiddlerText(operator.operand + operator.suffix)); + results.push(options.wiki.getTiddlerText(operator.operand + title) || operator.suffix); }); return results; }; diff --git a/core/modules/filters/math.js b/core/modules/filters/math.js index ac2b40117..f52a8c678 100644 --- a/core/modules/filters/math.js +++ b/core/modules/filters/math.js @@ -91,6 +91,20 @@ exports.exponential = makeNumericBinaryOperator( function(a,b) {return Number.prototype.toExponential.call(a,Math.min(Math.max(b,0),100));} ); +exports.power = makeNumericBinaryOperator( + function(a,b) {return Math.pow(a,b);} +); + +exports.log = makeNumericBinaryOperator( + function(a,b) { + if(b) { + return Math.log(a)/Math.log(b); + } else { + return Math.log(a); + } + } +); + exports.sum = makeNumericReducingOperator( function(accumulator,value) {return accumulator + value}, 0 // Initial value diff --git a/core/modules/filters/reduce.js b/core/modules/filters/reduce.js index 74d1131eb..fd5ccf568 100644 --- a/core/modules/filters/reduce.js +++ b/core/modules/filters/reduce.js @@ -23,7 +23,7 @@ exports.reduce = function(source,operator,options) { }); // Run the filter over each item var filterFn = options.wiki.compileFilter(operator.operand), - accumulator = operator.suffix || ""; + accumulator = operator.operands[1] || ""; for(var index=0; index= targetLength) { + results.push(title); + } else { + var padString = "", + padStringLength = targetLength - title.length; + while (padStringLength > padString.length) { + padString += fill; + } + //make sure we do not exceed the specified length + padString = padString.slice(0,padStringLength); + if(operator.suffix && (operator.suffix === "suffix")) { + title = title + padString; + } else { + title = padString + title; + } + results.push(title); + } + } + }); + return results; +} + })(); diff --git a/core/modules/filters/x-listops.js b/core/modules/filters/x-listops.js index 5b3a9aba1..cb8c031a2 100644 --- a/core/modules/filters/x-listops.js +++ b/core/modules/filters/x-listops.js @@ -188,23 +188,25 @@ Extended filter operators to manipulate the current list. return set; }; - var cycleValueInArray = function(results,operands) { + var cycleValueInArray = function(results,operands,stepSize) { var resultsIndex, + step = stepSize || 1, i = 0, + opLength = operands.length, nextOperandIndex; - for(i; i < operands.length; i++) { + for(i; i < opLength; i++) { resultsIndex = results.indexOf(operands[i]); if(resultsIndex !== -1) { break; } } if(resultsIndex !== -1) { - i++; - nextOperandIndex = (i === operands.length ? 0 : i); + i = i + step; + nextOperandIndex = (i < opLength ? i : i - opLength); if(operands.length > 1) { results.splice(resultsIndex,1,operands[nextOperandIndex]); } else { - results.splice(resultsIndex,1,); + results.splice(resultsIndex,1); } } else { results.push(operands[0]); @@ -221,11 +223,13 @@ Extended filter operators to manipulate the current list. exports.cycle = function(source,operator) { var results = prepare_results(source), - operands = (operator.operand.length ? $tw.utils.parseStringArray(operator.operand, "true") : [""]); - if(operator.suffix === "reverse") { + operands = (operator.operand.length ? $tw.utils.parseStringArray(operator.operand, "true") : [""]), + step = $tw.utils.getInt(operator.operands[1]||"",1); + if(step < 0) { operands.reverse(); - } - return cycleValueInArray(results,operands); + step = Math.abs(step); + } + return cycleValueInArray(results,operands,step); } -})(); \ No newline at end of file +})(); diff --git a/core/modules/info/platform.js b/core/modules/info/platform.js index 29ebdd594..b9c140956 100644 --- a/core/modules/info/platform.js +++ b/core/modules/info/platform.js @@ -12,7 +12,7 @@ Initialise basic platform $:/info/ tiddlers /*global $tw: false */ "use strict"; -exports.getInfoTiddlerFields = function() { +exports.getInfoTiddlerFields = function(updateInfoTiddlersCallback) { var mapBoolean = function(value) {return value ? "yes" : "no";}, infoTiddlerFields = []; // Basics @@ -36,6 +36,13 @@ exports.getInfoTiddlerFields = function() { // Screen size infoTiddlerFields.push({title: "$:/info/browser/screen/width", text: window.screen.width.toString()}); infoTiddlerFields.push({title: "$:/info/browser/screen/height", text: window.screen.height.toString()}); + // Dark mode through event listener on MediaQueryList + var mqList = window.matchMedia("(prefers-color-scheme: dark)"), + getDarkModeTiddler = function() {return {title: "$:/info/darkmode", text: mqList.matches ? "yes" : "no"};}; + infoTiddlerFields.push(getDarkModeTiddler()); + mqList.addListener(function(event) { + updateInfoTiddlersCallback([getDarkModeTiddler()]); + }); // Language infoTiddlerFields.push({title: "$:/info/browser/language", text: navigator.language || ""}); } diff --git a/core/modules/parsers/wikiparser/wikiparser.js b/core/modules/parsers/wikiparser/wikiparser.js index 673176038..dbeed9de2 100644 --- a/core/modules/parsers/wikiparser/wikiparser.js +++ b/core/modules/parsers/wikiparser/wikiparser.js @@ -386,22 +386,18 @@ Amend the rules used by this instance of the parser WikiParser.prototype.amendRules = function(type,names) { names = names || []; // Define the filter function - var keepFilter; + var target; if(type === "only") { - keepFilter = function(name) { - return names.indexOf(name) !== -1; - }; + target = true; } else if(type === "except") { - keepFilter = function(name) { - return names.indexOf(name) === -1; - }; + target = false; } else { return; } // Define a function to process each of our rule arrays var processRuleArray = function(ruleArray) { for(var t=ruleArray.length-1; t>=0; t--) { - if(!keepFilter(ruleArray[t].rule.name)) { + if((names.indexOf(ruleArray[t].rule.name) === -1) === target) { ruleArray.splice(t,1); } } diff --git a/core/modules/saver-handler.js b/core/modules/saver-handler.js index a4b7f4a4e..e2ac21361 100644 --- a/core/modules/saver-handler.js +++ b/core/modules/saver-handler.js @@ -197,8 +197,12 @@ SaverHandler.prototype.isDirty = function() { Update the document body with the class "tc-dirty" if the wiki has unsaved/unsynced changes */ SaverHandler.prototype.updateDirtyStatus = function() { + var self = this; if($tw.browser) { $tw.utils.toggleClass(document.body,"tc-dirty",this.isDirty()); + $tw.utils.each($tw.windows,function(win) { + $tw.utils.toggleClass(win.document.body,"tc-dirty",self.isDirty()); + }); } }; diff --git a/core/modules/savers/github.js b/core/modules/savers/github.js index 7585db34e..2276a2346 100644 --- a/core/modules/savers/github.js +++ b/core/modules/savers/github.js @@ -26,12 +26,13 @@ GitHubSaver.prototype.save = function(text,method,callback) { repo = this.wiki.getTiddlerText("$:/GitHub/Repo"), path = this.wiki.getTiddlerText("$:/GitHub/Path",""), filename = this.wiki.getTiddlerText("$:/GitHub/Filename"), - branch = this.wiki.getTiddlerText("$:/GitHub/Branch") || "master", + branch = this.wiki.getTiddlerText("$:/GitHub/Branch") || "main", endpoint = this.wiki.getTiddlerText("$:/GitHub/ServerURL") || "https://api.github.com", headers = { "Accept": "application/vnd.github.v3+json", "Content-Type": "application/json;charset=UTF-8", - "Authorization": "Basic " + window.btoa(username + ":" + password) + "Authorization": "Basic " + window.btoa(username + ":" + password), + "If-None-Match": "" }; // Bail if we don't have everything we need if(!username || !password || !repo || !filename) { diff --git a/core/modules/server/routes/get-tiddlers-json.js b/core/modules/server/routes/get-tiddlers-json.js index 7b8f63e8e..a44fa3a3c 100644 --- a/core/modules/server/routes/get-tiddlers-json.js +++ b/core/modules/server/routes/get-tiddlers-json.js @@ -29,6 +29,9 @@ exports.handler = function(request,response,state) { } } filter = filter + "-[subfilter{$:/config/Server/GlobalExclusionFilter}]"; + if(state.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "no") { + filter += "+[!is[system]]"; + } var excludeFields = (state.queryParameters.exclude || "text").split(","), titles = state.wiki.filterTiddlers(filter); response.writeHead(200, {"Content-Type": "application/json"}); diff --git a/core/modules/startup/info.js b/core/modules/startup/info.js index 7efaa5b0e..ed2305930 100644 --- a/core/modules/startup/info.js +++ b/core/modules/startup/info.js @@ -21,29 +21,37 @@ exports.synchronous = true; var TITLE_INFO_PLUGIN = "$:/temp/info-plugin"; exports.startup = function() { + // Function to bake the info plugin with new tiddlers + var updateInfoPlugin = function(tiddlerFieldsArray) { + // Get the existing tiddlers + var json = $tw.wiki.getTiddlerData(TITLE_INFO_PLUGIN,{tiddlers: {}}); + // Add the new ones + $tw.utils.each(tiddlerFieldsArray,function(fields) { + if(fields && fields.title) { + json.tiddlers[fields.title] = fields; + } + }); + // Bake the info tiddlers into a plugin. We use the non-standard plugin-type "info" because ordinary plugins are only registered asynchronously after being loaded dynamically + var fields = { + title: TITLE_INFO_PLUGIN, + type: "application/json", + "plugin-type": "info", + text: JSON.stringify(json,null,$tw.config.preferences.jsonSpaces) + }; + $tw.wiki.addTiddler(new $tw.Tiddler(fields)); + + }; // Collect up the info tiddlers - var infoTiddlerFields = {}; - // Give each info module a chance to fill in as many info tiddlers as they want + var tiddlerFieldsArray = []; + // Give each info module a chance to provide as many info tiddlers as they want as an array, and give them a callback for dynamically updating them $tw.modules.forEachModuleOfType("info",function(title,moduleExports) { if(moduleExports && moduleExports.getInfoTiddlerFields) { - var tiddlerFieldsArray = moduleExports.getInfoTiddlerFields(infoTiddlerFields); - $tw.utils.each(tiddlerFieldsArray,function(fields) { - if(fields) { - infoTiddlerFields[fields.title] = fields; - } - }); + Array.prototype.push.apply(tiddlerFieldsArray,moduleExports.getInfoTiddlerFields(updateInfoPlugin)); } }); - // Bake the info tiddlers into a plugin. We use the non-standard plugin-type "info" because ordinary plugins are only registered asynchronously after being loaded dynamically - var fields = { - title: TITLE_INFO_PLUGIN, - type: "application/json", - "plugin-type": "info", - text: JSON.stringify({tiddlers: infoTiddlerFields},null,$tw.config.preferences.jsonSpaces) - }; - $tw.wiki.addTiddler(new $tw.Tiddler(fields)); - $tw.wiki.readPluginInfo([TITLE_INFO_PLUGIN]); - $tw.wiki.registerPluginTiddlers("info"); + updateInfoPlugin(tiddlerFieldsArray); + var changes = $tw.wiki.readPluginInfo([TITLE_INFO_PLUGIN]); + $tw.wiki.registerPluginTiddlers("info",[TITLE_INFO_PLUGIN]); $tw.wiki.unpackPluginTiddlers(); }; diff --git a/core/modules/startup/plugins.js b/core/modules/startup/plugins.js index 907579dbe..cad61b104 100644 --- a/core/modules/startup/plugins.js +++ b/core/modules/startup/plugins.js @@ -24,6 +24,7 @@ var PREFIX_CONFIG_REGISTER_PLUGIN_TYPE = "$:/config/RegisterPluginType/"; exports.startup = function() { $tw.wiki.addTiddler({title: TITLE_REQUIRE_RELOAD_DUE_TO_PLUGIN_CHANGE,text: "no"}); $tw.wiki.addEventListener("change",function(changes) { + // Work out which of the changed tiddlers are plugins that we need to reregister var changesToProcess = [], requireReloadDueToPluginChange = false; $tw.utils.each(Object.keys(changes),function(title) { @@ -38,6 +39,7 @@ exports.startup = function() { } } }); + // Issue warning if any of the tiddlers require a reload if(requireReloadDueToPluginChange) { $tw.wiki.addTiddler({title: TITLE_REQUIRE_RELOAD_DUE_TO_PLUGIN_CHANGE,text: "yes"}); } @@ -45,12 +47,35 @@ exports.startup = function() { if(changesToProcess.length > 0) { var changes = $tw.wiki.readPluginInfo(changesToProcess); if(changes.modifiedPlugins.length > 0 || changes.deletedPlugins.length > 0) { + var changedShadowTiddlers = {}; + // Collect the shadow tiddlers of any deleted plugins + $tw.utils.each(changes.deletedPlugins,function(pluginTitle) { + var pluginInfo = $tw.wiki.getPluginInfo(pluginTitle); + if(pluginInfo) { + $tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) { + changedShadowTiddlers[title] = true; + }); + } + }); + // Collect the shadow tiddlers of any modified plugins + $tw.utils.each(changes.modifiedPlugins,function(pluginTitle) { + var pluginInfo = $tw.wiki.getPluginInfo(pluginTitle); + if(pluginInfo) { + $tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) { + changedShadowTiddlers[title] = false; + }); + } + }); // (Re-)register any modified plugins $tw.wiki.registerPluginTiddlers(null,changes.modifiedPlugins); // Unregister any deleted plugins $tw.wiki.unregisterPluginTiddlers(null,changes.deletedPlugins); // Unpack the shadow tiddlers $tw.wiki.unpackPluginTiddlers(); + // Queue change events for the changed shadow tiddlers + $tw.utils.each(Object.keys(changedShadowTiddlers),function(title) { + $tw.wiki.enqueueTiddlerEvent(title,changedShadowTiddlers[title]); + }); } } }); diff --git a/core/modules/startup/render.js b/core/modules/startup/render.js index 7ec6ec444..fa4d21003 100644 --- a/core/modules/startup/render.js +++ b/core/modules/startup/render.js @@ -107,7 +107,7 @@ exports.startup = function() { $tw.rootWidget.domNodes = [$tw.pageContainer]; $tw.rootWidget.children = [$tw.pageWidgetNode]; // Run any post-render startup actions - $tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction/PostRender"); + $tw.rootWidget.invokeActionsByTag("$:/tags/StartupAction/PostRender"); }; })(); diff --git a/core/modules/startup/rootwidget.js b/core/modules/startup/rootwidget.js index d02748b28..353c25958 100644 --- a/core/modules/startup/rootwidget.js +++ b/core/modules/startup/rootwidget.js @@ -25,6 +25,9 @@ exports.startup = function() { $tw.rootWidget.addEventListener("tm-modal",function(event) { $tw.modal.display(event.param,{variables: event.paramObject, event: event}); }); + $tw.rootWidget.addEventListener("tm-show-switcher",function(event) { + $tw.modal.display("$:/core/ui/SwitcherModal",{variables: event.paramObject, event: event}); + }); // Install the notification mechanism $tw.notifier = new $tw.utils.Notifier($tw.wiki); $tw.rootWidget.addEventListener("tm-notify",function(event) { diff --git a/core/modules/startup/startup.js b/core/modules/startup/startup.js index b7897a5ce..781852cea 100755 --- a/core/modules/startup/startup.js +++ b/core/modules/startup/startup.js @@ -64,12 +64,12 @@ exports.startup = function() { document: $tw.browser ? document : $tw.fakeDocument }); // Execute any startup actions - $tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction"); + $tw.rootWidget.invokeActionsByTag("$:/tags/StartupAction"); if($tw.browser) { - $tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction/Browser"); + $tw.rootWidget.invokeActionsByTag("$:/tags/StartupAction/Browser"); } if($tw.node) { - $tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction/Node"); + $tw.rootWidget.invokeActionsByTag("$:/tags/StartupAction/Node"); } // Kick off the language manager and switcher $tw.language = new $tw.Language(); diff --git a/core/modules/startup/windows.js b/core/modules/startup/windows.js index 16b8f0316..75786d026 100644 --- a/core/modules/startup/windows.js +++ b/core/modules/startup/windows.js @@ -19,7 +19,7 @@ exports.after = ["startup"]; exports.synchronous = true; // Global to keep track of open windows (hashmap by title) -var windows = {}; +$tw.windows = {}; exports.startup = function() { // Handle open window message @@ -44,7 +44,7 @@ exports.startup = function() { catch(e) { return; } - windows[title] = srcWindow; + $tw.windows[title] = srcWindow; // Check for reopening the same window if(srcWindow.haveInitialisedWindow) { return; @@ -54,7 +54,7 @@ exports.startup = function() { srcDocument.close(); srcDocument.title = windowTitle; srcWindow.addEventListener("beforeunload",function(event) { - delete windows[title]; + delete $tw.windows[title]; $tw.wiki.removeEventListener("change",refreshHandler); },false); // Set up the styles @@ -84,16 +84,13 @@ exports.startup = function() { name: "keydown", handlerObject: $tw.keyboardManager, handlerMethod: "handleKeydownEvent" - },{ - name: "click", - handlerObject: $tw.popup, - handlerMethod: "handleEvent" }]); + srcWindow.document.documentElement.addEventListener("click",$tw.popup,true); srcWindow.haveInitialisedWindow = true; }); // Close open windows when unloading main window $tw.addUnloadTask(function() { - $tw.utils.each(windows,function(win) { + $tw.utils.each($tw.windows,function(win) { win.close(); }); }); diff --git a/core/modules/syncer.js b/core/modules/syncer.js index 1ad9c3474..15374d40a 100644 --- a/core/modules/syncer.js +++ b/core/modules/syncer.js @@ -305,7 +305,8 @@ Syncer.prototype.syncFromServer = function() { self.pollTimerId = null; self.syncFromServer.call(self); },self.pollTimerInterval); - }; + }, + syncSystemFromServer = (self.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "yes" ? true : false); if(this.syncadaptor && this.syncadaptor.getUpdatedTiddlers) { this.logger.log("Retrieving updated tiddler list"); cancelNextSync(); @@ -320,9 +321,11 @@ Syncer.prototype.syncFromServer = function() { self.titlesToBeLoaded[title] = true; }); $tw.utils.each(updates.deletions,function(title) { - delete self.tiddlerInfo[title]; - self.logger.log("Deleting tiddler missing from server:",title); - self.wiki.deleteTiddler(title); + if(syncSystemFromServer || !self.wiki.isSystemTiddler(title)) { + delete self.tiddlerInfo[title]; + self.logger.log("Deleting tiddler missing from server:",title); + self.wiki.deleteTiddler(title); + } }); if(updates.modifications.length > 0 || updates.deletions.length > 0) { self.processTaskQueue(); @@ -365,9 +368,11 @@ Syncer.prototype.syncFromServer = function() { } // Delete any tiddlers that were previously reported but missing this time $tw.utils.each(previousTitles,function(title) { - delete self.tiddlerInfo[title]; - self.logger.log("Deleting tiddler missing from server:",title); - self.wiki.deleteTiddler(title); + if(syncSystemFromServer || !self.wiki.isSystemTiddler(title)) { + delete self.tiddlerInfo[title]; + self.logger.log("Deleting tiddler missing from server:",title); + self.wiki.deleteTiddler(title); + } }); self.processTaskQueue(); }); @@ -628,6 +633,10 @@ DeleteTiddlerTask.prototype.run = function(callback) { } // Remove the info stored about this tiddler delete self.syncer.tiddlerInfo[self.title]; + if($tw.boot.files){ + // Remove the tiddler from $tw.boot.files + delete $tw.boot.files[self.title]; + } // Invoke the callback callback(null); },{ diff --git a/core/modules/upgraders/plugins.js b/core/modules/upgraders/plugins.js index 83c762897..a7dd02982 100644 --- a/core/modules/upgraders/plugins.js +++ b/core/modules/upgraders/plugins.js @@ -57,7 +57,7 @@ exports.upgrade = function(wiki,titles,tiddlers) { // Reject the incoming plugin by blanking all its fields if($tw.utils.checkVersions(existingTiddler.fields.version,incomingTiddler.version)) { tiddlers[title] = Object.create(null); - messages[title] = requiresReload + $tw.language.getString("Import/Upgrader/Plugins/Suppressed/Version",{variables: {incoming: incomingTiddler.version, existing: existingTiddler.fields.version}}); + messages[title] = $tw.language.getString("Import/Upgrader/Plugins/Suppressed/Version",{variables: {incoming: incomingTiddler.version, existing: existingTiddler.fields.version}}); return; } } diff --git a/core/modules/utils/filesystem.js b/core/modules/utils/filesystem.js index df820a63c..9ee2e8acd 100644 --- a/core/modules/utils/filesystem.js +++ b/core/modules/utils/filesystem.js @@ -204,15 +204,19 @@ exports.deleteEmptyDirs = function(dirpath,callback) { /* Create a fileInfo object for saving a tiddler: filepath: the absolute path to the file containing the tiddler - type: the type of the tiddler file (NOT the type of the tiddler) + type: the type of the tiddler file on disk (NOT the type of the tiddler) hasMetaFile: true if the file also has a companion .meta file + isEditableFile: true if the tiddler was loaded via non-standard options & marked editable Options include: directory: absolute path of root directory to which we are saving pathFilters: optional array of filters to be used to generate the base path - wiki: optional wiki for evaluating the pathFilters + extFilters: optional array of filters to be used to generate the base path + wiki: optional wiki for evaluating the pathFilters, + fileInfo: an existing fileInfo to check against + originalpath: a preferred filepath if no pathFilters match */ exports.generateTiddlerFileInfo = function(tiddler,options) { - var fileInfo = {}; + var fileInfo = {}, metaExt; // Check if the tiddler has any unsafe fields that can't be expressed in a .tid or .meta file: containing control characters, or leading/trailing whitespace var hasUnsafeFields = false; $tw.utils.each(tiddler.getFieldStrings(),function(value,fieldName) { @@ -238,19 +242,71 @@ exports.generateTiddlerFileInfo = function(tiddler,options) { fileInfo.type = tiddlerType; fileInfo.hasMetaFile = true; } + if(options.extFilters) { + // Check for extension override + metaExt = $tw.utils.generateTiddlerExtension(tiddler.fields.title,{ + extFilters: options.extFilters, + wiki: options.wiki + }); + if(metaExt === ".tid") { + // Overriding to the .tid extension needs special handling + fileInfo.type = "application/x-tiddler"; + fileInfo.hasMetaFile = false; + } else if (metaExt === ".json") { + // Overriding to the .json extension needs special handling + fileInfo.type = "application/json"; + fileInfo.hasMetaFile = false; + } else if (metaExt) { + //If the new type matches a known extention, use that MIME type's encoding + var extInfo = $tw.utils.getFileExtensionInfo(metaExt); + fileInfo.type = extInfo ? extInfo.type : null; + fileInfo.encoding = $tw.utils.getTypeEncoding(metaExt); + fileInfo.hasMetaFile = true; + } + } } - // Take the file extension from the tiddler content type + // Take the file extension from the tiddler content type or metaExt var contentTypeInfo = $tw.config.contentTypeInfo[fileInfo.type] || {extension: ""}; // Generate the filepath fileInfo.filepath = $tw.utils.generateTiddlerFilepath(tiddler.fields.title,{ - extension: contentTypeInfo.extension, + extension: metaExt || contentTypeInfo.extension, directory: options.directory, pathFilters: options.pathFilters, - wiki: options.wiki + wiki: options.wiki, + fileInfo: options.fileInfo, + originalpath: options.originalpath }); + // Propigate the isEditableFile flag + if(options.fileInfo) { + fileInfo.isEditableFile = options.fileInfo.isEditableFile || false; + } return fileInfo; }; +/* +Generate the file extension for saving a tiddler +Options include: + extFilters: optional array of filters to be used to generate the extention + wiki: optional wiki for evaluating the extFilters +*/ +exports.generateTiddlerExtension = function(title,options) { + var self = this, + extension; + // Check if any of the extFilters applies + if(options.extFilters && options.wiki) { + $tw.utils.each(options.extFilters,function(filter) { + if(!extension) { + var source = options.wiki.makeTiddlerIterator([title]), + result = options.wiki.filterTiddlers(filter,null,source); + if(result.length > 0) { + extension = result[0]; + } + } + }); + } + return extension; +}; + /* Generate the filepath for saving a tiddler Options include: @@ -258,12 +314,14 @@ Options include: directory: absolute path of root directory to which we are saving pathFilters: optional array of filters to be used to generate the base path wiki: optional wiki for evaluating the pathFilters + fileInfo: an existing fileInfo object to check against */ exports.generateTiddlerFilepath = function(title,options) { var self = this, directory = options.directory || "", extension = options.extension || "", - filepath; + originalpath = options.originalpath || "", + filepath; // Check if any of the pathFilters applies if(options.pathFilters && options.wiki) { $tw.utils.each(options.pathFilters,function(filter) { @@ -276,8 +334,11 @@ exports.generateTiddlerFilepath = function(title,options) { } }); } - // If not, generate a base pathname - if(!filepath) { + if(!filepath && originalpath !== "") { + //Use the originalpath without the extension + var ext = path.extname(originalpath); + filepath = originalpath.substring(0,originalpath.length - ext.length);; + } else if(!filepath) { filepath = title; // If the filepath already ends in the extension then remove it if(filepath.substring(filepath.length - extension.length) === extension) { @@ -286,10 +347,13 @@ exports.generateTiddlerFilepath = function(title,options) { // Remove any forward or backward slashes so we don't create directories filepath = filepath.replace(/\/|\\/g,"_"); } - // Don't let the filename start with a dot because such files are invisible on *nix - filepath = filepath.replace(/^\./g,"_"); + //If the path does not start with "." or ".." and a path seperator, then + if(!/^\.{1,2}[/\\]/g.test(filepath)) { + // Don't let the filename start with any dots because such files are invisible on *nix + filepath = filepath.replace(/^\.+/g,"_"); + } // Remove any characters that can't be used in cross-platform filenames - filepath = $tw.utils.transliterate(filepath.replace(/<|>|\:|\"|\||\?|\*|\^/g,"_")); + filepath = $tw.utils.transliterate(filepath.replace(/<|>|~|\:|\"|\||\?|\*|\^/g,"_")); // Truncate the filename if it is too long if(filepath.length > 200) { filepath = filepath.substr(0,200); @@ -306,12 +370,21 @@ exports.generateTiddlerFilepath = function(title,options) { }); } // Add a uniquifier if the file already exists - var fullPath, + var fullPath, oldPath = (options.fileInfo) ? options.fileInfo.filepath : undefined, count = 0; do { fullPath = path.resolve(directory,filepath + (count ? "_" + count : "") + extension); + if(oldPath && oldPath == fullPath) { + break; + } count++; } while(fs.existsSync(fullPath)); + //If the path does not start with the wikiPath directory or the wikiTiddlersPath directory, or if the last write failed + var encode = !(fullPath.indexOf($tw.boot.wikiPath) == 0 || fullPath.indexOf($tw.boot.wikiTiddlersPath) == 0) || ((options.fileInfo || {writeError: false}).writeError == true); + if(encode){ + //encodeURIComponent() and then resolve to tiddler directory + fullPath = path.resolve(directory, encodeURIComponent(fullPath)); + } // Return the full path to the file return fullPath; }; @@ -366,4 +439,58 @@ exports.saveTiddlerToFileSync = function(tiddler,fileInfo) { } }; +/* +Delete a file described by the fileInfo if it exits +*/ +exports.deleteTiddlerFile = function(fileInfo, callback) { + //Only attempt to delete files that exist on disk + if(!fileInfo.filepath || !fs.existsSync(fileInfo.filepath)) { + return callback(null); + } + // Delete the file + fs.unlink(fileInfo.filepath,function(err) { + if(err) { + return callback(err); + } + // Delete the metafile if present + if(fileInfo.hasMetaFile && fs.existsSync(fileInfo.filepath + ".meta")) { + fs.unlink(fileInfo.filepath + ".meta",function(err) { + if(err) { + return callback(err); + } + return $tw.utils.deleteEmptyDirs(path.dirname(fileInfo.filepath),callback); + }); + } else { + return $tw.utils.deleteEmptyDirs(path.dirname(fileInfo.filepath),callback); + } + }); +}; + +/* +Cleanup old files on disk, by comparing the options values: + adaptorInfo from $tw.syncer.tiddlerInfo + bootInfo from $tw.boot.files +*/ +exports.cleanupTiddlerFiles = function(options, callback) { + var adaptorInfo = options.adaptorInfo || {}, + bootInfo = options.bootInfo || {}, + title = options.title || "undefined"; + if(adaptorInfo.filepath && bootInfo.filepath && adaptorInfo.filepath !== bootInfo.filepath) { + return $tw.utils.deleteTiddlerFile(adaptorInfo, function(err){ + if(err) { + if ((err.code == "EPERM" || err.code == "EACCES") && err.syscall == "unlink") { + // Error deleting the previous file on disk, should fail gracefully + $tw.syncer.displayError("Server desynchronized. Error cleaning up previous file for tiddler: "+title, err); + return callback(null); + } else { + return callback(err); + } + } + return callback(null); + }); + } else { + return callback(null); + } +}; + })(); diff --git a/core/modules/utils/utils.js b/core/modules/utils/utils.js index a606c2a2a..14d251f01 100644 --- a/core/modules/utils/utils.js +++ b/core/modules/utils/utils.js @@ -302,7 +302,7 @@ exports.formatDateString = function(date,template) { return $tw.utils.pad($tw.utils.getHours12(date)); }], [/^wYYYY/, function() { - return $tw.utils.getYearForWeekNo(date); + return $tw.utils.pad($tw.utils.getYearForWeekNo(date),4); }], [/^hh12/, function() { return $tw.utils.getHours12(date); @@ -311,7 +311,14 @@ exports.formatDateString = function(date,template) { return date.getDate() + $tw.utils.getDaySuffix(date); }], [/^YYYY/, function() { - return date.getFullYear(); + return $tw.utils.pad(date.getFullYear(),4); + }], + [/^aYYYY/, function() { + return $tw.utils.pad(Math.abs(date.getFullYear()),4); + }], + [/^\{era:([^,\|}]*)\|([^}\|]*)\|([^}]*)\}/, function(match) { + var year = date.getFullYear(); + return year === 0 ? match[2] : (year < 0 ? match[1] : match[3]); }], [/^0hh/, function() { return $tw.utils.pad(date.getHours()); @@ -400,7 +407,7 @@ exports.formatDateString = function(date,template) { $tw.utils.each(matches, function(m) { var match = m[0].exec(t); if(match) { - matchString = m[1].call(); + matchString = m[1].call(null,match); t = t.substr(match[0].length); return false; } @@ -557,7 +564,7 @@ exports.escape = function(ch) { // Turns a string into a legal JavaScript string // Copied from peg.js, thanks to David Majda -exports.stringify = function(s) { +exports.stringify = function(s, rawUnicode) { /* * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string * literal except for the closing quote character, backslash, carriage return, @@ -566,19 +573,21 @@ exports.stringify = function(s) { * * For portability, we also escape all non-ASCII characters. */ + var regex = rawUnicode ? /[\x00-\x1f]/g : /[\x00-\x1f\x80-\uFFFF]/g; return (s || "") .replace(/\\/g, '\\\\') // backslash .replace(/"/g, '\\"') // double quote character .replace(/'/g, "\\'") // single quote character .replace(/\r/g, '\\r') // carriage return .replace(/\n/g, '\\n') // line feed - .replace(/[\x00-\x1f\x80-\uFFFF]/g, exports.escape); // non-ASCII characters + .replace(regex, exports.escape); // non-ASCII characters }; // Turns a string into a legal JSON string // Derived from peg.js, thanks to David Majda -exports.jsonStringify = function(s) { +exports.jsonStringify = function(s, rawUnicode) { // See http://www.json.org/ + var regex = rawUnicode ? /[\x00-\x1f]/g : /[\x00-\x1f\x80-\uFFFF]/g; return (s || "") .replace(/\\/g, '\\\\') // backslash .replace(/"/g, '\\"') // double quote character @@ -587,7 +596,7 @@ exports.jsonStringify = function(s) { .replace(/\x08/g, '\\b') // backspace .replace(/\x0c/g, '\\f') // formfeed .replace(/\t/g, '\\t') // tab - .replace(/[\x00-\x1f\x80-\uFFFF]/g,function(s) { + .replace(regex,function(s) { return '\\u' + $tw.utils.pad(s.charCodeAt(0).toString(16).toUpperCase(),4); }); // non-ASCII characters }; diff --git a/core/modules/widgets/action-log.js b/core/modules/widgets/action-log.js index e3027a8e9..216eb1167 100644 --- a/core/modules/widgets/action-log.js +++ b/core/modules/widgets/action-log.js @@ -28,23 +28,66 @@ Render this widget into the DOM */ LogWidget.prototype.render = function(parent,nextSibling) { this.computeAttributes(); + this.execute(); }; +LogWidget.prototype.execute = function(){ + this.message = this.getAttribute("$$message","debug"); + this.logAll = this.getAttribute("$$all","no") === "yes" ? true : false; + this.filter = this.getAttribute("$$filter"); +} + /* Refresh the widget by ensuring our attributes are up to date */ LogWidget.prototype.refresh = function(changedTiddlers) { - return this.refreshChildren(changedTiddlers); + this.refreshSelf(); + return true; }; /* Invoke the action associated with this widget */ LogWidget.prototype.invokeAction = function(triggeringWidget,event) { - $tw.utils.logTable(this.attributes,["attribute name","value"]); + this.log(); return true; // Action was invoked }; +LogWidget.prototype.log = function() { + var data = {}, + dataCount, + allVars = {}, + filteredVars; + + $tw.utils.each(this.attributes,function(attribute,name) { + if(name.substring(0,2) !== "$$") { + data[name] = attribute; + } + }); + + for(var v in this.variables) { + allVars[v] = this.getVariable(v,{defaultValue:""}); + } + if(this.filter) { + filteredVars = this.wiki.compileFilter(this.filter).call(this.wiki,this.wiki.makeTiddlerIterator(allVars)); + $tw.utils.each(filteredVars,function(name) { + data[name] = allVars[name]; + }); + } + dataCount = $tw.utils.count(data); + + console.group(this.message); + if(dataCount > 0) { + $tw.utils.logTable(data,["name","value"]); + } + if(this.logAll || !dataCount) { + console.groupCollapsed("All variables"); + $tw.utils.logTable(allVars,["name","value"]); + console.groupEnd(); + } + console.groupEnd(); +} + exports["action-log"] = LogWidget; })(); diff --git a/core/modules/widgets/button.js b/core/modules/widgets/button.js index 0294ac0ba..5b15c875f 100644 --- a/core/modules/widgets/button.js +++ b/core/modules/widgets/button.js @@ -27,18 +27,20 @@ ButtonWidget.prototype = new Widget(); Render this widget into the DOM */ ButtonWidget.prototype.render = function(parent,nextSibling) { - var self = this; + var self = this, + tag = "button", + domNode; // Remember parent this.parentDomNode = parent; // Compute attributes and execute state this.computeAttributes(); this.execute(); // Create element - var tag = "button"; if(this.buttonTag && $tw.config.htmlUnsafeElements.indexOf(this.buttonTag) === -1) { tag = this.buttonTag; } - var domNode = this.document.createElement(tag); + domNode = this.document.createElement(tag); + this.domNode = domNode; // Assign classes var classes = this["class"].split(" ") || [], isPoppedUp = (this.popup || this.popupTitle) && this.isPoppedUp(); @@ -200,10 +202,10 @@ ButtonWidget.prototype.execute = function() { this.setTo = this.getAttribute("setTo"); this.popup = this.getAttribute("popup"); this.hover = this.getAttribute("hover"); - this["class"] = this.getAttribute("class",""); this["aria-label"] = this.getAttribute("aria-label"); this.tooltip = this.getAttribute("tooltip"); this.style = this.getAttribute("style"); + this["class"] = this.getAttribute("class",""); this.selectedClass = this.getAttribute("selectedClass"); this.defaultSetValue = this.getAttribute("default",""); this.buttonTag = this.getAttribute("tag"); @@ -219,14 +221,34 @@ ButtonWidget.prototype.execute = function() { this.makeChildWidgets(); }; +ButtonWidget.prototype.updateDomNodeClasses = function() { + var domNodeClasses = this.domNode.className.split(" "), + oldClasses = this.class.split(" "), + newClasses; + this["class"] = this.getAttribute("class",""); + newClasses = this.class.split(" "); + //Remove classes assigned from the old value of class attribute + $tw.utils.each(oldClasses,function(oldClass){ + var i = domNodeClasses.indexOf(oldClass); + if(i !== -1) { + domNodeClasses.splice(i,1); + } + }); + //Add new classes from updated class attribute. + $tw.utils.pushTop(domNodeClasses,newClasses); + this.domNode.className = domNodeClasses.join(" "); +} + /* Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering */ ButtonWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); - if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes["class"] || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled) { + if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled) { this.refreshSelf(); return true; + } else if(changedAttributes["class"]) { + this.updateDomNodeClasses(); } return this.refreshChildren(changedTiddlers); }; diff --git a/core/modules/widgets/droppable.js b/core/modules/widgets/droppable.js index e6678527b..87a130f39 100644 --- a/core/modules/widgets/droppable.js +++ b/core/modules/widgets/droppable.js @@ -27,21 +27,21 @@ DroppableWidget.prototype = new Widget(); Render this widget into the DOM */ DroppableWidget.prototype.render = function(parent,nextSibling) { - var self = this; + var self = this, + tag = this.parseTreeNode.isBlock ? "div" : "span", + domNode; // Remember parent this.parentDomNode = parent; // Compute attributes and execute state this.computeAttributes(); this.execute(); - var tag = this.parseTreeNode.isBlock ? "div" : "span"; if(this.droppableTag && $tw.config.htmlUnsafeElements.indexOf(this.droppableTag) === -1) { tag = this.droppableTag; } // Create element and assign classes - var domNode = this.document.createElement(tag), - classes = (this.droppableClass || "").split(" "); - classes.push("tc-droppable"); - domNode.className = classes.join(" "); + domNode = this.document.createElement(tag); + this.domNode = domNode; + this.assignDomNodeClasses(); // Add event handlers if(this.droppableEnable) { $tw.utils.addEventListeners(domNode,[ @@ -144,20 +144,27 @@ DroppableWidget.prototype.execute = function() { this.droppableActions = this.getAttribute("actions"); this.droppableEffect = this.getAttribute("effect","copy"); this.droppableTag = this.getAttribute("tag"); - this.droppableClass = this.getAttribute("class"); this.droppableEnable = (this.getAttribute("enable") || "yes") === "yes"; // Make child widgets this.makeChildWidgets(); }; +DroppableWidget.prototype.assignDomNodeClasses = function() { + var classes = this.getAttribute("class","").split(" "); + classes.push("tc-droppable"); + this.domNode.className = classes.join(" "); +}; + /* Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering */ DroppableWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); - if(changedAttributes["class"] || changedAttributes.tag || changedAttributes.enable) { + if(changedAttributes.tag || changedAttributes.enable) { this.refreshSelf(); return true; + } else if(changedAttributes["class"]) { + this.assignDomNodeClasses(); } return this.refreshChildren(changedTiddlers); }; diff --git a/core/modules/widgets/edit.js b/core/modules/widgets/edit.js index 6ee918170..e7bd49b93 100644 --- a/core/modules/widgets/edit.js +++ b/core/modules/widgets/edit.js @@ -51,6 +51,7 @@ EditWidget.prototype.execute = function() { this.editCancelPopups = this.getAttribute("cancelPopups",""); this.editInputActions = this.getAttribute("inputActions"); this.editRefreshTitle = this.getAttribute("refreshTitle"); + this.editAutoComplete = this.getAttribute("autocomplete"); // Choose the appropriate edit widget this.editorType = this.getEditorType(); // Make the child widgets @@ -89,7 +90,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of EditWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); // Refresh if an attribute has changed, or the type associated with the target tiddler has changed - if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) { + if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) { this.refreshSelf(); return true; } else { diff --git a/core/modules/widgets/eventcatcher.js b/core/modules/widgets/eventcatcher.js new file mode 100644 index 000000000..c014f8997 --- /dev/null +++ b/core/modules/widgets/eventcatcher.js @@ -0,0 +1,156 @@ +/*\ +title: $:/core/modules/widgets/eventcatcher.js +type: application/javascript +module-type: widget + +Event handler widget + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +var Widget = require("$:/core/modules/widgets/widget.js").widget; + +var EventWidget = function(parseTreeNode,options) { + this.initialise(parseTreeNode,options); +}; + +/* +Inherit from the base widget class +*/ +EventWidget.prototype = new Widget(); + +/* +Render this widget into the DOM +*/ +EventWidget.prototype.render = function(parent,nextSibling) { + var self = this; + // Remember parent + this.parentDomNode = parent; + // Compute attributes and execute state + this.computeAttributes(); + this.execute(); + // Create element + var tag = this.parseTreeNode.isBlock ? "div" : "span"; + if(this.elementTag && $tw.config.htmlUnsafeElements.indexOf(this.elementTag) === -1) { + tag = this.elementTag; + } + var domNode = this.document.createElement(tag); + this.domNode = domNode; + // Assign classes + this.assignDomNodeClasses(); + // Add our event handler + $tw.utils.each(this.types,function(type) { + domNode.addEventListener(type,function(event) { + var selector = self.getAttribute("selector"), + actions = self.getAttribute("actions-"+type), + selectedNode = event.target, + selectedNodeRect, + catcherNodeRect, + variables = {}; + if(selector) { + // Search ancestors for a node that matches the selector + while(!selectedNode.matches(selector) && selectedNode !== domNode) { + selectedNode = selectedNode.parentNode; + } + // If we found one, copy the attributes as variables, otherwise exit + if(selectedNode.matches(selector)) { + $tw.utils.each(selectedNode.attributes,function(attribute) { + variables["dom-" + attribute.name] = attribute.value.toString(); + }); + //Add a variable with a popup coordinate string for the selected node + variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")"; + + //Add variables for offset of selected node + variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString(); + variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString(); + variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString(); + variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString(); + + //Add variables for event X and Y position relative to selected node + selectedNodeRect = selectedNode.getBoundingClientRect(); + variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString(); + variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString(); + + //Add variables for event X and Y position relative to event catcher node + catcherNodeRect = self.domNode.getBoundingClientRect(); + variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString(); + variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString(); + } else { + return false; + } + } + // Execute our actions with the variables + if(actions) { + // Add a variable for the modifier key + variables.modifier = $tw.keyboardManager.getEventModifierKeyDescriptor(event); + // Add a variable for the mouse button + if("button" in event) { + if(event.button === 0) { + variables["event-mousebutton"] = "left"; + } else if(event.button === 1) { + variables["event-mousebutton"] = "middle"; + } else if(event.button === 2) { + variables["event-mousebutton"] = "right"; + } + } + variables["event-type"] = event.type.toString(); + if(typeof event.detail === "object" && !!event.detail) { + $tw.utils.each(event.detail,function(detailValue,detail) { + variables["event-detail-" + detail] = detailValue.toString(); + }); + } else if(!!event.detail) { + variables["event-detail"] = event.detail.toString(); + } + self.invokeActionString(actions,self,event,variables); + event.preventDefault(); + event.stopPropagation(); + return true; + } + return false; + },false); + }); + // Insert element + parent.insertBefore(domNode,nextSibling); + this.renderChildren(domNode,null); + this.domNodes.push(domNode); +}; + +/* +Compute the internal state of the widget +*/ +EventWidget.prototype.execute = function() { + var self = this; + // Get attributes that require a refresh on change + this.types = this.getAttribute("events","").split(" "); + this.elementTag = this.getAttribute("tag"); + // Make child widgets + this.makeChildWidgets(); +}; + +EventWidget.prototype.assignDomNodeClasses = function() { + var classes = this.getAttribute("class","").split(" "); + classes.push("tc-eventcatcher"); + this.domNode.className = classes.join(" "); +}; + +/* +Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering +*/ +EventWidget.prototype.refresh = function(changedTiddlers) { + var changedAttributes = this.computeAttributes(); + if(changedAttributes["events"] || changedAttributes["tag"]) { + this.refreshSelf(); + return true; + } else if(changedAttributes["class"]) { + this.assignDomNodeClasses(); + } + return this.refreshChildren(changedTiddlers); +}; + +exports.eventcatcher = EventWidget; + +})(); diff --git a/core/modules/widgets/log.js b/core/modules/widgets/log.js new file mode 100644 index 000000000..2615547ad --- /dev/null +++ b/core/modules/widgets/log.js @@ -0,0 +1,30 @@ +/*\ +title: $:/core/modules/widgets/log.js +type: application/javascript +module-type: widget-subclass + +Widget to log debug messages + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +exports.baseClass = "action-log"; + +exports.name = "log"; + +exports.constructor = function(parseTreeNode,options) { + this.initialise(parseTreeNode,options); +} + +exports.prototype = {}; + +exports.prototype.render = function(event) { + Object.getPrototypeOf(Object.getPrototypeOf(this)).render.call(this,event); + Object.getPrototypeOf(Object.getPrototypeOf(this)).log.call(this); +} + +})(); \ No newline at end of file diff --git a/core/modules/widgets/navigator.js b/core/modules/widgets/navigator.js index 189765396..2f8e2421e 100755 --- a/core/modules/widgets/navigator.js +++ b/core/modules/widgets/navigator.js @@ -128,7 +128,7 @@ NavigatorWidget.prototype.replaceFirstTitleInStory = function(storyList,oldTitle NavigatorWidget.prototype.addToStory = function(title,fromTitle) { if(this.storyTitle) { - this.story.addToStory(title,fromTitle,this.storyTitle,{ + this.story.addToStory(title,fromTitle,{ openLinkFromInsideRiver: this.getAttribute("openLinkFromInsideRiver","top"), openLinkFromOutsideRiver: this.getAttribute("openLinkFromOutsideRiver","top") }); @@ -529,6 +529,7 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) { $tw.utils.each(importData.tiddlers,function(tiddler,title) { if($tw.utils.count(tiddler) === 0) { newFields["selection-" + title] = "unchecked"; + newFields["suppressed-" + title] = "yes"; } }); // Save the $:/Import tiddler diff --git a/core/modules/widgets/radio.js b/core/modules/widgets/radio.js index c22aa5ecb..43b6e5dab 100644 --- a/core/modules/widgets/radio.js +++ b/core/modules/widgets/radio.js @@ -13,7 +13,6 @@ Set a field or index at a given tiddler via radio buttons "use strict"; var Widget = require("$:/core/modules/widgets/widget.js").widget; - var RadioWidget = function(parseTreeNode,options) { this.initialise(parseTreeNode,options); }; @@ -37,8 +36,8 @@ RadioWidget.prototype.render = function(parent,nextSibling) { // Create our elements this.labelDomNode = this.document.createElement("label"); this.labelDomNode.setAttribute("class", - "tc-radio " + this.radioClass + (isChecked ? " tc-radio-selected" : "") - ); + "tc-radio " + this.radioClass + (isChecked ? " tc-radio-selected" : "") + ); this.inputDomNode = this.document.createElement("input"); this.inputDomNode.setAttribute("type","radio"); if(isChecked) { @@ -86,6 +85,10 @@ RadioWidget.prototype.handleChangeEvent = function(event) { if(this.inputDomNode.checked) { this.setValue(); } + // Trigger actions + if(this.radioActions) { + this.invokeActionString(this.radioActions,this,event,{"actionValue": this.radioValue}); + } }; /* @@ -99,6 +102,7 @@ RadioWidget.prototype.execute = function() { this.radioValue = this.getAttribute("value"); this.radioClass = this.getAttribute("class",""); this.isDisabled = this.getAttribute("disabled","no"); + this.radioActions = this.getAttribute("actions",""); // Make the child widgets this.makeChildWidgets(); }; @@ -108,16 +112,11 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of */ RadioWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); - if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.value || changedAttributes["class"] || changedAttributes.disabled) { + if(($tw.utils.count(changedAttributes) > 0) || changedTiddlers[this.radioTitle]) { this.refreshSelf(); return true; } else { - var refreshed = false; - if(changedTiddlers[this.radioTitle]) { - this.inputDomNode.checked = this.getValue() === this.radioValue; - refreshed = true; - } - return this.refreshChildren(changedTiddlers) || refreshed; + return this.refreshChildren(changedTiddlers); } }; diff --git a/core/modules/widgets/range.js b/core/modules/widgets/range.js index 46e12061a..4dd55dc3c 100644 --- a/core/modules/widgets/range.js +++ b/core/modules/widgets/range.js @@ -52,8 +52,10 @@ RangeWidget.prototype.render = function(parent,nextSibling) { this.inputDomNode.value = this.getValue(); // Add a click event handler $tw.utils.addEventListeners(this.inputDomNode,[ - {name: "input", handlerObject: this, handlerMethod: "handleInputEvent"}, - {name: "change", handlerObject: this, handlerMethod: "handleInputEvent"} + {name:"mousedown", handlerObject:this, handlerMethod:"handleMouseDownEvent"}, + {name:"mouseup", handlerObject:this, handlerMethod:"handleMouseUpEvent"}, + {name:"change", handlerObject:this, handlerMethod:"handleChangeEvent"}, + {name:"input", handlerObject:this, handlerMethod:"handleInputEvent"}, ]); // Insert the label into the DOM and render any children parent.insertBefore(this.inputDomNode,nextSibling); @@ -62,23 +64,77 @@ RangeWidget.prototype.render = function(parent,nextSibling) { RangeWidget.prototype.getValue = function() { var tiddler = this.wiki.getTiddler(this.tiddlerTitle), - fieldName = this.tiddlerField || "text", - value = this.defaultValue; + fieldName = this.tiddlerField, + value = this.defaultValue; if(tiddler) { if(this.tiddlerIndex) { - value = this.wiki.extractTiddlerDataItem(tiddler,this.tiddlerIndex,this.defaultValue || ""); + value = this.wiki.extractTiddlerDataItem(tiddler,this.tiddlerIndex,this.defaultValue); } else { if($tw.utils.hop(tiddler.fields,fieldName)) { value = tiddler.fields[fieldName] || ""; } else { - value = this.defaultValue || ""; + value = this.defaultValue; } } } return value; }; +RangeWidget.prototype.getActionVariables = function(options) { + options = options || {}; + var hasChanged = (this.startValue !== this.inputDomNode.value) ? "yes" : "no"; + // Trigger actions. Use variables = {key:value, key:value ...} + // the "value" is needed. + return $tw.utils.extend({"actionValue": this.inputDomNode.value, "actionValueHasChanged": hasChanged}, options); +} + +// actionsStart +RangeWidget.prototype.handleMouseDownEvent = function(event) { + this.mouseDown = true; // TODO remove once IE is gone. + this.startValue = this.inputDomNode.value; // TODO remove this line once IE is gone! + this.handleEvent(event); + // Trigger actions + if(this.actionsMouseDown) { + var variables = this.getActionVariables() // TODO this line will go into the function call below. + this.invokeActionString(this.actionsMouseDown,this,event,variables); + } +} + +// actionsStop +RangeWidget.prototype.handleMouseUpEvent = function(event) { + this.mouseDown = false; // TODO remove once IE is gone. + this.handleEvent(event); + // Trigger actions + if(this.actionsMouseUp) { + var variables = this.getActionVariables() + this.invokeActionString(this.actionsMouseUp,this,event,variables); + } + // TODO remove the following if() once IE is gone! + if ($tw.browser.isIE) { + if (this.startValue !== this.inputDomNode.value) { + this.handleChangeEvent(event); + this.startValue = this.inputDomNode.value; + } + } +} + +RangeWidget.prototype.handleChangeEvent = function(event) { + if (this.mouseDown) { // TODO refactor this function once IE is gone. + this.handleInputEvent(event); + } +}; + RangeWidget.prototype.handleInputEvent = function(event) { + this.handleEvent(event); + // Trigger actions + if(this.actionsInput) { + // "tiddler" parameter may be missing. See .execute() below + var variables = this.getActionVariables({"actionValueHasChanged": "yes"}) // TODO this line will go into the function call below. + this.invokeActionString(this.actionsInput,this,event,variables); + } +}; + +RangeWidget.prototype.handleEvent = function(event) { if(this.getValue() !== this.inputDomNode.value) { if(this.tiddlerIndex) { this.wiki.setText(this.tiddlerTitle,"",this.tiddlerIndex,this.inputDomNode.value); @@ -92,16 +148,24 @@ RangeWidget.prototype.handleInputEvent = function(event) { Compute the internal state of the widget */ RangeWidget.prototype.execute = function() { + // TODO remove the next 1 lines once IE is gone! + this.mouseUp = true; // Needed for IE10 // Get the parameters from the attributes this.tiddlerTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler")); - this.tiddlerField = this.getAttribute("field"); + this.tiddlerField = this.getAttribute("field","text"); this.tiddlerIndex = this.getAttribute("index"); this.minValue = this.getAttribute("min"); this.maxValue = this.getAttribute("max"); this.increment = this.getAttribute("increment"); - this.defaultValue = this.getAttribute("default"); + this.defaultValue = this.getAttribute("default",""); this.elementClass = this.getAttribute("class",""); this.isDisabled = this.getAttribute("disabled","no"); + // Actions since 5.1.23 + // Next 2 only fire once! + this.actionsMouseDown = this.getAttribute("actionsStart",""); + this.actionsMouseUp = this.getAttribute("actionsStop",""); + // Input fires very often! + this.actionsInput = this.getAttribute("actions",""); // Make the child widgets this.makeChildWidgets(); }; @@ -111,7 +175,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of */ RangeWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); - if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes['min'] || changedAttributes['max'] || changedAttributes['increment'] || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.disabled) { + if($tw.utils.count(changedAttributes) > 0) { this.refreshSelf(); return true; } else { @@ -119,7 +183,7 @@ RangeWidget.prototype.refresh = function(changedTiddlers) { if(changedTiddlers[this.tiddlerTitle]) { var value = this.getValue(); if(this.inputDomNode.value !== value) { - this.inputDomNode.value = value; + this.inputDomNode.value = value; } refreshed = true; } diff --git a/core/modules/widgets/reveal.js b/core/modules/widgets/reveal.js index ebbf490b2..e6334dff2 100755 --- a/core/modules/widgets/reveal.js +++ b/core/modules/widgets/reveal.js @@ -70,6 +70,10 @@ RevealWidget.prototype.positionPopup = function(domNode) { left = this.popup.left + this.popup.width; top = this.popup.top + this.popup.height - domNode.offsetHeight; break; + case "belowright": + left = this.popup.left + this.popup.width; + top = this.popup.top + this.popup.height; + break; case "right": left = this.popup.left + this.popup.width; top = this.popup.top; @@ -78,6 +82,10 @@ RevealWidget.prototype.positionPopup = function(domNode) { left = this.popup.left + this.popup.width - domNode.offsetWidth; top = this.popup.top + this.popup.height; break; + case "aboveleft": + left = this.popup.left - domNode.offsetWidth; + top = this.popup.top - domNode.offsetHeight; + break; default: // Below left = this.popup.left; top = this.popup.top + this.popup.height; @@ -109,6 +117,7 @@ RevealWidget.prototype.execute = function() { this.retain = this.getAttribute("retain","no"); this.openAnimation = this.animate === "no" ? undefined : "open"; this.closeAnimation = this.animate === "no" ? undefined : "close"; + this.updatePopupPosition = this.getAttribute("updatePopupPosition","no") === "yes"; // Compute the title of the state tiddler and read it this.stateTiddlerTitle = this.state; this.stateTitle = this.getAttribute("stateTitle"); @@ -212,6 +221,8 @@ RevealWidget.prototype.refresh = function(changedTiddlers) { this.refreshSelf(); return true; } + } else if(this.type === "popup" && this.updatePopupPosition && (changedTiddlers[this.state] || changedTiddlers[this.stateTitle])) { + this.positionPopup(this.domNodes[0]); } return this.refreshChildren(changedTiddlers); } diff --git a/core/modules/widgets/widget.js b/core/modules/widgets/widget.js index bd66438e2..22112a516 100755 --- a/core/modules/widgets/widget.js +++ b/core/modules/widgets/widget.js @@ -574,10 +574,10 @@ Widget.prototype.invokeActionString = function(actions,triggeringWidget,event,va /* Execute action tiddlers by tag */ -Widget.prototype.executeStartupTiddlers = function(tag) { +Widget.prototype.invokeActionsByTag = function(tag,event,variables) { var self = this; $tw.utils.each(self.wiki.filterTiddlers("[all[shadows+tiddlers]tag[" + tag + "]!has[draft.of]]"),function(title) { - self.invokeActionString(self.wiki.getTiddlerText(title),self); + self.invokeActionString(self.wiki.getTiddlerText(title),self,event,variables); }); }; diff --git a/core/palettes/CupertinoDark.tid b/core/palettes/CupertinoDark.tid new file mode 100644 index 000000000..8097322cc --- /dev/null +++ b/core/palettes/CupertinoDark.tid @@ -0,0 +1,129 @@ +title: $:/palettes/CupertinoDark +tags: $:/tags/Palette +name: Cupertino Dark +description: A macOS inspired dark palette +type: application/x-tiddler-dictionary + +alert-background: #FF453A +alert-border: #FF453A +alert-highlight: #FFD60A +alert-muted-foreground: <> +background: #282828 +blockquote-bar: <> +button-foreground: <> +code-background: <> +code-border: <> +code-foreground: rgba(255, 255, 255, 0.54) +dirty-indicator: #FF453A +download-background: <> +download-foreground: <> +dragger-background: <> +dragger-foreground: <> +dropdown-background: <> +dropdown-border: <> +dropdown-tab-background-selected: #3F638B +dropdown-tab-background: #323232 +dropzone-background: #30D158 +external-link-background-hover: transparent +external-link-background-visited: transparent +external-link-background: transparent +external-link-foreground-hover: +external-link-foreground-visited: #BF5AF2 +external-link-foreground: #32D74B +foreground: #FFFFFF +menubar-background: #464646 +menubar-foreground: #ffffff +message-background: <> +message-border: <> +message-foreground: rgba(255, 255, 255, 0.54) +modal-backdrop: <> +modal-background: <> +modal-border: <> +modal-footer-background: <> +modal-footer-border: <> +modal-header-border: <> +muted-foreground: #98989D +notification-background: <> +notification-border: <> +page-background: #323232 +pre-background: #464646 +pre-border: transparent +primary: #0A84FF +select-tag-background: <> +select-tag-foreground: <> +sidebar-button-foreground: <> +sidebar-controls-foreground-hover: #FF9F0A +sidebar-controls-foreground: #8E8E93 +sidebar-foreground-shadow: transparent +sidebar-foreground: rgba(255, 255, 255, 0.54) +sidebar-muted-foreground-hover: rgba(255, 255, 255, 0.54) +sidebar-muted-foreground: rgba(255, 255, 255, 0.38) +sidebar-tab-background-selected: #3F638B +sidebar-tab-background: <> +sidebar-tab-border-selected: <> +sidebar-tab-border: <> +sidebar-tab-divider: <> +sidebar-tab-foreground-selected: rgba(255, 255, 255, 0.87) +sidebar-tab-foreground: rgba(255, 255, 255, 0.54) +sidebar-tiddler-link-foreground-hover: rgba(255, 255, 255, 0.7) +sidebar-tiddler-link-foreground: rgba(255, 255, 255, 0.54) +site-title-foreground: #ffffff +static-alert-foreground: #B4B4B4 +tab-background-selected: #3F638B +tab-background: <> +tab-border-selected: <> +tab-border: <> +tab-divider: <> +tab-foreground-selected: rgba(255, 255, 255, 0.87) +tab-foreground: rgba(255, 255, 255, 0.54) +table-border: #464646 +table-footer-background: <> +table-header-background: <> +tag-background: #48484A +tag-foreground: #323232 +tiddler-background: <> +tiddler-border: transparent +tiddler-controls-foreground-hover: <> +tiddler-controls-foreground-selected: <> +tiddler-controls-foreground: #48484A +tiddler-editor-background: transparent +tiddler-editor-border-image: +tiddler-editor-border: rgba(255, 255, 255, 0.08) +tiddler-editor-fields-even: rgba(255, 255, 255, 0.1) +tiddler-editor-fields-odd: rgba(255, 255, 255, 0.04) +tiddler-info-background: #1E1E1E +tiddler-info-border: #1E1E1E +tiddler-info-tab-background: #3F638B +tiddler-link-background: <> +tiddler-link-foreground: <> +tiddler-subtitle-foreground: <> +tiddler-title-foreground: #FFFFFF +toolbar-new-button: +toolbar-options-button: +toolbar-save-button: +toolbar-info-button: +toolbar-edit-button: +toolbar-close-button: +toolbar-delete-button: +toolbar-cancel-button: +toolbar-done-button: +untagged-background: <> +very-muted-foreground: #464646 +selection-background: #3F638B +selection-foreground: #ffffff +wikilist-background: <> +wikilist-button-background: <> +wikilist-button-foreground: <> +wikilist-button-open: #32D74B +wikilist-button-open-hover: #32D74B +wikilist-button-reveal: #0A84FF +wikilist-button-reveal-hover: #0A84FF +wikilist-button-remove: #FF453A +wikilist-button-remove-hover: #FF453A +wikilist-droplink-dragover: #32D74B +wikilist-item: <> +wikilist-toolbar-background: <> +wikilist-title: <> +wikilist-title-svg: <> +wikilist-toolbar-foreground: <> +wikilist-url: <> diff --git a/core/palettes/DesertSand.tid b/core/palettes/DesertSand.tid new file mode 100644 index 000000000..ab345d11f --- /dev/null +++ b/core/palettes/DesertSand.tid @@ -0,0 +1,138 @@ +title: $:/palettes/DesertSand +tags: $:/tags/Palette +name: Desert Sand +description: A desert sand palette +type: application/x-tiddler-dictionary + +alert-background: #ffe476 +alert-border: #b99e2f +alert-highlight: #881122 +alert-muted-foreground: #b99e2f +background: #E9E0C7 +blockquote-bar: <> +button-foreground: <> +code-background: #F3EDDF +code-border: #C3BAA1 +code-foreground: #ab3250 +diff-delete-background: #bd8b8b +diff-delete-foreground: <> +diff-equal-background: +diff-equal-foreground: <> +diff-insert-background: #91c093 +diff-insert-foreground: <> +diff-invisible-background: +diff-invisible-foreground: <> +dirty-indicator: #ad3434 +download-background: #6ca16c +download-foreground: <> +dragger-background: <> +dragger-foreground: <> +dropdown-background: <> +dropdown-border: <> +dropdown-tab-background-selected: #E9E0C7 +dropdown-tab-background: #BAB29C +dropzone-background: rgba(0,200,0,0.7) +external-link-background-hover: inherit +external-link-background-visited: inherit +external-link-background: inherit +external-link-foreground-hover: inherit +external-link-foreground-visited: #313163 +external-link-foreground: #555592 +foreground: #2D2A23 +menubar-background: #CDC2A6 +menubar-foreground: #5A5446 +message-background: #ECE5CF +message-border: #D6CBAA +message-foreground: #5f6e7d +modal-backdrop: <> +modal-background: <> +modal-border: #8A8885 +modal-footer-background: #CDC2A6 +modal-footer-border: #9D998E +modal-header-border: #9D998E +muted-foreground: #9D998E +notification-background: #F0E9D7 +notification-border: #939189 +page-background: #e0d3af +pre-background: #D6CBAA +pre-border: #CDC2A6 +primary: #5B6F55 +selection-background: #9D947B +selection-foreground: <> +select-tag-background: #F0E9D7 +select-tag-foreground: #2D2A23 +sidebar-button-foreground: <> +sidebar-controls-foreground-hover: #2D2A23 +sidebar-controls-foreground: #867F69 +sidebar-foreground-shadow: transparent +sidebar-foreground: #867F69 +sidebar-muted-foreground-hover: #706A58 +sidebar-muted-foreground: #B3A98C +sidebar-tab-background-selected: #e0d3af +sidebar-tab-background: #A6A193 +sidebar-tab-border-selected: #C3BAA1 +sidebar-tab-border: #C3BAA1 +sidebar-tab-divider: #CDC2A6 +sidebar-tab-foreground-selected: +sidebar-tab-foreground: #2D2A23 +sidebar-tiddler-link-foreground-hover: #433F35 +sidebar-tiddler-link-foreground: #706A58 +site-title-foreground: <> +static-alert-foreground: #A6A193 +tab-background-selected: #E9E0C7 +tab-background: #A6A193 +tab-border-selected: #C3BAA1 +tab-border: #C3BAA1 +tab-divider: #CDC2A6 +tab-foreground-selected: <> +tab-foreground: #2D2A23 +table-border: #9D998E +table-footer-background: #8A8885 +table-header-background: #B0AA98 +tag-background: #706A58 +tag-foreground: #E3D7B7 +tiddler-background: <> +tiddler-border: <> +tiddler-controls-foreground-hover: #9D947B +tiddler-controls-foreground-selected: #706A58 +tiddler-controls-foreground: #C3BAA1 +tiddler-editor-background: #E9E0C7 +tiddler-editor-border-image: #A6A193 +tiddler-editor-border: #A6A193 +tiddler-editor-fields-even: #D6CBAA +tiddler-editor-fields-odd: #C3BAA1 +tiddler-info-background: #E3D7B7 +tiddler-info-border: #BAB29C +tiddler-info-tab-background: #E9E0C7 +tiddler-link-background: <> +tiddler-link-foreground: <> +tiddler-subtitle-foreground: #867F69 +tiddler-title-foreground: #374464 +toolbar-new-button: +toolbar-options-button: +toolbar-save-button: +toolbar-info-button: +toolbar-edit-button: +toolbar-close-button: +toolbar-delete-button: +toolbar-cancel-button: +toolbar-done-button: +untagged-background: #8A8885 +very-muted-foreground: #CDC2A6 +wikilist-background: <> +wikilist-item: #CDC2A6 +wikilist-info: #161512 +wikilist-title: #433F35 +wikilist-title-svg: <> +wikilist-url: #706A58 +wikilist-button-open: #7db66a +wikilist-button-open-hover: #56a556 +wikilist-button-reveal: #5a6c9e +wikilist-button-reveal-hover: #454591 +wikilist-button-remove: #bc5972 +wikilist-button-remove-hover: #814040 +wikilist-toolbar-background: #CDC2A6 +wikilist-toolbar-foreground: #2D2A23 +wikilist-droplink-dragover: rgba(255,192,192,0.5) +wikilist-button-background: #A6A193 +wikilist-button-foreground: #161512 diff --git a/core/palettes/GruvBoxDark.tid b/core/palettes/GruvBoxDark.tid index c4b1cfc63..d53ec61e0 100644 --- a/core/palettes/GruvBoxDark.tid +++ b/core/palettes/GruvBoxDark.tid @@ -11,9 +11,7 @@ alert-highlight: #d79921 alert-muted-foreground: #504945 background: #3c3836 blockquote-bar: <> -button-background: #504945 -button-foreground: #fbf1c7 -button-border: transparent +button-foreground: <> code-background: #504945 code-border: #504945 code-foreground: #fb4934 @@ -62,7 +60,9 @@ pre-border: #504945 primary: #d79921 select-tag-background: #665c54 select-tag-foreground: <> -sidebar-button-foreground: <> +selection-background: #458588 +selection-foreground: <> +sidebar-button-foreground: <> sidebar-controls-foreground-hover: #7c6f64 sidebar-controls-foreground: #504945 sidebar-foreground-shadow: transparent diff --git a/core/palettes/Nord.tid b/core/palettes/Nord.tid index 73174a4d6..21d93a759 100644 --- a/core/palettes/Nord.tid +++ b/core/palettes/Nord.tid @@ -11,9 +11,7 @@ alert-highlight: #B48EAD alert-muted-foreground: #4C566A background: #3b4252 blockquote-bar: <> -button-background: #4C566A -button-foreground: #D8DEE9 -button-border: transparent +button-foreground: <> code-background: #2E3440 code-border: #2E3440 code-foreground: #BF616A @@ -62,7 +60,9 @@ pre-border: #2E3440 primary: #5E81AC select-tag-background: #3b4252 select-tag-foreground: <> -sidebar-button-foreground: <> +selection-background: #5E81AC +selection-foreground: <> +sidebar-button-foreground: <> sidebar-controls-foreground-hover: #D8DEE9 sidebar-controls-foreground: #4C566A sidebar-foreground-shadow: transparent diff --git a/core/templates/exporters/StaticRiver.tid b/core/templates/exporters/StaticRiver.tid index 48e62b1f2..4583bc1ce 100644 --- a/core/templates/exporters/StaticRiver.tid +++ b/core/templates/exporters/StaticRiver.tid @@ -26,7 +26,7 @@ extension: .html {{$:/StaticBanner||$:/core/templates/html-tiddler}} -
+
{{$:/core/templates/exporters/StaticRiver/Content||$:/core/templates/html-tiddler}}
diff --git a/core/templates/static.tiddler.html.tid b/core/templates/static.tiddler.html.tid index 0fdd4e2fe..a4537305a 100644 --- a/core/templates/static.tiddler.html.tid +++ b/core/templates/static.tiddler.html.tid @@ -22,9 +22,9 @@ title: $:/core/templates/static.tiddler.html `{{$:/StaticBanner||$:/core/templates/html-tiddler}}` -
+
`<$view tiddler="$:/core/ui/ViewTemplate" format="htmlwikified"/>`
-` \ No newline at end of file +` diff --git a/core/ui/Actions/new-image.tid b/core/ui/Actions/new-image.tid index d27d5c8c1..fc7316235 100644 --- a/core/ui/Actions/new-image.tid +++ b/core/ui/Actions/new-image.tid @@ -5,6 +5,7 @@ description: create a new image tiddler \define get-type() image/$(imageType)$ \end -<$vars imageType={{$:/config/NewImageType}}> -<$action-sendmessage $message="tm-new-tiddler" type=<> tags={{$:/config/NewTiddler/Tags}}/> +\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$ +<$vars imageType={{$:/config/NewImageType}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}}> +<$action-sendmessage $message="tm-new-tiddler" type=<> tags=<>/> diff --git a/core/ui/Actions/new-journal.tid b/core/ui/Actions/new-journal.tid index 4c5082f78..b5d1fe09f 100644 --- a/core/ui/Actions/new-journal.tid +++ b/core/ui/Actions/new-journal.tid @@ -2,13 +2,14 @@ title: $:/core/ui/Actions/new-journal tags: $:/tags/Actions description: create a new journal tiddler -<$vars journalTitleTemplate={{$:/config/NewJournal/Title}} journalTags={{$:/config/NewJournal/Tags}} journalText={{$:/config/NewJournal/Text}}> +\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$ +<$vars journalTitleTemplate={{$:/config/NewJournal/Title}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}} journalText={{$:/config/NewJournal/Text}}> <$wikify name="journalTitle" text="""<$macrocall $name="now" format=<>/>"""> <$reveal type="nomatch" state=<> text=""> -<$action-sendmessage $message="tm-new-tiddler" title=<> tags=<> text={{{ [get[]] }}}/> +<$action-sendmessage $message="tm-new-tiddler" title=<> tags=<> text={{{ [get[]] }}}/> <$reveal type="match" state=<> text=""> -<$action-sendmessage $message="tm-new-tiddler" title=<> tags=<> text=<>/> +<$action-sendmessage $message="tm-new-tiddler" title=<> tags=<> text=<>/> diff --git a/core/ui/Actions/new-tiddler.tid b/core/ui/Actions/new-tiddler.tid index 4a6eeac7b..c919a109e 100644 --- a/core/ui/Actions/new-tiddler.tid +++ b/core/ui/Actions/new-tiddler.tid @@ -2,4 +2,7 @@ title: $:/core/ui/Actions/new-tiddler tags: $:/tags/Actions description: create a new empty tiddler -<$action-sendmessage $message="tm-new-tiddler" tags={{$:/config/NewTiddler/Tags}}/> +\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$ +<$vars textFieldTags={{$:/config/NewTiddler/Tags}} tagsFieldTags={{$:/config/NewTiddler/Tags!!tags}}> +<$action-sendmessage $message="tm-new-tiddler" tags=<>/> + diff --git a/core/ui/ControlPanel/Basics.tid b/core/ui/ControlPanel/Basics.tid index 43f621901..4897d232a 100644 --- a/core/ui/ControlPanel/Basics.tid +++ b/core/ui/ControlPanel/Basics.tid @@ -26,8 +26,8 @@ caption: {{$:/language/ControlPanel/Basics/Caption}} |<$link to="$:/language/DefaultNewTiddlerTitle"><> |<$edit-text tiddler="$:/language/DefaultNewTiddlerTitle" default="" tag="input"/> | |<$link to="$:/config/NewJournal/Title"><> |<$edit-text tiddler="$:/config/NewJournal/Title" default="" tag="input"/> | |<$link to="$:/config/NewJournal/Text"><> |<$edit tiddler="$:/config/NewJournal/Text" tag="textarea" class="tc-edit-texteditor" default=""/> | -|<$link to="$:/config/NewTiddler/Tags"><> |<$vars currentTiddler="$:/config/NewTiddler/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}} | -|<$link to="$:/config/NewJournal/Tags"><> |<$vars currentTiddler="$:/config/NewJournal/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}} | +|<$link to="$:/config/NewTiddler/Tags"><> |<$vars currentTiddler="$:/config/NewTiddler/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><><$action-listops $tiddler=<> $field="text" $subfilter={{{ [get[tags]] }}}/><$action-setfield $tiddler=<> tags=""/> | +|<$link to="$:/config/NewJournal/Tags"><> |<$vars currentTiddler="$:/config/NewJournal/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><><$action-listops $tiddler=<> $field="text" $subfilter={{{ [get[tags]] }}}/><$action-setfield $tiddler=<> tags=""/> | |<$link to="$:/config/AutoFocus"><> |{{$:/snippets/minifocusswitcher}} | |<> |{{$:/snippets/minilanguageswitcher}} | |<> |<> | diff --git a/core/ui/ControlPanel/Saving/TiddlySpot.tid b/core/ui/ControlPanel/Saving/TiddlySpot.tid index 2497b300e..dad217251 100644 --- a/core/ui/ControlPanel/Saving/TiddlySpot.tid +++ b/core/ui/ControlPanel/Saving/TiddlySpot.tid @@ -20,6 +20,12 @@ http://$(userName)$.tiddlyspot.com/$path$/ \end +
+ +<> + +
+ <> |<> |<$edit-text tiddler="$:/UploadName" default="" tag="input"/> | @@ -34,4 +40,4 @@ http://$(userName)$.tiddlyspot.com/$path$/ |<> |<$edit-text tiddler="$:/UploadDir" default="." tag="input"/> | |<> |<$edit-text tiddler="$:/UploadBackupDir" default="." tag="input"/> | -<> \ No newline at end of file +<> diff --git a/core/ui/EditTemplate/fields.tid b/core/ui/EditTemplate/fields.tid index 84f0baa68..7afaf8ac1 100644 --- a/core/ui/EditTemplate/fields.tid +++ b/core/ui/EditTemplate/fields.tid @@ -57,7 +57,7 @@ $value={{{ [get[text]] }}}/> \whitespace trim
- +
<$list filter="[all[current]fields[]] +[sort[title]]" variable="currentField" storyview="pop"> <$list filter=<> variable="temp"> diff --git a/core/ui/EditToolbar/cancel.tid b/core/ui/EditToolbar/cancel.tid index 341ae9d0b..fe21c2e99 100644 --- a/core/ui/EditToolbar/cancel.tid +++ b/core/ui/EditToolbar/cancel.tid @@ -3,6 +3,7 @@ tags: $:/tags/EditToolbar caption: {{$:/core/images/cancel-button}} {{$:/language/Buttons/Cancel/Caption}} description: {{$:/language/Buttons/Cancel/Hint}} +\whitespace trim <$button actions=<> tooltip={{$:/language/Buttons/Cancel/Hint}} aria-label={{$:/language/Buttons/Cancel/Caption}} class=<>> <$list filter="[match[yes]]"> {{$:/core/images/cancel-button}} diff --git a/core/ui/EditToolbar/delete.tid b/core/ui/EditToolbar/delete.tid index 67e68c68b..fcaed4b48 100644 --- a/core/ui/EditToolbar/delete.tid +++ b/core/ui/EditToolbar/delete.tid @@ -3,6 +3,7 @@ tags: $:/tags/EditToolbar $:/tags/ViewToolbar caption: {{$:/core/images/delete-button}} {{$:/language/Buttons/Delete/Caption}} description: {{$:/language/Buttons/Delete/Hint}} +\whitespace trim <$button actions=<> tooltip={{$:/language/Buttons/Delete/Hint}} aria-label={{$:/language/Buttons/Delete/Caption}} class=<>> <$list filter="[match[yes]]"> {{$:/core/images/delete-button}} diff --git a/core/ui/EditToolbar/save.tid b/core/ui/EditToolbar/save.tid index cd69d7686..c539009ee 100644 --- a/core/ui/EditToolbar/save.tid +++ b/core/ui/EditToolbar/save.tid @@ -4,6 +4,7 @@ caption: {{$:/core/images/done-button}} {{$:/language/Buttons/Save/Caption}} description: {{$:/language/Buttons/Save/Hint}} \define save-tiddler-button() +\whitespace trim <$fieldmangler><$button tooltip={{$:/language/Buttons/Save/Hint}} aria-label={{$:/language/Buttons/Save/Caption}} class=<>> <> <$list filter="[match[yes]]"> diff --git a/core/ui/ImportListing.tid b/core/ui/ImportListing.tid index a2c371807..04ccd9a79 100644 --- a/core/ui/ImportListing.tid +++ b/core/ui/ImportListing.tid @@ -7,13 +7,17 @@ title: $:/core/ui/ImportListing \define payloadTitleFilter() [getminlength[1]else] \define overWriteWarning() +<$list filter="[!has]"> <$text text={{{[subfilter!is[tiddler]then[]] ~[addsuffix[Listing/Rename/OverwriteWarning]get[text]]}}}/> + \end \define selectionField() selection-$(payloadTiddler)$ \define renameField() rename-$(payloadTiddler)$ +\define suppressedField() suppressed-$(payloadTiddler)$ + \define newImportTitleTiddler() $:/temp/NewImportTitle-$(payloadTiddler)$ \define previewPopupState() $(currentTiddler)$!!popup-$(payloadTiddler)$ @@ -42,17 +46,17 @@ title: $:/core/ui/ImportListing <$list filter="[all[current]plugintiddlers[]sort[title]]" variable="payloadTiddler"> - +hasthen[tc-row-disabled]] ~[subfilteris[tiddler]then[tc-row-warning]] }}}>
-<$checkbox field=<> checked="checked" unchecked="unchecked" default="checked"/> +<$checkbox field=<> checked="checked" unchecked="unchecked" default="checked" disabled={{{[hasthen[yes]else[no]]}}}/> <$reveal type="nomatch" state=<> text="yes" tag="div"> <$reveal type="nomatch" state=<> text="yes" tag="div" class="tc-flex"> -<$button class="tc-btn-invisible tc-btn-dropdown tc-flex-grow-1 tc-word-break" set=<> setTo="yes"> +<$button class="tc-btn-invisible tc-btn-dropdown tc-flex-grow-1 tc-word-break" set=<> setTo="yes" disabled={{{[hasthen[yes]else[no]]}}}> {{$:/core/images/right-arrow}}<$text text={{{[subfilter]}}}/> -<$button class="tc-btn-invisible" set=<> setTo="yes" tooltip={{{[addsuffix[Listing/Rename/Tooltip]get[text]]}}}>{{$:/core/images/edit-button}} +<$list filter="[!has]"><$button class="tc-btn-invisible" set=<> setTo="yes" tooltip={{{[addsuffix[Listing/Rename/Tooltip]get[text]]}}}>{{$:/core/images/edit-button}} <$reveal type="match" state=<> text="yes" tag="div"> <$button class="tc-btn-invisible tc-btn-dropdown" set=<> setTo="no"> diff --git a/core/ui/KeyboardShortcuts/switcher.tid b/core/ui/KeyboardShortcuts/switcher.tid new file mode 100644 index 000000000..06dbae69d --- /dev/null +++ b/core/ui/KeyboardShortcuts/switcher.tid @@ -0,0 +1,5 @@ +title: $:/core/ui/KeyboardShortcuts/switcher +tags: $:/tags/KeyboardShortcut +key: ((layout-switcher)) + +<$action-sendmessage $message="tm-show-switcher" switch="layout"/> \ No newline at end of file diff --git a/core/ui/LayoutSwitcher.tid b/core/ui/LayoutSwitcher.tid new file mode 100644 index 000000000..28bc19158 --- /dev/null +++ b/core/ui/LayoutSwitcher.tid @@ -0,0 +1,17 @@ +title: $:/snippets/LayoutSwitcher +tags: $:/tags/ControlPanel/Appearance +caption: {{$:/language/ControlPanel/LayoutSwitcher/Caption}} + +<$linkcatcher to="$:/layout"> +
+<$list filter="[all[tiddlers+shadows]tag[$:/tags/Layout]] [[$:/core/ui/PageTemplate]] +[!is[draft]sort[name]]"> +<$list filter="[{$:/layout}!has[text]]" variable="ignore" emptyMessage=""" +<$set name="cls" filter="[all[current]field:title{$:/layout}]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
>><$link to={{!!title}}>''<$transclude field="name"/>'' - <$transclude field="description"/>
+ +"""> +<$set name="cls" filter="[all[current]field:title[$:/core/ui/PageTemplate]]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
>><$link to={{!!title}}>''<$transclude field="name"/>'' - <$transclude field="description"/>
+ + + +
+ diff --git a/core/ui/PageTemplate.tid b/core/ui/PageTemplate.tid index abb23a104..a432cc76a 100644 --- a/core/ui/PageTemplate.tid +++ b/core/ui/PageTemplate.tid @@ -1,4 +1,6 @@ title: $:/core/ui/PageTemplate +name: {{$:/language/PageTemplate/Name}} +description: {{$:/language/PageTemplate/Description}} \whitespace trim \define containerClasses() diff --git a/core/ui/SideBarSegments/search.tid b/core/ui/SideBarSegments/search.tid index ac96fa63b..a5b6f1b97 100644 --- a/core/ui/SideBarSegments/search.tid +++ b/core/ui/SideBarSegments/search.tid @@ -8,11 +8,13 @@ tags: $:/tags/SideBarSegment <$button popup=<> class="tc-btn-invisible"> {{$:/core/images/down-arrow}} <$list filter="[{$(searchTiddler)$}minlength{$:/config/Search/MinLength}limit[1]]" variable="listItem"> -<$set name="searchTerm" value={{{ [get[text]] }}}> -<$set name="resultCount" value="""<$count filter="[!is[system]search]"/>"""> +<$vars userInput={{{ [get[text]] }}} configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}] }}} replaceRegexp="limit\[\d+\]"> +<$vars primaryListFilter={{{ [get[first-search-filter]search-replace:g:regexp,[]] }}} secondaryListFilter={{{ [get[second-search-filter]search-replace:g:regexp,[]] }}}> +<$set name="resultCount" value="""<$count filter="[subfilter] [subfilter]"/>"""> {{$:/language/Search/Matches}} - + + \end diff --git a/core/ui/SwitcherModal.tid b/core/ui/SwitcherModal.tid new file mode 100644 index 000000000..3477f5778 --- /dev/null +++ b/core/ui/SwitcherModal.tid @@ -0,0 +1,11 @@ +title: $:/core/ui/SwitcherModal +subtitle: <$text text={{{[lookup[$:/language/Switcher/Subtitle/]]}}}/> +class: tc-modal-centered + +<$tiddler tiddler={{{[lookup[$:/config/SwitcherTargets/]]}}}> + + +<$transclude/> + + + \ No newline at end of file diff --git a/core/ui/TagPickerTagTemplate.tid b/core/ui/TagPickerTagTemplate.tid new file mode 100644 index 000000000..0588a0698 --- /dev/null +++ b/core/ui/TagPickerTagTemplate.tid @@ -0,0 +1,23 @@ +title: $:/core/ui/TagPickerTagTemplate + +\whitespace trim +<$button class=<> tag="a" tooltip={{$:/language/EditTemplate/Tags/Add/Button/Hint}}> +<$list filter="[minlength[1]]"> +<$action-listops $tiddler=<> $field=<> $subfilter="[]"/> + +<$set name="currentTiddlerCSSEscaped" value={{{ [escapecss[]] }}}> +<$action-sendmessage $message="tm-focus-selector" $param=<> preventScroll="true"/> + +<> +<$list filter="[minlength[1]]"> +<$action-setfield $tiddler=<> text="yes"/> + +<> +<$set name="backgroundColor" value={{!!color}}> +<$wikify name="foregroundColor" text="""<$macrocall $name="contrastcolour" target={{!!color}} fallbackTarget=<> colourA=<> colourB=<>/>"""> +>> +<$transclude tiddler={{!!icon}}/><$view field="title" format="text"/> + + + + diff --git a/core/wiki/config/RegisterPluginTypes.multids b/core/wiki/config/RegisterPluginTypes.multids index f0e52acd5..0ea7e1a01 100644 --- a/core/wiki/config/RegisterPluginTypes.multids +++ b/core/wiki/config/RegisterPluginTypes.multids @@ -3,5 +3,5 @@ title: $:/config/RegisterPluginType/ plugin: yes theme: no language: no -info: no +info: yes import: no diff --git a/core/wiki/config/ShortcutInfo.multids b/core/wiki/config/ShortcutInfo.multids index 8e26f9ad8..1f903dcad 100644 --- a/core/wiki/config/ShortcutInfo.multids +++ b/core/wiki/config/ShortcutInfo.multids @@ -22,6 +22,7 @@ input-tab-left: {{$:/language/Shortcuts/Input/Tab-Left/Hint}} input-tab-right: {{$:/language/Shortcuts/Input/Tab-Right/Hint}} input-up: {{$:/language/Shortcuts/Input/Up/Hint}} italic: {{$:/language/Buttons/Italic/Hint}} +layout-switcher: {{$:/language/LayoutSwitcher/Description}} link: {{$:/language/Buttons/Link/Hint}} linkify: {{$:/language/Buttons/Linkify/Hint}} list-bullet: {{$:/language/Buttons/ListBullet/Hint}} diff --git a/core/wiki/config/SwitcherTargets.multids b/core/wiki/config/SwitcherTargets.multids new file mode 100644 index 000000000..22583c872 --- /dev/null +++ b/core/wiki/config/SwitcherTargets.multids @@ -0,0 +1,6 @@ +title: $:/config/SwitcherTargets/ + +layout: $:/snippets/LayoutSwitcher +language: $:/snippets/languageswitcher +palette: $:/core/ui/ControlPanel/Palette +theme: $:/core/ui/ControlPanel/Theme \ No newline at end of file diff --git a/core/wiki/config/SyncFilter.tid b/core/wiki/config/SyncFilter.tid index 41d71537c..06b3f192f 100644 --- a/core/wiki/config/SyncFilter.tid +++ b/core/wiki/config/SyncFilter.tid @@ -1,3 +1,3 @@ title: $:/config/SyncFilter -[is[tiddler]] -[[$:/core]] -[prefix[$:/StoryList]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/isEncrypted]] -[prefix[$:/status/]] -[prefix[$:/state/]] -[prefix[$:/temp/]] +[is[tiddler]] -[[$:/core]] -[[$:/library/sjcl.js]] -[prefix[$:/boot/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/isEncrypted]] -[prefix[$:/status/]] -[prefix[$:/state/]] -[prefix[$:/temp/]] diff --git a/core/wiki/config/SyncSystemTiddlersFromServer.tid b/core/wiki/config/SyncSystemTiddlersFromServer.tid new file mode 100644 index 000000000..32fcb7a46 --- /dev/null +++ b/core/wiki/config/SyncSystemTiddlersFromServer.tid @@ -0,0 +1,3 @@ +title: $:/config/SyncSystemTiddlersFromServer + +no \ No newline at end of file diff --git a/core/wiki/config/shortcuts/shortcuts-mac.multids b/core/wiki/config/shortcuts/shortcuts-mac.multids index fc3fc060f..7b41dce17 100644 --- a/core/wiki/config/shortcuts/shortcuts-mac.multids +++ b/core/wiki/config/shortcuts/shortcuts-mac.multids @@ -1,6 +1,8 @@ title: $:/config/shortcuts-mac/ bold: meta-B +input-tab-left: ctrl-Left +input-tab-right: ctrl-Right italic: meta-I underline: meta-U new-image: ctrl-I diff --git a/core/wiki/config/shortcuts/shortcuts.multids b/core/wiki/config/shortcuts/shortcuts.multids index 78cefee4a..2a312cfa0 100644 --- a/core/wiki/config/shortcuts/shortcuts.multids +++ b/core/wiki/config/shortcuts/shortcuts.multids @@ -21,6 +21,7 @@ input-down: Down input-tab-left: alt-Left input-tab-right: alt-Right input-up: Up +layout-switcher: ctrl-shift-L link: ctrl-L linkify: alt-shift-L list-bullet: ctrl-shift-L diff --git a/core/wiki/macros/list.tid b/core/wiki/macros/list.tid index 01b527a07..cb25a7a88 100644 --- a/core/wiki/macros/list.tid +++ b/core/wiki/macros/list.tid @@ -39,7 +39,6 @@ tags: $:/tags/Macro - <$tiddler tiddler=""> <$droppable actions=<> tag="div" enable=<>>
@@ -48,6 +47,7 @@ tags: $:/tags/Macro
+ \end diff --git a/core/wiki/macros/tag-picker.tid b/core/wiki/macros/tag-picker.tid index 31d6c786d..8a48532b1 100644 --- a/core/wiki/macros/tag-picker.tid +++ b/core/wiki/macros/tag-picker.tid @@ -20,19 +20,6 @@ $actions$ <$action-setfield $tiddler=<> text="yes"/> \end -\define tag-button(actions,selectedClass,tagField:"tags") -<$button class="tc-btn-invisible $selectedClass$" tag="a" tooltip={{$:/language/EditTemplate/Tags/Add/Button/Hint}}> -<$action-listops $tiddler=<> $field=<<__tagField__>> $subfilter="[]"/> -<$set name="currentTiddlerCSSEscaped" value={{{ [escapecss[]] }}}> -<$action-sendmessage $message="tm-focus-selector" $param=<> preventScroll="true"/> - -<> -<$action-setfield $tiddler=<> text="yes"/> -$actions$ -<$macrocall $name="tag-pill" tag=<>/> - -\end - \define clear-tags-actions-inner() <$list filter="[has[text]] [has[text]]" variable="ignore" emptyMessage="""<>"""> <> @@ -49,7 +36,7 @@ $actions$ \define tag-picker-inner(actions,tagField:"tags") \whitespace trim -<$vars newTagNameInputTiddlerQualified=<> newTagNameSelectionTiddlerQualified=<>> +<$vars newTagNameInputTiddlerQualified=<> newTagNameSelectionTiddlerQualified=<> fallbackTarget={{$(palette)$##tag-background}} colourA={{$(palette)$##foreground}} colourB={{$(palette)$##background}}> <$vars storeTitle={{{ [!match[]] ~[] }}} tagSelectionState={{{ [!match[]] ~[] }}}> <$vars refreshTitle=<> nonSystemTagsFilter="[tags[]!is[system]search:titlesort[]]" systemTagsFilter="[tags[]is[system]search:titlesort[]]">
@@ -80,15 +67,15 @@ $actions$ <$set name="userInput" value={{{ [get[text]] }}}> <$list filter="[minlength{$:/config/Tags/MinLength}limit[1]]" emptyMessage="""
{{$:/language/Search/Search/TooShort}}
""" variable="listItem"> <$list filter=<> variable="tag"> -<$list filter="[addsuffix[-primaryList]] -[get[text]]" emptyMessage="""<$macrocall $name="tag-button" actions=<<__actions__>> selectedClass="tc-tag-button-selected"/>"""> -<$macrocall $name="tag-button" actions=<<__actions__>> tagField=<<__tagField__>>/> +<$list filter="[addsuffix[-primaryList]] -[get[text]]" emptyMessage="""<$vars button-classes="tc-btn-invisible tc-tag-button-selected" actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<>>{{||$:/core/ui/TagPickerTagTemplate}}"""> +<$vars button-classes="tc-btn-invisible" actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<>>{{||$:/core/ui/TagPickerTagTemplate}}
<$list filter="[minlength{$:/config/Tags/MinLength}limit[1]]" emptyMessage="""
{{$:/language/Search/Search/TooShort}}
""" variable="listItem"> <$list filter=<> variable="tag"> -<$list filter="[addsuffix[-secondaryList]] -[get[text]]" emptyMessage="""<$macrocall $name="tag-button" actions=<<__actions__>> selectedClass="tc-tag-button-selected"/>"""> -<$macrocall $name="tag-button" actions=<<__actions__>> tagField=<<__tagField__>>/> +<$list filter="[addsuffix[-secondaryList]] -[get[text]]" emptyMessage="""<$vars button-classes="tc-btn-invisible tc-tag-button-selected" actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<>>{{||$:/core/ui/TagPickerTagTemplate}}"""> +<$vars button-classes="tc-btn-invisible" actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<>>{{||$:/core/ui/TagPickerTagTemplate}} @@ -102,11 +89,11 @@ $actions$ \end \define tag-picker(actions,tagField:"tags") \whitespace trim -<$set name="saveTiddler" value=<>> +<$vars saveTiddler=<> palette={{$:/palette}}> <$list filter="[match[]]" emptyMessage="""<$macrocall $name="tag-picker-inner" actions=<<__actions__>> tagField=<<__tagField__>>/>"""> <$set name="newTagNameTiddler" value=<>> <$macrocall $name="tag-picker-inner" actions=<<__actions__>> tagField=<<__tagField__>>/> - + \end diff --git a/editions/codemirrordemo/tiddlers/cm-theme-tiddlywiki.tid b/editions/codemirrordemo/tiddlers/cm-theme-tiddlywiki.tid deleted file mode 100644 index 501b20b9a..000000000 --- a/editions/codemirrordemo/tiddlers/cm-theme-tiddlywiki.tid +++ /dev/null @@ -1,56 +0,0 @@ -title: $:/themes/codemirror/tiddlywiki -tags: $:/tags/Stylesheet -module-type: codemirror-theme -name: tiddlywiki - -.cm-s-tiddlywiki { - font-size: 1em; - line-height: 1.5em; - letter-spacing: 0.3px; - word-spacing: 1px; - background: <>; - color: <>; -} -.cm-s-tiddlywiki .CodeMirror-lines { - padding: 8px 0; -} -.cm-s-tiddlywiki .CodeMirror-gutters { - background-color: <>; - padding-right: 10px; - z-index: 3; - border: none; -} -.cm-s-tiddlywiki div.CodeMirror-cursor { - border-left: 3px solid <>; -} -.cm-s-tiddlywiki .CodeMirror-activeline-background { - background: <>; -} -.cm-s-tiddlywiki .CodeMirror-selected { - background: <>; -} -.cm-s-tiddlywiki .cm-comment { - font-style: italic; - color: <>; -} -.cm-s-tiddlywiki .CodeMirror-linenumber { - color: italic; -} - -.cm-s-tiddlywiki span.cm-atom, .cm-s-tiddlywiki span.cm-number, .cm-s-tiddlywiki span.cm-keyword, .cm-s-tiddlywiki span.cm-variable, .cm-s-tiddlywiki span.cm-attribute, .cm-s-tiddlywiki span.cm-quote, .cm-s-tiddlywiki-light span.cm-hr, .cm-s-tiddlywiki-light span.cm-link { color: #063289; } - -.cm-s-tiddlywiki span.cm-property { color: #b29762; } -.cm-s-tiddlywiki span.cm-punctuation, .cm-s-tiddlywiki span.cm-unit, .cm-s-tiddlywiki span.cm-negative { color: #063289; } -.cm-s-tiddlywiki span.cm-string, .cm-s-tiddlywiki span.cm-operator { color: #1659df; } -.cm-s-tiddlywiki span.cm-positive { color: #896724; } - -.cm-s-tiddlywiki span.cm-variable-2, .cm-s-tiddlywiki span.cm-variable-3, .cm-s-tiddlywiki span.cm-type, .cm-s-tiddlywiki span.cm-string-2, .cm-s-tiddlywiki span.cm-url { color: #896724; } -.cm-s-tiddlywiki span.cm-def, .cm-s-tiddlywiki span.cm-tag, .cm-s-tiddlywiki span.cm-builtin, .cm-s-tiddlywiki span.cm-qualifier, .cm-s-tiddlywiki span.cm-header, .cm-s-tiddlywiki span.cm-em { color: #2d2006; } -.cm-s-tiddlywiki span.cm-bracket, .cm-s-tiddlywiki span.cm-comment { color: #b6ad9a; } - -/* using #f00 red for errors, don't think any of the colorscheme variables will stand out enough, ... maybe by giving it a background-color ... */ -/* .cm-s-tiddlywiki span.cm-error { background: #896724; color: #728fcb; } */ -.cm-s-tiddlywiki span.cm-error, .cm-s-tiddlywiki span.cm-invalidchar { color: #f00; } - -.cm-s-tiddlywiki span.cm-header { font-weight: normal; } -.cm-s-tiddlywiki .CodeMirror-matchingbracket { text-decoration: underline; color: #faf8f5 !important; } diff --git a/editions/de-AT/tiddlers/bilder/New_Release_Banner.png.tid b/editions/de-AT/tiddlers/bilder/New_Release_Banner.png.tid deleted file mode 100644 index 02a927c13..000000000 --- a/editions/de-AT/tiddlers/bilder/New_Release_Banner.png.tid +++ /dev/null @@ -1,6 +0,0 @@ -created: 20150513150058938 -tags: picture -title: New Release Banner.png -type: image/png - -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 \ No newline at end of file diff --git a/editions/de-AT/tiddlers/external/tiddlywiki.files b/editions/de-AT/tiddlers/external/tiddlywiki.files new file mode 100644 index 000000000..0c59b7bc5 --- /dev/null +++ b/editions/de-AT/tiddlers/external/tiddlywiki.files @@ -0,0 +1,12 @@ +{ + "tiddlers": [ + { + "file": "../../../tw5.com/tiddlers/images/New Release Banner.png", + "fields": { + "type": "image/jpg", + "title": "New Release Banner", + "tags": "picture" + } + } + ] +} diff --git a/editions/de-AT/tiddlers/intro/HelloThumbnail_-_Latest_Version.tid b/editions/de-AT/tiddlers/intro/HelloThumbnail_-_Latest_Version.tid index e453a44db..ecc127e67 100644 --- a/editions/de-AT/tiddlers/intro/HelloThumbnail_-_Latest_Version.tid +++ b/editions/de-AT/tiddlers/intro/HelloThumbnail_-_Latest_Version.tid @@ -1,7 +1,7 @@ caption: Was ist neu in <> color: #fff created: 20150513145829381 -image: New Release Banner.png +image: New Release Banner link: Releases modified: 20150518143526750 tags: HelloThumbnail diff --git a/editions/prerelease/tiddlers/Release 5.1.23.tid b/editions/prerelease/tiddlers/Release 5.1.23.tid index b50e2116a..f3b26ec57 100644 --- a/editions/prerelease/tiddlers/Release 5.1.23.tid +++ b/editions/prerelease/tiddlers/Release 5.1.23.tid @@ -1,6 +1,6 @@ caption: 5.1.23 -created: 20201018143621963 -modified: 20201018143621963 +created: 20201128173201204 +modified: 20201128173201204 tags: ReleaseNotes title: Release 5.1.23 type: text/vnd.tiddlywiki @@ -9,7 +9,7 @@ type: text/vnd.tiddlywiki ! Major Improvements -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4725]] support for navigating the search and new tag dropdowns via the keyboard. The [[keyboard-driven-input Macro]] can be used to add this capability to other dropdowns. +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4725]] support for navigating the search and new tag dropdowns via the keyboard. The [[keyboard-driven-input Macro]] can be used to add this capability to other dropdowns * [[New|https://github.com/Jermolene/TiddlyWiki5/commit/4a84ed0018df7fd67000404bb5ef8a7ca50509c1]] [[Consent Banner Plugin]] to help make websites compliant with cookie legislation by displaying a consent banner * [[Extended|https://github.com/Jermolene/TiddlyWiki5/commit/6a0ff7db1807f45b73061ced82f5a85f1a529bbf]] [[JSZip Plugin]] ability to dynamically create Zip files, giving TiddlyWiki the ability to build static sites within the browser * [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/14a28b77796461c9167898793ab9851e029e0354]] new [[filter|filter Operator]] and [[reduce|reduce Operator]] operators for processing lists of items @@ -20,15 +20,25 @@ type: text/vnd.tiddlywiki * New Arabic (Palestine) translation * Improved Catalan translation * Improved Chinese translation +* Improved Dutch translation +* Improved French translation +* Improved German translation ! Performance Improvements * [[Updated|https://github.com/Jermolene/TiddlyWiki5/pull/4659]] templates to use a single VarsWidget instead of several [[SetVariableWidgets|SetVariableWidget]], for improved performance and easier debugging -* [[Updated|https://github.com/Jermolene/TiddlyWiki5/pull/4954]] ListWidget to not initialize parsers for blank `emptyMessage` attributes. -* [[Refactored|https://github.com/Jermolene/TiddlyWiki5/pull/4200]] `story.js` to remove dependency on `wiki.js` for story start up and navigator. +* [[Updated|https://github.com/Jermolene/TiddlyWiki5/pull/4954]] ListWidget to not initialize parsers for blank `emptyMessage` attributes +* [[Refactored|https://github.com/Jermolene/TiddlyWiki5/pull/4200]] `story.js` to remove dependency on `wiki.js` for story start up and navigator ! Usability Improvements +* Several improvements to the import mechanism: +** [[Improved|https://github.com/Jermolene/TiddlyWiki5/commit/527638d5e60114653385ed39dc55c736a67e58d2]] status messages in the import listing +** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5067]] colour coding for import items that will overwrite existing tiddlers, and for other warnings +** [[Extended|https://github.com/Jermolene/TiddlyWiki5/pull/4937]] the Import UI to allow renaming tiddlers and to warn about tiddlers that already exist +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5037]] new ActionConfirm widget +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5092]] new "Desert Sand" palette +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5100]] new "Cupertino Dark" palette * [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/8cf458d3b3f1e38c14a2819529e08dca4a7e297c]] "Solarized Dark" palette * [[Updated|https://github.com/Jermolene/TiddlyWiki5/pull/4590]] (and [[here|https://github.com/Jermolene/TiddlyWiki5/commit/274a07b4fd2ca2d1b95c8ddf52fe055c44260d9b]]) the Vanilla theme to optionally use palette colours for the [[browser selection outline|https://developer.mozilla.org/en-US/docs/Web/CSS/::selection]] * [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/1546a4a1895b93a47b79c9d37b94be039604443a]] warning message about using the online plugin library with the client-server configuration @@ -36,34 +46,44 @@ type: text/vnd.tiddlywiki * [[Changed|https://github.com/Jermolene/TiddlyWiki5/commit/9cd5415dfe54b47819920aa3cf6ac2d5e3a9188e]] favicon for the prerelease edition * [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/484c9e986fc6f323e30460a88f134da3a4e8a89e]] the $:/PaletteManager to show "indirect" colours (ie, colours defined by another `<>` macro) * [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4791]] a 'tabIndex' property to the tiddler editor input area to make it easier to use the tab key to move between edit controls -* [[Extended|https://github.com/Jermolene/TiddlyWiki5/pull/4937]] the Import UI to allow renaming tiddlers and to warn about tiddlers that already exist. * Added keyboard support: -** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4909]] keyboard support for cycling through the tabs in $:/AdvancedSearch. -** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4921]] keyboard support for navigating the field name dropdown in the Edit Template. -** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4989]] keyboard support or navigating the `type` field input in the Edit Template. -** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4919]] keyboard support for using the ''insert wikilink'' toolbar dropdown in the Edit Template. -** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4927]] keyboard shortcut for saving the wiki. -** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4978]] keyboard shortcut for deleting a field in the Edit Template. +** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4909]] keyboard support for cycling through the tabs in $:/AdvancedSearch +** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4921]] keyboard support for navigating the field name dropdown in the Edit Template +** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4989]] keyboard support or navigating the `type` field input in the Edit Template +** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4919]] keyboard support for using the ''insert wikilink'' toolbar dropdown in the Edit Template +** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4927]] keyboard shortcut for saving the wiki +** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4978]] keyboard shortcut for deleting a field in the Edit Template * [[Removed|https://github.com/Jermolene/TiddlyWiki5/commit/22e25c05eb5e5cc5b670a362d1eead1d62dedbb9]] normalize.css's styling of search input fields and [[updated|https://github.com/Jermolene/TiddlyWiki5/commit/9003c810393d90ee20db083fda35b6469acc592a]] to a modern fork of normalize.css +* [[Removed|https://github.com/Jermolene/TiddlyWiki5/commit/bb6fee4e1c79a2b1cbf75cd0326ecb8fb1ccb86b]] unneeded editor toolbar buttons when editing SVG tiddlers +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5089]] global keyboard shortcut for switching layouts +* [[Updated|https://github.com/Jermolene/TiddlyWiki5/pull/5128]] the [[CodeMirror Plugin]] and the [[Hightlight Plugin]] to use palette colours ! Filter Improvements +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5080]] [[power Operator]] and [[log Operator]] * [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/4966f6ab625c8ce2c9f0812a726ba928d68ea00b]] new [[slugify Operator]] and [[duplicateslugs Operator]] for generating human readable filenames/URLs * [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/619c0752bd3c6e71d1fcdb74daa03cfe8257afe4]] new [[sortsub Operator]] for sorting by a user defined subfilter * [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4785]] new [[format Operator]] for formatting dates * [[Extended|https://github.com/Jermolene/TiddlyWiki5/pull/4811]] the [[trim Operator]] to optionally trim a given string instead of whitespace, and trim from front, back, or both sides of input tiddlers -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4991]] new [[draft Operator|is Operator]] to check if a tiddler is a draft of another tiddler. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4973]] new [[search-replace Operator]] to search and replace in strings. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4948]] new [[enlist-input Operator]] to parse its input titles as a title lists. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/14a28b77796461c9167898793ab9851e029e0354]] new [[reduce Operator]] to apply a subfilter to each input title in turn, accumulating a single value . -* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/14a28b77796461c9167898793ab9851e029e0354]] new [[filter Operator]] to apply a subfilter to each input title and return the titles that return a non-empty result from the subfilter. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4918]] new [[:filter filter run prefix|Filter Expression]] which is analagous to the new [[filter Operator]] but applies to a filter run. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4959]] new [[:intersection filter run prefix|Filter Expression]] to get the intersection of two filter runs. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4990]] new [[toggle Operator]] to toggle a title in a list. - +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4991]] new [[draft Operator|is Operator]] to check if a tiddler is a draft of another tiddler +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4973]] new [[search-replace Operator]] to search and replace in strings +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4948]] new [[enlist-input Operator]] to parse its input titles as a title lists +* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/14a28b77796461c9167898793ab9851e029e0354]] new [[reduce Operator]] to apply a subfilter to each input title in turn, accumulating a single value +* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/14a28b77796461c9167898793ab9851e029e0354]] new [[filter Operator]] to apply a subfilter to each input title and return the titles that return a non-empty result from the subfilter +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4918]] new [[:filter filter run prefix|Filter Expression]] which is analagous to the new [[filter Operator]] but applies to a filter run +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4959]] new [[:intersection filter run prefix|Filter Expression]] to get the intersection of two filter runs +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4990]] new [[toggle Operator]] to toggle a title in a list +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5021]] new [[cycle Operator]] ! Hackability Improvements +* [[Extended|https://github.com/Jermolene/TiddlyWiki5/pull/5091]] ButtonWidget and DroppableWidget so that changing the class attribute does not trigger a refresh. This makes it easier to use classes to trigger CSS animations +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5086]] EventCatcherWidget for low level event handling +* [[Extended|https://github.com/Jermolene/TiddlyWiki5/pull/5087]] the RevealWidget to optionally dynamically refresh popup positions when the state tiddler changes +* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/5027]] modals to incorporate a NavigatorWidget so that links work as expected +* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/1b31c25ea77ee4dce86a9aac4375337423ebd3a6]] new LogWidget and ActionLogWidget to help debugging +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5014]] support for ''disabled'' attribute to EditWidget, EditTextWidget, CheckboxWidget, RadioWidget and RangeWidget +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5010]] support for ''disabled'' attribute to ButtonWidget * [[Extended|https://github.com/Jermolene/TiddlyWiki5/commit/5af76c5ea10db2b59cc20f963a836c6a9faa8b10]] the [[Table-of-Contents Macros]] to support custom link targets * [[Extended|https://github.com/Jermolene/TiddlyWiki5/commit/ae13a0fee118c50169b7835c950df1dade33788f]] the MacroCallWidget to be able to optionally render the raw text of the macro (previously the output was always wikified) * [[Adedd|https://github.com/Jermolene/TiddlyWiki5/pull/4777]] new Hyperdrive saver for use with Beaker Browser v1.0 @@ -82,26 +102,31 @@ type: text/vnd.tiddlywiki * [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4724]] original event to `tm-navigate` event * [[Extended|https://github.com/Jermolene/TiddlyWiki5/commit/651fb777abd11c88e58b4bdfbced01d6db508852]] the password prompt to enable it to be customised * [[Extended|https://github.com/Jermolene/TiddlyWiki5/commit/69c12618d963c711edd72a60427bd15ec4fa0e6e]] syncer to enable syncadaptors to customise the login prompt -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4979]] support for switching page templates. -* [[Extended|https://github.com/Jermolene/TiddlyWiki5/commit/a1b486436e9278078c524c6aa11f7f4de6cbc877]] the [[tabs Macro]] to support `actions` and `explicitState` attributes. -* [[Updated|https://github.com/Jermolene/TiddlyWiki5/pull/4906]] (and [[here|https://github.com/Jermolene/TiddlyWiki5/pull/4907]]) filters used for syncing on node.js and saving the single file version to exclude multiple story lists and history lists based on their prefix, as well as multiple tiddlers that might be used for the import process. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/5cc1600072f5aa50c8ff5f5d2e748d81a7067420]] post-render startup actions. +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4979]] support for switching page templates +* [[Extended|https://github.com/Jermolene/TiddlyWiki5/commit/a1b486436e9278078c524c6aa11f7f4de6cbc877]] the [[tabs Macro]] to support `actions` and `explicitState` attributes +* [[Updated|https://github.com/Jermolene/TiddlyWiki5/pull/4906]] (and [[here|https://github.com/Jermolene/TiddlyWiki5/pull/4907]]) filters used for syncing on node.js and saving the single file version to exclude multiple story lists and history lists based on their prefix, as well as multiple tiddlers that might be used for the import process +* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/5cc1600072f5aa50c8ff5f5d2e748d81a7067420]] post-render startup actions * [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/f7f55e8eff8b172d8fd04f095781efa2420b1be6]] support for username/password parameters for `tm-login` message -* [[Extended|https://github.com/Jermolene/TiddlyWiki5/pull/4914]] [[tiddlywiki.files Files]] specification with `isEditableFile` attribute allowing files to be saved back to their original location. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/4c6de2271124fc3a4b01e4324a0d5e401500cca2]] support for the content type `image/jpg`. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4908]] support for an override saver. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4923]] utility CSS classes to replace use of ` ` to introduce visual separation. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4952]] a keyboard shortcut to change the sidebar layout. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4983]] option to configure the tag used for TableOfContents in the menubar. -* [[Modified|https://github.com/Jermolene/TiddlyWiki5/pull/4971]] the KeyboardWidget to not trap keys if there are no actions to be invoked. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4975]] buttons to the Edit Template toolbar for the editor-height and the stamp tool for tiddlers of type `application/javascript`,`application/json` and `application/x-tiddler-dictionary`. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4915]] support for named filter run prefixes. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4964]] support for multiple operands for filter operators. -* [[Updated|https://github.com/Jermolene/TiddlyWiki5/pull/4985]] all instance of the [[tabs Macro]] in the core to use the explicitState attribute. -* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5000]] support for the `meta` key as a modifier in actions. +* [[Extended|https://github.com/Jermolene/TiddlyWiki5/pull/4914]] [[tiddlywiki.files Files]] specification with `isEditableFile` attribute allowing files to be saved back to their original location +* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/4c6de2271124fc3a4b01e4324a0d5e401500cca2]] support for the content type `image/jpg` +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4908]] support for an override saver +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4923]] utility CSS classes to replace use of ` ` to introduce visual separation +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4952]] a keyboard shortcut to change the sidebar layout +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4983]] option to configure the tag used for TableOfContents in the menubar +* [[Modified|https://github.com/Jermolene/TiddlyWiki5/pull/4971]] the KeyboardWidget to not trap keys if there are no actions to be invoked +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4975]] buttons to the Edit Template toolbar for the editor-height and the stamp tool for tiddlers of type `application/javascript`,`application/json` and `application/x-tiddler-dictionary` +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4915]] support for named filter run prefixes +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4964]] support for multiple operands for filter operators +* [[Updated|https://github.com/Jermolene/TiddlyWiki5/pull/4985]] all instance of the [[tabs Macro]] in the core to use the explicitState attribute +* [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/5000]] support for the `meta` key as a modifier in actions +* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/c854e518faa2d2661b7b7278634b10607ab0a5f5]] support for $:/info/darkmode to the InfoMechanism, reflecting the browser dark mode vs. light mode setting ! Bug Fixes +* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/5126]] "409 conflict" errors with the ~GitHub saver when saving within 60 seconds of the last save +* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/5088]] incorrect behaviour of default values with [[lookup Operator]] +* [[Restored|https://github.com/Jermolene/TiddlyWiki5/pull/4987]] behaviour of system tiddler syncing with the client server configuration. By default, changes to system tiddlers are not synced from the server to the client, restoring the behaviour from v5.1.21 and earlier. Bidirectional syncing of system tiddlers can be enabled with the configuration tiddler $:/config/SyncSystemTiddlersFromServer +* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/cc3462999b80461fe30b8f4b4f272ccfbbb78b35]] content type of imported `.tid` files that do not have a `type` field * [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/4632]] hover effect for search dropdown items * [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/4584]] restored missing parameter to `saveTiddler()` method of syncadaptors * [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/678e25f510786fbc38f505f8b594f57f39e33a04]] MakeLibraryCommand to skip non-directories @@ -130,12 +155,14 @@ type: text/vnd.tiddlywiki * [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4751]] a `plugin-priority` field to the TiddlyWeb plugin so that language plugins can override its language strings * [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/4853]] bug whereby joining an empty list would not return an empty list * [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/59f233cd46616646fa8889f65aa9cc7d704d8c9a]] bug exporting tiddlers with double quoted titles -* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/issues/4900]] bug with syncing plugin tiddlers. -* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/4877891980f077c6c31e99cc6a9eb45b5d1230e1]] bug with the position of the tiddler title when there is no icon in use. -* [[Disabled|https://github.com/Jermolene/TiddlyWiki5/commit/3153c588ecddfdc97cc8289720d36b1fb15ef236]] autosave in the upgrade wizard. -* [[Disabled|https://github.com/Jermolene/TiddlyWiki5/pull/4938]] saving of `$:/temp` tiddlers in single file wikis. -* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/4839]] a bug with the `sortan` filter operator when used with date fields. -* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/4947]] a bug for location hashes that contain a `#` character. +* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/issues/4900]] bug with syncing plugin tiddlers +* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/4877891980f077c6c31e99cc6a9eb45b5d1230e1]] bug with the position of the tiddler title when there is no icon in use +* [[Disabled|https://github.com/Jermolene/TiddlyWiki5/commit/3153c588ecddfdc97cc8289720d36b1fb15ef236]] autosave in the upgrade wizard +* [[Disabled|https://github.com/Jermolene/TiddlyWiki5/pull/4938]] saving of `$:/temp` tiddlers in single file wikis +* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/4839]] a bug with the `sortan` filter operator when used with date fields +* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/4947]] a bug for location hashes that contain a `#` character +* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/5055]] default branch to ''main'' for saving to ~GitHub +* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/7327a3fb92fa2ae17d7264c66ab0409d43b18fdc]] shadow tiddlers not refreshing when their plugin is deleted or modified ! Plugin Improvements @@ -153,7 +180,7 @@ type: text/vnd.tiddlywiki ** [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/4680]] encoding of Markdown image files ** [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/e01b354f7d9e137cb355f7090f5e68661a4ead41]] issue with whitespace and linebreaks ** [[Added|https://github.com/Jermolene/TiddlyWiki5/pull/4862]] ''tc-tiddlylink-external'' class to external links -** [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/4771]] to add `rel="noopener noreferrer"` to external links. +** [[Fixed|https://github.com/Jermolene/TiddlyWiki5/pull/4771]] to add `rel="noopener noreferrer"` to external links * [[Amazon Web Services Plugin]] ** [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/0338f0fee23d176a94de9009492d2e43a916fbfa]] a new ''aws-encodeuricomponent'' filter that also encodes single quotes * ~BibTeX Plugin @@ -161,9 +188,9 @@ type: text/vnd.tiddlywiki * Menubar Plugin ** [[Updated|https://github.com/Jermolene/TiddlyWiki5/pull/4974]] so the top margin of the side bar adjusts to the height of the menu * Dynannotate Plugin -** [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/4394b8e723f78b3d2562a95155aeb91a3d6bbd5f]] examples of usage in the View Template. +** [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/4394b8e723f78b3d2562a95155aeb91a3d6bbd5f]] examples of usage in the View Template * External Attachments Plugin -** [[Fixed|https://github.com/Jermolene/TiddlyWiki5/issues/4549]] a bug with relative paths in the External Attachments plugin. +** [[Fixed|https://github.com/Jermolene/TiddlyWiki5/issues/4549]] a bug with relative paths in the External Attachments plugin ! Contributors @@ -175,6 +202,7 @@ type: text/vnd.tiddlywiki * [[@BramChen|https://github.com/BramChen]] * [[@BurningTreeC|https://github.com/BurningTreeC]] * [[@danielo515|https://github.com/danielo515]] +* [[@default-kramer|https://github.com/default-kramer]] * [[@ento|https://github.com/ento]] * [[@favadi|https://github.com/favadi]] * [[@fkohrt|https://github.com/fkohrt]] @@ -184,13 +212,15 @@ type: text/vnd.tiddlywiki * [[@idotobi|https://github.com/idotobi]] * [[@jdangerx|https://github.com/jdangerx]] * [[@jjduhamel|https://github.com/jjduhamel]] +* [[@kookma|https://github.com/kookma]] * [[@Kamal-Habash|https://github.com/Kamal-Habash]] * [[@Marxsal|https://github.com/Marxsal]] * [[@mocsa|https://github.com/mocsa]] -* [[@NicolasPeton|https://github.com/NicolasPeton]] +* [[@NicolasPetton|https://github.com/NicolasPetton]] * [[@passuf|https://github.com/passuf]] * [[@pmario|https://github.com/pmario]] * [[@rmunn|https://github.com/rmunn]] +* [[@SmilyOrg|https://github.com/SmilyOrg]] * [[@saqimtiaz|https://github.com/saqimtiaz]] * [[@twMat|https://github.com/twMat]] -* [[@default-kramer|https://github.com/default-kramer]] +* [[@xcazin|https://github.com/xcazin]] diff --git a/editions/test/tiddlers/tests/test-filters.js b/editions/test/tiddlers/tests/test-filters.js index dedfd5179..4a9e9f950 100644 --- a/editions/test/tiddlers/tests/test-filters.js +++ b/editions/test/tiddlers/tests/test-filters.js @@ -184,6 +184,9 @@ function runTests(wiki) { it("should handle the enlist-input operator", function() { expect(wiki.filterTiddlers("[[one two three]enlist-input[]]").join(",")).toBe("one,two,three"); + expect(wiki.filterTiddlers("[[one two two three]enlist-input[]]").join(",")).toBe("one,two,three"); + expect(wiki.filterTiddlers("[[one two two three]enlist-input:dedupe[]]").join(",")).toBe("one,two,three"); + expect(wiki.filterTiddlers("[[one two two three]enlist-input:raw[]]").join(",")).toBe("one,two,two,three"); expect(wiki.filterTiddlers("[[one two three]] [[four five six]] +[enlist-input[]]").join(",")).toBe("one,two,three,four,five,six"); expect(wiki.filterTiddlers("[[one two three]] [[four five six]] [[seven eight]] +[enlist-input[]]").join(",")).toBe("one,two,three,four,five,six,seven,eight"); expect(wiki.filterTiddlers("[[]] +[enlist-input[]]").join(",")).toBe(""); @@ -207,7 +210,7 @@ function runTests(wiki) { it("should handle the lookup operator", function() { expect(wiki.filterTiddlers("Six Seventh 8 +[lookup[Tiddler]]").join(",")).toBe("Missing inaction from TiddlerOne,,Tidd"); - expect(wiki.filterTiddlers("Six Seventh 8 +[lookup:8[Tiddler]]").join(",")).toBe("Missing inaction from TiddlerOne,Tidd,Tidd"); + expect(wiki.filterTiddlers("Six Seventh 8 +[lookup:8[Tiddler]]").join(",")).toBe("Missing inaction from TiddlerOne,8,Tidd"); }); it("should retrieve shadow tiddlers", function() { @@ -456,7 +459,7 @@ function runTests(wiki) { it("should handle indirect operands", function() { expect(wiki.filterTiddlers("[prefix{Tiddler8}] +[sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne"); expect(wiki.filterTiddlers("[modifier{Tiddler8!!test-field}] +[sort[title]]").join(",")).toBe("TiddlerOne"); - var fakeWidget = {getVariable: function() {return "Tiddler Three";}}; + var fakeWidget = {wiki: wiki, getVariable: function() {return "Tiddler Three";}}; expect(wiki.filterTiddlers("[modifier{!!modifier}] +[sort[title]]",fakeWidget).join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three"); }); @@ -777,6 +780,17 @@ function runTests(wiki) { expect(wiki.filterTiddlers("[[Hello There]search-replace::regexp,[]]",anchorWidget).join(",")).toBe("Hllo There"); expect(wiki.filterTiddlers("[[Hello There]search-replace:gi[H],[]]",anchorWidget).join(",")).toBe("ello Tere"); }); + + it("should handle the pad operator", function() { + expect(wiki.filterTiddlers("[[2]pad[]]").join(",")).toBe("2"); + expect(wiki.filterTiddlers("[[2]pad[0]]").join(",")).toBe("2"); + expect(wiki.filterTiddlers("[[2]pad[1]]").join(",")).toBe("2"); + expect(wiki.filterTiddlers("2 20 +[pad[3]]").join(",")).toBe("002,020"); + expect(wiki.filterTiddlers("[[2]pad[9]]").join(",")).toBe("000000002"); + expect(wiki.filterTiddlers("[[2]pad[9],[a]]").join(",")).toBe("aaaaaaaa2"); + expect(wiki.filterTiddlers("[[12]pad[9],[abc]]").join(",")).toBe("abcabca12"); + expect(wiki.filterTiddlers("[[12]pad:suffix[9],[abc]]").join(",")).toBe("12abcabca"); + }); } }); diff --git a/editions/test/tiddlers/tests/test-utils.js b/editions/test/tiddlers/tests/test-utils.js index ec60a6691..e8f4de32f 100644 --- a/editions/test/tiddlers/tests/test-utils.js +++ b/editions/test/tiddlers/tests/test-utils.js @@ -25,6 +25,16 @@ describe("Utility tests", function() { expect(psa(" [[Tidd\u00a0ler8]] two ")).toEqual(["Tidd\u00a0ler8","two"]); }); + it("should handle parsing a date", function() { + var pd = function(v) { + return $tw.utils.parseDate(v).toUTCString(); + }; + expect(pd("20150428204930183")).toEqual("Tue, 28 Apr 2015 20:49:30 GMT"); + expect(pd("-20150428204930183")).toEqual("Sun, 28 Apr -2015 20:49:30 GMT"); + expect(pd("00730428204930183")).toEqual("Fri, 28 Apr 0073 20:49:30 GMT"); + expect(pd("-00730428204930183")).toEqual("Thu, 28 Apr -0073 20:49:30 GMT"); + }); + it("should handle base64 encoding emojis", function() { var booksEmoji = "📚"; expect(booksEmoji).toBe(booksEmoji); @@ -62,6 +72,8 @@ describe("Utility tests", function() { var fds = $tw.utils.formatDateString, // nov is month: 10! d = new Date(2014,10,9,17,41,28,542); + expect(fds(d,"{era:bce||ce}")).toBe("ce"); + expect(fds(d,"YYYY")).toBe("2014"); expect(fds(d,"DDD DD MMM YYYY")).toBe("Sunday 9 November 2014"); expect(fds(d,"ddd hh mm ssss")).toBe("Sun 17 41 2828"); expect(fds(d,"MM0DD")).toBe("1109"); @@ -92,6 +104,19 @@ describe("Utility tests", function() { d = new Date(2014,11,29,23,59,59); expect(fds(d,"WW")).toBe("1"); expect(fds(d,"wYYYY")).toBe("2015"); + + // Negative years + d = new Date(-2014,10,9,17,41,28,542); + expect(fds(d,"YYYY")).toBe("-2014"); + expect(fds(d,"aYYYY")).toBe("2014"); + expect(fds(d,"{era:bce||ce}")).toBe("bce"); + + // Zero years + d = new Date(0,10,9,17,41,28,542); + d.setUTCFullYear(0); // See https://stackoverflow.com/a/5870822 + expect(fds(d,"YYYY")).toBe("0000"); + expect(fds(d,"aYYYY")).toBe("0000"); + expect(fds(d,"{era:bce|z|ce}")).toBe("z"); }); it("should parse text references", function() { diff --git a/editions/tw5.com/tiddlers/community/resources/Favorites by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Favorites by Mohammad.tid new file mode 100644 index 000000000..17d6532b4 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Favorites by Mohammad.tid @@ -0,0 +1,18 @@ +created: 20201117155737569 +modified: 20201117155943559 +tags: Resources Plugings +title: Favorites by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW-Favorites/ + +Favorites plugin is a set of tool for creating favorites (bookmarks) in Tiddlywiki. Each favorite item is a shortcut to a tiddler. + +{{!!url}} + +A favorite item also called a bookmark is a shortcut, you are creating for quick access to it. You can access that bookmark at any time and view that as many times as you want without having to search and find it again. + +The Favorites plugin contains three modes + +* flat mode: one favorite list, no folder +* structured mode: use folder, search tool, export and delete tool +* frozen list: read only, simple table of content style diff --git a/editions/tw5.com/tiddlers/community/resources/GitHub Saver Tutorial by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/GitHub Saver Tutorial by Mohammad.tid new file mode 100644 index 000000000..07534dd5c --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/GitHub Saver Tutorial by Mohammad.tid @@ -0,0 +1,23 @@ +created: 20201117163027900 +modified: 20201117163855463 +tags: Resources +title: GitHub Saver Tutorial by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW5-GitHub-Saver/ + +GitHub Saver is a step by step tutorial shows how to integrate Tiddlywiki 5 and GitHub Pages to create websites hosted on https://github.com/. + +{{!!url}} + +This instruction is based on Tiddlywiki single html file model, while it can use subfolder for extra materials like images, audios, videos, pdfs,... in separate folders. + +!! Other tutorials + +;Tiddlywiki, Travis-CI and GitHub Pages +:https://kookma.github.io/Tiddlywiki-Travis-CI/ +:This wiki shows how to set up websites hosted on [[GitHub Pages|https://pages.github.com/]] using [[Travis-CI|https://travis-ci.org]] and [[Tiddlywiki 5|https://tiddlywiki.com]] on Node.js. + + +;Tiddlywiki and GitHub Pages +:https://kookma.github.io/Tiddlywiki-and-GitHub-Pages/ +:This instruction is based on local edit, save and push to GitHub. It does NOT use the new GitHub Saver mechanism (requires TW 5.1.20+) which lets edit and save directly from Tiddlywiki! \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/community/resources/Kookma Plugin Library by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Kookma Plugin Library by Mohammad.tid new file mode 100644 index 000000000..69cfc8181 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Kookma Plugin Library by Mohammad.tid @@ -0,0 +1,15 @@ +created: 20201117160603290 +modified: 20201117160819308 +tags: Resources Plugings +title: Kookma Plugin Library by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW-PluginLibrary/ + +This library contains most useful plugins developed under the name [[Kookma|https://github.com/kookma]] for Tiddlywiki 5. + +{{!!url}} + + +It has two parts + +The plugin library introduces a very simple mechanism like Tiddlywiki Official Plugin Library to let select among the published plugins and install any number of them you like. \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/community/resources/Refnotes by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Refnotes by Mohammad.tid new file mode 100644 index 000000000..3f400bc19 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Refnotes by Mohammad.tid @@ -0,0 +1,22 @@ +created: 20201117161853918 +modified: 20201117162122822 +tags: Resources Plugings +title: Refnotes by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/Refnotes/ + +Refnotes plugin is a set of macros and stylesheets for creating abbreviations, footnotes and citations. It also makes tables of footnotes, abbreviations (glossaery) and references (bibliography table). + +{{!!url}} + +Refnotes contains codes and elements to + +;Create and insert +:Abbreviation +:Footnote +:Reference + +;Create tables of +:Abbreviations or glossary +:Footnotes and endnote +:References (bibliography) using different output style \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/community/resources/RegExp in Tiddlywiki by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/RegExp in Tiddlywiki by Mohammad.tid new file mode 100644 index 000000000..8d962586e --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/RegExp in Tiddlywiki by Mohammad.tid @@ -0,0 +1,19 @@ +created: 20201117164024930 +modified: 20201117164308641 +tags: Resources +title: RegExp in Tiddlywiki by Mohammad +type: text/vnd.tiddlywiki +url: http://tw-regexp.tiddlyspot.com/ + +~RegExp in Tiddlywiki contains practical use cases of reular expression in Tiddlywiki. + +{{!!url}} + +The regular expression is a way to describe complex search patterns using sequences of characters . + +~RegExp in Tiddlywiki has four main parts + +* Using regular expression to match a pattern in tiddler title +* Using regular expression to match a pattern in tiddler fields excluding tiddler text (body) +* Using regular expression to match a pattern in tiddler body (text field) +* Using regular expression for validation like username, password, etc. \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/community/resources/Searchwikis by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Searchwikis by Mohammad.tid new file mode 100644 index 000000000..3f7cbc729 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Searchwikis by Mohammad.tid @@ -0,0 +1,21 @@ +created: 20201117160302426 +modified: 20201117160443306 +tags: Resources Plugings +title: Searchwikis by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW-Searchwikis/ + +Searchwikis plugin uses index (dataTiddler) to search multiple external Tiddlywikis. + +{{!!url}} + + +It has two parts + +# An indexer, to build an index of all tiddlers in an external wiki +# A search tool to search indexes and display a link to a tiddler found in an external wiki + +Then one master wiki can hosts many index tiddlers and lets to search several external wikis through index tiddlers. + +Searchwikis enable to have a central wiki and search all other wikis from one place. + diff --git a/editions/tw5.com/tiddlers/community/resources/Semantic Colors by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Semantic Colors by Mohammad.tid new file mode 100644 index 000000000..834348b94 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Semantic Colors by Mohammad.tid @@ -0,0 +1,22 @@ +created: 20201117162254751 +modified: 20201117162601326 +tags: Resources +title: Semantic Colors by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW-Semantic-Colors/ + +Semantic colors are set of CSS to apply colorful theme to individual tiddlers for categorization purpose. + +{{!!url}} + +Tiddlywiki "semantic colors" has two objectives: + +# How it is simply possible to apply theme to an individual tiddler +# Use semantic colors for categorization + +;Some use cases +:Learning materials (each topic, category can have dedicated semantic color, like learning a foreign language) +:Slideshow (section divider, each part can have a semantic color) +:Books and tutorials ( different semantic colors can be applied to chapters, specific subjects, like example tiddlers) +:Visual tags (instead of looking for tag bar and see to what category this subject (tiddler) belongs, you can identify it by its semantic color) + diff --git a/editions/tw5.com/tiddlers/community/resources/Shiraz by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Shiraz by Mohammad.tid new file mode 100644 index 000000000..38d743552 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Shiraz by Mohammad.tid @@ -0,0 +1,32 @@ +created: 20201116204317018 +modified: 20201116210618803 +tags: Resources Plugings +title: Shiraz by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW-Shiraz/ + +Shiraz plugin is a very small in size and framework to create stylish contents in Tiddlywiki. + +{{!!url}} + +Shiraz plugin contains extended markups, macros, styles, and many customization to empty Tiddlywiki and can be used as a ''starter kit''. + +Some of Shiraz features are: + +* Customized elements like, alerts, cards, panels, badges +* Dynamic tables +* Sortable tables +* Display on demand, slider, and details +* Images, basic image macros, slidein, and overlay images, polaroid and pretty images +* Table customization tools +* Sticky footer +* Multi columns tiddler +* Multi column story river +* List search +* Badge status +* Notebook style +* Test utilities +* Stylish buttons + + +Adding Shiraz plugin to any Tiddlywiki, convert it to a full production tool. Shiraz uses modified CSS classes from [[Bootstrap|https://getbootstrap.com/]]. \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/community/resources/Slider by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Slider by Mohammad.tid new file mode 100644 index 000000000..8373e86c8 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Slider by Mohammad.tid @@ -0,0 +1,18 @@ +created: 20201117162655614 +modified: 20201117162926714 +tags: Resources Plugings +title: Slider by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/slider/ + +Slider is a plugin to create an ordered set of tiddlers also called Trail. + +{{!!url}} + +A trail can be used to create a sequence of selected contents like step by step tutorial, guided help, lessons and similar. + +The slider plugin user interface contains three sections + +* A sidebar tab called Trails to manage trails +* A dashboard for each trail (where trail structure is managed) +* Tiddlers in a trail, also called slides diff --git a/editions/tw5.com/tiddlers/community/resources/TW-Scripts by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/TW-Scripts by Mohammad.tid new file mode 100644 index 000000000..d269023b6 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/TW-Scripts by Mohammad.tid @@ -0,0 +1,22 @@ +created: 20180830194141190 +modified: 20201116203625120 +tags: Resources +title: TW-Scripts by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW-Scripts/ + +TW-Scripts is one of the most comprehensive collections of solutions for Tiddlywiki 5. + +{{!!url}} + +TW-Scripts includes: + +* Collected solutions to questions in [[Tiddlywiki Google groups|https://groups.google.com/group/TiddlyWiki]] +* Learn through examples +* Templates, stylesheets +* Wikitext, macros, and snippets +* Tips and tricks +* Search tools  + + + diff --git a/editions/tw5.com/tiddlers/community/resources/Tiddler Commander by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Tiddler Commander by Mohammad.tid new file mode 100644 index 000000000..d2c873745 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Tiddler Commander by Mohammad.tid @@ -0,0 +1,25 @@ +created: 20201116203717105 +modified: 20201116204652385 +tags: Resources Plugings +title: Tiddler Commander by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW-Commander/ + +Tiddler Commander plugin, in short ''Commander'' is a unique tool for batch operations on tiddlers. + +{{!!url}} + +Commander has many features including: + +* Bulk tiddler creation/deletion +* Selective operation +* Combo search to filter and select tiddlers +* Title operation: add, remove prefixes and suffixes, also remove cahras form begining and end of title (on renaming tiddlers, [[relink|https://flibbles.github.io/tw5-relink/]] can be used to update title in other tiddlers) +* Tag operation: add, remove, replace +* Field operation: add, remove, rename, and set field value +* ~SnR, search and replace in all fields including text, tags, //title//, and common fields +* Inspect, to review and inspect tiddlers in one place, scroll among them and edit all fields (including common fields), tags, text (title is an exception!) +* Log, create logs of all operations +* Search, //save and load// any combination of filter search + + diff --git a/editions/tw5.com/tiddlers/community/resources/Tiddlyshow by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Tiddlyshow by Mohammad.tid new file mode 100644 index 000000000..50a639ac8 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Tiddlyshow by Mohammad.tid @@ -0,0 +1,16 @@ +created: 20201117160944367 +modified: 20201117162735263 +tags: Resources Plugings +title: Tiddlyshow by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/Tiddlyshow/ + +Tiddlyshow is a small application of Tiddlywiki for presentation and slideshow. It can also be used as a plugin. + +{{!!url}} + +Tiddlyshow contains the following features + +* Tools for preparing slides +* Shortcut keys for navigation (forward and backward) +* Themes to colorify and customize the slideshow diff --git a/editions/tw5.com/tiddlers/community/resources/Timelines by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Timelines by Mohammad.tid new file mode 100644 index 000000000..d1e6fa7cc --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Timelines by Mohammad.tid @@ -0,0 +1,14 @@ +created: 20201117161434779 +modified: 20201117161728094 +tags: Resources Plugings +title: Timelines by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW-Timelines/ + +Timelines plugin is for creating vertical and horizontal timeline and sequences. + +{{!!url}} + +The content or description and data of events are stored in individual tiddlers. + +Timelines contain two timeline macros and two sequence macros. A sequence macro shows event contents in sequence not necessarily in chronological order. The order can be determined by tag or list field or other methods. diff --git a/editions/tw5.com/tiddlers/community/resources/Todolist by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Todolist by Mohammad.tid new file mode 100644 index 000000000..5dcb15b75 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Todolist by Mohammad.tid @@ -0,0 +1,14 @@ +created: 20201116210711381 +modified: 20201116212041642 +tags: Resources Plugings +title: Todolist by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW-Todolist/ + +Todolist is a small pure wikitext plugin, contain all tools to work with todo list. + +{{!!url}} + +With Todolist, easily organize and prioritize your tasks and projects so you’ll always know exactly what to work on next. + +Todolist creates custom UI and lets you to add new items, set priority, done/undone items, archive, delete. Using Todolist plugin it is possible to create several todo lists in one Tiddlywiki. diff --git a/editions/tw5.com/tiddlers/community/resources/Trashbin by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Trashbin by Mohammad.tid new file mode 100644 index 000000000..c8e442ae9 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Trashbin by Mohammad.tid @@ -0,0 +1,14 @@ +created: 20201117155328920 +modified: 20201117155604253 +tags: Resources Plugings +title: Trashbin by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW-Trashbin/ + +The concept behind Trashbin plugin is to have a simple mechanism to move deleted tiddlers to Trashbin and be able to restore them later if required. + +{{!!url}} + +The trash (also known as the Recycle Bin in Microsoft Windows) is a temporary storage for tiddlers that have been deleted in a Tiddlywiki by the user, but not yet permanently erased. + +Typically, a trash bin is presented as a special storage, allowing the user to browse deleted (removed) tiddlers, undelete those that were deleted by mistake, or delete them permanently (either one by one, or by the "Empty Trash" function). diff --git a/editions/tw5.com/tiddlers/community/resources/Utility by Mohammad.tid b/editions/tw5.com/tiddlers/community/resources/Utility by Mohammad.tid new file mode 100644 index 000000000..38da64a30 --- /dev/null +++ b/editions/tw5.com/tiddlers/community/resources/Utility by Mohammad.tid @@ -0,0 +1,13 @@ +created: 20201117160011169 +modified: 20201117160235750 +tags: Resources Plugings +title: Utility by Mohammad +type: text/vnd.tiddlywiki +url: https://kookma.github.io/TW-Utility/ + +The utility plugin objective is to provide set of tools for developers and authors. + +{{!!url}} + + +These tools include simple transclusions, show raw contents of tiddlers, author tools, wikitext macros, show fields in view mode, etc. diff --git a/editions/tw5.com/tiddlers/concepts/Date Fields.tid b/editions/tw5.com/tiddlers/concepts/Date Fields.tid index b1dcbe82d..7ffb40c5c 100644 --- a/editions/tw5.com/tiddlers/concepts/Date Fields.tid +++ b/editions/tw5.com/tiddlers/concepts/Date Fields.tid @@ -1,15 +1,16 @@ created: 20150117190213631 -modified: 20150124214537000 +modified: 20201201154211507 tags: Concepts title: Date Fields type: text/vnd.tiddlywiki -Certain [[fields|TiddlerFields]] of a tiddler are used to store dates and times. +Certain [[fields|TiddlerFields]] of a tiddler are used to store dates and times. TiddlyWiki supports dates from the year -9999 to the year 9999. The two standard date fields are <<.field created>> and <<.field modified>>. -Values of date fields are 17-character strings: +Values of date fields are 17 or 18-character strings: +* <<.from-version "5.1.23">> an optional minus sign `-` to indicate a negative year * 4 digits for the year * 2 digits for the month * 2 digits for the day diff --git a/editions/tw5.com/tiddlers/concepts/InfoPanel.tid b/editions/tw5.com/tiddlers/concepts/InfoPanel.tid index 8c422a5c5..280f417d5 100644 --- a/editions/tw5.com/tiddlers/concepts/InfoPanel.tid +++ b/editions/tw5.com/tiddlers/concepts/InfoPanel.tid @@ -1,5 +1,5 @@ created: 20150917193630604 -modified: 20150917193631731 +modified: 20201129183045031 tags: Features title: InfoPanel type: text/vnd.tiddlywiki @@ -9,7 +9,7 @@ Each tiddler has a panel of additional information. To reveal it, click the <<.i The info panel has the following tabs: * ''Tools'' - This offers buttons for various actions you can perform on the tiddler. The checkbox next to each button lets you promote an action to the tiddler's toolbar - this will affect all of the tiddlers in your wiki -* ''References'', ''Tagging'', ''List'' and ''Listed'' - These list various kinds of related tiddlers. See [[Using links to navigate between tiddlers]] +* ''Backlinks'', ''Tagging'', ''List'' and ''Listed'' - These list various kinds of related tiddlers. See [[Using links to navigate between tiddlers]] * ''Fields'' - This summarises all of the tiddler's [[fields|TiddlerFields]], except for ''text'' * ''Advanced'' - This indicates whether the tiddler is a [[shadow|ShadowTiddlers]]. If it is, this also reveals which plugin it comes from and whether it has been overridden by an ordinary tiddler diff --git a/editions/tw5.com/tiddlers/concepts/SystemTags.tid b/editions/tw5.com/tiddlers/concepts/SystemTags.tid index d7f01cbf1..6b6d4a5a1 100644 --- a/editions/tw5.com/tiddlers/concepts/SystemTags.tid +++ b/editions/tw5.com/tiddlers/concepts/SystemTags.tid @@ -1,5 +1,6 @@ created: 20130822080600000 -modified: 20180927080631239 +list: [[SystemTag: $:/tags/AboveStory]] [[SystemTag: $:/tags/AdvancedSearch]] [[SystemTag: $:/tags/AdvancedSearch/FilterButton]] [[SystemTag: $:/tags/Alert]] [[SystemTag: $:/tags/BelowStory]] [[SystemTag: $:/tags/ControlPanel]] [[SystemTag: $:/tags/ControlPanel/Advanced]] [[SystemTag: $:/tags/ControlPanel/Appearance]] [[SystemTag: $:/tags/ControlPanel/Info]] [[SystemTag: $:/tags/ControlPanel/Saving]] [[SystemTag: $:/tags/ControlPanel/Settings]] [[SystemTag: $:/tags/ControlPanel/Toolbars]] [[SystemTag: $:/tags/EditorToolbar]] [[SystemTag: $:/tags/EditPreview]] [[SystemTag: $:/tags/EditTemplate]] [[SystemTag: $:/tags/EditToolbar]] [[SystemTag: $:/tags/Exporter]] [[SystemTag: $:/tags/Filter]] [[SystemTag: $:/tags/Image]] [[SystemTag: $:/tags/ImportPreview]] [[SystemTag: $:/tags/KeyboardShortcut]] [[SystemTag: $:/tags/Layout]] [[SystemTag: $:/tags/Macro]] [[SystemTag: $:/tags/Macro/View]] [[SystemTag: $:/tags/Manager/ItemMain]] [[SystemTag: $:/tags/Manager/ItemSidebar]] [[SystemTag: $:/tags/MoreSideBar]] [[SystemTag: $:/tags/MoreSideBar/Plugins]] [[SystemTag: $:/tags/PageControls]] [[SystemTag: $:/tags/PageTemplate]] [[SystemTag: $:/tags/Palette]] [[SystemTag: $:/tags/PluginLibrary]] [[SystemTag: $:/tags/RawMarkup]] [[SystemTag: $:/tags/RawMarkupWikified]] [[SystemTag: $:/tags/RawMarkupWikified/BottomBody]] [[SystemTag: $:/tags/RawMarkupWikified/TopBody]] [[SystemTag: $:/tags/RawMarkupWikified/TopHead]] [[SystemTag: $:/tags/RawStaticContent]] [[SystemTag: $:/tags/RemoteAssetInfo]] [[SystemTag: $:/tags/SearchResults]] [[SystemTag: $:/tags/ServerConnection]] [[SystemTag: $:/tags/SideBar]] [[SystemTag: $:/tags/SideBarSegment]] [[SystemTag: $:/tags/StartupAction]] [[SystemTag: $:/tags/StartupAction/Browser]] [[SystemTag: $:/tags/StartupAction/Node]] [[SystemTag: $:/tags/Stylesheet]] [[SystemTag: $:/tags/TagDropdown]] [[SystemTag: $:/tags/TextEditor/Snippet]] [[SystemTag: $:/tags/TiddlerInfo]] [[SystemTag: $:/tags/TiddlerInfo/Advanced]] [[SystemTag: $:/tags/TiddlerInfoSegment]] [[SystemTag: $:/tags/ToolbarButtonStyle]] [[SystemTag: $:/tags/TopLeftBar]] [[SystemTag: $:/tags/TopRightBar]] [[SystemTag: $:/tags/ViewTemplate]] [[SystemTag: $:/tags/ViewToolbar]] +modified: 20201123192434277 tags: Reference Concepts title: SystemTags type: text/vnd.tiddlywiki diff --git a/editions/tw5.com/tiddlers/customising/Alternative page layouts.tid b/editions/tw5.com/tiddlers/customising/Alternative page layouts.tid new file mode 100644 index 000000000..554313b73 --- /dev/null +++ b/editions/tw5.com/tiddlers/customising/Alternative page layouts.tid @@ -0,0 +1,15 @@ +created: 20201123172925848 +modified: 20201123192845498 +tags: [[Customise TiddlyWiki]] +title: Alternative page layouts +type: text/vnd.tiddlywiki + +<<.from-version "5.1.23">> You can have multiple alternative page layouts and switch between them. To see a list of available layouts and switch between them, use the keyboard shortcut <>. + +! Creating an alternative page layout + +Creating an alternative layout goes beyond [[adding or removing features|Page and tiddler layout customisation]] from the default interface and allows you to create an entirely new layout from scratch. + +To create an alternative page layout and have the ability to switch to it, you need to create an alternative page template tiddler with the [[SystemTag: $:/tags/Layout]]. + +This alternative page template can either be a tweaked and modified version of the [[default page template|$:/core/ui/PageTemplate]], or something entirely different. The layout switching mechanism requires that your page template tiddler has the fields `name` and `description`, which are used in the listing in the switching user interface. \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/customising/Configuring startup tiddlers.tid b/editions/tw5.com/tiddlers/customising/Configuring startup tiddlers.tid index c1697f55e..752415fd9 100644 --- a/editions/tw5.com/tiddlers/customising/Configuring startup tiddlers.tid +++ b/editions/tw5.com/tiddlers/customising/Configuring startup tiddlers.tid @@ -22,4 +22,6 @@ You can also use [[filter expressions|Filter Expression]] to open more than one will open all tiddlers tagged as <>. -You can also use this technique to [[preserve open tiddlers at startup|Preserving open tiddlers at startup]] \ No newline at end of file +You can also use this technique to [[preserve open tiddlers at startup|Preserving open tiddlers at startup]] + +See also [[StartupActions]] for controlling more advanced startup behaviours. diff --git a/editions/tw5.com/tiddlers/customising/Customise TiddlyWiki.tid b/editions/tw5.com/tiddlers/customising/Customise TiddlyWiki.tid index 29820d5a9..3c1327366 100644 --- a/editions/tw5.com/tiddlers/customising/Customise TiddlyWiki.tid +++ b/editions/tw5.com/tiddlers/customising/Customise TiddlyWiki.tid @@ -1,8 +1,9 @@ -title: Customise TiddlyWiki +created: 20140904101600000 +list: [[Adding a table of contents to the sidebar]] [[Configuring startup tiddlers]] [[Configuring the default TiddlerInfo tab]] [[Creating a custom export format]] [[Creating a splash screen]] [[Customising search results]] [[Hidden Settings]] [[How to add a new tab to the sidebar]] [[How to apply custom styles]] [[How to create keyboard shortcuts]] [[How to turn off camel case linking]] [[How to widen tiddlers (aka storyriver)]] [[Making a custom journal button]] [[Page and tiddler layout customisation]] [[Alternative page layouts]] [[Preserving open tiddlers at startup]] [[Setting a favicon]] [[Setting a page background image]] [[Using Stylesheets]] +modified: 20201123173044437 tags: TableOfContents -created: 201409041016 -modified: 201409041016 -list: [[Initial customisation]] +title: Customise TiddlyWiki +type: text/vnd.tiddlywiki Information about customising TiddlyWiki diff --git a/editions/tw5.com/tiddlers/customising/Page and tiddler layout customisation.tid b/editions/tw5.com/tiddlers/customising/Page and tiddler layout customisation.tid index 7a233d396..a99687aac 100644 --- a/editions/tw5.com/tiddlers/customising/Page and tiddler layout customisation.tid +++ b/editions/tw5.com/tiddlers/customising/Page and tiddler layout customisation.tid @@ -1,7 +1,8 @@ -title: Page and tiddler layout customisation +created: 20141120125300000 +modified: 20201123173002935 tags: [[Customise TiddlyWiki]] -created: 201411201253 -modified: 201411201253 +title: Page and tiddler layout customisation +type: text/vnd.tiddlywiki One major feature of TiddlyWiki that many new users are unaware of is the degree to which TiddlyWiki can be customised, just by adding or removing SystemTags in key shadow tiddlers or in your own custom tiddlers. @@ -11,6 +12,8 @@ One major feature of TiddlyWiki that many new users are unaware of is the degree Once you know what you are doing, all of these things are actually pretty easy to do. +<<.from-version "5.1.23">> You can also create [[alternative page layouts|Alternative page layouts]] and switch between them. + ! Adding custom-made tiddlers to the user interface You can also create any tiddler you want and tag it with the appropriate SystemTag, and it will appear in that place. For example, if you create a tiddler 'Reminder to self', add the text 'This is a reminder' and tag it `$:/tags/EditTemplate`, the words 'This is a reminder' will appear inside every tiddler when you edit it. diff --git a/editions/tw5.com/tiddlers/definitions/Web Developer Tools.tid b/editions/tw5.com/tiddlers/definitions/Web Developer Tools.tid new file mode 100644 index 000000000..c02f4c277 --- /dev/null +++ b/editions/tw5.com/tiddlers/definitions/Web Developer Tools.tid @@ -0,0 +1,7 @@ +created: 20201120153119665 +modified: 20201120154646100 +tags: Definitions +title: Web Developer Tools +type: text/vnd.tiddlywiki + +Most browsers provide ''Web Developer Tools'' that include a JavaScript console. In Chrome and Firefox it can be opened via the ''Tools'' menu, or by pressing Ctrl + Shift + J (Cmd + Shift + J on a Mac). \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/features/DateFormat.tid b/editions/tw5.com/tiddlers/features/DateFormat.tid index 4d138e576..d0426565e 100644 --- a/editions/tw5.com/tiddlers/features/DateFormat.tid +++ b/editions/tw5.com/tiddlers/features/DateFormat.tid @@ -1,5 +1,5 @@ created: 20140418142957325 -modified: 20180730201626985 +modified: 20201201154521138 tags: Features title: DateFormat type: text/vnd.tiddlywiki @@ -21,7 +21,9 @@ When used to display date values (with the `format` attribute set to ''date''), |`YYYY` |Full year | |`YY` |Two digit year | |`wYYYY` |Full year with respect to week number | +|`aYYYY` |<<.from-version "5.1.23">> Full year but negative dates are displayed as positive | |`wYY` |Two digit year with respect to week number | +|`{era:BCE||CE}` |<<.from-version "5.1.23">> Displays a different string for years that are negative, zero or positive (see below) | |`hh` |Hours | |`0hh` |Adds a leading zero | |`hh12` |Hours in 12 hour clock | @@ -40,6 +42,8 @@ When used to display date values (with the `format` attribute set to ''date''), Note that other text is passed through unchanged, allowing commas, colons or other separators to be used. +The `{era:BCE||CE}` notation can specify different strings for years that are negative, zero or positive. For example `{era:BC|Z|AD}` would display `BC` for negative years, `AD` for positive years, and `Z` for year zero. + ! Examples |!Template |!Output | diff --git a/editions/tw5.com/tiddlers/features/Modals.tid b/editions/tw5.com/tiddlers/features/Modals.tid index aa87ab68c..06b43a880 100644 --- a/editions/tw5.com/tiddlers/features/Modals.tid +++ b/editions/tw5.com/tiddlers/features/Modals.tid @@ -1,5 +1,5 @@ created: 20160107225427489 -modified: 20200312172056083 +modified: 20201117081054556 tags: Features title: Modals type: text/vnd.tiddlywiki @@ -10,9 +10,11 @@ The tiddler to be displayed can contain the following optional fields that are u |!Field |!Description | |footer|The footer text for the modal| -|subtitle|The subtitle text for a modal| +|subtitle|The subtitle text for a modal, displayed in a `h3` html tag| |class|An additional class to apply to the modal wrapper| +Note that the footer and subtitle fields are not limited to plain text, and wiki text features such as widgets and transclusions can be used as well. + Modals are displayed with the [[WidgetMessage: tm-modal]]. <$button message="tm-modal" param="SampleWizard">Open demo modal diff --git a/editions/tw5.com/tiddlers/filters/compare Operator.tid b/editions/tw5.com/tiddlers/filters/compare Operator.tid index a882914ae..95bdce2a9 100644 --- a/editions/tw5.com/tiddlers/filters/compare Operator.tid +++ b/editions/tw5.com/tiddlers/filters/compare Operator.tid @@ -30,7 +30,7 @@ The ''type'' can be: The ''mode'' can be: * "eq" - equal to -* "ne" - not equal ot +* "ne" - not equal to * "gteq" - greater than or equal to * "gt" - greater than * "lteq" - less than or equal to diff --git a/editions/tw5.com/tiddlers/filters/cycle Operator.tid b/editions/tw5.com/tiddlers/filters/cycle Operator.tid new file mode 100644 index 000000000..f54316f29 --- /dev/null +++ b/editions/tw5.com/tiddlers/filters/cycle Operator.tid @@ -0,0 +1,24 @@ +caption: cycle +created: 20201118172906835 +modified: 20201118192136472 +op-input: a list of items +op-output: the input list with the titles specified in the parameter toggled in a cyclical manner +op-parameter: the <<.op cycle>> operator accepts 1 or 2 parameters, see below for details +op-purpose: toggle in the input, the titles specified in the first operand in a cyclical manner +tags: [[Filter Operators]] [[Listops Operators]] [[Order Operators]] +title: cycle Operator +type: text/vnd.tiddlywiki + +<<.from-version "5.1.23">> + +The <<.op cycle>> operator requires at least one parameter. + +``` +[cycle[],[step-size]] +``` +* ''titles'' : a title list to toggle in the input list cyclically. If no title from the parameter is present in the input, the first title is added. If a title from the parameter is present in the input, it is replaced with the next title from the parameter. Note that all titles specified in this parameter should be unique. +* ''step-size'': (optional). Defaults to 1. Specifies the number of steps in the parameter list to move each time. Can be a negative number. + +<$macrocall $name=".tip" _="While the <<.op cycle>> operator interprets its first parameter as a list of titles to cycle through, the [[toggle Operator]] accepts an unlimited number of distinct parameters and offers similar functionality."/> + +<<.operator-examples "cycle">> diff --git a/editions/tw5.com/tiddlers/filters/enlist-input Operator.tid b/editions/tw5.com/tiddlers/filters/enlist-input Operator.tid index 3a9dd529a..a561a8e12 100644 --- a/editions/tw5.com/tiddlers/filters/enlist-input Operator.tid +++ b/editions/tw5.com/tiddlers/filters/enlist-input Operator.tid @@ -4,6 +4,8 @@ modified: 20201102221854719 op-input: a [[selection of titles|Title Selection]] op-output: the titles stored as a [[title list|Title List]] in each input title op-purpose: select titles by interpreting each input title as a [[title list|Title List]] +op-suffix: `dedupe` (the default) to remove duplicates, `raw` to leave duplicates untouched +op-suffix-name: D tags: [[Filter Operators]] [[String Operators]] [[Selection Constructors]] title: enlist-input Operator type: text/vnd.tiddlywiki diff --git a/editions/tw5.com/tiddlers/filters/examples/How to remove stop words.tid b/editions/tw5.com/tiddlers/filters/examples/How to remove stop words.tid new file mode 100644 index 000000000..a228e4404 --- /dev/null +++ b/editions/tw5.com/tiddlers/filters/examples/How to remove stop words.tid @@ -0,0 +1,28 @@ +created: 20201118094513209 +modified: 20201118103414384 +tags: [[Operator Examples]] [[search-replace Operator]] [[sortsub Operator]] +title: How to remove stop words +type: text/vnd.tiddlywiki + +\define book-list() +[[A Tale of Two Cities]] +[[The Dice Man]] +[[A New Kind of Science]] +[[The Recursive Universe]] +[[Great Expectations]] +[[Animal Farm]] +\end + +\define compare-without-stopwords() +[search-replace:i:regexp[^The |A ],[]] +\end + +You can use the [[search-replace Operator]] in combination with the [[sortsub Operator]] to ignore stop words like "A" and "The" at the beginning of titles when sorting. (Note for example that "A Tale of Two Cities" sorts under "T" rather than "A") +<<.operator-example 6 "[enlistsortsub]">> + +You can also customise the listing so that "A Tale of Two Cities" is listed as "Tale of Two Cities, A" but still links to the correct tiddler. +< +<$list filter="[enlistsortsub]"> +
  • <$link><$text text={{{[search-replace:i:regexp[(^The |A )(.*)],[$2, $1]]}}}/>
  • + +""">> \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/filters/examples/cycle Operator (Examples).tid b/editions/tw5.com/tiddlers/filters/examples/cycle Operator (Examples).tid new file mode 100644 index 000000000..0ff1d0336 --- /dev/null +++ b/editions/tw5.com/tiddlers/filters/examples/cycle Operator (Examples).tid @@ -0,0 +1,21 @@ +created: 20201118174250896 +modified: 20201118175415868 +tags: [[Operator Examples]] [[cycle Operator]] +title: cycle Operator (Examples) +type: text/vnd.tiddlywiki + +Cycle through a list of values to add as a tag: + +``` +<$action-listops $tiddler="target" $tags="+[cycle[todo soon now maybe done ]]" /> +``` + +Cycle through a list of values to add as a tag, in reverse order: + +``` +<$action-listops $tiddler="target" $tags="+[cycle[todo soon now maybe done ],[-1]]" /> +``` + +<<.using-days-of-week>> +<<.operator-example 1 """[list[Days of the Week]first[]] +[cycle{Days of the Week!!list}]""">> +<<.operator-example 1 """[list[Days of the Week]first[]] +[cycle{Days of the Week!!list},[2]]""">> \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/filters/examples/enlist-input Operator (Examples).tid b/editions/tw5.com/tiddlers/filters/examples/enlist-input Operator (Examples).tid index c02a85c4c..7e4eee4a7 100644 --- a/editions/tw5.com/tiddlers/filters/examples/enlist-input Operator (Examples).tid +++ b/editions/tw5.com/tiddlers/filters/examples/enlist-input Operator (Examples).tid @@ -7,4 +7,6 @@ type: text/vnd.tiddlywiki <<.operator-example 1 "[[Days of the Week]get[list]enlist-input[]]">> Contrast with: <<.operator-example 2 "[[Days of the Week]get[list]]">> <<.operator-example 3 "'HelloThere GettingStarted [[Customise TiddlyWiki]]' +[enlist-input[]]">> -Contrast with: <<.operator-example 4 "'HelloThere GettingStarted [[Customise TiddlyWiki]]'">> \ No newline at end of file +Contrast with: <<.operator-example 4 "'HelloThere GettingStarted [[Customise TiddlyWiki]]'">> +<<.operator-example 5 "'HelloThere HelloThere GettingStarted [[Customise TiddlyWiki]]' +[enlist-input:raw[]]">> +Contrast with: <<.operator-example 6 "'HelloThere HelloThere GettingStarted [[Customise TiddlyWiki]]' +[enlist-input[]]">> diff --git a/editions/tw5.com/tiddlers/filters/examples/jsonstringify Operator (Examples).tid b/editions/tw5.com/tiddlers/filters/examples/jsonstringify Operator (Examples).tid index 20f7bff75..ead9ffb38 100644 --- a/editions/tw5.com/tiddlers/filters/examples/jsonstringify Operator (Examples).tid +++ b/editions/tw5.com/tiddlers/filters/examples/jsonstringify Operator (Examples).tid @@ -5,3 +5,5 @@ title: jsonstringify Operator (Examples) type: text/vnd.tiddlywiki <<.operator-example 1 """[[Title with "double quotes" and single ' and \backslash]] +[jsonstringify[]]""">> +<<.operator-example 2 """[[Accents and emojis -> äñøßπ ⌛🎄🍪🍓 without suffix]] +[jsonstringify[]]""">> +<<.operator-example 3 """[[Accents and emojis -> äñøßπ ⌛🎄🍪🍓 with rawunicode suffix]] +[jsonstringify:rawunicode[]]""">> diff --git a/editions/tw5.com/tiddlers/filters/examples/log Operator (Examples).tid b/editions/tw5.com/tiddlers/filters/examples/log Operator (Examples).tid new file mode 100644 index 000000000..371952170 --- /dev/null +++ b/editions/tw5.com/tiddlers/filters/examples/log Operator (Examples).tid @@ -0,0 +1,14 @@ +created: 20201120041503515 +modified: 20201120042024813 +tags: [[Operator Examples]] [[log Operator]] +title: log Operator (Examples) +type: text/vnd.tiddlywiki + +Logarithm of `8` with base `2`: +<<.operator-example 1 "[[8]log[2]]">> + +Logarithm of `100` with base `10`: +<<.operator-example 2 "[[100]log[10]]">> + +Natural logarithm of 10 (base `e`), equivalent to `ln(10)` in mathematics: +<<.operator-example 2 "[[10]log[]]">> diff --git a/editions/tw5.com/tiddlers/filters/examples/pad Operator (Examples).tid b/editions/tw5.com/tiddlers/filters/examples/pad Operator (Examples).tid new file mode 100644 index 000000000..2ccf8ea77 --- /dev/null +++ b/editions/tw5.com/tiddlers/filters/examples/pad Operator (Examples).tid @@ -0,0 +1,13 @@ +created: 20201129174833980 +modified: 20201129180011580 +tags: [[Operator Examples]] [[pad Operator]] +title: pad Operator (Examples) +type: text/vnd.tiddlywiki + +<<.operator-example 1 """[[2]pad[3]]""">> + +<<.operator-example 2 """[[2]pad[3],[a]]""">> + +<<.operator-example 3 """[[12]pad[9],[abc]]""">> + +<<.operator-example 4 """[[12]pad:suffix[9],[abc]]""">> \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/filters/examples/power Operator (Examples).tid b/editions/tw5.com/tiddlers/filters/examples/power Operator (Examples).tid new file mode 100644 index 000000000..e2bfdb0f5 --- /dev/null +++ b/editions/tw5.com/tiddlers/filters/examples/power Operator (Examples).tid @@ -0,0 +1,8 @@ +created: 20201120040913073 +modified: 20201120041513726 +tags: [[Operator Examples]] [[power Operator]] +title: power Operator (Examples) +type: text/vnd.tiddlywiki + +<<.operator-example 1 "[[3]power[3]]">> +<<.operator-example 2 "9 +[power[2]]">> diff --git a/editions/tw5.com/tiddlers/filters/examples/reduce Operator (Examples).tid b/editions/tw5.com/tiddlers/filters/examples/reduce Operator (Examples).tid index 9d92ea0c8..1c619c506 100644 --- a/editions/tw5.com/tiddlers/filters/examples/reduce Operator (Examples).tid +++ b/editions/tw5.com/tiddlers/filters/examples/reduce Operator (Examples).tid @@ -1,5 +1,5 @@ created: 20201004154413968 -modified: 20201006181831622 +modified: 20201204131137081 tags: [[Operator Examples]] [[reduce Operator]] title: reduce Operator (Examples) type: text/vnd.tiddlywiki @@ -42,7 +42,7 @@ Using `` to act differently on the first item than the rest: <<.operator-example 3 "[tag[shopping]reduce]">> -Empty input, no suffix: +Empty input, no second parameter: <<.operator-example 4 "[tag[non-existent]reduce]">> @@ -50,12 +50,12 @@ Note how the output contains a single item with no text. This is not "empty outp <$macrocall $name=".tip" _=<> /> -Empty input, no suffix, followed by <<.op else>>: +Empty input, no second parameter, followed by <<.op else>>: <<.operator-example 5 "[tag[non-existent]reduceelse[0]]">> -Note how the output still contains a single item with no text: <<.op else>> did not trigger. If you want the value to be 0 when <<.op reduce>> has no items to process, you need to specify 0 as the initial value by passing it as a suffix to <<.op reduce>>. +Note how the output still contains a single item with no text: <<.op else>> did not trigger. If you want the value to be 0 when <<.op reduce>> has no items to process, you need to specify 0 as the initial value by passing it as a second parameter to <<.op reduce>>. -Empty input, suffix provided: +Empty input, second parameter provided: -<<.operator-example 6 "[tag[non-existent]reduce:0]">> +<<.operator-example 6 "[tag[non-existent]reduce,[0]]">> diff --git a/editions/tw5.com/tiddlers/filters/search-replace Operator (Examples).tid b/editions/tw5.com/tiddlers/filters/examples/search-replace Operator (Examples).tid similarity index 91% rename from editions/tw5.com/tiddlers/filters/search-replace Operator (Examples).tid rename to editions/tw5.com/tiddlers/filters/examples/search-replace Operator (Examples).tid index 79c9b60b6..5bcb57509 100644 --- a/editions/tw5.com/tiddlers/filters/search-replace Operator (Examples).tid +++ b/editions/tw5.com/tiddlers/filters/examples/search-replace Operator (Examples).tid @@ -1,5 +1,5 @@ created: 20201107112846692 -modified: 20201107113536230 +modified: 20201118103305351 tags: [[Operator Examples]] [[search-replace Operator]] title: search-replace Operator (Examples) type: text/vnd.tiddlywiki @@ -20,6 +20,7 @@ Replace all matches of a string irrespective of case: <<.operator-example 3 """[[Hello There]search-replace:gi[H],[]]""">> You can also use regular expression capture groups in the replacement string: - `\define names() (\w+)\s(\w+)` -<<.operator-example 4 """[[John Smith]search-replace::regexp,[$2,$1]]""" >> \ No newline at end of file +<<.operator-example 4 """[[John Smith]search-replace::regexp,[$2,$1]]""" >> + +{{How to remove stop words}} diff --git a/editions/tw5.com/tiddlers/filters/examples/sortsub Operator (Examples).tid b/editions/tw5.com/tiddlers/filters/examples/sortsub Operator (Examples).tid index 475413155..ea91205d9 100644 --- a/editions/tw5.com/tiddlers/filters/examples/sortsub Operator (Examples).tid +++ b/editions/tw5.com/tiddlers/filters/examples/sortsub Operator (Examples).tid @@ -1,5 +1,5 @@ created: 20200425110427700 -modified: 20200425110427700 +modified: 20201118103327392 tags: [[sortsub Operator]] [[Operator Examples]] title: sortsub Operator (Examples) type: text/vnd.tiddlywiki @@ -29,4 +29,6 @@ These examples make use of the following variables: <<.operator-example 4 "[!sortsub:numberlimit[10]]">> <<.operator-example 5 "[tag[Field Operators]sortsub:date]">> +{{How to remove stop words}} + \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/filters/examples/stringify_Operator_(Examples).tid b/editions/tw5.com/tiddlers/filters/examples/stringify_Operator_(Examples).tid index 1378287f5..a664cf7d2 100644 --- a/editions/tw5.com/tiddlers/filters/examples/stringify_Operator_(Examples).tid +++ b/editions/tw5.com/tiddlers/filters/examples/stringify_Operator_(Examples).tid @@ -5,3 +5,5 @@ title: stringify Operator (Examples) type: text/vnd.tiddlywiki <<.operator-example 1 """[[Title with "double quotes" and single ' and \backslash]] +[stringify[]]""">> +<<.operator-example 2 """[[Accents and emojis -> äñøßπ ⌛🎄🍪🍓 without suffix]] +[stringify[]]""">> +<<.operator-example 3 """[[Accents and emojis -> äñøßπ ⌛🎄🍪🍓 with rawunicode suffix]] +[stringify:rawunicode[]]""">> diff --git a/editions/tw5.com/tiddlers/filters/toggle Operator (Examples).tid b/editions/tw5.com/tiddlers/filters/examples/toggle Operator (Examples).tid similarity index 87% rename from editions/tw5.com/tiddlers/filters/toggle Operator (Examples).tid rename to editions/tw5.com/tiddlers/filters/examples/toggle Operator (Examples).tid index 95e3d56a8..7fa986b7e 100644 --- a/editions/tw5.com/tiddlers/filters/toggle Operator (Examples).tid +++ b/editions/tw5.com/tiddlers/filters/examples/toggle Operator (Examples).tid @@ -1,5 +1,6 @@ created: 20201107154352695 -modified: 20201109104951727 +modified: 20201118174726982 +tags: [[Operator Examples]] [[toggle Operator]] title: toggle Operator (Examples) type: text/vnd.tiddlywiki diff --git a/editions/tw5.com/tiddlers/filters/jsonstringify Operator.tid b/editions/tw5.com/tiddlers/filters/jsonstringify Operator.tid index ff361450e..a7e4d565c 100644 --- a/editions/tw5.com/tiddlers/filters/jsonstringify Operator.tid +++ b/editions/tw5.com/tiddlers/filters/jsonstringify Operator.tid @@ -7,22 +7,29 @@ op-output: the input with JSON string encodings applied op-parameter: op-parameter-name: op-purpose: apply JSON string encoding to a string +op-suffix: <<.from-version "5.1.23">> optionally, the keyword `rawunicode` +op-suffix-name: R tags: [[Filter Operators]] [[String Operators]] title: jsonstringify Operator type: text/vnd.tiddlywiki The following substitutions are made: -|!Character |!Replacement | -|`\` |`\\` | -|`"` |`\"` | -|`\r` (carriage return) |`\\r` | -|`\n` (line feed) |`\\n` | -|`\x08` (backspace) |`\\b` | -|`\x0c` (form field) |`\\f` | -|`\t` (tab) |`\\t` | -|Characters from 0x00 to 0x1f |`\\x##` where ## is two hex digits | -|Characters from 0x80 to 0xffff |`\\u####` where #### is four hex digits | +|!Character |!Replacement |!Condition | +|`\` |`\\` |Always | +|`"` |`\"` |Always | +|Carriage return (0x0d) |`\\r` |Always | +|Line feed (0x0a) |`\\n` |Always | +|Backspace (0x08) |`\\b` |Always | +|Form field (0x0c) |`\\f` |Always | +|Tab (0x09) |`\\t` |Always | +|Characters from 0x00 to 0x1f |`\\u####` where #### is four hex digits |Always | +|Characters from 0x80 to 0xffff|`\\u####` where #### is four hex digits |If `rawunicode` suffix is not present (default) | +|Characters from 0x80 to 0xffff|Unchanged |If `rawunicode` suffix is present <<.from-version "5.1.23">> | + +<<.from-version "5.1.23">> If the suffix `rawunicode` is present, Unicode characters above 0x80 (such as ß, ä, ñ or 🎄) will be passed through unchanged. Without the suffix, they will be substituted with `\\u` codes, which was the default behavior before 5.1.23. + +<<.note """Technical note: Characters outside the Basic Multilingual Plane, such as 🎄 and other emojis, will be encoded as a UTF-16 surrogate pair, i.e. with two `\u` sequences.""">> Also see the [[stringify Operator]]. diff --git a/editions/tw5.com/tiddlers/filters/log Operator.tid b/editions/tw5.com/tiddlers/filters/log Operator.tid new file mode 100644 index 000000000..bfca18853 --- /dev/null +++ b/editions/tw5.com/tiddlers/filters/log Operator.tid @@ -0,0 +1,15 @@ +caption: log +created: 20201120041113537 +modified: 20201120041443518 +op-input: a [[selection of titles|Title Selection]] +op-output: the logarithm of each input title as numbers, with base <<.place N>> if specified otherwise base `e` +op-parameter: a number +op-parameter-name: N +op-purpose: treating each input title as a number, return its logarithm with base equal to the numeric value of the operand if specified, otherwise base `e` +tags: [[Filter Operators]] [[Mathematics Operators]] [[Binary Mathematics Operators]] +title: log Operator +type: text/vnd.tiddlywiki + +<<.from-version "5.1.23">> + +<<.operator-examples "log">> diff --git a/editions/tw5.com/tiddlers/filters/pad Operator.tid b/editions/tw5.com/tiddlers/filters/pad Operator.tid new file mode 100644 index 000000000..defacf117 --- /dev/null +++ b/editions/tw5.com/tiddlers/filters/pad Operator.tid @@ -0,0 +1,23 @@ +caption: pad +created: 20201129174215674 +modified: 20201129175301148 +op-input: a [[selection of titles|Title Selection]] +op-output: the input titles padded to the specified length +op-parameter: the <<.op pad>> operator accepts 1 or more parameters, see below for details +op-purpose: returns each item in the list padded to the specified length +op-suffix: (optional). Whether to pad by adding a "suffix" or "prefix". Defaults to "prefix". +tags: [[Filter Operators]] [[String Operators]] +title: pad Operator +type: text/vnd.tiddlywiki + +<<.from-version "5.1.23">> + +The <<.op pad>> operator requires at least one parameter which specifies the desired length of the input titles. A second optional parameter can be used to specify the string to pad with (defaults to "0"). + +``` +[pad[],[]] +``` +* ''length'' : the desired final length of the input titles. +* ''padding-string'': (optional). The string to use to pad to the desired length. Defaults to "0". + +<<.operator-examples "pad">> diff --git a/editions/tw5.com/tiddlers/filters/power Operator.tid b/editions/tw5.com/tiddlers/filters/power Operator.tid new file mode 100644 index 000000000..d4afb67ce --- /dev/null +++ b/editions/tw5.com/tiddlers/filters/power Operator.tid @@ -0,0 +1,15 @@ +caption: power +created: 20201120040720190 +modified: 20201120040852980 +op-input: a [[selection of titles|Title Selection]] +op-output: the input as numbers, but with each one raised to the power of <<.place N>> +op-parameter: a number +op-parameter-name: N +op-purpose: treating each input title as a number, raise it to the power of the numeric value of the operand +tags: [[Filter Operators]] [[Mathematics Operators]] [[Binary Mathematics Operators]] +title: power Operator +type: text/vnd.tiddlywiki + +<<.from-version "5.1.23">> + +<<.operator-examples "power">> diff --git a/editions/tw5.com/tiddlers/filters/reduce.tid b/editions/tw5.com/tiddlers/filters/reduce.tid index d47955da3..debd28c9f 100644 --- a/editions/tw5.com/tiddlers/filters/reduce.tid +++ b/editions/tw5.com/tiddlers/filters/reduce.tid @@ -1,19 +1,17 @@ caption: reduce created: 20201004154131193 -modified: 20201006174749170 +modified: 20201204130601564 op-input: a [[selection of titles|Title Selection]] passed as input to the filter op-output: the final result of running the subfilter <<.place S>> -op-parameter: a [[filter expression|Filter Expression]] +op-parameter: a [[filter expression|Filter Expression]]. Optional second parameter for initial value for accumulator op-parameter-name: S op-purpose: apply a subfilter to each input title in turn, accumulating a single value -op-suffix: Initial value for accumulator -op-suffix-name: V tags: [[Filter Operators]] title: reduce Operator type: text/vnd.tiddlywiki \define reduce-tip() -The <<.op reduce>> operator will always produce output, even if its input was empty. If its input is empty, the output of <<.op reduce>> will be the initial value of the accumulator, i.e. the value of the suffix. One result of this fact is that the <<.op else>> operator will never be triggered if it follows a <<.op reduce>>. The "Empty input" examples show what happens when <<.op reduce>> receives no input. +The <<.op reduce>> operator will always produce output, even if its input was empty. If its input is empty, the output of <<.op reduce>> will be the initial value of the accumulator, i.e. the value of the second parameter. One result of this fact is that the <<.op else>> operator will never be triggered if it follows a <<.op reduce>>. The "Empty input" examples show what happens when <<.op reduce>> receives no input. \end <<.from-version "5.1.23">> The <<.op reduce>> operator runs a subfilter for each input title, passing the result of the previous subfilter run as a variable. The initial value of the accumulator can optionally be specified. It returns the result of the final subfilter run. diff --git a/editions/tw5.com/tiddlers/filters/stringify_Operator.tid b/editions/tw5.com/tiddlers/filters/stringify_Operator.tid index 7bd0847d9..e06be4387 100644 --- a/editions/tw5.com/tiddlers/filters/stringify_Operator.tid +++ b/editions/tw5.com/tiddlers/filters/stringify_Operator.tid @@ -6,6 +6,8 @@ op-output: the input with ~JavaScript string encodings applied op-parameter: op-parameter-name: op-purpose: apply ~JavaScript string encoding to a string +op-suffix: <<.from-version "5.1.23">> optionally, the keyword `rawunicode` +op-suffix-name: R tags: [[Filter Operators]] [[String Operators]] title: stringify Operator type: text/vnd.tiddlywiki @@ -13,15 +15,21 @@ from-version: 5.1.14 The following substitutions are made: -|!Character |!Replacement | -|`\` |`\\` | -|`"` |`\"` | -|`\r` (carriage return) |`\\r` | -|`\n` (line feed) |`\\n` | -|`\x08` (backspace) |`\\b` | -|`\x0c` (form feed) |`\\f` | -|`\t` (tab) |`\\t` | -|Characters from 0x00 to 0x1f and characters from 0x80 to 0xffff |`\\u####` where #### is four hex digits | +|!Character |!Replacement |!Condition | +|`\` |`\\` |Always | +|`"` |`\"` |Always | +|Carriage return (0x0d) |`\\r` |Always | +|Line feed (0x0a) |`\\n` |Always | +|Backspace (0x08) |`\\b` |Always | +|Form field (0x0c) |`\\f` |Always | +|Tab (0x09) |`\\t` |Always | +|Characters from 0x00 to 0x1f |`\\x##` where ## is two hex digits |Always | +|Characters from 0x80 to 0xffff|`\\u####` where #### is four hex digits |If `rawunicode` suffix is not present (default) | +|Characters from 0x80 to 0xffff|<<.from-version "5.1.23">> Unchanged |If `rawunicode` suffix is present | + +<<.from-version "5.1.23">> If the suffix `rawunicode` is present, Unicode characters above 0x80 (such as ß, ä, ñ or 🎄) will be passed through unchanged. Without the suffix, they will be substituted with `\\u` codes, which was the default behavior before 5.1.23. + +<<.note """Technical note: Characters outside the Basic Multilingual Plane, such as 🎄 and other emojis, will be encoded as a UTF-16 surrogate pair, i.e. with two `\u` sequences.""">> Also see the [[jsonstringify Operator]]. diff --git a/editions/tw5.com/tiddlers/filters/syntax/Filter Expression.tid b/editions/tw5.com/tiddlers/filters/syntax/Filter Expression.tid index 57de4a9f9..fb2a1704e 100644 --- a/editions/tw5.com/tiddlers/filters/syntax/Filter Expression.tid +++ b/editions/tw5.com/tiddlers/filters/syntax/Filter Expression.tid @@ -37,6 +37,8 @@ In technical / logical terms: |`~run` |`:else[run]` |else |... ELSE run | ||`:intersection`|intersection of sets|| +For the difference between `+` and `:intersection`, see [[Filter Run Prefix (Examples)]]. + The input of a run is normally a list of all the non-[[shadow|ShadowTiddlers]] tiddler titles in the wiki (in no particular order). But the `+` prefix can change this: |Prefix|Input|h @@ -56,15 +58,3 @@ In order to remove `$:/baz` in any case, existing or not, simply use the `+` pre * <$link to="is Operator">`foo bar $:/baz +[!is[system]]` * <$link to="prefix Operator">`foo bar $:/baz +[!prefix[$:/]]` - -There is also a difference between the `:intersection` and `+` prefixes due to varying inputs. - -The `+` prefix should be thought of as an "AND" in formal logic, e.g. "give me all titles that satisfy condition A ''and'' condition B". But it's not suitable for all cases; if condition B uses a filter operator that replaces its input, then it will be difficult to use the `+` prefix. For example, if you wanted to find out what tags two tiddlers have in common, you might try to write a filter expression like: - -* <$link to="tags Operator">`[[field Operator]tags[]] +[[compare Operator]tags[]]` - -But that won't work, because the second filter run will end up throwing away its input and replacing it with an input consisting of the single title `[[compare Operator]]`. So the result you'd get from that filter expression would be just the tags of the `compare Operator` tiddler. - -For cases like this, the `:intersection` prefix is what you need. It takes the filter output so far, //sets it aside// in temporary storage, and starts the next filter run with all tiddler titles as input. Then once the latest filter run has completed, it takes the latest output, compares it to the set-aside output, and produces a new output that contains only titles that appeared in both the set-aside output and the latest output. So to get only the tags that the `field Operator` and `compare Operator` tiddlers have in common, you would write a filter expresison like this: - -* <$link to="tags Operator">`[[field Operator]tags[]] :intersection[[compare Operator]tags[]]` diff --git a/editions/tw5.com/tiddlers/filters/syntax/Filter Run Prefix (Examples).tid b/editions/tw5.com/tiddlers/filters/syntax/Filter Run Prefix (Examples).tid new file mode 100644 index 000000000..eb88c339b --- /dev/null +++ b/editions/tw5.com/tiddlers/filters/syntax/Filter Run Prefix (Examples).tid @@ -0,0 +1,25 @@ +created: 20201117073343969 +modified: 20201117074106350 +tags: [[Filter Syntax]] +title: Filter Run Prefix (Examples) + +!! Difference between `+` and `:intersection` + +The `+` prefix should be thought of as an "AND" in formal logic, e.g. "give me all titles that satisfy condition A ''and'' condition B". But it's not suitable for all cases; if condition B uses a filter operator that replaces its input, then it will be difficult to use the `+` prefix. For example, if you wanted to find out what tags two tiddlers have in common, you might try to write a filter expression like: + +* <$link to="tags Operator">`[[field Operator]tags[]] +[[compare Operator]tags[]]` + +But that won't work, because the second filter run will end up throwing away its input and replacing it with an input consisting of the single title `[[compare Operator]]`. So the result you'd get from that filter expression would be just the tags of the `compare Operator` tiddler. + +For cases like this, the `:intersection` prefix is what you need. It takes the filter output so far, //sets it aside//, and starts the next filter run with all tiddler titles as input. Then once the latest filter run has completed, it takes the latest output, compares it to the set-aside output, and produces a new output that contains only titles that appeared in both the set-aside output and the latest output. So to get only the tags that the `field Operator` and `compare Operator` tiddlers have in common, you would write a filter expression like this: + +* <$link to="tags Operator">`[[field Operator]tags[]] :intersection[[compare Operator]tags[]]` + +The following examples use the [[field Operator]] and [[compare Operator]] tiddlers and their respective tags. + +<<.operator-example 1 "[[field Operator]tags[]]">> +<<.operator-example 2 "[[compare Operator]tags[]]">> + +<<.operator-example 3 "[[field Operator]tags[]] +[[compare Operator]tags[]]" """The "field Operator" tiddler's tags are lost, so only the "compare Operator" tiddler's tags are returned""">> + +<<.operator-example 4 "[[field Operator]tags[]] :intersection[[compare Operator]tags[]]" """Returns the tags that both tiddlers have in common""">> diff --git a/editions/tw5.com/tiddlers/filters/toggle Operator.tid b/editions/tw5.com/tiddlers/filters/toggle Operator.tid index 2c2738134..13e971990 100644 --- a/editions/tw5.com/tiddlers/filters/toggle Operator.tid +++ b/editions/tw5.com/tiddlers/filters/toggle Operator.tid @@ -1,9 +1,9 @@ caption: toggle created: 20201107153758990 -modified: 20201109104654310 +modified: 20201118192155504 op-input: a list of items op-output: the input list with the title specified in the parameter toggled -op-parameter: the <<.op toggle>> operator accepts 1 or 2 parameters, see below for details +op-parameter: the <<.op toggle>> operator accepts 1 or more parameters, see below for details op-purpose: toggle the title specified in the operand in the input tags: [[Filter Operators]] [[Listops Operators]] [[Order Operators]] title: toggle Operator @@ -11,7 +11,7 @@ type: text/vnd.tiddlywiki <<.from-version "5.1.23">> -The <<.op toggle>> operator requires at least one parameter and can accept a second optional parameter: +The <<.op toggle>> operator requires at least one parameter and can accept additional optional parameters. With a second optional parameter it can be used to toggle between a pair of titles: ``` [toggle[],[]] @@ -19,5 +19,8 @@ The <<.op toggle>> operator requires at least one parameter and can accept a sec * ''title1'' : a title to toggle in the input list. If it is already present, it is removed. Otherwise, it is added. * ''title2'': (optional). When the second parameter is provided, the operator toggles between the two values in the input list. If neither is present, the first parameter takes precedence is added to the list. +With more than two parameters, the <<.op toggle>> behaves similar to the [[cycle|cycle Operator]] and can be used to cycle through a list of values. Note that all operands should be unique. + +<$macrocall $name=".tip" _="While the <<.op cycle>> operator interprets its first parameter as a list of titles to cycle through and offers similar functionality, the <<.op toggle>> operator accepts an unlimited number of distinct parameters."/> <<.operator-examples "toggle">> diff --git a/editions/tw5.com/tiddlers/filters/trim Operator.tid b/editions/tw5.com/tiddlers/filters/trim Operator.tid index 199c8cd7f..a24790eb0 100644 --- a/editions/tw5.com/tiddlers/filters/trim Operator.tid +++ b/editions/tw5.com/tiddlers/filters/trim Operator.tid @@ -1,12 +1,14 @@ caption: trim created: 20190613153740241 -modified: 20190613153820282 +modified: 20201130141111438 op-purpose: returns each item in the list with whitespace, or a given character string, trimmed from the start and/or end op-input: a [[selection of titles|Title Selection]] op-parameter: <<.from-version "5.1.23">> a string of characters op-parameter-name: S op-output: the input titles with <<.place S>>, or whitespace if <<.place S>> is not specified, trimmed from the start and/or end -tags: [[Filter Operators]] +op-suffix: <<.from-version "5.1.23">> `prefix` to trim from the start only, `suffix` to trim from the end only. If omitted (default), trim from both start and end +op-suffix-name: T +tags: [[Filter Operators]] [[String Operators]] title: trim Operator type: text/vnd.tiddlywiki diff --git a/editions/tw5.com/tiddlers/mechanisms/InfoMechanism.tid b/editions/tw5.com/tiddlers/mechanisms/InfoMechanism.tid index 62d907076..c56bd47eb 100644 --- a/editions/tw5.com/tiddlers/mechanisms/InfoMechanism.tid +++ b/editions/tw5.com/tiddlers/mechanisms/InfoMechanism.tid @@ -1,5 +1,5 @@ created: 20140720164948099 -modified: 20200506110435897 +modified: 20201124185829706 tags: Mechanisms title: InfoMechanism type: text/vnd.tiddlywiki @@ -27,3 +27,4 @@ System tiddlers in the namespace `$:/info/` are used to expose information about |[[$:/info/url/port]] |<<.from-version "5.1.14">> Port portion of URL of wiki (eg, ''<>'') | |[[$:/info/url/protocol]] |<<.from-version "5.1.14">> Protocol portion of URL of wiki (eg, ''<>'') | |[[$:/info/url/search]] |<<.from-version "5.1.14">> Search portion of URL of wiki (eg, ''<>'') | +|[[$:/info/darkmode]] |<<.from-version "5.1.23">> Is dark mode enabled? ("yes" or "no") | diff --git a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-modal.tid b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-modal.tid index a1b90b688..b6db37eef 100644 --- a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-modal.tid +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-modal.tid @@ -1,22 +1,25 @@ +caption: tm-modal created: 20140811112133701 -modified: 20141107142803042 +modified: 20201117081247738 tags: Messages title: WidgetMessage: tm-modal type: text/vnd.tiddlywiki -caption: tm-modal |!Name |!Description | |param |Title of the tiddler to be displayed | -|paramObject |Hashmap of variables to be provided to the modal | +|paramObject |Hashmap of variables to be provided to the modal, contains all extra parameters passed to the widget sending the message. | |rootwindow |<<.from-version 5.1.18>> ''yes'' or ''true'' will always display a modal in the wiki-root-window | The "currentTiddler" variable is set to the title of the modal tiddler, but can be overridden by specifying a different value in `paramObject`. The modal message is usually generated with the ButtonWidget. The modal message is handled by the TiddlyWiki core. +[[Fields within the tiddler|Modals]] being displayed in the modal can be used to customize its appearance. + ! Example Here is an example of displaying a modal and passing parameters to it: +(Note how all parameters to `action-sendmessage` other than `$param` and `$message` are available as variables within the modal.) <$macrocall $name='wikitext-example-without-html' src='Your name: <$edit-text tiddler="$:/temp/yourName" tag="input" default="Your name"/> @@ -29,5 +32,9 @@ Your message: Click me! '/> + <<.tip """<$macrocall $name=".from-version" version="5.1.18"/> if triggered from within a ''new window'', the above examples will be displayed within that window. The <$macrocall $name=".attr" _="rootwindow"/> attribute can be set to ''yes'' or ''true'' to inherit this behavior and to display the Modal within the ''root'' window""">> +<<.tip """<$macrocall $name=".from-version" version="5.1.23"/> Links to tiddlers within a modal will open in the same story as the widget that sent the `tm-modal` message. You can override this by specifying values for the variables `tv-story-list` and `tv-history-list` when sending the `tm-modal` message. + +""">> \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/nodejs/Customising Tiddler File Naming.tid b/editions/tw5.com/tiddlers/nodejs/Customising Tiddler File Naming.tid index 8bd4d121c..3aef1351f 100644 --- a/editions/tw5.com/tiddlers/nodejs/Customising Tiddler File Naming.tid +++ b/editions/tw5.com/tiddlers/nodejs/Customising Tiddler File Naming.tid @@ -1,25 +1,52 @@ created: 20160424181300000 -modified: 20160424181300000 +modified: 20201201000000000 tags: [[TiddlyWiki on Node.js]] title: Customising Tiddler File Naming type: text/vnd.tiddlywiki -By default, a [[TiddlyWiki on Node.js]] instance using a [[wiki folder|TiddlyWikiFolders]] will create new tiddler files by using the sanitised and disambiguated title as filename. +By default, a [[TiddlyWiki on Node.js]] instance using a [[wiki folder|TiddlyWikiFolders]] will create new tiddler files by using the sanitised and disambiguated title as filename and write them to the wiki folder's `tiddlers/` directory. This can be overridden by mapping a path in the wiki's tiddlywiki.info file, using a `default-tiddler-location` property in the `config` object. All filepath operations are relative to this `$tw.boot.wikiTiddlersPath` internal javacript variable. -This can be customised by creating a tiddler [[$:/config/FileSystemPaths]] containing one or more [[filter expressions|Filter Syntax]], each on a line of its own. Newly created tiddlers are matched to each filter in turn, and the first output of the first filter to produce any output is taken as a logical path to be used for the tiddler file. Logical paths don't include the `.tid` extension, and they can use `/` or `\` as directory separator (when generating the physical path, this is replaced by the correct separator for the platform ~TiddlyWiki is running on). If none of the filters matches, the logical path is simply the title with all occurences of `/` replaced by `_` (for backwards compatibility). +The default file extension of `.tid` is used for tiddlers that are missing the `type` field, or for tiddlers of type "text/vnd.tiddlywiki". Tidders of other types are saved according to their IMIE types (defined at boot startup). Both the logical path (directory and file name) and the file extension can be customized independently by creating optional tiddlers: [[$:/config/FileSystemPaths]] and [[$:/config/FileSystemExtensions]]. -In both cases, the characters `<>:"\|?*^` are replaced by `_` in order to guarantee that the resulting path is legal on all supported platforms. +! File System Paths + +The logical path can be customised by creating a tiddler [[$:/config/FileSystemPaths]] containing one or more [[filter expressions|Filter Syntax]], each on a line of its own. Newly created tiddlers are matched to each filter in turn, and the first output of the first filter to produce any output is taken as a logical path to be used for the tiddler file. Tiddlers are also tested against the [[$:/config/FileSystemPaths]] on every save to disk, and if the logical path has changed a new file is created and the old file deleted. + +Tiddlers are limited to being written to the [[wiki folder|TiddlyWikiFolders]]. Any error saving a tiddler to disk, with a logical path that does not start with the wiki folder's path the most common error, causes the filepath to be encoded via Javascript's `encodeURIComponent()` method and the tiddler is saved as this file in the wiki folder's `$tw.boot.wikiTiddlersPath` directory. + +Logical paths do not include the file-on-disk's extension (see below), and they can use `/` or `\` as directory separator (when generating the physical path, this is replaced by the correct separator for the platform ~TiddlyWiki is running on). If none of the filters matches, the logical path is simply the title with all occurences of `/` replaced by `_` (for backwards compatibility). + +In both cases, the characters `<>~:"\|?*^` are replaced by `_` in order to guarantee that the resulting path is legal on all supported platforms. !! Example ``` -[is[system]removeprefix[$:/]addprefix[_system/]] +[is[system]!has[draft.of]removeprefix[$:/]addprefix[_system/]] +[is[draft]search-replace:g:regexp[/|\\],[_]addprefix[drafts/]] [tag[task]addprefix[mytasks/]] -[!has[draft.of]] +[!tag[externalnote]addprefix[wiki/]] ``` -This will store newly created system tiddlers in `tiddlers/_system` (after stripping the `$:/` prefix), tiddlers tagged [[task]] in a subdirectory `tiddlers/mytasks`, and also create subdirectory structures for all other non-draft tiddlers. +This will store newly created system tiddlers that are not drafts of other tiddlers in `tiddlers/_system` (after stripping the `$:/` prefix). Next, all drafts have the path seperator characters in their titles replaced by "_" and are stored in `tiddlers/drafts/`. Then tiddlers tagged [[task]] are stored in a subdirectory `tiddlers/mytasks/`. Finally, all tidders not tagged with "externalnote" will match the final `[!tag[externalnote]addprefix[wiki/]]` storing these in `/wiki/`. In this example, tiddlers tagged with "externalnote" have been imported using [[tiddlywiki.files Files|tiddlywiki.files_Files]] with an "isEditableFile" flag set to true, causing the server to remember their original file path. -Thus, $:/config/FileSystemPaths itself will end up in `tiddlers/_system/config/FileSystemPaths.tid` or `tiddlers\_system\config\FileSystemPaths.tid`, depending on the platform. +Whenever a tiddler generates a $:/config/FileSystemPaths filter match, any `/` or `\` in the tiddler title is mapped to a path separator. With the above filters, the non-system, non-draft tiddler `some/thing/entirely/new` (with no tags) will be saved to `/tiddlers/wiki/some/thing/entirely/new.tid` (ie, the file `new.tid` in a directory called `entirely/`). Thus, $:/config/FileSystemPaths itself will end up in `tiddlers/_system/config/FileSystemPaths.tid` or `tiddlers\_system\config\FileSystemPaths.tid`, depending on the platform. -The final `[!has[draft.of]]` will match all remaining non-draft tiddlers. Because there was a match, any `/` or `\` in the tiddler title is mapped to a path separator. Thus, `some/thing/entirely/new` will be saved to `tiddlers/some/thing/entirely/new.tid` (ie, the file `new.tid` in a directory called `entirely`). +! File System Extensions + +Normally, the file system extension of a tiddler on disk is determined by the existance of bad fields (multi-line fields other than the text field, fields that can be trimmed of spaces from the fron or back, etc), in which case the single-file ".json" tiddler-file format is used. If the tiddler does not have bad fields, then the `type` field is referenced to find a matching file-type. Tiddlywiki's boot engine defines a set of these tiddler-type to file-type relationships in the [[$:/boot/boot.js]] tiddler. Search for `// Add file extension information` to find the section of code that defines these relationships. + +The file extension of individual tidders can be customised by creating a tiddler [[$:/config/FileSystemExtensions]] containing one or more [[filter expressions|Filter Syntax]], each on a line of its own. Newly created tiddlers are matched to each filter in turn, and the first output of the first filter to produce any output is taken as the file extension to be used for the tiddler file. Extensions should always start with a leading dot (see example). Tiddlers are also tested against the $:/config/FileSystemExtensions on every save to disk, and if the extension has changed a new file is created and the old file deleted. If no filter matches, the default extension is used. + +Two special cases should be noted: Result of ".tid" will force the tiddler to be written to disk as a single-file text tiddler. A result of ".json" will force the tiddler to be written to disk as a single-file tiddler in json-format (a single tiddler fields object in an array), NOT as a tiddler of type "application/json". All other recognized file-types will be saved using their defined extention along with an acompanying *.meta file of the same name which describes all fields but the "text" field. + +!! Example + +``` +[tag[.txt]then[.txt]] +[tag[.json]then[.json]] +[tag[.tid]then[.tid]] +``` + +This will cause all tidders that have the tag ".txt" in their tags field to be saved at the filepath determined by the File System Paths filters, but with their text field saved as a *.txt file, and all other fields saved as a *.txt.meta file. + +Next, all tiddlers that have the ".json" tag are saved as *.json single-file tiddlers. Finally, all tiddlers that have tag ".tid" are saved as single-file text tiddlers. If a tiddler matches none of the filters, the default extension determined by the tiddler's `type` field would be used. \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/nodejs/tiddlywiki.files_Files.tid b/editions/tw5.com/tiddlers/nodejs/tiddlywiki.files_Files.tid index 59c9a679d..b519b6bf7 100644 --- a/editions/tw5.com/tiddlers/nodejs/tiddlywiki.files_Files.tid +++ b/editions/tw5.com/tiddlers/nodejs/tiddlywiki.files_Files.tid @@ -1,5 +1,5 @@ created: 20161015114118243 -modified: 20161015170604353 +modified: 20201201000000000 tags: TiddlyWikiFolders title: tiddlywiki.files Files type: text/vnd.tiddlywiki @@ -51,7 +51,7 @@ Directory specifications in the `directories` array may take the following forms ** ''path'' - (required) the absolute or relative path to the directory containing the tiddler files (relative paths are interpreted relative to the path of the `tiddlywiki.files` file). Note that the directory is not recursively searched; sub-directories are ignored ** ''filesRegExp'' - (optional) a [[regular expression|https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions]] that matches the filenames of the files that should be processed within the directory ** ''isTiddlerFile'' - (required) if `true`, the file will be treated as a [[tiddler file|TiddlerFiles]] and deserialised to extract the tiddlers. Otherwise, the raw content of the file is assigned to the `text` field without any parsing -** ''isEditableFile'' - (optional) if `true`, changes to the tiddler be saved back to the original file. <<.from-version "5.1.23">> +** ''isEditableFile'' - (optional) if `true`, changes to the tiddler be saved back to the original file. The tiddler will be saved back to the original filepath as long as it does not generate a result from the $:/config/FileSystemPath filters, which will override the final filepath generated if a result is returned from a filter. <<.from-version "5.1.23">> ** ''fields'' - (required) an object containing values that override or customise the fields provided in the tiddler file (see above) Fields can be overridden for particular files by creating a file with the same name plus the suffix `.meta` -- see TiddlerFiles. @@ -64,7 +64,7 @@ There are also several examples of `tiddlywiki.files` files in the main [[Tiddly !! Importing a folder of PDFs -This example retrieves all the files with the extension `.pdf` from a folder specified by a relative path. Each tiddler is set up for LazyLoading with the following fields: +This example retrieves all the files with the extension `.pdf` from a folder specified by a relative path. This path starts with "../../../" indicating 3 directory levels above the folder holdng this confog fole. Each tiddler is set up for LazyLoading with the following fields: * ''title'' - set to the URI decoded base filename of the PDF file. [[URI decoding|https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent]] allows characters like "/" to be included in titles by URI encoding them as "%2F" * ''created'' - set to the creation date/time of the PDF file @@ -94,3 +94,39 @@ This example retrieves all the files with the extension `.pdf` from a folder spe ] } ``` +!! Importing a folder of text files + +This example retrieves all the files with the extension `.txt` from a folder specified by a relative path. This folder is within the wiki's base directory, and the current config file is in a directory within the wiki's "tiddlers/" directory. So, in this case the path starts with "../../" to traverse upwards two directory levels, and then down into the "externalnotes/" directory. Each tiddler is set up with the following fields: + +* ''title'' - set to the URI decoded base filename of the text file. [[URI decoding|https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent]] allows characters like "/" to be included in titles by URI encoding them as "%2F" +* ''created'' - set to the creation date/time of the text file +* ''modified'' - set to the modification date/time of the text file +* ''type'' - set to `text/plain` +* ''tags'' - set to `[[note]] [[externalnote]] [[.txt]]` (using array notation) +* ''text'' - not set, thus the content of the file is loaded as the text field + +``` +{ + "directories": [ + { + "path": "../../externalnotes", + "filesRegExp": ".+\\.txt", + "isTiddlerFile": false, + "isEditableFile": true, + "fields": { + "title": {"source": "basename-uri-decoded"}, + "created": {"source": "created"}, + "modified": {"source": "modified"}, + "type": "text/plain", + "tags": ["note", "externalnote", ".txt"] + } + } + ] +} +``` + +This will load all text files in the `../../externalnotes/` directory into the wiki as individual tiddlers. These can be a collection of snippets in various markup-languages. Then, the `type` field of each of these tiddlers can be changed to match their languages For example, "text/vnd.tiddlywiki" for wikitext, or "text/markdown" for markdown files. Then, using $:/config/FileSystemPaths and $:/config/FileSystemExtentions tiddlers with the following lines we can cause any changes to these tiddlers to be saved back to the directory they started from, and also as "*.txt" files with accompanying "*.txt.meta" files. These meta files will be generated as required, and will then over-ride any fields generated from the config `tiddlywiki.files` file (such as the tiddler's `type` field) when the server is restarted. + +From the examples in [[Customising Tiddler File Naming]] we see that the final `[!tag[externalnote]addprefix[wiki/]]` filter in the $:/config/FileSystemPaths tiddler excludes all tiddlers tagged with `externalnotes` (that have not matched an earlier filter). These tiddlers have their filepath retrieved from the $:/config/OriginalTiddlerPaths generated upon boot startup. + +Then, the `[tag[.txt]then[.txt]]` filter in the $:/config/FileSystemExtensions tiddler forces all these tiddlers to be saved back to disk as *.txt and accompanying *.txt.meta files (overriding the normal tiddler-type to file-type mapping). In this case, allowing the snippets of Tiddlywiki wikitext or markdown-text to be saved back to "text" *.txt files. \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/saving/Saving to a Git service.tid b/editions/tw5.com/tiddlers/saving/Saving to a Git service.tid index b6bb269db..ab4186f6c 100644 --- a/editions/tw5.com/tiddlers/saving/Saving to a Git service.tid +++ b/editions/tw5.com/tiddlers/saving/Saving to a Git service.tid @@ -17,7 +17,7 @@ Saving to a Git service is configured in the [[$:/ControlPanel]] in the ''Git Se * ''Username'' - (mandatory) the username for the Git service account used for saving changes * ''Password'' - (mandatory) the password, OAUTH token or personal access token for the specified account. Note that GitHub permits [[several different mechanisms|https://developer.github.com/v3/#authentication]] for authentication * ''Repository'' - (mandatory) the name of the Git repository. Both the owner name and the repository name must be specified. For example `Jermolene/TiddlyWiki5` -* ''Branch'' - (optional) the name of the branch to be used within the Git repository. Defaults to `master` +* ''Branch'' - (optional) the name of the branch to be used within the Git repository. Defaults to `main` (~GitHub) or `master` (~GitLab)" * ''Path'' - (optional) the path to the target file. Defaults to `/` * ''Filename'' - (mandatory) the filename of the target file diff --git a/editions/tw5.com/tiddlers/systemtags/SystemTag_ $__tags_Layout.tid b/editions/tw5.com/tiddlers/systemtags/SystemTag_ $__tags_Layout.tid new file mode 100644 index 000000000..537ca1d91 --- /dev/null +++ b/editions/tw5.com/tiddlers/systemtags/SystemTag_ $__tags_Layout.tid @@ -0,0 +1,9 @@ +caption: $:/tags/Layout +created: 20201123191935978 +description: marks alternative page layouts +modified: 20201123192158739 +tags: SystemTags +title: SystemTag: $:/tags/Layout +type: text/vnd.tiddlywiki + +The [[system tag|SystemTags]] `$:/tags/Layout` marks [[alternative page layouts|Alternative page layouts]] that can be switched to. \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/variables/modifier Variable.tid b/editions/tw5.com/tiddlers/variables/modifier Variable.tid index d5db7d702..3d1322e7f 100644 --- a/editions/tw5.com/tiddlers/variables/modifier Variable.tid +++ b/editions/tw5.com/tiddlers/variables/modifier Variable.tid @@ -1,9 +1,11 @@ +created: 20201123120203415 +modified: 20201123120211360 tags: Variables [[Core Variables]] title: modifier Variable type: text/vnd.tiddlywiki -Within the ''action'' string of the DroppableWidget, the ''action'' string of the ButtonWidget and the ''action'' string of the LinkCatcherWidget, the <<.def modifier>> [[variable|Variables]] contains the modifier key(s) held during the drag-process. -The possible keys are ''meta'', ''ctrl'', ''shift'', ''alt'', ''meta'' and ''ctrl'', ''meta'' and ''shift'', ''meta'' and ''alt'', ''ctrl'' and ''shift'', ''alt'' and ''shift'', ''ctrl'' and ''alt'', ''ctrl'' and ''alt'' and ''shift'', ''meta'' and ''alt'' and ''shift'', ''meta'' and ''ctrl'' and ''shift'', ''meta'' and ''ctrl'' and ''alt'', ''meta'' and ''ctrl'' and ''alt'' and ''shift'' +Within the ''action'' string of the DroppableWidget, the ''action'' string of the ButtonWidget and the ''action'' string of the LinkCatcherWidget and the EventCatcherWidget, the <<.def modifier>> [[variable|Variables]] contains the modifier key(s) held during the drag-process. +Possible key combinations are listed in the table below. The variable contains a string that identifies the keys: diff --git a/editions/tw5.com/tiddlers/webserver/WebServer Parameter_ path-prefix.tid b/editions/tw5.com/tiddlers/webserver/WebServer Parameter_ path-prefix.tid index 365407a65..4a0b4dc86 100644 --- a/editions/tw5.com/tiddlers/webserver/WebServer Parameter_ path-prefix.tid +++ b/editions/tw5.com/tiddlers/webserver/WebServer Parameter_ path-prefix.tid @@ -1,6 +1,6 @@ caption: path-prefix created: 20180630180514893 -modified: 20200311171847360 +modified: 20201027122943281 tags: [[WebServer Parameters]] title: WebServer Parameter: path-prefix type: text/vnd.tiddlywiki @@ -13,4 +13,7 @@ This example causes the server to serve from http://127.0.0.1/MyApp instead of t tiddlywiki mywikifolder --listen "path-prefix=/MyApp" ``` -Note that further steps are required to configure the client-side components to use the prefix. See [[Using a custom path prefix with the client-server edition]]. \ No newline at end of file +Notes: + +* Further steps are required to configure the client-side components to use the prefix. See [[Using a custom path prefix with the client-server edition]] +* If no path prefix is required then the `path-prefix` parameter should be omitted or set to the empty string, and not to `\` as might be expected diff --git a/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 1.tid b/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 1.tid index 5e4e84432..d5560be3b 100644 --- a/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 1.tid +++ b/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 1.tid @@ -1,5 +1,5 @@ created: 20200131142401129 -modified: 20200131152023958 +modified: 20201020112608874 tags: ActionCreateTiddlerWidget title: ActionCreateTiddlerWidget Example 1 type: text/vnd.tiddlywiki @@ -21,6 +21,6 @@ Create Tiddler ``` <$button actions=<> > -<$action-setfield $tiddler="$:/state/tab/sidebar-1206596165" text="$:/core/ui/SideBar/Recent"/> +<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/Recent"/> Create Tiddler - Clicking this button, will also open the Right sidebar: Recent tab diff --git a/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 2.tid b/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 2.tid index 089ab4763..876e5fbba 100644 --- a/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 2.tid +++ b/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 2.tid @@ -1,5 +1,5 @@ created: 20200131144828713 -modified: 20200131152102232 +modified: 20201020112601032 tags: ActionCreateTiddlerWidget title: ActionCreateTiddlerWidget Example 2 type: text/vnd.tiddlywiki @@ -23,6 +23,6 @@ Create Tiddler ``` <$button actions=<> > -<$action-setfield $tiddler="$:/state/tab/sidebar-1206596165" text="$:/core/ui/SideBar/Recent"/> +<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/Recent"/> Create Tiddler - Clicking this button, will also open the Right sidebar: Recent tab diff --git a/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 3.tid b/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 3.tid index 325499fc0..54524108a 100644 --- a/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 3.tid +++ b/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 3.tid @@ -1,5 +1,5 @@ created: 20200131145355658 -modified: 20200131152045990 +modified: 20201020112553050 tags: ActionCreateTiddlerWidget title: ActionCreateTiddlerWidget Example 3 type: text/vnd.tiddlywiki @@ -23,6 +23,6 @@ Create Tiddler ``` <$button actions=<> > -<$action-setfield $tiddler="$:/state/tab/sidebar-1206596165" text="$:/core/ui/SideBar/Recent"/> +<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/Recent"/> Create Tiddler - Clicking this button, will also open the Right sidebar: Recent tab diff --git a/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 4.tid b/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 4.tid index b116ee5e7..b1eb7275f 100644 --- a/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 4.tid +++ b/editions/tw5.com/tiddlers/widgets/ActionCreateTiddlerWidget Example 4.tid @@ -1,5 +1,5 @@ created: 20200131150229551 -modified: 20200131152051626 +modified: 20201020112544146 tags: ActionCreateTiddlerWidget title: ActionCreateTiddlerWidget Example 4 type: text/vnd.tiddlywiki @@ -23,6 +23,6 @@ Create Tiddler ``` <$button actions=<> > -<$action-setfield $tiddler="$:/state/tab/sidebar-1206596165" text="$:/core/ui/SideBar/Recent"/> +<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/Recent"/> Create Tiddler - Clicking this button, will also open the Right sidebar: Recent tab diff --git a/editions/tw5.com/tiddlers/widgets/ActionLogWidget.tid b/editions/tw5.com/tiddlers/widgets/ActionLogWidget.tid index b8440f31b..2fa75cfad 100644 --- a/editions/tw5.com/tiddlers/widgets/ActionLogWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/ActionLogWidget.tid @@ -1,21 +1,29 @@ caption: action-log created: 20201114113318785 -modified: 20201114125859948 -tags: Widgets ActionWidgets +modified: 20201120155202652 +tags: Widgets ActionWidgets [[Debugging Widgets]] title: ActionLogWidget type: text/vnd.tiddlywiki ! Introduction -<<.from-version "5.1.23">> The ''action-log'' widget is an [[action widget|ActionWidgets]] that can be used to output debugging information to the JavaScript console supported by most browsers. This can be useful because otherwise it is difficult to observe what is going on within a sequence of actions. +<<.from-version "5.1.23">> The ''action-log'' widget is an [[action widget|ActionWidgets]] that can be used to output debugging information to the [[JavaScript console|Web Developer Tools]] supported by most browsers. This can be useful because otherwise it is difficult to observe what is going on within a sequence of actions. ActionWidgets are used within triggering widgets such as the ButtonWidget. +<<.tip """ For debugging outside of actions see [[LogWidget]]""">> + ! Content and Attributes The ''action-log'' widget is invisible. Any content within it is ignored. When the actions are invoked, the names and values of all attributes are logged to the JavaScript console. +In addition there are optional attributes that can be used: + +|!Optional Attribute |!Description | +|$$filter|All variables matching this filter will also be logged. | +|$$message |A message to display as the title of the information logged. Useful when several `action-log` widgets are used in sequence. | +|$$all |Set to "yes" to log all variables in a collapsed table. Note that if there is nothing specified to log, all variables are always logged instead.| <<.tip """A handy tip if an action widget is not behaving as expected is to temporarily change it to an `<$action-log>` widget so that the attributes can be observed.""">> @@ -28,3 +36,15 @@ Here is an example of logging two variables: <$action-log myVar=<> otherVar=<>/> ``` +To log all variables: + +``` +<$action-log /> +``` + + +To log two variables as well as all core variables (which start with `tv-`): + +``` +<$action-log myVar=<> other={{!!status}} $$filter="[prefix[tv-]]"/> +``` diff --git a/editions/tw5.com/tiddlers/widgets/ButtonWidget.tid b/editions/tw5.com/tiddlers/widgets/ButtonWidget.tid index f2c8c6b84..19294444b 100644 --- a/editions/tw5.com/tiddlers/widgets/ButtonWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/ButtonWidget.tid @@ -29,7 +29,7 @@ The content of the `<$button>` widget is displayed within the button. |message |The name of the [[widget message|Messages]] to send when the button is clicked | |param |The optional parameter to the message | |set |A TextReference to which a new value will be assigned | -|setTitle |A title to which a new value will be assigned, ''without'' TextReference. Gets preferred over <<.attr state>> | +|setTitle |A title to which a new value will be assigned, ''without'' TextReference. Gets preferred over <<.attr set>> | |setField |A ''field name'' to which the new value will be assigned, if the attribute <<.attr setTitle>> is present. Defaults to the ''text'' field | |setIndex |An ''index'' to which the new value will be assigned, if the attribute <<.attr setTitle>> is present | |setTo |The new value to assign to the TextReference identified in the `set` attribute or the text field / the field specified through <<.attr setField>> / the index specified through <<.attr setIndex>> of the title given through <<.attr setTitle>> | diff --git a/editions/tw5.com/tiddlers/widgets/EditTextWidget.tid b/editions/tw5.com/tiddlers/widgets/EditTextWidget.tid index 5205741d2..c2e57e755 100644 --- a/editions/tw5.com/tiddlers/widgets/EditTextWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/EditTextWidget.tid @@ -1,6 +1,6 @@ caption: edit-text created: 20131024141900000 -modified: 20201109093034856 +modified: 20201130184701532 tags: Widgets title: EditTextWidget type: text/vnd.tiddlywiki @@ -25,6 +25,7 @@ The content of the `<$edit-text>` widget is ignored. |focusPopup |Title of a state tiddler for a popup that is displayed when the editing element has focus | |focus |Set to "yes" or "true" to automatically focus the editor after creation | |tabindex |Sets the `tabindex` attribute of the input or textarea to the given value | +|autocomplete |<<.from-version 5.1.23>> An optional string to provide a hint to the browser how to handle autocomplete for this input | |tag |Overrides the generated HTML editing element tag. For a multi-line editor use `tag=textarea`. For a single-line editor use `tag=input` | |type |Overrides the generated HTML editing element `type` attribute | |size |The size of the input field (in characters) | diff --git a/editions/tw5.com/tiddlers/widgets/EditWidget.tid b/editions/tw5.com/tiddlers/widgets/EditWidget.tid index 930319d70..78d85f3fe 100644 --- a/editions/tw5.com/tiddlers/widgets/EditWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/EditWidget.tid @@ -1,8 +1,9 @@ -title: EditWidget -created: 201310241419 -modified: 20150220161220000 -tags: Widgets caption: edit +created: 20131024141900000 +modified: 20201130184647904 +tags: Widgets +title: EditWidget +type: text/vnd.tiddlywiki ! Introduction @@ -18,6 +19,7 @@ The content of the `<$edit>` widget is ignored. |index |The index to edit | |class |A CSS class to be added the generated editing widget | |tabindex |Sets the `tabindex` attribute of the input or textarea to the given value | +|autocomplete |<<.from-version 5.1.23>> An optional string to provide a hint to the browser how to handle autocomplete for this input | |cancelPopups |<<.from-version "5.1.23">> if set to "yes", cancels all popups when the input gets focus | |inputActions |<<.from-version 5.1.23>> Optional actions that are triggered every time an input event occurs within the input field or textarea | |refreshTitle |<<.from-version 5.1.23>> An optional tiddler title that makes the input field update whenever the specified tiddler changes | diff --git a/editions/tw5.com/tiddlers/widgets/EventCatcherWidget.tid b/editions/tw5.com/tiddlers/widgets/EventCatcherWidget.tid new file mode 100644 index 000000000..9a4b498c5 --- /dev/null +++ b/editions/tw5.com/tiddlers/widgets/EventCatcherWidget.tid @@ -0,0 +1,85 @@ +created: 20201123113532200 +modified: 20201202200719126 +tags: Widgets +title: EventCatcherWidget +type: text/vnd.tiddlywiki + +! Introduction + +<<.from-version "5.1.23">> +The event catcher widget traps JavaScript events dispatched within its child content, and allows invoking a series of ActionWidgets in response to the events. + +In order for the events to be trapped they must: + +* be of one of the types specified as a parameter to the event catcher widget. +* arise within a DOM node matching the selector specified as a parameter to the widget. + +Use of the event catcher widget is beneficial when using large numbers of other trigger widgets such as the ButtonWidget is causing performance problems. The workflow it enables is akin to what is referred to as "event delegation" in JavaScript parlance. + +//This is an advanced widget intended to be used by those familiar with HTML, CSS and JavaScript.// + +! Content and Attributes + +The content of the `<$eventcatcher>` widget is displayed normally. + +|!Attribute |!Description | +|events |Space separated list of JavaScript events to be trapped, for example "click" or "click dblclick" | +|selector |A CSS selector. Only events originating inside a DOM node with this selector will be trapped. | +|actions-* |Action strings to be invoked when a matching event is trapped. Each event is mapped to an action attribute name of the form `actions-"event"` where `event` represents the type of the event. For example: `actions-click` or `actions-dblclick` | +|class |An optional CSS class name to be assigned to the HTML element | +|tag |Optional. The html element the widget creates to capture the events, defaults to:
    » `span` when parsed in inline-mode
    » `div` when parsed in block-mode | + +! Variables + +The following variables are made available to the actions: + +|!Variables |!Description | +|`dom-*` |All DOM attributes of the node matching the given selector are made available as variables, with the prefix `dom-` | +|`modifier` |The [[modifier Variable]] contains the Modifier Key held during the event (can be "normal", "ctrl", "shift", "alt" or combinations thereof) | +|`event-mousebutton`|The mouse button (if any) used to trigger the event (can be "left", "right" or "middle"). Note that not all event types support the mousebutton property | +|`event-type`|The type property of the JavaScript event | +|`event-detail-*`|Any properties in the detail attribute of the event are made available with the prefix `event-detail-` | +|`tv-popup-coords`|A co-ordinate string that can be used with the ActionPopupWidget to trigger a popup at the DOM node matching the selector where the event originated | +|`tv-selectednode-posx`|`x` offset position of the selected DOM node | +|`tv-selectednode-posy`|`y` offset position of the selected DOM node | +|`tv-selectednode-width`|`offsetWidth` of the selected DOM node | +|`tv-selectednode-height`|`offsetHeight` of the selected DOM node | +|`event-fromselected-posx`|`x` position of the event relative to the selected DOM node | +|`event-fromselected-posy`|`y` position of the event relative to the selected DOM node | +|`event-fromcatcher-posx`|`x` position of the event relative to the event catcher DOM node | +|`event-fromcatcher-posy`|`y` position of the event relative to the event catcher DOM node | + +! Example + +This example uses the ActionLogWidget and will log the `data-item-id` attribute of the clicked DOM node to the browser's JavaScript [[console|Web Developer Tools]] + +``` +\define clickactions() +<$action-log item=<> event=<>/> +\end + +\define contextmenu-actions() +<$action-log item=<> event=<>/> +\end + +<$eventcatcher events="click contextmenu" selector=".item" actions-click=<> actions-contextmenu=<> tag="div"> + +
    +Click events here will be trapped +
    + +
    +And here too +
    + +
    +Not here +
    + +
    +And here +
    + + +``` + diff --git a/editions/tw5.com/tiddlers/widgets/LogWidget.tid b/editions/tw5.com/tiddlers/widgets/LogWidget.tid new file mode 100644 index 000000000..71cb01b03 --- /dev/null +++ b/editions/tw5.com/tiddlers/widgets/LogWidget.tid @@ -0,0 +1,45 @@ +created: 20201120152706842 +modified: 20201120154927696 +tags: Widgets [[Debugging Widgets]] +title: LogWidget +type: text/vnd.tiddlywiki + +! Introduction + +<<.from-version "5.1.23">> The ''log'' widget can be used to output debugging information to the [[JavaScript console|Web Developer Tools]] supported by most browsers. + +<<.tip """ For use with ActionWidgets see [[ActionLogWidget]] which uses identical parameters""">> + +! Content and Attributes + +The ''log'' widget is invisible. Any content within it is ignored. Note that the widget will log to the console both when it is first rendered and also every time it refreshes. + +When the widget is rendered, the names and values of all attributes are logged to the JavaScript console. +In addition there are optional attributes that can be used: + +|!Optional Attribute |!Description | +|$$filter|All variables matching this filter will also be logged. | +|$$message |A message to display as the title of the information logged. Useful when several `log` widgets are used in sequence. | +|$$all |Set to "yes" to log all variables in a collapsed table. Note that if there is nothing specified to log, all variables are always logged instead.| + + +! Example + +Here is an example of logging two variables: + +``` +<$log myVar=<> otherVar=<>/> +``` + +To log all variables: + +``` +<$log /> +``` + + +To log two variables as well as all core variables (which start with `tv-`): + +``` +<$log myVar=<> other={{!!status}} $$filter="[prefix[tv-]]"/> +``` diff --git a/editions/tw5.com/tiddlers/widgets/RadioWidget Example.tid b/editions/tw5.com/tiddlers/widgets/RadioWidget Example.tid new file mode 100644 index 000000000..64d8914c1 --- /dev/null +++ b/editions/tw5.com/tiddlers/widgets/RadioWidget Example.tid @@ -0,0 +1,32 @@ +created: 20201130181015815 +modified: 20201130183426619 +tags: RadioWidget +title: RadioWidget Example +type: text/vnd.tiddlywiki + +\define newText() value: $(actionValue)$ + +\define radioActions() +<$action-sendmessage $message="tm-notify" $param="RadioWidget ExampleTemplate" value=<> current=<> /> +<$action-createtiddler $basetitle="$:/temp/test/value" $overwrite="yes" text=<>/> +<$action-navigate $to="$:/temp/test/value"/> +\end + +!! Using Actions + +If you select an option, the value is written to $:/temp/test/value and the ''id'' field of tiddler: $:/temp/test will be updated. + +A notification showing the ''actionValue'' will be shown. + +<$tiddler tiddler="$:/temp/test"> + <$radio field="id" value="a" actions=<> > Option a | + <$radio field="id" value="b" actions=<> > Option b | + <$radio field="id" value="c" actions=<> > Option c | + + +--- + +
    + Show the code [[RadioWidget Example]] +
    <$view mode=text&>
    
    +
    diff --git a/editions/tw5.com/tiddlers/widgets/RadioWidget ExampleTemplate.tid b/editions/tw5.com/tiddlers/widgets/RadioWidget ExampleTemplate.tid new file mode 100644 index 000000000..13be1572a --- /dev/null +++ b/editions/tw5.com/tiddlers/widgets/RadioWidget ExampleTemplate.tid @@ -0,0 +1,7 @@ +created: 20201130181111808 +modified: 20201130182421491 +tags: RadioWidget +title: RadioWidget ExampleTemplate +type: text/vnd.tiddlywiki + +value = <> \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/widgets/RadioWidget.tid b/editions/tw5.com/tiddlers/widgets/RadioWidget.tid index 7a62c03ed..c8798900f 100644 --- a/editions/tw5.com/tiddlers/widgets/RadioWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/RadioWidget.tid @@ -1,6 +1,6 @@ caption: radio created: 20131212195353929 -modified: 20201109091807432 +modified: 20201130184330254 tags: Widgets title: RadioWidget type: text/vnd.tiddlywiki @@ -19,6 +19,7 @@ The content of the `<$radio>` widget is displayed within an HTML `