See the detailed change history on GitHub and other releases.
Introduction
Release v5.4.0 is an important release because it deliberately and forensically loosens backwards compatibility where needed to allow significant new features and fundamental improvements to be made.
Please note that this release note is not yet fully completed, please see the change history on GitHub for the full list of changes included in this release.
See the project plan for full details.
Changes
Translation
Plugin
BugfixMarkdown: Fix missing inline support and macrocall args parsing error
- Fix markdown parser to respect parseAsInline option #8917.
- Fix improper parsing of macrocall, whenenver args contain
>character. - Use $tw.log.MARKDOWN flag to enable debug messages.
DeprecationPurge deprecated plugins and editions
Remove deprecated plugins and editions and some legacy plugins, including:
- Blog
- Cecily
- D3 Plugin and its demo
- HammerJS
- Highlight (Legacy)
- Markdown (Legacy)
- Mobile Drag And Drop Shim Plugin
- nw.js Saver
- TahoeLAFS and its demo
Usability
Enhancementlist-links-draggable defaults to currentTiddler if tiddler parameter is missing
- If macro
list-links-draggablemisses the tiddler parameter it points tocurrentTiddlervariable by default now - Also discussed at Talk Tiddlywiki
EnhancementSet modal's mask-closable attribute to yes by default
EnhancementImprove switcher (UI) accessibility
Theme
EnhancementMuted palette, minor adjustments
EnhancementReplace CSS property macros in Snow White theme
EnhancementUse currentColor to style SVG
#333333 if its parent element has color property setReplaces hardcoded fill attributes with one fill: currentColor rule to solve the compatibility issues of migrating to lucide icons.
Hackability
EnhancementMulti-valued variables and let filter run prefix
This PR introduces a new filter run prefix :let that assigns the result of the filter run to a variable that is made available for the remaining filter runs of the filter expression. It solves the problem that previously it was impossible to compute values for filter operator parameters; parameters could only be a literal string, text reference or variable reference.
This PR also introduces multi-valued variables, the ability to store a list of results in a variable, not just a single string. They can be assigned with the new :let filter run prefix, or the existing <$let> widget. The full list of values can be retrieved using round brackets instead of the usual angle brackets. In all other contexts only the first item in the list is used as the variable value.
Widget
EnhancementAllow button widget to use all aria attributes
EnhancementAllow link widget to use all aria attributes
Allow LinkWidget to use all aria attributes directly.
DeprecationRemove support for Internet Explorer in RangeWidget
BugfixFix widgets generating leading space in class attribute when additional class is empty
Fixed a bug in the RevealWidget, DroppableWidget, EventcatcherWidget, and KeyboardWidget where an empty class attribute would generate a leading space in the rendered HTML. By trimming the resulting class string, we shorten the HTML and avoid potential confusion.
BugfixFix ActionLogWidget sluggishness
PR #8972 introduced a change in the ActionLogWidget that could lead to a significant slowdown, which has been fixed.
Filters
BugfixModify output of some math operators for empty inputs
These math operators will now output an empty list when the input list is empty:
The following math operators are changed to output an empty list when the input list is empty:
- sum[]
- product[]
- maxall[]
- minall[]
- average[]
- variance[]
- standard-deviation[]
FeatureAdded jsondelete operator for deleting properties from JSON objects
Added the jsondelete operator for deleting properties from JSON strings. The operator uses the same code path as jsonset to locate the correct part of the object, ensuring consistency between setting and deleting operations. It supports deleting both object properties and array elements, with support for negative array indexes counted from the end.
Node.js
EnhancementWeb server get-file route now supports HTTP Range headers and streaming
The web server's get-file route now supports HTTP Range requests and file streaming, enabling better loading and playback of large media files.
Features
- HTTP Range header: Enables partial content delivery with
206 Partial Contentresponses, which is used when the user drags the progress bar in video/audio playback - Streaming file delivery: Browsers can now properly seek and stream video files from the
/files/directory. Files are read using Node.js streams for better performance and memory efficiency. - Resumable downloads: To save interrupted downloads
BugfixAdd output directory to eslint ignore configuration
This PR adds the **/output/** directory to eslint ignore configuration
BugfixFix crash when processing large files from tiddlywiki.files
- skip reading file content when
_canonical_uriis present - skip loading file when file size is too large
Internal
PerformanceDifferent Stylesheets are now included as single <style> tags in the Header
Previously, all stylesheets were combined in a single <style> tag in the <head>.
Now, a separate <style> tag is created in the <head> for each stylesheet.
As part of these changes, the 'view widget' has also been updated. It can now respond dynamically to changes in the 'wikified' formats as well.
SecuritySet AES strength to 256 bit default
This PR changes the default AES encryption setting from 128 bit to 256 bit.
- Download emtpy.html v5.3.8 from the archve which uses AES 128 bit
- Create some content
- Save encrypted as eg: aes-128.html
- Create aes-256.html with TW v5.4.x
- Create some content
- Save encrypted as: aes-256.html
Import decryption test
- Import aes-256.html into aes-128.html -> Decryption and import works
- Import aes-128.html into aes-256.html -> Decryption and import works
PerformanceUse sticky flag to improve regexp search performance
DeprecationRender s tag instead of strike
PerformanceOffload server-only components to a plugin
$:/core-server pluginIt is not necessary for wikis to explicitly include the $:/core-server plugin.
This change reduces the size of the core plugin by 119.3KB or about 4.5%.
EnhancementFix nested span.tc-keyboard element in core
Removes nested <span class="tc-keyboard"> element in core search field.
PerformanceSwitch to native support for converting utf-8 between base64
Replace base64-utf8 module with TextEncoder method to convert between utf-8 and Base64.
EnhancementSplit release notes into individual change notes
Doing so enables us to filter and group changes. For example, we could show all the breaking changes between two releases.
BugfixLet tiddler modules overwrite shadow modules with the same exports but different names
Tiddlers were previously processed before shadows during module registration. The shadow modules registration algorithm only checked for a matching title to prevent overwriting, but a differently named tiddler with the same exports would be overwritten by a shadow. This change swaps the order of $tw.wiki.defineTiddlerModules() and $tw.wiki.defineShadowModules() in boot.js, so that tiddlers are processed after shadows and can therefore override them.
Each group (tiddlers or shadows) is sorted alphabetically, so plugin shadows would previously correctly overwrite core shadows (assuming their name starts with $:/plugins/), which remains unchanged. This change only affects module tiddlers that have the same export as a shadow, but a different name.
PerformanceRemove redundant code in format/json.js
Remove redundant code in core/modules/filters/format/json.js.
DeprecationRemove Opera & Microsoft prefix in browser.js
Remove Opera & Microsoft prefix in $:/core/modules/utils/dom/browser.js.
BugfixFix markup not included in external core edition
Fix the problem that tiddlywiki's raw markup shadow tiddlers in $:/core is not included in HTML.
EnhancementAdd the prevailing mimetype for CSV parser
CSV parser used to support only the very obscure text/tab-delimited-values mimetype so this change adds the more common text/tab-separated-values.
Developer
FeatureAdd ability to serialize WikiText AST nodes back to wikitext strings
This PR introduces a new utility $tw.utils.serializeWikitextParseTree() that can convert WikiText Abstract Syntax Tree (AST) nodes back into wikitext strings.
There is also a utility serializeAttribute for a single attribute node, like an attribute of a widget.
Use Cases
- Programmatically manipulating wikitext content by modifying the AST, and use this to write it back
- Building WYSIWYG editors
- Creating wikitext formatters and linters
Implementation
- New core plugin
tiddlywiki/wikitext-serializecontaining most of the logic - Separate serialize handlers for each WikiText rule as
module-type: wikiruleserializer - Test suite with tag
$:/tags/wikitext-serialize-test-spec - It uses each parser's name as rule (
nextMatch.rule.name), each AST node that needs serialization has atypeproperty matching the rule name- HTML tags and widgets are handled by the
htmlserializer
- HTML tags and widgets are handled by the
Example Usage
// Parse a tiddler's wikitext to AST
var parseTree = $tw.wiki.parseTiddler("MyTiddler").tree;
// Serialize AST back to wikitext string
var wikitextString = $tw.utils.serializeWikitextParseTree(parseTree).trimEnd();This feature offers new tools for JS plugin developers. It is not a user-facing change.
EnhancementAdd support for commands and startups which return promises
This adds support for async functions to commands and startups.
In both synchronous: true and synchronous: false mode, if you return a promise (manually or by using the async keyword), it will wait for the promise to resolve, and then proceed using the resolved value as the return value of the function.
Importantly, in synchronous: false mode, returning a promise will not change the callback behavior. So you can safely use an async function and still call the callback to continue execution.
Previously, in synchronous: true mode, returning a promise would have just logged the promise to console and halted execution. Now the promise will be awaited, and if the value is truthy, it will be logged to console and halt execution. If the promise resolves to a falsy value, execution will continue. This is the main breaking change, but since logging an opaque promise to console is the most useless of all error messages, this is unlikely to seriously break anything in practice. Throwing anything, truthy or not, will still stop execution (in synchronous: true mode).
This also does not add any error handling code. Rejected promises should still be logged to console as unhandled rejections just as uncaught exceptions are currently.
EnhancementUpdate ESLint target to ES2017
Updates the eslint config to check for syntax newer than ES2017. This uses a plugin to check for newer syntax, for better error messages, and may need to be updated regularly along with eslint to catch the latest features.
DeprecationDeprecate CSS macros supported in 2017 baseline
Mark CSS macros supported in 2017 baseline as deprecated. They are moved to $:/core/macros/deprecated now.
EnhancementAdd th-debug-element hook to allow plugins to add additional info
This PR adds:
th-dom-rendering-elementhook, that is called right before the DOM node is inserted into the DOM- It allows plugins to add debug info
- An example using an experimental hook can be found at: #9222
BugfixModules in draft tidders should not be executed
Modules in draft tiddlers should not be executed.
This PR:
- Checks for drafts in
$tw.Wiki.prototype.defineTiddlerModules - It also reports and blocks draft modules that come from plugins
EnhancementMigrate most deprecated rules
Migrate eslint deprecated rules (except for nodejs related rules). Format related rules are replaced by @stylistic/eslint-plugin.
EnhancementRepacking plugins should update modified timestamp
This PR modifies $tw.utils.repackPlugin() so that it adds the standard tiddler modification fields to plugin tiddlers when they are repacked.
EnhancementUpdate eslint configuration
- Enforce tab indentation, semicolon
- Switch off
max-classes-per-file - Switch on
no-evalrule and disable it in $:/boot/boot.js with one comment - Show warning for unused variables
- Disable
@stylistic/indentrule in $:/boot/boot.js and $:/boot/bootprefix.js
Acknowledgements
A warm thank you to the developers who have contributed to this release:











