diff --git a/.gitignore b/.gitignore
index 0ab5b300f..412759161 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,4 @@ node_modules/
/test-results/
/playwright-report/
/playwright/.cache/
+$__StoryList.tid
diff --git a/bin/build-site.sh b/bin/build-site.sh
index 5b36de4e1..a2193953d 100755
--- a/bin/build-site.sh
+++ b/bin/build-site.sh
@@ -5,7 +5,7 @@
# Default to the current version number for building the plugin library
if [ -z "$TW5_BUILD_VERSION" ]; then
- TW5_BUILD_VERSION=v5.3.2
+ TW5_BUILD_VERSION=v5.3.3
fi
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
@@ -156,6 +156,28 @@ node $TW5_BUILD_TIDDLYWIKI \
--build index favicon static \
|| exit 1
+# /tour.html tour edition
+node $TW5_BUILD_TIDDLYWIKI \
+ ./editions/tour \
+ --verbose \
+ --output $TW5_BUILD_OUTPUT \
+ --rendertiddler $:/core/save/all tour.html text/plain \
+ || exit 1
+
+# /dev/index.html Developer docs
+# /dev/favicon.ico Favicon for dev site
+# /dev/static.html Static rendering of default tiddlers
+# /dev/alltiddlers.html Static rendering of all tiddlers
+# /dev/static/* Static single tiddlers
+# /dev/static/static.css Static stylesheet
+node $TW5_BUILD_TIDDLYWIKI \
+ ./editions/dev \
+ --verbose \
+ --load $TW5_BUILD_OUTPUT/build.tid \
+ --output $TW5_BUILD_OUTPUT/dev \
+ --build index favicon static \
+ || exit 1
+
# /share.html Custom edition for sharing via the URL
node $TW5_BUILD_TIDDLYWIKI \
./editions/share \
diff --git a/boot/boot.js b/boot/boot.js
index 1468e00b6..d993499b6 100644
--- a/boot/boot.js
+++ b/boot/boot.js
@@ -177,6 +177,7 @@ document: defaults to current document
eventListeners: array of event listeners (this option won't work until $tw.utils.addEventListeners() has been loaded)
*/
$tw.utils.domMaker = function(tag,options) {
+ var options = options || {};
var doc = options.document || document;
var element = doc.createElementNS(options.namespace || "http://www.w3.org/1999/xhtml",tag);
if(options["class"]) {
@@ -218,9 +219,34 @@ $tw.utils.error = function(err) {
heading = dm("h1",{text: errHeading}),
prompt = dm("div",{text: promptMsg, "class": "tc-error-prompt"}),
message = dm("div",{text: err, "class":"tc-error-message"}),
- button = dm("div",{children: [dm("button",{text: ( $tw.language == undefined ? "close" : $tw.language.getString("Buttons/Close/Caption") )})], "class": "tc-error-prompt"}),
- form = dm("form",{children: [heading,prompt,message,button], "class": "tc-error-form"});
+ closeButton = dm("div",{children: [dm("button",{text: ( $tw.language == undefined ? "close" : $tw.language.getString("Buttons/Close/Caption") )})], "class": "tc-error-prompt"}),
+ downloadButton = dm("div",{children: [dm("button",{text: ( $tw.language == undefined ? "download tiddlers" : $tw.language.getString("Buttons/EmergencyDownload/Caption") )})], "class": "tc-error-prompt"}),
+ form = dm("form",{children: [heading,prompt,downloadButton,message,closeButton], "class": "tc-error-form"});
document.body.insertBefore(form,document.body.firstChild);
+ downloadButton.addEventListener("click",function(event) {
+ if($tw && $tw.wiki) {
+ var tiddlers = [];
+ $tw.wiki.each(function(tiddler,title) {
+ tiddlers.push(tiddler.fields);
+ });
+ var link = dm("a"),
+ text = JSON.stringify(tiddlers);
+ if(Blob !== undefined) {
+ var blob = new Blob([text], {type: "text/html"});
+ link.setAttribute("href", URL.createObjectURL(blob));
+ } else {
+ link.setAttribute("href","data:text/html," + encodeURIComponent(text));
+ }
+ link.setAttribute("download","emergency-tiddlers-" + (new Date()) + ".json");
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ } else {
+ alert("Emergency tiddler download is not available");
+ }
+ event.preventDefault();
+ return false;
+ },true);
form.addEventListener("submit",function(event) {
document.body.removeChild(form);
event.preventDefault();
@@ -786,6 +812,7 @@ $tw.utils.Crypto = function() {
}
return outputText;
};
+ $tw.sjcl = sjcl;
this.setPassword = function(newPassword) {
currentPassword = newPassword;
this.updateCryptoStateTiddler();
@@ -1967,10 +1994,10 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
var value = tiddler[name];
switch(fieldInfo.source) {
case "subdirectories":
- value = path.relative(rootPath, filename).split('/').slice(0, -1);
+ value = path.relative(rootPath, filename).split(path.sep).slice(0, -1);
break;
case "filepath":
- value = path.relative(rootPath, filename);
+ value = path.relative(rootPath, filename).split(path.sep).join('/');
break;
case "filename":
value = path.basename(filename);
@@ -2438,6 +2465,7 @@ $tw.boot.initStartup = function(options) {
$tw.utils.registerFileType("image/svg+xml","utf8",".svg",{flags:["image"]});
$tw.utils.registerFileType("image/vnd.microsoft.icon","base64",".ico",{flags:["image"]});
$tw.utils.registerFileType("image/x-icon","base64",".ico",{flags:["image"]});
+ $tw.utils.registerFileType("application/wasm","base64",".wasm");
$tw.utils.registerFileType("application/font-woff","base64",".woff");
$tw.utils.registerFileType("application/x-font-ttf","base64",".woff");
$tw.utils.registerFileType("application/font-woff2","base64",".woff2");
@@ -2452,8 +2480,12 @@ $tw.boot.initStartup = function(options) {
$tw.utils.registerFileType("text/x-markdown","utf8",[".md",".markdown"]);
$tw.utils.registerFileType("application/enex+xml","utf8",".enex");
$tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.wordprocessingml.document","base64",".docx");
+ $tw.utils.registerFileType("application/msword","base64",".doc");
$tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","base64",".xlsx");
+ $tw.utils.registerFileType("application/excel","base64",".xls");
+ $tw.utils.registerFileType("application/vnd.ms-excel","base64",".xls");
$tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.presentationml.presentation","base64",".pptx");
+ $tw.utils.registerFileType("application/mspowerpoint","base64",".ppt");
$tw.utils.registerFileType("text/x-bibtex","utf8",".bib",{deserializerType:"application/x-bibtex"});
$tw.utils.registerFileType("application/x-bibtex","utf8",".bib");
$tw.utils.registerFileType("application/epub+zip","base64",".epub");
diff --git a/core/copyright.tid b/core/copyright.tid
index ce0d6b02f..3f52380cc 100644
--- a/core/copyright.tid
+++ b/core/copyright.tid
@@ -4,7 +4,7 @@ type: text/plain
TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)
Copyright (c) 2004-2007, Jeremy Ruston
-Copyright (c) 2007-2023, UnaMesa Association
+Copyright (c) 2007-2024, UnaMesa Association
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/core/images/default-layout.tid b/core/images/default-layout.tid
new file mode 100644
index 000000000..4e5295d76
--- /dev/null
+++ b/core/images/default-layout.tid
@@ -0,0 +1,7 @@
+title: $:/core/images/default-layout
+tags: $:/tags/Image
+
+\parameters (size:"22pt")
+
\ No newline at end of file
diff --git a/core/language/en-GB/Buttons.multids b/core/language/en-GB/Buttons.multids
index fa769d117..3ee898b4f 100644
--- a/core/language/en-GB/Buttons.multids
+++ b/core/language/en-GB/Buttons.multids
@@ -28,6 +28,7 @@ Encryption/ClearPassword/Caption: clear password
Encryption/ClearPassword/Hint: Clear the password and save this wiki without encryption
Encryption/SetPassword/Caption: set password
Encryption/SetPassword/Hint: Set a password for saving this wiki with encryption
+EmergencyDownload/Caption: download tiddlers as json
ExportPage/Caption: export all
ExportPage/Hint: Export all tiddlers
ExportTiddler/Caption: export tiddler
diff --git a/core/language/en-GB/Docs/ModuleTypes.multids b/core/language/en-GB/Docs/ModuleTypes.multids
index 9a03d8887..5d5902c76 100644
--- a/core/language/en-GB/Docs/ModuleTypes.multids
+++ b/core/language/en-GB/Docs/ModuleTypes.multids
@@ -9,7 +9,7 @@ config: Data to be inserted into `$tw.config`.
filteroperator: Individual filter operator methods.
global: Global data to be inserted into `$tw`.
info: Publishes system information via the [[$:/temp/info-plugin]] pseudo-plugin.
-isfilteroperator: Operands for the ''is'' filter operator.
+isfilteroperator: Parameters for the ''is'' filter operator.
library: Generic module type for general purpose JavaScript modules.
macro: JavaScript macro definitions.
parser: Parsers for different content types.
diff --git a/core/language/en-GB/Fields.multids b/core/language/en-GB/Fields.multids
index 1330e60a0..68804f082 100644
--- a/core/language/en-GB/Fields.multids
+++ b/core/language/en-GB/Fields.multids
@@ -4,6 +4,7 @@ _canonical_uri: The full URI of an external image tiddler
author: Name of the author of a plugin
bag: The name of the bag from which a tiddler came
caption: The text to be displayed on a tab or button
+class: The CSS class applied to a tiddler when rendering it - see [[Custom styles by user-class]]. Also used for [[Modals]]
code-body: The view template will display the tiddler as code if set to ''yes''
color: The CSS color value associated with a tiddler
component: The name of the component responsible for an [[alert tiddler|AlertMechanism]]
diff --git a/core/language/en-GB/Misc.multids b/core/language/en-GB/Misc.multids
index 2c10d1acb..b5e6e2374 100644
--- a/core/language/en-GB/Misc.multids
+++ b/core/language/en-GB/Misc.multids
@@ -30,7 +30,7 @@ Error/DeserializeOperator/UnknownDeserializer: Filter Error: Unknown deserialize
Error/Filter: Filter error
Error/FilterSyntax: Syntax error in filter expression
Error/FilterRunPrefix: Filter Error: Unknown prefix for filter run
-Error/IsFilterOperator: Filter Error: Unknown operand for the 'is' filter operator
+Error/IsFilterOperator: Filter Error: Unknown parameter for the 'is' filter operator
Error/FormatFilterOperator: Filter Error: Unknown suffix for the 'format' filter operator
Error/LoadingPluginLibrary: Error loading plugin library
Error/NetworkErrorAlert: `
''Network Error''
It looks like the connection to the server has been lost. This may indicate a problem with your network connection. Please attempt to restore network connectivity before continuing.