1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-06-26 07:02:51 +00:00

Merge branch 'master' into multi-wiki-support

This commit is contained in:
Jeremy Ruston 2024-05-29 21:42:34 +01:00
commit d03ad0bca6
32 changed files with 351 additions and 116 deletions

View File

@ -1,6 +1,3 @@
title: $:/boot/boot.css
type: text/css
/* /*
Basic styles used before we boot up the parsing engine Basic styles used before we boot up the parsing engine
*/ */

View File

@ -1,3 +0,0 @@
title: $:/library/sjcl.js
type: application/javascript
library: yes

35
boot/tiddlywiki.files Normal file
View File

@ -0,0 +1,35 @@
{
"tiddlers": [
{
"file": "sjcl.js",
"fields": {
"title": "$:/library/sjcl.js",
"type": "application/javascript",
"library": "yes"
},
"prefix": "(function(define) {\n",
"suffix": "\n})(function (_,defined){window.sjcl = defined()})\n"
},
{
"file": "boot.js",
"fields": {
"title": "$:/boot/boot.js",
"type": "application/javascript"
}
},
{
"file": "bootprefix.js",
"fields": {
"title": "$:/boot/bootprefix.js",
"type": "application/javascript"
}
},
{
"file": "boot.css",
"fields": {
"title": "$:/boot/boot.css",
"type": "text/css"
}
}
]
}

View File

@ -1,7 +1,7 @@
title: $:/core/images/default-layout title: $:/core/images/standard-layout
tags: $:/tags/Image tags: $:/tags/Image
\parameters (size:"22pt") \parameters (size:"22pt")
<svg width=<<size>> height=<<size>> class="tc-image-default-layout tc-image-button" viewBox="0 0 128 128"> <svg width=<<size>> height=<<size>> class="tc-image-standard-layout tc-image-button" viewBox="0 0 128 128">
<path d="M71.93 72A8.07 8.07 0 0 1 80 80.07v7.86A8.071 8.071 0 0 1 71.93 96H8.07A8.067 8.067 0 0 1 0 87.93v-7.86A8.072 8.072 0 0 1 8.07 72h63.86Zm0 32a8.07 8.07 0 0 1 8.07 8.07v7.86a8.071 8.071 0 0 1-8.07 8.07H8.07A8.067 8.067 0 0 1 0 119.93v-7.86A8.072 8.072 0 0 1 8.07 104h63.86Zm0-104A8.068 8.068 0 0 1 80 8.07v47.86A8.073 8.073 0 0 1 71.93 64H8.07A8.07 8.07 0 0 1 0 55.93V8.07A8.072 8.072 0 0 1 8.07 0h63.86Zm48 0c2.14 0 4.193.85 5.706 2.364A8.067 8.067 0 0 1 128 8.07v111.86c0 2.14-.85 4.193-2.364 5.706A8.067 8.067 0 0 1 119.93 128H96.07c-2.14 0-4.193-.85-5.706-2.364A8.067 8.067 0 0 1 88 119.93V8.07c0-2.14.85-4.193 2.364-5.706A8.067 8.067 0 0 1 96.07 0h23.86ZM116 24h-16a3.995 3.995 0 0 0-2.828 1.172 3.995 3.995 0 0 0 0 5.656A3.995 3.995 0 0 0 100 32h16a3.995 3.995 0 0 0 2.828-1.172 3.995 3.995 0 0 0 0-5.656A3.995 3.995 0 0 0 116 24Z"/> <path d="M71.93 72A8.07 8.07 0 0 1 80 80.07v7.86A8.071 8.071 0 0 1 71.93 96H8.07A8.067 8.067 0 0 1 0 87.93v-7.86A8.072 8.072 0 0 1 8.07 72h63.86Zm0 32a8.07 8.07 0 0 1 8.07 8.07v7.86a8.071 8.071 0 0 1-8.07 8.07H8.07A8.067 8.067 0 0 1 0 119.93v-7.86A8.072 8.072 0 0 1 8.07 104h63.86Zm0-104A8.068 8.068 0 0 1 80 8.07v47.86A8.073 8.073 0 0 1 71.93 64H8.07A8.07 8.07 0 0 1 0 55.93V8.07A8.072 8.072 0 0 1 8.07 0h63.86Zm48 0c2.14 0 4.193.85 5.706 2.364A8.067 8.067 0 0 1 128 8.07v111.86c0 2.14-.85 4.193-2.364 5.706A8.067 8.067 0 0 1 119.93 128H96.07c-2.14 0-4.193-.85-5.706-2.364A8.067 8.067 0 0 1 88 119.93V8.07c0-2.14.85-4.193 2.364-5.706A8.067 8.067 0 0 1 96.07 0h23.86ZM116 24h-16a3.995 3.995 0 0 0-2.828 1.172 3.995 3.995 0 0 0 0 5.656A3.995 3.995 0 0 0 100 32h16a3.995 3.995 0 0 0 2.828-1.172 3.995 3.995 0 0 0 0-5.656A3.995 3.995 0 0 0 116 24Z"/>
</svg> </svg>

View File

@ -70,7 +70,7 @@ No: No
OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library 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. 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/Description: the default ~TiddlyWiki layout
PageTemplate/Name: Default ~PageTemplate PageTemplate/Name: Standard Layout
PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect 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 RecentChanges/DateFormat: DDth MMM YYYY
Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field

View File

@ -70,6 +70,9 @@ BackSubIndexer.prototype.rebuild = function() {
* Get things that is being referenced in the text, e.g. tiddler names in the link syntax. * Get things that is being referenced in the text, e.g. tiddler names in the link syntax.
*/ */
BackSubIndexer.prototype._getTarget = function(tiddler) { BackSubIndexer.prototype._getTarget = function(tiddler) {
if(this.wiki.isBinaryTiddler(tiddler.fields.text)) {
return [];
}
var parser = this.wiki.parseText(tiddler.fields.type, tiddler.fields.text, {}); var parser = this.wiki.parseText(tiddler.fields.type, tiddler.fields.text, {});
if(parser) { if(parser) {
return this.wiki[this.extractor](parser.tree); return this.wiki[this.extractor](parser.tree);

View File

@ -68,7 +68,10 @@ exports.startup = function() {
}); });
// Install the copy-to-clipboard mechanism // Install the copy-to-clipboard mechanism
$tw.rootWidget.addEventListener("tm-copy-to-clipboard",function(event) { $tw.rootWidget.addEventListener("tm-copy-to-clipboard",function(event) {
$tw.utils.copyToClipboard(event.param); $tw.utils.copyToClipboard(event.param,{
successNotification: event.paramObject.successNotification,
failureNotification: event.paramObject.failureNotification
});
}); });
// Install the tm-focus-selector message // Install the tm-focus-selector message
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) { $tw.rootWidget.addEventListener("tm-focus-selector",function(event) {

View File

@ -93,7 +93,9 @@ exports.startup = function() {
updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permalink" : "none", updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permalink" : "none",
updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(), updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(),
targetTiddler: event.param || event.tiddlerTitle, targetTiddler: event.param || event.tiddlerTitle,
copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permalink" : "none" copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permalink" : "none",
successNotification: event.paramObject && event.paramObject.successNotification,
failureNotification: event.paramObject && event.paramObject.failureNotification
}); });
}); });
// Listen for the tm-permaview message // Listen for the tm-permaview message
@ -102,7 +104,9 @@ exports.startup = function() {
updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permaview" : "none", updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permaview" : "none",
updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(), updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(),
targetTiddler: event.param || event.tiddlerTitle, targetTiddler: event.param || event.tiddlerTitle,
copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permaview" : "none" copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permaview" : "none",
successNotification: event.paramObject && event.paramObject.successNotification,
failureNotification: event.paramObject && event.paramObject.failureNotification
}); });
}); });
} }
@ -177,6 +181,8 @@ options.updateAddressBar: "permalink", "permaview" or "no" (defaults to "permavi
options.updateHistory: "yes" or "no" (defaults to "no") options.updateHistory: "yes" or "no" (defaults to "no")
options.copyToClipboard: "permalink", "permaview" or "no" (defaults to "no") options.copyToClipboard: "permalink", "permaview" or "no" (defaults to "no")
options.targetTiddler: optional title of target tiddler for permalink options.targetTiddler: optional title of target tiddler for permalink
options.successNotification: optional title of tiddler to use as the notification in case of success
options.failureNotification: optional title of tiddler to use as the notification in case of failure
*/ */
function updateLocationHash(options) { function updateLocationHash(options) {
// Get the story and the history stack // Get the story and the history stack
@ -205,14 +211,18 @@ function updateLocationHash(options) {
break; break;
} }
// Copy URL to the clipboard // Copy URL to the clipboard
var url = "";
switch(options.copyToClipboard) { switch(options.copyToClipboard) {
case "permalink": case "permalink":
$tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler)); url = $tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler);
break; break;
case "permaview": case "permaview":
$tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList))); url = $tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList));
break; break;
} }
if(url) {
$tw.utils.copyToClipboard(url,{successNotification: options.successNotification, failureNotification: options.failureNotification});
}
// Only change the location hash if we must, thus avoiding unnecessary onhashchange events // Only change the location hash if we must, thus avoiding unnecessary onhashchange events
if($tw.utils.getLocationHash() !== $tw.locationHash) { if($tw.utils.getLocationHash() !== $tw.locationHash) {
if(options.updateHistory === "yes") { if(options.updateHistory === "yes") {

View File

@ -292,7 +292,9 @@ exports.copyToClipboard = function(text,options) {
} catch (err) { } catch (err) {
} }
if(!options.doNotNotify) { if(!options.doNotNotify) {
$tw.notifier.display(succeeded ? "$:/language/Notifications/CopiedToClipboard/Succeeded" : "$:/language/Notifications/CopiedToClipboard/Failed"); var successNotification = options.successNotification || "$:/language/Notifications/CopiedToClipboard/Succeeded",
failureNotification = options.failureNotification || "$:/language/Notifications/CopiedToClipboard/Failed"
$tw.notifier.display(succeeded ? successNotification : failureNotification);
} }
document.body.removeChild(textArea); document.body.removeChild(textArea);
}; };

View File

@ -825,7 +825,7 @@ options.length .. number of characters returned defaults to 64
*/ */
exports.sha256 = function(str, options) { exports.sha256 = function(str, options) {
options = options || {} options = options || {}
return sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(str)).substr(0,options.length || 64); return $tw.sjcl.codec.hex.fromBits($tw.sjcl.hash.sha256.hash(str)).substr(0,options.length || 64);
} }
/* /*

View File

@ -77,8 +77,13 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) {
this.setVariable("transclusion",$tw.utils.hashString(jsonPayload)); this.setVariable("transclusion",$tw.utils.hashString(jsonPayload));
// Generate a `payloadTiddlers` variable that contains the payload in JSON format // Generate a `payloadTiddlers` variable that contains the payload in JSON format
this.setVariable("payloadTiddlers",jsonPayload); this.setVariable("payloadTiddlers",jsonPayload);
// Only run the tests if the testcase output and expected results were specified, and those tiddlers actually exist in the wiki
var shouldRunTests = false;
if(this.testcaseTestOutput && this.testcaseWiki.tiddlerExists(this.testcaseTestOutput) && this.testcaseTestExpectedResult && this.testcaseWiki.tiddlerExists(this.testcaseTestExpectedResult)) {
shouldRunTests = true;
}
// Render the test rendering if required // Render the test rendering if required
if(this.testcaseTestOutput && this.testcaseTestExpectedResult) { if(shouldRunTests) {
var testcaseOutputContainer = $tw.fakeDocument.createElement("div"); var testcaseOutputContainer = $tw.fakeDocument.createElement("div");
var testcaseOutputWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTestOutput,{ var testcaseOutputWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTestOutput,{
document: $tw.fakeDocument, document: $tw.fakeDocument,
@ -101,7 +106,7 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) {
var testResult = "", var testResult = "",
outputHTML = "", outputHTML = "",
expectedHTML = ""; expectedHTML = "";
if(this.testcaseTestOutput && this.testcaseTestExpectedResult) { if(shouldRunTests) {
outputHTML = testcaseOutputContainer.children[0].innerHTML; outputHTML = testcaseOutputContainer.children[0].innerHTML;
expectedHTML = this.testcaseWiki.getTiddlerText(this.testcaseTestExpectedResult); expectedHTML = this.testcaseWiki.getTiddlerText(this.testcaseTestExpectedResult);
if(outputHTML === expectedHTML) { if(outputHTML === expectedHTML) {
@ -115,7 +120,7 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) {
this.setVariable("currentTiddler",this.testcaseTestOutput); this.setVariable("currentTiddler",this.testcaseTestOutput);
} }
// Don't display anything if testHideIfPass is "yes" and the tests have passed // Don't display anything if testHideIfPass is "yes" and the tests have passed
if(this.testcaseHideIfPass === "yes" && testResult === "pass") { if(this.testcaseHideIfPass === "yes" && testResult !== "fail") {
return; return;
} }
// Render the page root template of the subwiki // Render the page root template of the subwiki

View File

@ -163,6 +163,8 @@ Widget.prototype.getVariableInfo = function(name,options) {
}); });
resultList = this.wiki.filterTiddlers(value,this.makeFakeWidgetWithVariables(variables),options.source); resultList = this.wiki.filterTiddlers(value,this.makeFakeWidgetWithVariables(variables),options.source);
value = resultList[0] || ""; value = resultList[0] || "";
} else {
params = variable.params;
} }
return { return {
text: value, text: value,

View File

@ -1,7 +1,7 @@
title: $:/core/ui/PageTemplate title: $:/core/ui/PageTemplate
name: {{$:/language/PageTemplate/Name}} name: {{$:/language/PageTemplate/Name}}
description: {{$:/language/PageTemplate/Description}} description: {{$:/language/PageTemplate/Description}}
icon: $:/core/images/default-layout icon: $:/core/images/standard-layout
code-body: yes code-body: yes
\whitespace trim \whitespace trim

View File

@ -5,6 +5,7 @@ title: $:/core/ui/TestCaseTemplate
<$let <$let
linkTarget="yes" linkTarget="yes"
displayFormat={{!!display-format}} displayFormat={{!!display-format}}
testcaseTiddler=<<currentTiddler>>
> >
<$testcase <$testcase
testOutput="Output" testOutput="Output"

View File

@ -15,7 +15,7 @@ title: $:/core/ui/testcases/DefaultTemplate
<div class="tc-test-case-wrapper"> <div class="tc-test-case-wrapper">
<div class="tc-test-case-header"> <div class="tc-test-case-header">
<h2> <h2>
<$genesis $type={{{ [<linkTarget>!match[]then[$link]else[div]] }}}> <$genesis $type={{{ [<linkTarget>!match[]then[$link]else[div]] }}} to=<<testcaseTiddler>>>
<%if [<testResult>!match[]] %> <%if [<testResult>!match[]] %>
<span class={{{ tc-test-case-result-icon [<testResult>!match[fail]then[tc-test-case-result-icon-pass]] [<testResult>match[fail]then[tc-test-case-result-icon-fail]] +[join[ ]] }}}> <span class={{{ tc-test-case-result-icon [<testResult>!match[fail]then[tc-test-case-result-icon-pass]] [<testResult>match[fail]then[tc-test-case-result-icon-fail]] +[join[ ]] }}}>
<%if [<testResult>!match[fail]] %> <%if [<testResult>!match[fail]] %>
@ -55,7 +55,9 @@ title: $:/core/ui/testcases/DefaultTemplate
<pre><$view tiddler="Output" format="plainwikified" mode="block"/></pre> <pre><$view tiddler="Output" format="plainwikified" mode="block"/></pre>
<%else%> <%else%>
<$linkcatcher actions=<<linkcatcherActions>>> <$linkcatcher actions=<<linkcatcherActions>>>
<$transclude $tiddler="Output" $mode="block"/> <$tiddler tiddler="Output">
<$transclude $tiddler="Output" $mode="block"/>
</$tiddler>
</$linkcatcher> </$linkcatcher>
<%endif%> <%endif%>
</div> </div>

View File

@ -1,6 +1,6 @@
caption: 5.3.4 caption: 5.3.4
created: 20231223102229103 created: 20240529100240232
modified: 20231223102229103 modified: 20240529100240232
tags: ReleaseNotes tags: ReleaseNotes
title: Release 5.3.4 title: Release 5.3.4
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
@ -10,6 +10,8 @@ description: Under development
! Major Improvements ! Major Improvements
!! Tour Plugin
<<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7734">> several new features that together allow interactive learning tours to be created and presented in TiddlyWiki. <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7734">> several new features that together allow interactive learning tours to be created and presented in TiddlyWiki.
The demo TiddlyWiki interactive tour can be seen at https://tiddlywiki.com/prerelease/tour The demo TiddlyWiki interactive tour can be seen at https://tiddlywiki.com/prerelease/tour
@ -20,6 +22,20 @@ The new features include:
* The new Confetti Plugin that allows animated bursts of confetti to be displayed * The new Confetti Plugin that allows animated bursts of confetti to be displayed
* Improvements to the Dynannotate Plugin to add the ability to highlight screen elements using an animated spotlight effect * Improvements to the Dynannotate Plugin to add the ability to highlight screen elements using an animated spotlight effect
!! <<.wlink TestCaseWidget>> Widget
<<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7817">> new <<.wlink TestCaseWidget>> widget that is intended to solve a problem with the examples that we feature in the documentation. The existing macros are workable for simple, self-contained examples, but can be hard to follow in cases where the examples use additional tiddlers. The <<.wlink TestCaseWidget>> widget displays complete, self-contained interactive examples showing the output together with a tabbed display of the constituent tiddlers that produce it:
<<testcase "TestCases/TestCaseWidget/TwoPlusTwo">>
The payload tiddlers for a test case are specified with the <<.wlink DataWidget>> widget. Test cases are run as an independent, self-contained nested wiki in a similar way to the [[Innerwiki Plugin]], but are much more lightweight. The disadvantage is that test cases are rendered as part of the main page, and so any styling changes will leak out to the rest of the page.
Test cases can also specify the raw HTML of the expected result which causes them to be executed as tests, with success or failure indicated by an icon:
<<testcase "TestCases/TestCaseWidget/FailingTest">>
The easiest way to use the <<.wlink TestCaseWidget>> is by creating TestCaseTiddlers using the new CompoundTiddlers format. There are also many test cases to view in the TiddlyWiki test edition at https://tiddlywiki.com/prerelease/test.html
! Translation improvements ! Translation improvements
Improvements to the following translations: Improvements to the following translations:
@ -30,7 +46,7 @@ Improvements to the following translations:
! Plugin Improvements ! Plugin Improvements
* * <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/8198">> badges to the core plugins to indicate their [[stability level|Plugin Stability]] from "deprecated", "experimental", "stable" and "legacy". These badges are shown in the plugin library and in the control panel
! Widget Improvements ! Widget Improvements
@ -43,14 +59,18 @@ Improvements to the following translations:
! Usability Improvements ! Usability Improvements
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/issues/8121">> new keyboard shortcut for refreshing the page * <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/issues/8121">> new keyboard shortcut for refreshing the page
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/commit/f3614c1e47e6ac5d5fec221b060699e975cd5ef6">> and simplified the splash screen for tiddlywiki.com. See [[Creating a splash screen]] for instructions on creating your own splash screen
! Hackability Improvements ! Hackability Improvements
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7882">> infinite recursion handling using a custom exception
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7966">> button to the JavaScript error popup allowing tiddlers to be saved to a local JSON file * <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7966">> button to the JavaScript error popup allowing tiddlers to be saved to a local JSON file
* <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/issues/8120">> to latest version of modern-normalize 2.0.0 * <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/issues/8120">> to latest version of modern-normalize 2.0.0
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/8211">> [[tm-permalink|WidgetMessage: tm-permalink]], [[tm-permaview|WidgetMessage: tm-permaview]] and [[tm-copy-to-clipboard|WidgetMessage: tm-copy-to-clipboard]] messages to allow the notification text to be customised
! Bug Fixes ! Bug Fixes
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8186">> nested [[Block Quotes in WikiText]]
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7933">> TiddlyWikiClassic build process * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7933">> TiddlyWikiClassic build process
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7935">> LinkWidget not refreshing when the `to` attribute changes * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7935">> LinkWidget not refreshing when the `to` attribute changes
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/3460">> parsing bug with empty procedures/macros * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/3460">> parsing bug with empty procedures/macros
@ -67,6 +87,7 @@ Improvements to the following translations:
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/801ed0ea1164aab4f88547322f9d73704388143f">> crash with [[cycle Operator]] if the the step size is larger than the number of operands * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/801ed0ea1164aab4f88547322f9d73704388143f">> crash with [[cycle Operator]] if the the step size is larger than the number of operands
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/8095">> proper DOCTYPE for the open window template * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/8095">> proper DOCTYPE for the open window template
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7945">> theme font size settings to open in new window CSS * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7945">> theme font size settings to open in new window CSS
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8098">> backlink parser to prevent it parsing binary tiddlers
! Node.js Improvements ! Node.js Improvements
@ -79,7 +100,9 @@ Improvements to the following translations:
! Developer Improvements ! Developer Improvements
* * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8195">> issue with fakedom TW_Node inheritence
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8099">> SJCL library creating variables in global scope
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8179">> fix `widget.getVariableInfo()` to always return a `params` property
! Infrastructure Improvements ! Infrastructure Improvements
@ -114,5 +137,6 @@ rmunn
saqimtiaz saqimtiaz
sarna sarna
Telumire Telumire
twMat
yaisog yaisog
""">> """>>

View File

@ -12,6 +12,24 @@ Tests the backlinks mechanism.
"use strict"; "use strict";
describe('Backlinks tests', function() { describe('Backlinks tests', function() {
function setupWiki(wikiOptions) {
wikiOptions = wikiOptions || {};
// Create a wiki
var wiki = new $tw.Wiki(wikiOptions);
wiki.addIndexersToWiki();
wiki.addTiddler({
title: 'TestIncoming',
text: '',
});
wiki.addTiddler({
title: 'TestOutgoing',
text: 'A link to [[TestIncoming]]',
});
return wiki;
}
describe('a tiddler with no links to it', function() { describe('a tiddler with no links to it', function() {
var wiki = new $tw.Wiki(); var wiki = new $tw.Wiki();
@ -25,15 +43,7 @@ describe('Backlinks tests', function() {
}); });
describe('A tiddler added to the wiki with a link to it', function() { describe('A tiddler added to the wiki with a link to it', function() {
var wiki = new $tw.Wiki(); var wiki = setupWiki();
wiki.addTiddler({
title: 'TestIncoming',
text: ''});
wiki.addTiddler({
title: 'TestOutgoing',
text: 'A link to [[TestIncoming]]'});
it('should have a backlink', function() { it('should have a backlink', function() {
expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing'); expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing');
@ -42,15 +52,7 @@ describe('Backlinks tests', function() {
describe('A tiddler that has a link added to it later', function() { describe('A tiddler that has a link added to it later', function() {
it('should have an additional backlink', function() { it('should have an additional backlink', function() {
var wiki = new $tw.Wiki(); var wiki = setupWiki();
wiki.addTiddler({
title: 'TestIncoming',
text: ''});
wiki.addTiddler({
title: 'TestOutgoing',
text: 'A link to [[TestIncoming]]'});
wiki.addTiddler({ wiki.addTiddler({
title: 'TestOutgoing2', title: 'TestOutgoing2',
@ -67,15 +69,7 @@ describe('Backlinks tests', function() {
}); });
describe('A tiddler that has a link remove from it later', function() { describe('A tiddler that has a link remove from it later', function() {
var wiki = new $tw.Wiki(); var wiki = setupWiki();
wiki.addTiddler({
title: 'TestIncoming',
text: ''});
wiki.addTiddler({
title: 'TestOutgoing',
text: 'A link to [[TestIncoming]]'});
it('should have one fewer backlink', function() { it('should have one fewer backlink', function() {
expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing'); expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing');
@ -89,15 +83,7 @@ describe('Backlinks tests', function() {
}); });
describe('A tiddler linking to another that gets renamed', function() { describe('A tiddler linking to another that gets renamed', function() {
var wiki = new $tw.Wiki(); var wiki = setupWiki();
wiki.addTiddler({
title: 'TestIncoming',
text: ''});
wiki.addTiddler({
title: 'TestOutgoing',
text: 'A link to [[TestIncoming]]'});
it('should have its name changed in the backlinks', function() { it('should have its name changed in the backlinks', function() {
expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing'); expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing');
@ -109,15 +95,7 @@ describe('Backlinks tests', function() {
}); });
describe('A tiddler linking to another that gets deleted', function() { describe('A tiddler linking to another that gets deleted', function() {
var wiki = new $tw.Wiki(); var wiki = setupWiki();
wiki.addTiddler({
title: 'TestIncoming',
text: ''});
wiki.addTiddler({
title: 'TestOutgoing',
text: 'A link to [[TestIncoming]]'});
it('should be removed from backlinks', function() { it('should be removed from backlinks', function() {
expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing'); expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing');
@ -127,6 +105,41 @@ describe('Backlinks tests', function() {
expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe(''); expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('');
}); });
}); });
describe('Binary tiddlers should not be parsed', function() {
var wiki = setupWiki();
wiki.addTiddler({
title: 'TestDoc.doc',
text: 'A link to [[TestOutgoing]]',
type: 'application/msword'
});
wiki.addTiddler({
title: 'TestExcel.xls',
text: 'A link to [[TestOutgoing]]',
type: 'application/excel'
});
wiki.addTiddler({
title: 'TestOutgoing',
text: 'Some links to [[TestDoc.doc]] and [[TestExcel.xls]].'
});
it('should ignore office files', function() {
expect(wiki.getIndexer("BackIndexer").subIndexers.link._getTarget(wiki.getTiddler('TestExcel.xls'))).toEqual([]);
expect(wiki.filterTiddlers('[all[]] +[backlinks[]]').join(',')).toBe('TestOutgoing');
// make it tw5 tiddler
wiki.addTiddler({
title: 'TestExcel.xls',
text: 'A link to [[TestOutgoing]]'
});
expect(wiki.filterTiddlers('[all[]] +[backlinks[]]').join(',')).toBe('TestOutgoing,TestExcel.xls');
});
});
}); });
})(); })();

View File

@ -22,22 +22,30 @@ if($tw.node) {
describe("every plugin should have the required standard fields", function() { describe("every plugin should have the required standard fields", function() {
var titles = Object.keys(tiddlers); var titles = Object.keys(tiddlers);
$tw.utils.each(titles,function(title) { $tw.utils.each(titles,function(title) {
it("plugin " + title + " should have the required standard fields",function() { var fields = tiddlers[title];
var fields = tiddlers[title]; it("plugin should have a recognised plugin-type field",function() {
expect(fields["plugin-type"]).toMatch(/^(?:plugin|language|theme)$/); expect(["plugin","language","theme"].indexOf(fields["plugin-type"]) !== -1).toEqual(true);
switch(fields["plugin-type"]) {
case "plugin":
expect(!!(fields.name && fields.description && fields.list)).toEqual(true);
expect(fields.stability).toMatch(/^(?:STABILITY_0_DEPRECATED|STABILITY_1_EXPERIMENTAL|STABILITY_2_STABLE|STABILITY_3_LEGACY)$/);
break;
case "language":
expect(!!(fields.name && fields.description)).toEqual(true);
break;
case "theme":
expect(!!(fields.name && fields.description)).toEqual(true);
break;
}
}); });
switch(fields["plugin-type"]) {
case "plugin":
it("plugin " + title + " should have name, description and list fields",function() {
expect(!!(fields.name && fields.description && fields.list)).toBe(true);
});
it("plugin " + title + " should have a valid stability field",function() {
expect(["STABILITY_0_DEPRECATED","STABILITY_1_EXPERIMENTAL","STABILITY_2_STABLE","STABILITY_3_LEGACY"].indexOf(fields.stability) !== -1).toBe(true);
});
break;
case "language":
it("language " + title + " should have name and description fields",function() {
expect(!!(fields.name && fields.description)).toEqual(true);
});
break;
case "theme":
it("theme " + title + " should have name and description fields",function() {
expect(!!(fields.name && fields.description)).toEqual(true);
});
break;
}
}); });
}); });
}); });

View File

@ -0,0 +1,95 @@
/*\
title: test-widget-getVariableInfo.js
type: application/javascript
tags: [[$:/tags/test-spec]]
Tests the wikitext rendering pipeline end-to-end. We also need tests that individually test parsers, rendertreenodes etc., but this gets us started.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
describe("Widget module", function() {
var widget = require("$:/core/modules/widgets/widget.js");
function createWidgetNode(parseTreeNode,wiki) {
return new widget.widget(parseTreeNode,{
wiki: wiki,
document: $tw.fakeDocument
});
}
function parseText(text,wiki,options) {
var parser = wiki.parseText("text/vnd.tiddlywiki",text,options);
return parser ? {type: "widget", children: parser.tree} : undefined;
}
function renderWidgetNode(widgetNode) {
$tw.fakeDocument.setSequenceNumber(0);
var wrapper = $tw.fakeDocument.createElement("div");
widgetNode.render(wrapper,null);
// console.log(require("util").inspect(wrapper,{depth: 8}));
return wrapper;
}
function refreshWidgetNode(widgetNode,wrapper,changes) {
var changedTiddlers = {};
if(changes) {
$tw.utils.each(changes,function(title) {
changedTiddlers[title] = true;
});
}
widgetNode.refresh(changedTiddlers,wrapper,null);
// console.log(require("util").inspect(wrapper,{depth: 8}));
}
it("should make sure that getVariableInfo returns all expected parameters", function() {
var wiki = new $tw.Wiki();
wiki.addTiddlers([
{title: "A", text: "\\define macro(a:aa) aaa"},
{title: "B", text: "\\function fn(f:ff) fff\n\\function x() [<fn>]"},
{title: "C", text: "\\procedure proc(p:pp) ppp"},
{title: "D", text: "\\widget $my.widget(w:ww) www"}
]);
var text = "\\import A B C D\n\n<$let abc=def>";
var widgetNode = createWidgetNode(parseText(text,wiki),wiki);
// Render the widget node to the DOM
renderWidgetNode(widgetNode);
var childNode = widgetNode;
while(childNode.children.length > 0) {
childNode = childNode.children[0];
}
expect(childNode.getVariableInfo("macro",{allowSelfAssigned:true}).params).toEqual([{name:"a",value:"aa"}]);
// function params
expect(childNode.getVariableInfo("fn", {allowSelfAssigned:true}).params).toEqual([{name:"f",value:"ff"}]);
// functions have a text and a value
expect(childNode.getVariableInfo("x", {allowSelfAssigned:true}).text).toBe("fff");
expect(childNode.getVariableInfo("x", {allowSelfAssigned:true}).srcVariable.value).toBe("[<fn>]");
// procedures and widgets failed prior to v5.3.4
expect(childNode.getVariableInfo("proc", {allowSelfAssigned:true}).params).toEqual([{name:"p",default:"pp"}]);
expect(childNode.getVariableInfo("$my.widget", {allowSelfAssigned:true}).params).toEqual([{name:"w",default:"ww"}]);
// no params expected
expect(childNode.getVariableInfo("abc", {allowSelfAssigned:true})).toEqual({text:"def"});
// debugger; Find code in browser
// Find values to be compated to
// console.log("macro", childNode.getVariableInfo("macro",{allowSelfAssigned:true}));
// console.log("function", childNode.getVariableInfo("fn",{allowSelfAssigned:true}));
// console.log("function x", childNode.getVariableInfo("x",{allowSelfAssigned:true}));
// console.log("procedure", childNode.getVariableInfo("proc",{allowSelfAssigned:true}));
// console.log("widget", childNode.getVariableInfo("$my.widget",{allowSelfAssigned:true}));
// console.log("let", childNode.getVariableInfo("abc",{allowSelfAssigned:true}));
});
});
})();

View File

@ -23,5 +23,4 @@ Some payload tiddlers are set aside for special purposes:
|''Narrative'' |Narrative description of the test, intended to explain the purpose and operation of the test | |''Narrative'' |Narrative description of the test, intended to explain the purpose and operation of the test |
|''Output'' |The tiddler that produces the test output | |''Output'' |The tiddler that produces the test output |
|''~ExpectedResult'' |HTML of expected result of rendering the ''Output'' tiddler | |''~ExpectedResult'' |HTML of expected result of rendering the ''Output'' tiddler |
|''Description'' |Set to the text of the <<.field description>> field |

View File

@ -1,6 +1,6 @@
caption: tm-copy-to-clipboard caption: tm-copy-to-clipboard
created: 20171215150056004 created: 20171215150056004
modified: 20171215150600888 modified: 20240523174013095
tags: Messages tags: Messages
title: WidgetMessage: tm-copy-to-clipboard title: WidgetMessage: tm-copy-to-clipboard
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
@ -11,6 +11,8 @@ It requires the following properties on the `event` object:
|!Name |!Description | |!Name |!Description |
|param |Text to be copied to the clipboard | |param |Text to be copied to the clipboard |
|successNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation succeeds |
|failureNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation fails |
This message is usually generated with the ButtonWidget. It is handled by the TiddlyWiki core. This message is usually generated with the ButtonWidget. It is handled by the TiddlyWiki core.

View File

@ -1,5 +1,5 @@
created: 20140723103751357 created: 20140723103751357
modified: 20140723103751357 modified: 20240523174013095
tags: Messages tags: Messages
title: WidgetMessage: tm-permalink title: WidgetMessage: tm-permalink
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
@ -12,5 +12,7 @@ The permalink message supports the following properties on the `event` object:
|!Name |!Description | |!Name |!Description |
|param |Title of the tiddler to be permalinked | |param |Title of the tiddler to be permalinked |
|tiddlerTitle |The current tiddler (used by default if the tiddler title isn't specified in the `param`) | |tiddlerTitle |The current tiddler (used by default if the tiddler title isn't specified in the `param`) |
|successNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation succeeds |
|failureNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation fails |
The permalink message can be generated by the ButtonWidget, and is handled by the story mechanism. The permalink message can be generated by the ButtonWidget, and is handled by the story mechanism.

View File

@ -1,5 +1,5 @@
created: 20140723103751357 created: 20140723103751357
modified: 20140723103751357 modified: 20240523174013095
tags: Messages tags: Messages
title: WidgetMessage: tm-permaview title: WidgetMessage: tm-permaview
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
@ -12,5 +12,7 @@ The permaview message supports the following properties on the `event` object:
|!Name |!Description | |!Name |!Description |
|param |Title of the tiddler to be navigated within the permaview | |param |Title of the tiddler to be navigated within the permaview |
|tiddlerTitle |The current tiddler (used by default if the tiddler title isn't specified in the `param`) | |tiddlerTitle |The current tiddler (used by default if the tiddler title isn't specified in the `param`) |
|successNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation succeeds |
|failureNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation fails |
The permaview message can be generated by the ButtonWidget, and is handled by the story mechanism. The permaview message can be generated by the ButtonWidget, and is handled by the story mechanism.

View File

@ -113,7 +113,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</div> </div>
<div class="tc-splash-text"> <div class="tc-splash-text">
Please wait while {{$:/SiteTitle}} is loading <strong>{{$:/SiteTitle}}</strong>
<br/>
is loading
</div> </div>
<!-- Demonstrating how to embed a bitmap graphic --> <!-- Demonstrating how to embed a bitmap graphic -->

View File

@ -5,7 +5,7 @@ description: An example of a failing test
title: Narrative title: Narrative
This test case intentionally fails to show how failures are displayed. This test case intentionally fails (in order to show how failures are displayed)
+ +
title: Output title: Output

View File

@ -0,0 +1,12 @@
title: TestCases/TestCaseWidget/NoExpectedResults
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
description: A testcase that does not specify expected results
title: Narrative
This testcase will display without the pass/fail icons because it does not include an `ExpectedResults` tiddler, and so will only be rendered, and not be executed as a test
+
title: Output
This is the output

View File

@ -0,0 +1,18 @@
title: TestCases/TestCaseWidget/TwoPlusTwo
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec-failing]]
description: A testcase to calculate 2+2
title: Narrative
This test case shows an elaborate way to calculate 2+2 involving multiple tiddlers
+
title: Output
The sum is <$text text={{{ [{FirstNumber}add{SecondNumber}] }}}/>
+
title: FirstNumber
text: 2
+
title: SecondNumber
text: 2

View File

@ -1,6 +1,6 @@
caption: action-listops caption: action-listops
created: 20141025120850184 created: 20141025120850184
modified: 20230805103548113 modified: 20240509135041526
myfield: myfield:
tags: ActionWidgets Widgets tags: ActionWidgets Widgets
title: ActionListopsWidget title: ActionListopsWidget
@ -35,10 +35,12 @@ The above widget will toggle the presence of the element <<.value "List Item">>
Similarly, if an element is to always be removed when it is present, the `-` / `:except` [[filter run prefix|Filter Expression]] can be used. Both of the following yield the same result: Similarly, if an element is to always be removed when it is present, the `-` / `:except` [[filter run prefix|Filter Expression]] can be used. Both of the following yield the same result:
``` ```
<$action-listops $subfilter="-[[List Item]]"/> <$action-listops $subfilter="-[[ListItem]]"/>
<$action-listops $subfilter="+[remove[List Item]]"/> <$action-listops $subfilter="+[remove[ListItem]]"/>
``` ```
<<.infoBox """Note that the parameter of the [[remove Operator]] is a [[Title List]]. To remove one or more titles containing spaces the individual titles must be wrapped in double square brackets, usually via a soft [[Filter Parameter]]. See //Filtered List Variable Assignment// in the [[SetWidget]] documentation to learn more.""">>
Without any prefixes, the filter run output is simply [[dominantly appended|Dominant Append]] to the list. Without any prefixes, the filter run output is simply [[dominantly appended|Dominant Append]] to the list.
See also the [[Examples|ActionListopsWidget (Examples)]]. See also the [[Examples|ActionListopsWidget (Examples)]].

View File

@ -75,7 +75,7 @@ The test case wiki will inherit variables that are visible to the <<.wid testcas
A custom template can be specified for special purposes. For example, the provided template $:/core/ui/testcases/RawJSONTemplate just displays the payload tiddlers in JSON, which can be used for debugging purposes. A custom template can be specified for special purposes. For example, the provided template $:/core/ui/testcases/RawJSONTemplate just displays the payload tiddlers in JSON, which can be used for debugging purposes.
! Test Czase Template Variables ! Test Case Template Variables
The <<.wid testcase>> widget makes the following variables available within the rendered template: The <<.wid testcase>> widget makes the following variables available within the rendered template:

View File

@ -69,8 +69,8 @@ MissingTiddler/Hint: 佚失条目 "<$text text=<<currentTiddler>>/>" - 点击 {{
No: 否 No: 否
OfficialPluginLibrary: ~TiddlyWiki 官方插件库 OfficialPluginLibrary: ~TiddlyWiki 官方插件库
OfficialPluginLibrary/Hint: 此为在 tiddlywiki.com 的 ~TiddlyWiki 官方插件库。由核心团队维护的插件、主题和语言包。 OfficialPluginLibrary/Hint: 此为在 tiddlywiki.com 的 ~TiddlyWiki 官方插件库。由核心团队维护的插件、主题和语言包。
PageTemplate/Description: 默认的 ~Tiddlywiki 布局 PageTemplate/Description: 默认的太微布局
PageTemplate/Name: 默认的 ~PageTemplate PageTemplate/Name: 标准布局
PluginReloadWarning: 请保存 {{$:/core/ui/Buttons/save-wiki}} 并刷新页面 {{$:/core/ui/Buttons/refresh}} ,使 ~JavaScript 插件的更改生效 PluginReloadWarning: 请保存 {{$:/core/ui/Buttons/save-wiki}} 并刷新页面 {{$:/core/ui/Buttons/refresh}} ,使 ~JavaScript 插件的更改生效
RecentChanges/DateFormat: YYYY年0MM月0DD日 RecentChanges/DateFormat: YYYY年0MM月0DD日
Shortcuts/Input/Accept/Hint: 接受选取的项目 Shortcuts/Input/Accept/Hint: 接受选取的项目

View File

@ -70,7 +70,7 @@ No: 否
OfficialPluginLibrary: ~TiddlyWiki 官方插件程式庫 OfficialPluginLibrary: ~TiddlyWiki 官方插件程式庫
OfficialPluginLibrary/Hint: 此為在 tiddlywiki.com 的 ~TiddlyWiki 官方插件程式庫。由核心團隊維護的插件、主題和語言包。 OfficialPluginLibrary/Hint: 此為在 tiddlywiki.com 的 ~TiddlyWiki 官方插件程式庫。由核心團隊維護的插件、主題和語言包。
PageTemplate/Description: 預設的 ~Tiddlywiki 佈局 PageTemplate/Description: 預設的 ~Tiddlywiki 佈局
PageTemplate/Name: 預設的 ~PageTemplate PageTemplate/Name: 標准佈局
PluginReloadWarning: 請儲存 {{$:/core/ui/Buttons/save-wiki}} 並刷新頁面 {{$:/core/ui/Buttons/refresh}} ,使 ~JavaScript 插件的更改生效 PluginReloadWarning: 請儲存 {{$:/core/ui/Buttons/save-wiki}} 並刷新頁面 {{$:/core/ui/Buttons/refresh}} ,使 ~JavaScript 插件的更改生效
RecentChanges/DateFormat: YYYY年0MM月0DD日 RecentChanges/DateFormat: YYYY年0MM月0DD日
Shortcuts/Input/Accept/Hint: 接受選取的項目 Shortcuts/Input/Accept/Hint: 接受選取的項目

View File

@ -34,23 +34,22 @@ describe("Wiki-based tests", function() {
if(!wiki.tiddlerExists("Output")) { if(!wiki.tiddlerExists("Output")) {
throw "Missing 'Output' tiddler"; throw "Missing 'Output' tiddler";
} }
if(!wiki.tiddlerExists("ExpectedResult")) { if(wiki.tiddlerExists("ExpectedResult")) {
throw "Missing 'ExpectedResult' tiddler"; // Construct the widget node
var text = "{{Output}}\n\n";
var widgetNode = createWidgetNode(parseText(text,wiki),wiki);
// Render the widget node to the DOM
var wrapper = renderWidgetNode(widgetNode);
// Clear changes queue
wiki.clearTiddlerEventQueue();
// Run the actions if provided
if(wiki.tiddlerExists("Actions")) {
widgetNode.invokeActionString(wiki.getTiddlerText("Actions"));
refreshWidgetNode(widgetNode,wrapper);
}
// Test the rendering
expect(wrapper.innerHTML).toBe(wiki.getTiddlerText("ExpectedResult"));
} }
// Construct the widget node
var text = "{{Output}}\n\n";
var widgetNode = createWidgetNode(parseText(text,wiki),wiki);
// Render the widget node to the DOM
var wrapper = renderWidgetNode(widgetNode);
// Clear changes queue
wiki.clearTiddlerEventQueue();
// Run the actions if provided
if(wiki.tiddlerExists("Actions")) {
widgetNode.invokeActionString(wiki.getTiddlerText("Actions"));
refreshWidgetNode(widgetNode,wrapper);
}
// Test the rendering
expect(wrapper.innerHTML).toBe(wiki.getTiddlerText("ExpectedResult"));
}); });
}); });