From 09f04cb5a6000e86c62c5aecca303a5cd896f597 Mon Sep 17 00:00:00 2001 From: poc2go Date: Sat, 16 Mar 2024 13:33:13 -0400 Subject: [PATCH 001/306] Signing the CLA (#8077) --- licenses/cla-individual.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/licenses/cla-individual.md b/licenses/cla-individual.md index 5f7a833c3..3dafcf352 100644 --- a/licenses/cla-individual.md +++ b/licenses/cla-individual.md @@ -561,3 +561,5 @@ Wang Ke, @Gk0Wk, 2023/10/17 John Long, @drevarr, 2023/12/12 Ed Holsinger, @eschlon, 2024/02/08 + +Kim I. McKinley, @PotOfCoffee2Go, 2024/03/16 From 0b6db6e860ed0fdeab81027a2caddba5a68227e3 Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Sat, 16 Mar 2024 20:03:36 +0100 Subject: [PATCH 002/306] Fix indentation for tiddlers that set tv-config-toolbar-class (#8079) human readable in preparation to add data-title=<> for better UX defining a "read only" theme Changes to be committed: modified: core/ui/EditTemplate/controls.tid modified: core/ui/PageControls.tid modified: core/ui/PageControls/more-page-actions.tid modified: core/ui/ViewTemplate/title.tid modified: core/ui/ViewToolbar/more-tiddler-actions.tid modified: plugins/tiddlywiki/menubar/items/pagecontrols.tid --- core/ui/EditTemplate/controls.tid | 18 +++-- core/ui/PageControls.tid | 23 +++--- core/ui/PageControls/more-page-actions.tid | 79 +++++++++---------- core/ui/ViewTemplate/title.tid | 59 ++++++++------ core/ui/ViewToolbar/more-tiddler-actions.tid | 78 ++++++++---------- .../tiddlywiki/menubar/items/pagecontrols.tid | 19 +++-- 6 files changed, 136 insertions(+), 140 deletions(-) diff --git a/core/ui/EditTemplate/controls.tid b/core/ui/EditTemplate/controls.tid index 3e94d371d..e97cedd78 100644 --- a/core/ui/EditTemplate/controls.tid +++ b/core/ui/EditTemplate/controls.tid @@ -1,12 +1,18 @@ title: $:/core/ui/EditTemplate/controls tags: $:/tags/EditTemplate -\define config-title() -$:/config/EditToolbarButtons/Visibility/$(listItem)$ -\end +\define config-title() $:/config/EditToolbarButtons/Visibility/$(listItem)$ \whitespace trim
-<$view field="title"/> -<$list filter="[all[shadows+tiddlers]tag[$:/tags/EditToolbar]!has[draft.of]]" variable="listItem"><$let tv-config-toolbar-class={{{ [enlist] [encodeuricomponent[]addprefix[tc-btn-]] +[join[ ]]}}}><$reveal type="nomatch" state=<> text="hide"><$transclude tiddler=<>/> -
+ <$view field="title"/> + + <$list filter="[all[shadows+tiddlers]tag[$:/tags/EditToolbar]!has[draft.of]]" variable="listItem"> + <$let tv-config-toolbar-class={{{ [enlist] [encodeuricomponent[]addprefix[tc-btn-]] +[join[ ]] }}}> + <$reveal type="nomatch" state=<> text="hide"> + <$transclude $tiddler=<>/> + + + + +
diff --git a/core/ui/PageControls.tid b/core/ui/PageControls.tid index 93a7bc224..2b579050c 100644 --- a/core/ui/PageControls.tid +++ b/core/ui/PageControls.tid @@ -1,17 +1,16 @@ title: $:/core/ui/PageTemplate/pagecontrols \whitespace trim -\define config-title() -$:/config/PageControlButtons/Visibility/$(listItem)$ -\end +\define config-title() $:/config/PageControlButtons/Visibility/$(listItem)$ +
-<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]" variable="listItem"> -<$set name="hidden" value=<>> -<$list filter="[!text[hide]]" storyview="pop" variable="ignore"> -<$set name="tv-config-toolbar-class" filter="[] [encodeuricomponent[]addprefix[tc-btn-]]"> -<$transclude tiddler=<> mode="inline"/> - - - - + <$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]" variable="listItem"> + <$set name="hidden" value=<>> + <$list filter="[!text[hide]]" storyview="pop" variable="ignore"> + <$set name="tv-config-toolbar-class" filter="[] [encodeuricomponent[]addprefix[tc-btn-]]"> + <$transclude tiddler=<> mode="inline"/> + + + +
diff --git a/core/ui/PageControls/more-page-actions.tid b/core/ui/PageControls/more-page-actions.tid index b52f99ec9..3acaef2b6 100644 --- a/core/ui/PageControls/more-page-actions.tid +++ b/core/ui/PageControls/more-page-actions.tid @@ -4,48 +4,41 @@ caption: {{$:/core/images/down-arrow}} {{$:/language/Buttons/More/Caption}} description: {{$:/language/Buttons/More/Hint}} \whitespace trim -\define config-title() -$:/config/PageControlButtons/Visibility/$(listItem)$ -\end -<$button popup=<> tooltip={{$:/language/Buttons/More/Hint}} aria-label={{$:/language/Buttons/More/Caption}} class=<> selectedClass="tc-selected"> -<$list filter="[match[yes]]"> -{{$:/core/images/down-arrow}} - -<$list filter="[match[yes]]"> - -<$text text={{$:/language/Buttons/More/Caption}}/> - - -<$reveal state=<> type="popup" position="below" animate="yes"> - -
- -<$set name="tv-config-toolbar-icons" value="yes"> - -<$set name="tv-config-toolbar-text" value="yes"> - -<$set name="tv-config-toolbar-class" value="tc-btn-invisible"> - -<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]] -[[$:/core/ui/Buttons/more-page-actions]]" variable="listItem"> - -<$reveal type="match" state=<> text="hide"> - -<$set name="tv-config-toolbar-class" filter="[] [encodeuricomponent[]addprefix[tc-btn-]]"> - -<$transclude tiddler=<> mode="inline"/> - - - - - - - - - - - - - -
+\define config-title() $:/config/PageControlButtons/Visibility/$(listItem)$ +<$button popup=<> + tooltip={{$:/language/Buttons/More/Hint}} + aria-label={{$:/language/Buttons/More/Caption}} + class=<> + selectedClass="tc-selected" +> + <$list filter="[match[yes]]"> + {{$:/core/images/down-arrow}} + + <$list filter="[match[yes]]"> + + <$text text={{$:/language/Buttons/More/Caption}}/> + + + +<$reveal state=<> type="popup" position="below" animate="yes"> +
+ <$set name="tv-config-toolbar-icons" value="yes"> + <$set name="tv-config-toolbar-text" value="yes"> + <$set name="tv-config-toolbar-class" value="tc-btn-invisible"> + <$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]] -[[$:/core/ui/Buttons/more-page-actions]]" + variable="listItem" + > + <$reveal type="match" state=<> text="hide"> + <$set name="tv-config-toolbar-class" + filter="[] [encodeuricomponent[]addprefix[tc-btn-]]" + > + <$transclude tiddler=<> mode="inline"/> + + + + + + +
\ No newline at end of file diff --git a/core/ui/ViewTemplate/title.tid b/core/ui/ViewTemplate/title.tid index 98695f6bf..e5be2eba5 100644 --- a/core/ui/ViewTemplate/title.tid +++ b/core/ui/ViewTemplate/title.tid @@ -2,31 +2,38 @@ title: $:/core/ui/ViewTemplate/title tags: $:/tags/ViewTemplate \whitespace trim -\define title-styles() -fill:$(foregroundColor)$; -\end +\define title-styles() fill:$(foregroundColor)$; +
-
- -<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]] :filter[lookup[$:/config/ViewToolbarButtons/Visibility/]!match[hide]]" storyview="pop" variable="listItem"><$set name="tv-config-toolbar-class" filter="[] [encodeuricomponent[]addprefix[tc-btn-]]"><$transclude tiddler=<>/> - -<$set name="tv-wikilinks" value={{$:/config/Tiddlers/TitleLinks}}> -<$link> -<$list filter="[] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] +[!is[blank]]" variable="ignore"> -<$let foregroundColor={{{ [] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}> ->> -{{||$:/core/ui/TiddlerIcon}} - - - -<$transclude tiddler={{{ [] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateTitleFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/title/default]] }}} /> - - -
- -<$reveal type="nomatch" text="" default="" state=<> class="tc-tiddler-info tc-popup-handle" animate="yes" retain="yes"> - -<$list filter="[all[shadows+tiddlers]tag[$:/tags/TiddlerInfoSegment]!has[draft.of]] [[$:/core/ui/TiddlerInfo]]" variable="listItem"><$transclude tiddler=<> mode="block"/> - - +
+ + <$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]] :filter[lookup[$:/config/ViewToolbarButtons/Visibility/]!match[hide]]" + storyview="pop" + variable="listItem" + > + <$set name="tv-config-toolbar-class" filter="[] [encodeuricomponent[]addprefix[tc-btn-]]"> + <$transclude tiddler=<>/> + + + + <$set name="tv-wikilinks" value={{$:/config/Tiddlers/TitleLinks}}> + <$link> + <$list filter="[] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] +[!is[blank]]" + variable="ignore" + > + <$let foregroundColor={{{ [] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}> + >> + {{||$:/core/ui/TiddlerIcon}} + + + + <$transclude tiddler={{{ [] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateTitleFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/title/default]] }}} /> + + +
+ <$reveal type="nomatch" text="" default="" state=<> class="tc-tiddler-info tc-popup-handle" animate="yes" retain="yes"> + <$list filter="[all[shadows+tiddlers]tag[$:/tags/TiddlerInfoSegment]!has[draft.of]] [[$:/core/ui/TiddlerInfo]]" variable="listItem"> + <$transclude tiddler=<> mode="block"/> + +
diff --git a/core/ui/ViewToolbar/more-tiddler-actions.tid b/core/ui/ViewToolbar/more-tiddler-actions.tid index 6b24db362..e7e75a79b 100644 --- a/core/ui/ViewToolbar/more-tiddler-actions.tid +++ b/core/ui/ViewToolbar/more-tiddler-actions.tid @@ -4,49 +4,41 @@ caption: {{$:/core/images/down-arrow}} {{$:/language/Buttons/More/Caption}} description: {{$:/language/Buttons/More/Hint}} \whitespace trim -\define config-title() -$:/config/ViewToolbarButtons/Visibility/$(listItem)$ -\end -<$button popup=<> tooltip={{$:/language/Buttons/More/Hint}} aria-label={{$:/language/Buttons/More/Caption}} class=<> selectedClass="tc-selected"> -<$list filter="[match[yes]]"> -{{$:/core/images/down-arrow}} - -<$list filter="[match[yes]]"> - -<$text text={{$:/language/Buttons/More/Caption}}/> - - +\define config-title() $:/config/ViewToolbarButtons/Visibility/$(listItem)$ + +<$button popup=<> + tooltip={{$:/language/Buttons/More/Hint}} + aria-label={{$:/language/Buttons/More/Caption}} + class=<> + selectedClass="tc-selected" +> + <$list filter="[match[yes]]"> + {{$:/core/images/down-arrow}} + + <$list filter="[match[yes]]"> + + <$text text={{$:/language/Buttons/More/Caption}}/> + + <$reveal state=<> type="popup" position="belowleft" animate="yes"> - -
- -<$set name="tv-config-toolbar-icons" value="yes"> - -<$set name="tv-config-toolbar-text" value="yes"> - -<$set name="tv-config-toolbar-class" value="tc-btn-invisible"> - -<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]] -[[$:/core/ui/Buttons/more-tiddler-actions]]" variable="listItem"> - -<$reveal type="match" state=<> text="hide"> - -<$set name="tv-config-toolbar-class" filter="[] [encodeuricomponent[]addprefix[tc-btn-]]"> - -<$transclude tiddler=<> mode="inline"/> - - - - - - - - - - - - - -
- +
+ <$set name="tv-config-toolbar-icons" value="yes"> + <$set name="tv-config-toolbar-text" value="yes"> + <$set name="tv-config-toolbar-class" value="tc-btn-invisible"> + <$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]] -[[$:/core/ui/Buttons/more-tiddler-actions]]" + variable="listItem" + > + <$reveal type="match" state=<> text="hide"> + <$set name="tv-config-toolbar-class" + filter="[] [encodeuricomponent[]addprefix[tc-btn-]]" + > + <$transclude tiddler=<> mode="inline"/> + + + + + + +
\ No newline at end of file diff --git a/plugins/tiddlywiki/menubar/items/pagecontrols.tid b/plugins/tiddlywiki/menubar/items/pagecontrols.tid index 833d035f4..af4026664 100644 --- a/plugins/tiddlywiki/menubar/items/pagecontrols.tid +++ b/plugins/tiddlywiki/menubar/items/pagecontrols.tid @@ -5,15 +5,14 @@ caption: Page controls custom-menu-content: <$transclude tiddler="$:/plugins/tiddlywiki/menubar/items/pagecontrols" mode="inline"/> \whitespace trim -\define config-title() -$:/config/PageControlButtons/Visibility/$(listItem)$ -\end +\define config-title() $:/config/PageControlButtons/Visibility/$(listItem)$ + <$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]" variable="listItem"> -<$set name="hidden" value=<>> -<$list filter="[!text[hide]]" storyview="pop" variable="ignore"> -<$set name="tv-config-toolbar-class" filter="[] [encodeuricomponent[]addprefix[tc-btn-]]"> -<$transclude tiddler=<> mode="inline"/> - - - + <$set name="hidden" value=<>> + <$list filter="[!text[hide]]" storyview="pop" variable="ignore"> + <$set name="tv-config-toolbar-class" filter="[] [encodeuricomponent[]addprefix[tc-btn-]]"> + <$transclude tiddler=<> mode="inline"/> + + + From 31ec1bdd50ce7fa58e4e2c8701106bd809c47dc3 Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Mon, 18 Mar 2024 10:08:11 +0100 Subject: [PATCH 003/306] Add tag parameter to reveal-widget to fix regression (#8084) --- core/ui/ViewTemplate/title.tid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ui/ViewTemplate/title.tid b/core/ui/ViewTemplate/title.tid index e5be2eba5..225ea4351 100644 --- a/core/ui/ViewTemplate/title.tid +++ b/core/ui/ViewTemplate/title.tid @@ -31,7 +31,7 @@ tags: $:/tags/ViewTemplate - <$reveal type="nomatch" text="" default="" state=<> class="tc-tiddler-info tc-popup-handle" animate="yes" retain="yes"> + <$reveal tag="div" type="nomatch" text="" default="" state=<> class="tc-tiddler-info tc-popup-handle" animate="yes" retain="yes"> <$list filter="[all[shadows+tiddlers]tag[$:/tags/TiddlerInfoSegment]!has[draft.of]] [[$:/core/ui/TiddlerInfo]]" variable="listItem"> <$transclude tiddler=<> mode="block"/> From 801ed0ea1164aab4f88547322f9d73704388143f Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 26 Mar 2024 16:04:13 +0000 Subject: [PATCH 004/306] Fix cycle operator crashing if step size is larger than the number of operands See https://talk.tiddlywiki.org/t/bug-report-javascript-error-at-tw-com-within-cycle-operator-try-it/9430/1 --- core/modules/filters/x-listops.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/filters/x-listops.js b/core/modules/filters/x-listops.js index 760f581a1..ae17297a5 100644 --- a/core/modules/filters/x-listops.js +++ b/core/modules/filters/x-listops.js @@ -202,7 +202,7 @@ Extended filter operators to manipulate the current list. } if(resultsIndex !== -1) { i = i + step; - nextOperandIndex = (i < opLength ? i : i - opLength); + nextOperandIndex = (i < opLength ? i : i % opLength); if(operands.length > 1) { results.splice(resultsIndex,1,operands[nextOperandIndex]); } else { From e02cafb938be8c96d59d0fbe11310f6cc8460ffb Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 27 Mar 2024 08:35:56 +0000 Subject: [PATCH 005/306] Add docs about using Basic Authentication in HTTP requests --- ...p-request Example Basic Authentication.tid | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request Example Basic Authentication.tid diff --git a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request Example Basic Authentication.tid b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request Example Basic Authentication.tid new file mode 100644 index 000000000..e16428d4a --- /dev/null +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request Example Basic Authentication.tid @@ -0,0 +1,34 @@ +title: WidgetMessage: tm-http-request Example - Basic Authentication +tags: $:/tags/Global + + +!! HTTP Basic Authentication + +[[HTTP Basic Authentication|https://en.wikipedia.org/wiki/Basic_access_authentication]] is a simple scheme for HTTP clients pass a username and password to an HTTP server. + +The credentials are passed via the "Authorization" header as the string "Basic " (note the space) followed by the base64-encoded username and password joined with a colon. + +Here is a simple, illustrative example: + +``` +\procedure get-tiddler-list-from-tiddlywiki-server(url,username,password) + \procedure completion-get-json() + \import [subfilter{$:/core/config/GlobalImportFilter}] + <$action-log msg="In completion-get-json"/> + <$action-log/> + \end completion-get-json + <$action-sendmessage + $message="tm-http-request" + url=<> + method="GET" + header-Authorization={{{ [addsuffix[:]addsuffixencodebase64[]addprefix[Basic ]] }}} + oncompletion=<> + /> +\end get-tiddler-list-from-tiddlywiki-server + +<$button> +<> +Download + +``` + From d37d6595b54e7816e0d4256129f92ea72a30b95c Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 27 Mar 2024 10:09:46 +0000 Subject: [PATCH 006/306] Docs: Add link to Basic Auth example --- .../tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid | 1 + 1 file changed, 1 insertion(+) diff --git a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid index e370ad72c..d2dd6eed7 100644 --- a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid @@ -51,3 +51,4 @@ Note that the state tiddler $:/state/http-requests contains a number representin * [[Zotero's|https://www.zotero.org/]] API for retrieving reference items: [[WidgetMessage: tm-http-request Example - Zotero]] * [[Random Dog's|https://random.dog/]] API for retrieving random pictures of dogs showing how to retrieve binary data: [[WidgetMessage: tm-http-request Example - Random Dog]] +* Example of using HTTP Basic Authentication: [[WidgetMessage: tm-http-request Example - Basic Authentication]] From 32cbd534231bbfcc9c5c80982e29b68806150ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9lumire?= <31185220+Telumire@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:20:35 +0100 Subject: [PATCH 007/306] Set a proper doctype for the open window template (#8095) --- core/modules/startup/windows.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/startup/windows.js b/core/modules/startup/windows.js index aa9f982ed..34f45d7a5 100644 --- a/core/modules/startup/windows.js +++ b/core/modules/startup/windows.js @@ -56,7 +56,7 @@ exports.startup = function() { return; } // Initialise the document - srcDocument.write(""); + srcDocument.write(""); srcDocument.close(); srcDocument.title = windowTitle; srcWindow.addEventListener("beforeunload",function(event) { From b6eab1afd68d72b173ba48496deaf8366dc2d79f Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Thu, 28 Mar 2024 19:36:33 +0100 Subject: [PATCH 008/306] Add theme font size settings to Open in New Window CSS (#7945) * add theme font size settings to Open in New Window CSS * add DOCTYPE html to New Window startup template * fix merge typo * fix merge typo one more time --- themes/tiddlywiki/vanilla/base.tid | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/themes/tiddlywiki/vanilla/base.tid b/themes/tiddlywiki/vanilla/base.tid index 1ca85c6a7..5b19dd61f 100644 --- a/themes/tiddlywiki/vanilla/base.tid +++ b/themes/tiddlywiki/vanilla/base.tid @@ -1335,6 +1335,7 @@ canvas.tc-edit-bitmapeditor { clear: both; } +.tc-single-tiddler-window .tc-tiddler-body, .tc-tiddler-frame .tc-tiddler-body { font-size: {{$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize}}; line-height: {{$:/themes/tiddlywiki/vanilla/metrics/bodylineheight}}; @@ -1344,6 +1345,11 @@ canvas.tc-edit-bitmapeditor { overflow: hidden; /* https://github.com/Jermolene/TiddlyWiki5/issues/282 */ } +/* +* Tiddler in a new window. +* Also see: .tc-single-tiddler-window .tc-tiddler-body, above +*/ + html body.tc-body.tc-single-tiddler-window { margin: 1em; background: <>; From b4d7e34a5a669b8fdf7ee19efc6ee69ada36e763 Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Thu, 28 Mar 2024 19:39:57 +0100 Subject: [PATCH 009/306] Add unusedtitle macro tests - should have full code covery (#7939) * add unusedtitle macro tests - should have full code covery * remove numbering from tests --- .../unusedtitle/basic-params-draft-exists.tid | 27 ++++++++++ .../basic-params-empty-tiddler-exists.tid | 23 +++++++++ .../macros/unusedtitle/basic-params-empty.tid | 20 ++++++++ .../basic-params-tiddlers-exist.tid | 28 +++++++++++ .../data/macros/unusedtitle/basic-params.tid | 20 ++++++++ .../template-empty-params-tiddler-exist.tid | 50 +++++++++++++++++++ .../unusedtitle/template-empty-params.tid | 24 +++++++++ .../data/macros/unusedtitle/template.tid | 28 +++++++++++ 8 files changed, 220 insertions(+) create mode 100644 editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-draft-exists.tid create mode 100644 editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-empty-tiddler-exists.tid create mode 100644 editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-empty.tid create mode 100644 editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-tiddlers-exist.tid create mode 100644 editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params.tid create mode 100644 editions/test/tiddlers/tests/data/macros/unusedtitle/template-empty-params-tiddler-exist.tid create mode 100644 editions/test/tiddlers/tests/data/macros/unusedtitle/template-empty-params.tid create mode 100644 editions/test/tiddlers/tests/data/macros/unusedtitle/template.tid diff --git a/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-draft-exists.tid b/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-draft-exists.tid new file mode 100644 index 000000000..10cff1ef9 --- /dev/null +++ b/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-draft-exists.tid @@ -0,0 +1,27 @@ +title: Macros/unusedtitle/basic-draft-exists +description: test <> with basic macro parameters but they are empty +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Draft of 'test' +draft.of: test +draft.title: test + ++ +title: Draft of 'asdf 0' +draft.of: asdf 0 +draft.title: asdf 0 + ++ +title: Output + + +<> + + +<> + ++ +title: ExpectedResult + +

test 1

asdf 1

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-empty-tiddler-exists.tid b/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-empty-tiddler-exists.tid new file mode 100644 index 000000000..7cf80fd20 --- /dev/null +++ b/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-empty-tiddler-exists.tid @@ -0,0 +1,23 @@ +title: Macros/unusedtitle/basic-params-empty-tiddler-exists +description: test <> with basic macro parameters but they are empty +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: New Tiddler + ++ +title: Output + + +<> + + +<> + + +<> + ++ +title: ExpectedResult + +

New Tiddler 1

New Tiddler 1

New Tiddler 1

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-empty.tid b/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-empty.tid new file mode 100644 index 000000000..990f88623 --- /dev/null +++ b/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-empty.tid @@ -0,0 +1,20 @@ +title: Macros/unusedtitle/basic-params-empty +description: test <> with basic macro parameters but they are empty +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + + +<> + + +<> + + +<> + ++ +title: ExpectedResult + +

New Tiddler

New Tiddler

New Tiddler

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-tiddlers-exist.tid b/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-tiddlers-exist.tid new file mode 100644 index 000000000..a01f1262d --- /dev/null +++ b/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params-tiddlers-exist.tid @@ -0,0 +1,28 @@ +title: Macros/unusedtitle/basic-params-tiddlers-exist +description: test <> with basic macro parameters, where new-name tiddlers already exist +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: New Tiddler + ++ +title: anotherBase + ++ +title: About + ++ +title: Output + +<> + +<> + +<> + +<> + ++ +title: ExpectedResult + +

New Tiddler 1

New Tiddler-1

anotherBase 1

About-1

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params.tid b/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params.tid new file mode 100644 index 000000000..5e1ae482d --- /dev/null +++ b/editions/test/tiddlers/tests/data/macros/unusedtitle/basic-params.tid @@ -0,0 +1,20 @@ +title: Macros/unusedtitle/basic-params +description: test <> with basic macro parameters +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +<> + + +<> + +<> + +<> + ++ +title: ExpectedResult + +

New Tiddler

New Tiddler

anotherBase

About

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/macros/unusedtitle/template-empty-params-tiddler-exist.tid b/editions/test/tiddlers/tests/data/macros/unusedtitle/template-empty-params-tiddler-exist.tid new file mode 100644 index 000000000..66ff810b1 --- /dev/null +++ b/editions/test/tiddlers/tests/data/macros/unusedtitle/template-empty-params-tiddler-exist.tid @@ -0,0 +1,50 @@ +title: Macros/unusedtitle/template-empty-params-tiddler-exist +description: test <> with templates where parameters are empty +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: New Tiddler + ++ +title: xxx + ++ +title: 00-New Tiddler + ++ +title: 0000 asdf + ++ +title: 0001 asdf + ++ +title: 0000 abc + ++ +title: Output + + +<> + + +<> + +<> + + +<> + + +<> + + ++ +title: ExpectedResult + +

New Tiddler 1

xxx-y-1

01-New Tiddler

0002 asdf

0001 abc

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/macros/unusedtitle/template-empty-params.tid b/editions/test/tiddlers/tests/data/macros/unusedtitle/template-empty-params.tid new file mode 100644 index 000000000..bdde68a98 --- /dev/null +++ b/editions/test/tiddlers/tests/data/macros/unusedtitle/template-empty-params.tid @@ -0,0 +1,24 @@ +title: Macros/unusedtitle/template-empty-params +description: test <> with templates where parameters are empty +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + + +<> + + +<> + +<> + +<> + ++ +title: ExpectedResult + +

New Tiddler

xxx

00-New Tiddler

0000 asdf

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/macros/unusedtitle/template.tid b/editions/test/tiddlers/tests/data/macros/unusedtitle/template.tid new file mode 100644 index 000000000..66bd0f763 --- /dev/null +++ b/editions/test/tiddlers/tests/data/macros/unusedtitle/template.tid @@ -0,0 +1,28 @@ +title: Macros/unusedtitle/template +description: test <> with templates +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + + +<> + +<> + +<> + + +<> + +<> + + +<> + +<> + ++ +title: ExpectedResult + +

New Tiddler

count-missing

00-new

00-base

00-New Tiddler

00-asdf

00 asdf

\ No newline at end of file From 2e0e541ebfcfdc1738d97b59690b65e8f6b98f6d Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Thu, 28 Mar 2024 20:07:54 +0100 Subject: [PATCH 010/306] Add tc-tag-missing or tc-tag-exists to tag pills including docs (#7951) * add tc-tag-missing or tc-tag-exists to tag pills including docs * changes as requested * macros not needed anymore - so remove * fix the tag Macro docs --- core/wiki/macros/tag.tid | 4 ++- editions/tw5.com/tiddlers/macros/TagMacro.tid | 32 +++++++++++++++++-- .../tw5.com/tiddlers/macros/examples/tag.tid | 12 ++++--- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/core/wiki/macros/tag.tid b/core/wiki/macros/tag.tid index 0dfe8e52a..eedbd0c4c 100644 --- a/core/wiki/macros/tag.tid +++ b/core/wiki/macros/tag.tid @@ -21,7 +21,9 @@ color:$(foregroundColor)$; > <<__actions__>> <$transclude tiddler=<<__icon__>>/> - <$view tiddler=<<__tag__>> field="title" format="text" /> + is[missing]then[tc-tag-missing]else[tc-tag-exists]] }}}> + <$view tiddler=<<__tag__>> field="title" format="text" /> + \end diff --git a/editions/tw5.com/tiddlers/macros/TagMacro.tid b/editions/tw5.com/tiddlers/macros/TagMacro.tid index eda75dcb9..f90eb44b7 100644 --- a/editions/tw5.com/tiddlers/macros/TagMacro.tid +++ b/editions/tw5.com/tiddlers/macros/TagMacro.tid @@ -1,6 +1,6 @@ caption: tag created: 20141206130540337 -modified: 20230725201240201 +modified: 20240228131301798 tags: Macros [[Core Macros]] title: tag Macro type: text/vnd.tiddlywiki @@ -11,7 +11,35 @@ The <<.def tag>> [[macro|Macros]] generates a tag pill for a specified tag. Clic !! Parameters -;tag +; tag : The title of the tag, defaulting to the [[current tiddler|Current Tiddler]] +!! CSS classes + +<<.from-version "v5.3.4">> + +; `tc-tag-missing` +: This class is defined if a tag does ''not exist'' as a tiddler. + +; `tc-tag-exists` +: This class is defined if a tag does exist as a tiddler + +!!! Defining the class + +To define the `tc-tag-missing` class a stylesheet tiddler needs to be created. The default font-style for missing tiddler links is //italic//, so it's used for the example code below. Eg: + +''title:'' `myTagsStylesheet`
+''tag:'' `$:/tags/Stylesheet` + +<> +``` +.tc-tag-missing { + font-style: italic; +} +``` + <<.macro-examples "tag">> diff --git a/editions/tw5.com/tiddlers/macros/examples/tag.tid b/editions/tw5.com/tiddlers/macros/examples/tag.tid index 103a5eab7..fbbeffb8e 100644 --- a/editions/tw5.com/tiddlers/macros/examples/tag.tid +++ b/editions/tw5.com/tiddlers/macros/examples/tag.tid @@ -1,5 +1,5 @@ created: 20150221211317000 -modified: 20230725203751870 +modified: 20240228131331605 tags: [[tag Macro]] [[Macro Examples]] title: tag Macro (Examples) type: text/vnd.tiddlywiki @@ -7,22 +7,26 @@ type: text/vnd.tiddlywiki <$macrocall $name=".example" n="1" eg="""<>"""/> <$macrocall $name=".example" n="2" eg="""<>"""/> +The Following tag can be shown with a font-style: //italic// if the corresponding stylesheet exists. See: [[tag Macro]] + +<$macrocall $name=".example" n="3" eg="""<>"""/> + If a [[list widget|ListWidget]] generates multiple tag macros for the same tag, clicking any of them opens dropdowns on all of them, as in the example below. This is usually unwanted. -<$macrocall $name=".example" n="3" eg="""<$list filter="[tag[HelloThere]]"> +<$macrocall $name=".example" n="4" eg="""<$list filter="[tag[HelloThere]]"> * <$link/> is tagged with: <$list filter="[tags[]]"> <> """/> Adding the `counter="transclusion"` attribute to the list widget that generates multiple identical tag macros causes each of them to be identified as a unique one. Clicking on any of them opens only a single dropdown. -<$macrocall $name=".example" n="4" eg="""<$list filter="[tag[HelloThere]]" counter="transclusion"> +<$macrocall $name=".example" n="5" eg="""<$list filter="[tag[HelloThere]]" counter="transclusion"> * <$link/> is tagged with: <$list filter="[tags[]]"> <> """/> A slightly more performant option is to use the `variable="transclusion"` attribute in the list widget. In this case, the variable `<>` has to be used inside the list widget instead of the `<>` . -<$macrocall $name=".example" n="5" eg="""<$list filter="[tag[HelloThere]]" variable="transclusion"> +<$macrocall $name=".example" n="6" eg="""<$list filter="[tag[HelloThere]]" variable="transclusion"> * <$link to=<>/> is tagged with: <$list filter="[tags[]]"> <> From 2d92a6fd78796ec3ad33afa7916f5274db0cbc33 Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Thu, 28 Mar 2024 20:09:31 +0100 Subject: [PATCH 011/306] Tag picker rewritten using new v5.3.x syntax (#7978) * tag-picker add Examples * tag-picker - use new v5.3.x wikitext syntax * tag-picker - more inline docs * tag-picker - fix add button * rename local functions: tag, userInput to _tf.getTag and _tf.getUersName to make the code and variable scopes more understandable * tag-picker - move local variables definitions into one place: tag-picker macro * tag-picker - replace reveal-widget with conditional IF syntax * tag-picker - remove logs and test tag-picker - actions parameer -> OK * tag-picker - add tag-picker Macro docs * tag-picker docs - change \define -> \procedure * tag-picker -- fix problem with focus loss if elements selected by mouse click * tag-picker -- add tf. prefix only to new function definition names for backwards compatibility. * tag-picker -- update example docs * re-add tags: $:/tags/Macro --- core/wiki/macros/tag-picker.tid | 279 +++++++++--------- .../tiddlers/macros/tag-picker_Macro.tid | 18 +- .../tiddlers/tag-picker Macro (Examples).tid | 69 +++++ 3 files changed, 229 insertions(+), 137 deletions(-) create mode 100644 editions/tw5.com/tiddlers/tag-picker Macro (Examples).tid diff --git a/core/wiki/macros/tag-picker.tid b/core/wiki/macros/tag-picker.tid index 80086e4d3..4618285be 100644 --- a/core/wiki/macros/tag-picker.tid +++ b/core/wiki/macros/tag-picker.tid @@ -1,167 +1,182 @@ title: $:/core/macros/tag-picker -tags: $:/tags/Macro $:/tags/Global -first-search-filter: [tags[]!is[system]search:titlesort[]] -second-search-filter: [tags[]is[system]search:titlesort[]] +tags: tags: $:/tags/Macro $:/tags/Global +first-search-filter: [subfilter!is[system]search:titlesort[]] +second-search-filter: [subfilteris[system]search:titlesort[]] -\procedure get-tagpicker-focus-selector() -\function currentTiddlerCSSEscaped() [escapecss[]] -[data-tiddler-title=`$(currentTiddlerCSSEscaped)$`] .tc-add-tag-name input + + +\whitespace trim + + +\function tf.tagpicker-dropdown-id() + [] + [[$(saveTiddler)$-[$(tagField)$-$(tagListFilter)$]substitute[]sha256[]] +[join[/]] \end -\procedure delete-tag-state-tiddlers() <$action-deletetiddler $filter="[] [] []"/> +\function tf.tagpicker-dropdown-class() [sha256[]addprefix[tc-]] +\function tf.get-tagpicker-focus-selector() [addprefix[.]] .tc-popup-handle +[join[ ]] + + +\procedure delete-tag-state-tiddlers() +<$action-deletetiddler $filter="[] [] []"/> +\end + + \procedure add-tag-actions() -\whitespace trim -<$let tag=<>> -<$action-listops $tiddler=<> $field=<> $subfilter='+[toggletrim[]]'/> -<$list - filter="[] :intersection[getenlist-input[]]" - variable="ignore" - emptyMessage="<>" -/> - -<> -<$action-setfield $tiddler=<> text="yes"/> -\end - -\procedure clear-tags-actions-inner() -\whitespace trim -<$list - filter="[has[text]] ~[has[text]]" - variable="ignore" - emptyMessage="<>" -> +<$let tag=<<_tf.getTag>> > + <$action-listops $tiddler=<> $field=<> $subfilter='+[toggletrim[]]'/> + <% if [] :intersection[getenlist-input[]] %> + + <% else %> + <> + <% endif %> <> - + <$action-setfield $tiddler=<> text="yes"/> + +\end + + + +\procedure clear-tags-actions-inner() +<% if [has[text]] ~[has[text]] %> + <> +<% else %> + <> +<% endif %> \end + \procedure clear-tags-actions() -\whitespace trim -<$let userInput=<>> - <$list - filter="[get[text]!match]" - emptyMessage="<>" - > +<$let userInput=<<_tf.getUserInput>> > + + <$list filter="[get[text]!match]" > + <$list-empty> + <> + <$action-setfield $tiddler=<> text=<>/> <$action-setfield $tiddler=<> text="yes"/> \end + \procedure add-button-actions() <$action-listops $tiddler=<> $field=<> $subfilter="[trim[]]"/> <> <> -<$action-sendmessage $message="tm-focus-selector" $param=<>/> +<$action-sendmessage $message="tm-focus-selector" $param=<>/> \end + -\procedure list-tags(filter, suffix) -\whitespace trim -<$list - filter="[minlength{$:/config/Tags/MinLength}limit[1]]" - emptyMessage="
{{$:/language/Search/Search/TooShort}}
" variable="listItem" -> - <$list filter=<> variable="tag"> - <$let - button-classes=`tc-btn-invisible ${ [addsuffix] -[get[text]] :then[[]] ~tc-tag-button-selected }$` - currentTiddler=<> - > - {{||$:/core/ui/TagPickerTagTemplate}} - + +\procedure tag-picker-listTags(filter, suffix) +<$let userInput=<<_tf.getUserInput>> > + <$list filter="[minlength{$:/config/Tags/MinLength}limit[1]]" + emptyMessage="
{{$:/language/Search/Search/TooShort}}
" variable="listItem" + > + <$list filter=<> variable="tag"> + + + <$let currentTiddler=<> + button-classes=`tc-btn-invisible ${[addsuffix] -[get[text]] :then[[]] ~tc-tag-button-selected }$` + get-tagpicker-focus-selector=`${[]}$` + > + {{||$:/core/ui/TagPickerTagTemplate}} + + - + \end + \procedure tag-picker-inner() -\whitespace trim +
] +[join[ ]] }}}> +
+ + <$macrocall $name="keyboard-driven-input" + tiddler=<> + storeTitle=<> + refreshTitle=<> + selectionStateTitle=<> + inputAcceptActions=<> + inputCancelActions=<> + tag="input" + placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}} + focusPopup=<> + class="tc-edit-texteditor tc-popup-handle" + tabindex=<> + focus={{{ [{$:/config/AutoFocus}match[tags]then[true]] ~[[false]] }}} + filterMinLength={{$:/config/Tags/MinLength}} + cancelPopups=<> + configTiddlerFilter="[[$:/core/macros/tag-picker]]" + /> + + <$button popup=<> class="tc-btn-invisible tc-btn-dropdown" + tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}} + > + {{$:/core/images/down-arrow}} + + <% if [has[text]] %> + <$button actions=<> class="tc-btn-invisible tc-small-gap tc-btn-dropdown" + tooltip={{$:/language/EditTemplate/Tags/ClearInput/Hint}} aria-label={{$:/language/EditTemplate/Tags/ClearInput/Caption}} + > + {{$:/core/images/close-button}} + + <% endif %> + + <$let tag=<<_tf.getTag>>> + <$button set=<> actions=<> > + {{$:/language/EditTemplate/Tags/Add/Button}} + + + +
+
+ <% if [has[text]] %> +
+ <$macrocall $name="tag-picker-listTags" filter=<> suffix="-primaryList" /> +
+ <$macrocall $name="tag-picker-listTags" filter=<> suffix="-secondaryList" /> +
+ <% endif %> +
+
+\end + + +\procedure tag-picker(actions, tagField:"tags", tiddler, tagListFilter:"[tags[]]") + +\function _tf.getUserInput() [get[text]] +\function _tf.getTag() [get[text]] + + <$let - newTagNameInputTiddlerQualified=<> - newTagNameSelectionTiddlerQualified=<> - fallbackTarget={{{ [getindex[tag-background]] }}} + palette={{$:/palette}} colourA={{{ [getindex[foreground]] }}} colourB={{{ [getindex[background]] }}} + fallbackTarget={{{ [getindex[tag-background]] }}} - storeTitle={{{ [!match[]] ~[] }}} + saveTiddler={{{ [is[blank]thenelse] }}} + + newTagNameTiddler={{{ [[$:/temp/NewTagName]] [!match[tags]] +[join[/]] [] +[join[]] }}} + storeTitle={{{ [[$:/temp/NewTagName/input]] [!match[tags]] +[join[/]] [] +[join[]] }}} + + newTagNameSelectionTiddlerQualified=<> tagSelectionState={{{ [!match[]] ~[] }}} - tagAutoComplete=<> - refreshTitle=<> - nonSystemTagsFilter="[tags[]!is[system]search:titlesort[]]" - systemTagsFilter="[tags[]is[system]search:titlesort[]]" -> -
-
- - <$transclude - $variable="keyboard-driven-input" - tiddler=<> - storeTitle=<> - refreshTitle=<> - selectionStateTitle=<> - inputAcceptActions=<> - inputCancelActions=<> - tag="input" - placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}} - focusPopup=<> - class="tc-edit-texteditor tc-popup-handle" - tabindex=<> - focus={{{ [{$:/config/AutoFocus}match[tags]then[true]] ~[[false]] }}} - filterMinLength={{$:/config/Tags/MinLength}} - cancelPopups=<> - configTiddlerFilter="[[$:/core/macros/tag-picker]]" - /> - - <$button popup=<> - class="tc-btn-invisible tc-btn-dropdown" - tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} - aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}} - > - {{$:/core/images/down-arrow}} - - <$reveal state=<> type="nomatch" text=""> - <$button actions=<> - class="tc-btn-invisible tc-small-gap tc-btn-dropdown" - tooltip={{$:/language/EditTemplate/Tags/ClearInput/Hint}} - aria-label={{$:/language/EditTemplate/Tags/ClearInput/Caption}} - > - {{$:/core/images/close-button}} - - - - <$let tag=<>> - <$button set=<> setTo="" - actions=<> - > - {{$:/language/EditTemplate/Tags/Add/Button}} - - - -
-
- <$reveal state=<> type="nomatch" text=""> -
- <$let userInput=<>> - <$transclude $variable="list-tags" filter=<> suffix="-primaryList" /> -
- <$transclude $variable="list-tags" filter=<> suffix="-secondaryList" /> - -
- -
-
- -\end + refreshTitle=<> -\procedure tag-picker(actions, tagField:"tags") -\function userInput() [get[text]] -\function tag() [get[text]] -\whitespace trim -<$let - saveTiddler=<> - palette={{$:/palette}} - qualified=<> - newTagNameTiddler={{{ [!match[]] ~[] }}} + nonSystemTagsFilter="[subfilter!is[system]search:titlesort[]]" + systemTagsFilter="[subfilteris[system]search:titlesort[]]" + + cancelPopups="yes" > - <$transclude $variable="tag-picker-inner" /> + <$macrocall $name="tag-picker-inner"/> -\end +\end \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/macros/tag-picker_Macro.tid b/editions/tw5.com/tiddlers/macros/tag-picker_Macro.tid index bd67256c9..612b9365a 100644 --- a/editions/tw5.com/tiddlers/macros/tag-picker_Macro.tid +++ b/editions/tw5.com/tiddlers/macros/tag-picker_Macro.tid @@ -1,6 +1,6 @@ caption: tag-picker created: 20161128191316701 -modified: 20161128191435641 +modified: 20230616114543787 tags: Macros [[Core Macros]] title: tag-picker Macro type: text/vnd.tiddlywiki @@ -9,9 +9,17 @@ The <<.def tag-picker>> [[macro|Macros]] generates a combination of a text box a !! Parameters -;actions -: Action widgets to be triggered when the pill is clicked. Within the text, the variable ''tag'' contains the title of the selected tag. -;tagField -: <<.from-version 5.1.23>> The ''field'' that gets updated with the selected tag. Defaults to ''tags''. +; actions +: Action widgets to be triggered when the pill is clicked. Within the text, the variable <<.var tag>> contains the title of the selected tag. + +; tagField +: <<.from-version 5.1.23>> The specified ''field'' that gets updated with the selected tag. Defaults to `tags`. + +; tiddler +: <<.from-version 5.3.4>> Defines the target tiddler, which should be manipulated. Defaults to: <<.var currentTiddler>>. + +; tagListFilter +: <<.from-version 5.3.4>> This parameter defaults to: `[tags[]]` which creates a list of all existing tags. If the tag list should come from a different source the filter should look similar to eg: `[get[field-name]enlist-input[]]`. + <<.macro-examples "tag-picker">> diff --git a/editions/tw5.com/tiddlers/tag-picker Macro (Examples).tid b/editions/tw5.com/tiddlers/tag-picker Macro (Examples).tid new file mode 100644 index 000000000..1fc150dcc --- /dev/null +++ b/editions/tw5.com/tiddlers/tag-picker Macro (Examples).tid @@ -0,0 +1,69 @@ +created: 20230616104546608 +modified: 20240214174032498 +tags: [[tag-picker Macro]] [[Macro Examples]] +title: tag-picker Macro (Examples) +type: text/vnd.tiddlywiki + +<<.warning """The first example will set the tag of the <<.tid currentTiddler>> so you should copy / paste it to a new tiddler for testing. Otherwise you'll change "this tiddler" """>> + +<$macrocall $name=".example" n="1" +eg="""Use all existing tags and set the ''tags'' field here: <> +"""/> + +---- + +<$let transclusion=test> + +<<.tip """The following examples use a temporary tiddler: $:/temp/test/tag-picker. So this tiddler will not be changed """>> + + +<$macrocall $name=".example" n="2" +eg="""$:/temp/test/tag-picker ''tags'': <$text text={{{ [[$:/temp/test/tag-picker]get[tags]enlist-input[]join[, ]else[n/a]] }}}/> + +Use all existing tags and set the $:/temp/test/tag-picker ''tags'' field: <> +"""/> + +---- + +<<.tip """Use the following example to populate the $:/temp/test/tag-picker ''foo''-field, which are needed by some examples below """>> + +<$macrocall $name=".example" n="3" +eg="""$:/temp/test/tag-picker ''foo'': <$text text={{{ [[$:/temp/test/tag-picker]get[foo]enlist-input[]join[, ]else[n/a]] }}}/> + +Use all existing tags and set the $:/temp/test/tag-picker ''foo'' field: <> +"""/> + +---- + +<<.tip """The following example expects some values in the "foo" field of the tiddler $:/temp/test/tag-picker, which can be created by the example above.""">> + +<$macrocall $name=".example" n="4" eg="""\procedure listSource() $:/temp/test/tag-picker + +$:/temp/test/tag-picker foo: <$text text={{{ [[$:/temp/test/tag-picker]get[foo]enlist-input[]join[, ]else[n/a]] }}}/>
+$:/temp/test/tag-picker bar: <$text text={{{ [[$:/temp/test/tag-picker]get[bar]enlist-input[]join[, ]else[n/a]] }}}/> + +Use $:/temp/test/tag-picker ''foo'' field as source and set ''bar'': <get[foo]enlist-input[]]" tiddler:"$:/temp/test/tag-picker">> +"""/> + +---- + +<<.tip """The following example expects some values in the "foo" field of the tiddler $:/temp/test/tag-picker, which can be created by the example above.
+It will also add completely new tags to the bar-field and the source tiddlers foo-field. New tags can be entered by typing into the tag-name input +""">> + +<$macrocall $name=".example" n="5" eg=""" +\procedure listSource() $:/temp/test/tag-picker +\procedure listSourceField() foo + +\procedure addNewTagToSource() + <$action-listops $tiddler=<> $field=<> $subfilter='[getenlist-input[]] [trim[]]'/> +\end + +$:/temp/test/tag-picker foo: <$text text={{{ [[$:/temp/test/tag-picker]get[foo]enlist-input[]join[, ]else[n/a]] }}}/>
+$:/temp/test/tag-picker ''bar'': <$text text={{{ [[$:/temp/test/tag-picker]get[bar]enlist-input[]join[, ]else[n/a]] }}}/> + +Use $:/temp/test/tag-picker ''foo'' field as source and set ''bar'': <$macrocall $name="tag-picker" tagField="bar" tagListFilter="[getenlist-input[]]" tiddler="$:/temp/test/tag-picker" actions=<>/> + +"""/> + + \ No newline at end of file From f1e707bff4c26cb0e2759b60365f953f8a6e8e1f Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Thu, 28 Mar 2024 20:27:58 +0100 Subject: [PATCH 012/306] Refactor GitHub-fork-ribbon plugin for better compatibility (#8075) --- .../tiddlywiki/github-fork-ribbon/readme.tid | 6 +- .../tiddlywiki/github-fork-ribbon/styles.tid | 21 ++--- .../github-fork-ribbon/template.tid | 26 ++++++ .../tiddlywiki/github-fork-ribbon/usage.tid | 93 +++++++++++++++---- 4 files changed, 112 insertions(+), 34 deletions(-) create mode 100644 plugins/tiddlywiki/github-fork-ribbon/template.tid diff --git a/plugins/tiddlywiki/github-fork-ribbon/readme.tid b/plugins/tiddlywiki/github-fork-ribbon/readme.tid index 95d0f7095..4707aaa6b 100644 --- a/plugins/tiddlywiki/github-fork-ribbon/readme.tid +++ b/plugins/tiddlywiki/github-fork-ribbon/readme.tid @@ -4,8 +4,6 @@ This plugin provides a diagonal ribbon across the corner of the window. It resem The ribbon can be positioned over any corner, and can incorporate user defined text, colours and a link. -The CSS stylesheet is adapted from work by Simon Whitaker: +The CSS stylesheet is adapted from work by [[Simon Whitaker|https://github.com/simonwhitaker/github-fork-ribbon-css/]] -https://github.com/simonwhitaker/github-fork-ribbon-css/ - -[[Source code|https://github.com/Jermolene/TiddlyWiki5/blob/master/plugins/tiddlywiki/github-fork-ribbon]] +[[Plugin source code|https://github.com/Jermolene/TiddlyWiki5/blob/master/plugins/tiddlywiki/github-fork-ribbon]] diff --git a/plugins/tiddlywiki/github-fork-ribbon/styles.tid b/plugins/tiddlywiki/github-fork-ribbon/styles.tid index 66bddbc7e..d22e28ac2 100644 --- a/plugins/tiddlywiki/github-fork-ribbon/styles.tid +++ b/plugins/tiddlywiki/github-fork-ribbon/styles.tid @@ -1,5 +1,4 @@ title: $:/plugins/tiddlywiki/github-fork-ribbon/styles -tags: [[$:/tags/Stylesheet]] /* Left will inherit from right (so we don't need to duplicate code */ .github-fork-ribbon { @@ -10,7 +9,7 @@ tags: [[$:/tags/Stylesheet]] padding: 2px 0; /* Set the base colour */ - background-color: #a00; + background-color: <>; /* Set a gradient: transparent black at the top to almost-transparent black at the bottom */ background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.00)), to(rgba(0, 0, 0, 0.15))); @@ -25,7 +24,7 @@ tags: [[$:/tags/Stylesheet]] -webkit-box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); - z-index: 999; + z-index: 700; pointer-events: auto; } @@ -61,8 +60,8 @@ tags: [[$:/tags/Stylesheet]] height: 150px; position: absolute; overflow: hidden; - top: 0; - z-index: 999; + top: <>; + z-index: 700; pointer-events: none; } @@ -71,25 +70,25 @@ tags: [[$:/tags/Stylesheet]] } .github-fork-ribbon-wrapper.left { - left: 0; + left: <>; } .github-fork-ribbon-wrapper.right { - right: 0; + right: <>; } .github-fork-ribbon-wrapper.left-bottom { position: fixed; top: inherit; - bottom: 0; - left: 0; + bottom: <>; + left: <>; } .github-fork-ribbon-wrapper.right-bottom { position: fixed; top: inherit; - bottom: 0; - right: 0; + bottom: <>; + right: <>; } .github-fork-ribbon-wrapper.right .github-fork-ribbon { diff --git a/plugins/tiddlywiki/github-fork-ribbon/template.tid b/plugins/tiddlywiki/github-fork-ribbon/template.tid new file mode 100644 index 000000000..22cee156d --- /dev/null +++ b/plugins/tiddlywiki/github-fork-ribbon/template.tid @@ -0,0 +1,26 @@ +title: $:/plugins/tiddlywiki/github-fork-ribbon/template + + +\parameters (position:"right", url:"https://github.com/Jermolene/TiddlyWiki5", text:"Fork me on ~GitHub" color:"#aa0000" top:"0" bottom:"0" left:"0" right:"0" fixed:"") + + + +
] [] +[join[ ]] }}}> + +
diff --git a/plugins/tiddlywiki/github-fork-ribbon/usage.tid b/plugins/tiddlywiki/github-fork-ribbon/usage.tid index c6d5311e0..aea2e3dba 100644 --- a/plugins/tiddlywiki/github-fork-ribbon/usage.tid +++ b/plugins/tiddlywiki/github-fork-ribbon/usage.tid @@ -1,26 +1,81 @@ title: $:/plugins/tiddlywiki/github-fork-ribbon/usage -Copy appropriate chunks on a new tiddler and tag it `$:/tags/PageControls`. Name of the new tiddler does not matter. Only the tag matters. +\procedure ribbonCode() +\whitespace trim +<$transclude $tiddler="$:/plugins/tiddlywiki/github-fork-ribbon/template" top="30px" fixed=fixed color="green"/> +\end -``` - - - +\procedure ribbonCreateActions() +<% if [[$:/github-ribbon]!is[tiddler]] %> + <$action-setfield $tiddler="$:/github-ribbon" $field="text" $value=<> + tags="$:/tags/PageTemplate" + code-body="yes" /> +<% endif %> +<$action-navigate $to="$:/github-ribbon" /> +\end - - - +\procedure createRibbon() +<$button actions=<> > +<%if [[$:/github-ribbon]!is[tiddler]] %> +Create +<% else %> +Show +<% endif %> ~$:/github-ribbon + +\end + +\procedure ribbonToggleTagActions() +<$action-listops $tiddler="$:/github-ribbon" $field="tags" $subfilter="+[toggle[$:/tags/PageTemplate]]" /> +\end + +\procedure ribbonToggleTag() <$button actions=<> >Toggle Tag - - - +`$:/plugins/tiddlywiki/github-fork-ribbon/template` is a template tiddler, that can be used with a transclusion and parameters. - - - -``` +!! Usage + +* Create a new tiddler eg: $:/github-ribbon +* Tag it `$:/tags/PageTemplate` +* Copy the code below + +
<$text text=<>/>
+ +<> <> + +!! Parameters + +; position +: "right" (default), "left", "right-bottom" and "left-bottom" + +; url +: Target URL, default: https://github.com/Jermolene/TiddlyWiki5 + +; text +: Ribbon text. default: `Fork me on ~GitHub` + +; color +: Ribbon background color: default: `#aa0000` + +; top +: Offset from the top if postion is top. default: `0` eg: `30px`, if the menu-toolbar plugin is installed + +; bottom +: Offset from the bottom in px + +; left +: Offset from the left in px + +; right +: Offset from the right in px + +; fixed +: If position is ''top'', the ribbon will scroll out of the viewport by default +: If the parameter `fixed="fixed"` it will be fixed + +!! Remove the Ribbon + +* Disable the plugin +* ''Remove the tag'' from $:/github-ribbon tiddler +* Delete the $:/github-ribbon tiddler +* <> \ No newline at end of file From e43cd2d989bd564fa983ad0a28369345e20855d7 Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Thu, 28 Mar 2024 20:29:16 +0100 Subject: [PATCH 013/306] Use v5.3.x syntax for $:/core/ui/PageTemplate/pagecontrols (#8088) --- core/ui/PageControls.tid | 16 +++++++--------- themes/tiddlywiki/vanilla/base.tid | 1 + 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/core/ui/PageControls.tid b/core/ui/PageControls.tid index 2b579050c..833b4cbcb 100644 --- a/core/ui/PageControls.tid +++ b/core/ui/PageControls.tid @@ -1,16 +1,14 @@ title: $:/core/ui/PageTemplate/pagecontrols \whitespace trim -\define config-title() $:/config/PageControlButtons/Visibility/$(listItem)$ +\function config-title() [[$:/config/PageControlButtons/Visibility/$(listItem)$]substitute[]]
<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]" variable="listItem"> - <$set name="hidden" value=<>> - <$list filter="[!text[hide]]" storyview="pop" variable="ignore"> - <$set name="tv-config-toolbar-class" filter="[] [encodeuricomponent[]addprefix[tc-btn-]]"> - <$transclude tiddler=<> mode="inline"/> - - - + <$list filter="[!text[hide]]" storyview="pop" variable="ignore"> + <$let tv-config-toolbar-class={{{ [enlist] [encodeuricomponent[]addprefix[tc-btn-]] +[join[ ]] }}}> + <$transclude $tiddler=<> $mode="inline"/> + + -
+ \ No newline at end of file diff --git a/themes/tiddlywiki/vanilla/base.tid b/themes/tiddlywiki/vanilla/base.tid index 5b19dd61f..69ba8e680 100644 --- a/themes/tiddlywiki/vanilla/base.tid +++ b/themes/tiddlywiki/vanilla/base.tid @@ -931,6 +931,7 @@ button.tc-btn-invisible.tc-remove-tag-button { .tc-page-controls { margin-top: 14px; + margin-bottom: 14px; font-size: 1.5em; } From 9cd6affcae382be8081990eda1abc572f4689fde Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Thu, 28 Mar 2024 20:29:57 +0100 Subject: [PATCH 014/306] Minor changes to Widgets tiddler (#8107) --- editions/tw5.com/tiddlers/widgets/Widgets.tid | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/editions/tw5.com/tiddlers/widgets/Widgets.tid b/editions/tw5.com/tiddlers/widgets/Widgets.tid index 5b682766f..66793f47d 100644 --- a/editions/tw5.com/tiddlers/widgets/Widgets.tid +++ b/editions/tw5.com/tiddlers/widgets/Widgets.tid @@ -1,14 +1,14 @@ created: 20140908130500000 -modified: 20150219182745000 +modified: 20240326164134356 tags: Concepts Reference title: Widgets type: text/vnd.tiddlywiki ~TiddlyWiki's display is driven by an underlying collection of <<.def widgets>>. These are organised into a tree structure: each widget has a parent widget and zero or more child widgets. -~TiddlyWiki generates this <<.def "widget tree">> by parsing the WikiText of tiddlers. Each component of the WikiText syntax, including even the trivial case of ordinary text, generates a corresponding widget. The widget tree is an intermediate representation that is subsequently rendered into the actual display. +~TiddlyWiki generates this <<.def "widget tree">> by parsing the ~WikiText of tiddlers. Each component of the ~WikiText syntax, including even the trivial case of ordinary text, generates a corresponding widget. The widget tree is an intermediate representation that is subsequently rendered into the actual display. -Widgets are analogous to elements in an HTML document. Indeed, HTML tags in WikiText generate dedicated <<.def "element widgets">>. +Widgets are analogous to elements in an HTML document. Indeed, HTML tags in ~WikiText generate dedicated <<.def "element widgets">>. Each class of widget contributes a specific ability to the overall functionality, such as the ability to <<.wlink2 "display an image" ImageWidget>> or <<.wlink2 "a button" ButtonWidget>>, to <<.wlink2 "call a macro" MacroCallWidget>> or <<.wlink2 "transclude text from elsewhere" TranscludeWidget>>, or to [[mark a piece of text as a heading|HTML in WikiText]]. @@ -16,4 +16,4 @@ The more specialised widgets use a general-purpose [[widget syntax|Widgets in Wi The following classes of widget are built into the core: -<> +<> From b595651fe12817902e014dcf3e0058c94fc66e6d Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Thu, 28 Mar 2024 22:50:22 +0100 Subject: [PATCH 015/306] Fix hide-show button code needs to be transcluded mode=block (#8082) --- editions/tw5.com/tiddlers/system/doc-macros.tid | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/editions/tw5.com/tiddlers/system/doc-macros.tid b/editions/tw5.com/tiddlers/system/doc-macros.tid index 5f83c75a8..d0574fe5f 100644 --- a/editions/tw5.com/tiddlers/system/doc-macros.tid +++ b/editions/tw5.com/tiddlers/system/doc-macros.tid @@ -1,8 +1,8 @@ +code-body: yes created: 20150117152607000 -modified: 20240229155550000 +modified: 20240317091700545 tags: $:/tags/Macro title: $:/editions/tw5.com/doc-macros -code-body: yes type: text/vnd.tiddlywiki \whitespace trim @@ -165,7 +165,7 @@ This is an example tiddler. See [[Table-of-Contents Macros (Examples)]].
<$button set=<<.state>> setTo="">Hide
- <> + <$transclude $variable="eg" $mode="block"/>
From 993975969062a49f213b9c9c7ded291e1d20d257 Mon Sep 17 00:00:00 2001 From: Rob Hoelz Date: Fri, 29 Mar 2024 09:47:22 -0500 Subject: [PATCH 016/306] Report throttled refreshes (#8116) Fixes GH #6054 --- core/modules/startup/render.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/modules/startup/render.js b/core/modules/startup/render.js index e50512463..caa8db2ef 100644 --- a/core/modules/startup/render.js +++ b/core/modules/startup/render.js @@ -81,6 +81,8 @@ exports.startup = function() { deferredChanges = Object.create(null); $tw.hooks.invokeHook("th-page-refreshed"); } + var throttledRefresh = $tw.perf.report("throttledRefresh",refresh); + // Add the change event handler $tw.wiki.addEventListener("change",$tw.perf.report("mainRefresh",function(changes) { // Check if only tiddlers that are throttled have changed @@ -101,7 +103,7 @@ exports.startup = function() { if(isNaN(timeout)) { timeout = THROTTLE_REFRESH_TIMEOUT; } - timerId = setTimeout(refresh,timeout); + timerId = setTimeout(throttledRefresh,timeout); $tw.utils.extend(deferredChanges,changes); } else { $tw.utils.extend(deferredChanges,changes); From 804f227815e22ca5a1adc0a0e02fb62b7f5bfb29 Mon Sep 17 00:00:00 2001 From: Crystal Person <135565126+jinix6@users.noreply.github.com> Date: Sun, 31 Mar 2024 21:38:09 +0530 Subject: [PATCH 017/306] Signing CLA (#8126) --- licenses/cla-individual.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/licenses/cla-individual.md b/licenses/cla-individual.md index 3dafcf352..5db3cddfc 100644 --- a/licenses/cla-individual.md +++ b/licenses/cla-individual.md @@ -563,3 +563,5 @@ John Long, @drevarr, 2023/12/12 Ed Holsinger, @eschlon, 2024/02/08 Kim I. McKinley, @PotOfCoffee2Go, 2024/03/16 + +@Jinix6, 2024/03/31 \ No newline at end of file From 7ce85a2ddb50ca7b4ef262c4cda31aa3ccc1f70c Mon Sep 17 00:00:00 2001 From: Simon Huber Date: Tue, 2 Apr 2024 18:35:10 +0200 Subject: [PATCH 018/306] Update reset.tid to use modern-normalize 2.0.0 (#8120) This PR updates the vanilla/reset stylesheet to use the newer `modern-normalize 2.0.0` --- themes/tiddlywiki/vanilla/reset.tid | 146 ++++++++++++---------------- 1 file changed, 61 insertions(+), 85 deletions(-) diff --git a/themes/tiddlywiki/vanilla/reset.tid b/themes/tiddlywiki/vanilla/reset.tid index 0f7d24eab..938ecc7b1 100644 --- a/themes/tiddlywiki/vanilla/reset.tid +++ b/themes/tiddlywiki/vanilla/reset.tid @@ -1,7 +1,7 @@ title: $:/themes/tiddlywiki/vanilla/reset type: text/css -/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */ +/*! modern-normalize v2.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */ /* Document @@ -13,28 +13,26 @@ Use a better box model (opinionated). */ *, -*::before, -*::after { - box-sizing: border-box; +::before, +::after { + box-sizing: border-box; } -/** -Use a more readable tab size (opinionated). -*/ - -:root { - -moz-tab-size: 4; - tab-size: 4; -} - -/** -1. Correct the line height in all browsers. -2. Prevent adjustments of font size after orientation changes in iOS. -*/ - html { - line-height: 1.15; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ + /* Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) */ + font-family: + system-ui, + 'Segoe UI', + Roboto, + Helvetica, + Arial, + sans-serif, + 'Apple Color Emoji', + 'Segoe UI Emoji'; + line-height: 1.15; /* 1. Correct the line height in all browsers. */ + -webkit-text-size-adjust: 100%; /* 2. Prevent adjustments of font size after orientation changes in iOS. */ + -moz-tab-size: 4; /* 3. Use a more readable tab size (opinionated). */ + tab-size: 4; /* 3 */ } /* @@ -42,29 +40,8 @@ Sections ======== */ -/** -Remove the margin in all browsers. -*/ - body { - margin: 0; -} - -/** -Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) -*/ - -body { - font-family: - system-ui, - -apple-system, /* Firefox supports this but not yet `system-ui` */ - 'Segoe UI', - Roboto, - Helvetica, - Arial, - sans-serif, - 'Apple Color Emoji', - 'Segoe UI Emoji'; + margin: 0; /* Remove the margin in all browsers. */ } /* @@ -78,8 +55,8 @@ Grouping content */ hr { - height: 0; /* 1 */ - color: inherit; /* 2 */ + height: 0; /* 1 */ + color: inherit; /* 2 */ } /* @@ -92,7 +69,7 @@ Add the correct text decoration in Chrome, Edge, and Safari. */ abbr[title] { - text-decoration: underline dotted; + text-decoration: underline dotted; } /** @@ -101,7 +78,7 @@ Add the correct font weight in Edge and Safari. b, strong { - font-weight: bolder; + font-weight: bolder; } /** @@ -113,14 +90,14 @@ code, kbd, samp, pre { - font-family: - ui-monospace, - SFMono-Regular, - Consolas, - 'Liberation Mono', - Menlo, - monospace; /* 1 */ - font-size: 1em; /* 2 */ + font-family: + ui-monospace, + SFMono-Regular, + Consolas, + 'Liberation Mono', + Menlo, + monospace; /* 1 */ + font-size: 1em; /* 2 */ } /** @@ -128,7 +105,7 @@ Add the correct font size in all browsers. */ small { - font-size: 80%; + font-size: 80%; } /** @@ -137,18 +114,18 @@ Prevent 'sub' and 'sup' elements from affecting the line height in all browsers. sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } sub { - bottom: -0.25em; + bottom: -0.25em; } sup { - top: -0.5em; + top: -0.5em; } /* @@ -158,12 +135,12 @@ Tabular data /** 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) -2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +2. Correct table border color inheritance in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) */ table { - text-indent: 0; /* 1 */ - border-color: inherit; /* 2 */ + text-indent: 0; /* 1 */ + border-color: inherit; /* 2 */ } /* @@ -181,20 +158,19 @@ input, optgroup, select, textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 1 */ - line-height: 1.15; /* 1 */ - margin: 0; /* 2 */ + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ } /** Remove the inheritance of text transform in Edge and Firefox. -1. Remove the inheritance of text transform in Firefox. */ button, -select { /* 1 */ - text-transform: none; +select { + text-transform: none; } /** @@ -205,7 +181,7 @@ button, [type='button'], [type='reset'], [type='submit'] { - -webkit-appearance: button; + -webkit-appearance: button; } /** @@ -213,8 +189,8 @@ Remove the inner border and padding in Firefox. */ ::-moz-focus-inner { - border-style: none; - padding: 0; + border-style: none; + padding: 0; } /** @@ -222,7 +198,7 @@ Restore the focus styles unset by the previous rule. */ :-moz-focusring { - outline: 1px dotted ButtonText; + outline: 1px dotted ButtonText; } /** @@ -231,7 +207,7 @@ See: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d4 */ :-moz-ui-invalid { - box-shadow: none; + box-shadow: none; } /** @@ -239,7 +215,7 @@ Remove the padding so developers are not caught out when they zero out 'fieldset */ legend { - padding: 0; + padding: 0; } /** @@ -247,7 +223,7 @@ Add the correct vertical alignment in Chrome and Firefox. */ progress { - vertical-align: baseline; + vertical-align: baseline; } /** @@ -256,7 +232,7 @@ Correct the cursor style of increment and decrement buttons in Safari. ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { - height: auto; + height: auto; } /** @@ -265,8 +241,8 @@ Correct the cursor style of increment and decrement buttons in Safari. */ [type='search'] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } /** @@ -274,7 +250,7 @@ Remove the inner padding in Chrome and Safari on macOS. */ ::-webkit-search-decoration { - -webkit-appearance: none; + -webkit-appearance: none; } /** @@ -283,8 +259,8 @@ Remove the inner padding in Chrome and Safari on macOS. */ ::-webkit-file-upload-button { - -webkit-appearance: button; /* 1 */ - font: inherit; /* 2 */ + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } /* @@ -297,5 +273,5 @@ Add the correct display in Chrome and Safari. */ summary { - display: list-item; + display: list-item; } From eeb4e7a7f70d62ebc4feec391363fbb35bc9a62d Mon Sep 17 00:00:00 2001 From: Simon Huber Date: Wed, 3 Apr 2024 10:58:56 +0200 Subject: [PATCH 019/306] Add a "Refresh Browser" keyboard shortcut (#8121) * Create a `refresh` keyboard shortcut This creates a `refresh` keyboard shortcut that refreshes the page. In TiddlyDesktop ctrl-R doesn't work * Update refresh.tid * Update shortcuts-not-mac.multids * Update shortcuts-mac.multids * Update ShortcutInfo.multids --- core/ui/KeyboardShortcuts/refresh.tid | 5 +++++ core/wiki/config/ShortcutInfo.multids | 1 + core/wiki/config/shortcuts/shortcuts-mac.multids | 1 + core/wiki/config/shortcuts/shortcuts-not-mac.multids | 1 + 4 files changed, 8 insertions(+) create mode 100644 core/ui/KeyboardShortcuts/refresh.tid diff --git a/core/ui/KeyboardShortcuts/refresh.tid b/core/ui/KeyboardShortcuts/refresh.tid new file mode 100644 index 000000000..6776c9d73 --- /dev/null +++ b/core/ui/KeyboardShortcuts/refresh.tid @@ -0,0 +1,5 @@ +title: $:/core/ui/KeyboardShortcuts/refresh +tags: $:/tags/KeyboardShortcut +key: ((refresh)) + +<$action-sendmessage $message="tm-browser-refresh"/> diff --git a/core/wiki/config/ShortcutInfo.multids b/core/wiki/config/ShortcutInfo.multids index 1f903dcad..bebd02dea 100644 --- a/core/wiki/config/ShortcutInfo.multids +++ b/core/wiki/config/ShortcutInfo.multids @@ -35,6 +35,7 @@ new-tiddler: {{$:/language/Buttons/NewTiddler/Hint}} picture: {{$:/language/Buttons/Picture/Hint}} preview: {{$:/language/Buttons/Preview/Hint}} quote: {{$:/language/Buttons/Quote/Hint}} +refresh: {{$:/language/Buttons/Refresh/Hint}} save-tiddler: {{$:/language/Buttons/Save/Hint}} save-wiki: {{$:/language/Buttons/SaveWiki/Hint}} sidebar-search: {{$:/language/Buttons/SidebarSearch/Hint}} diff --git a/core/wiki/config/shortcuts/shortcuts-mac.multids b/core/wiki/config/shortcuts/shortcuts-mac.multids index fc3fc060f..bc7e50fda 100644 --- a/core/wiki/config/shortcuts/shortcuts-mac.multids +++ b/core/wiki/config/shortcuts/shortcuts-mac.multids @@ -6,4 +6,5 @@ underline: meta-U new-image: ctrl-I new-journal: ctrl-J new-tiddler: ctrl-N +refresh: meta-R save-wiki: meta-S diff --git a/core/wiki/config/shortcuts/shortcuts-not-mac.multids b/core/wiki/config/shortcuts/shortcuts-not-mac.multids index a50563f2d..272169552 100644 --- a/core/wiki/config/shortcuts/shortcuts-not-mac.multids +++ b/core/wiki/config/shortcuts/shortcuts-not-mac.multids @@ -6,3 +6,4 @@ underline: ctrl-U new-image: alt-I new-journal: alt-J new-tiddler: alt-N +refresh: ctrl-R From e9aa3c6c931da5537e36e92c3c30f1e3c4b72fd4 Mon Sep 17 00:00:00 2001 From: Rob Hoelz Date: Thu, 4 Apr 2024 10:03:15 -0500 Subject: [PATCH 020/306] Add $timestamp argument for <$action-deletefield> widget (#8115) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Start on some tests for <$action-deletefield /> * Only update modified field if we actually delete a field …in the <$action-deletefield /> widget. Fixes a bug where <$action-deletefield foo /> would update the modified field if the "foo" field wasn't present on a tiddler. * action-deletefield: Test when modified does and doesn't exist * Add $timestamp argument to action-deletefield To make it more consistent with other tiddler-manipulating action widgets * Add docs for action-deletefield $timestamp --- core/modules/widgets/action-deletefield.js | 9 +- .../tiddlers/tests/test-action-deletefield.js | 176 ++++++++++++++++++ .../widgets/ActionDeleteFieldWidget.tid | 1 + 3 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 editions/test/tiddlers/tests/test-action-deletefield.js diff --git a/core/modules/widgets/action-deletefield.js b/core/modules/widgets/action-deletefield.js index 54068471e..00f06562d 100644 --- a/core/modules/widgets/action-deletefield.js +++ b/core/modules/widgets/action-deletefield.js @@ -37,6 +37,7 @@ Compute the internal state of the widget DeleteFieldWidget.prototype.execute = function() { this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler")); this.actionField = this.getAttribute("$field",null); + this.actionTimestamp = this.getAttribute("$timestamp","yes") === "yes"; }; /* @@ -69,11 +70,15 @@ DeleteFieldWidget.prototype.invokeAction = function(triggeringWidget,event) { $tw.utils.each(this.attributes,function(attribute,name) { if(name.charAt(0) !== "$" && name !== "title") { removeFields[name] = undefined; - hasChanged = true; + if(name in tiddler.fields) { + hasChanged = true; + } } }); if(hasChanged) { - this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,removeFields,this.wiki.getModificationFields())); + var creationFields = this.actionTimestamp ? this.wiki.getCreationFields() : {}; + var modificationFields = this.actionTimestamp ? this.wiki.getModificationFields() : {}; + this.wiki.addTiddler(new $tw.Tiddler(creationFields,tiddler,removeFields,modificationFields)); } } return true; // Action was invoked diff --git a/editions/test/tiddlers/tests/test-action-deletefield.js b/editions/test/tiddlers/tests/test-action-deletefield.js new file mode 100644 index 000000000..876f44d8e --- /dev/null +++ b/editions/test/tiddlers/tests/test-action-deletefield.js @@ -0,0 +1,176 @@ +/*\ +title: test-action-deletefield.js +type: application/javascript +tags: [[$:/tags/test-spec]] + +Tests <$action-deletefield />. + +\*/ +(function(){ + +/* jslint node: true, browser: true */ +/* eslint-env node, browser, jasmine */ +/* eslint no-mixed-spaces-and-tabs: ["error", "smart-tabs"]*/ +/* global $tw, require */ +"use strict"; + +describe("<$action-deletefield /> tests", function() { + +const TEST_TIDDLER_TITLE = "TargetTiddler"; +const TEST_TIDDLER_MODIFIED = "20240313114828368"; + +function setupWiki(condition, targetField, wikiOptions) { + // Create a wiki + var wiki = new $tw.Wiki({}); + var tiddlers = [{ + title: "Root", + text: "Some dummy content" + }]; + var tiddler; + if(condition.targetTiddlerExists) { + var fields = { + title: TEST_TIDDLER_TITLE, + }; + if(condition.modifiedFieldExists) { + fields.modified = TEST_TIDDLER_MODIFIED; + } + if(condition.targetFieldExists) { + fields[targetField] = "some text"; + } + var tiddler = new $tw.Tiddler(fields); + tiddlers.push(tiddler); + } + wiki.addTiddlers(tiddlers); + wiki.addIndexersToWiki(); + var widgetNode = wiki.makeTranscludeWidget("Root",{document: $tw.fakeDocument, parseAsInline: true}); + var container = $tw.fakeDocument.createElement("div"); + widgetNode.render(container,null); + return { + wiki: wiki, + widgetNode: widgetNode, + contaienr: container, + tiddler: tiddler, + }; +} + +function generateTestConditions() { + var conditions = []; + + $tw.utils.each([true, false], function(tiddlerArgumentIsPresent) { + $tw.utils.each([true, false], function(targetTiddlerExists) { + $tw.utils.each([true, false], function(targetFieldExists) { + $tw.utils.each([true, false], function(fieldArgumentIsUsed) { + $tw.utils.each([true, false], function(modifiedFieldExists) { + $tw.utils.each(["", "yes", "no"], function(timestampArgument) { + conditions.push({ + tiddlerArgumentIsPresent: tiddlerArgumentIsPresent, + targetTiddlerExists: targetTiddlerExists, + targetFieldExists: targetFieldExists, + fieldArgumentIsUsed: fieldArgumentIsUsed, + modifiedFieldExists: modifiedFieldExists, + timestampArgument: timestampArgument, + }); + }); + }); + }); + }); + }); + }); + + return conditions; +} + +function generateActionWikitext(condition, targetField) { + var actionPieces = [ + "<$action-deletefield", + (condition.tiddlerArgumentIsPresent ? "$tiddler='" + TEST_TIDDLER_TITLE + "'" : ""), + (condition.fieldArgumentIsUsed ? "$field='" + targetField + "'" : targetField), + (condition.timestampArgument !== "" ? "$timestamp='" + condition.timestampArgument + "'" : ""), + "/>", + ]; + + return actionPieces.join(" "); +} + +function generateTestContext(action, tiddler) { + var expectationContext = "action: " + action + "\ntiddler:\n\n"; + if(tiddler) { + expectationContext += tiddler.getFieldStringBlock({exclude: ["text"]}); + if(tiddler.text) { + expectationContext += "\n\n" + tiddler.text; + } + expectationContext += "\n\n"; + } else { + expectationContext += "null"; + } + + return expectationContext; +} + +it("should correctly delete fields", function() { + var fields = ['caption', 'description', 'text']; + + var conditions = generateTestConditions(); + + $tw.utils.each(conditions, function(condition) { + $tw.utils.each(fields, function(field) { + var info = setupWiki(condition, field); + var originalTiddler = info.tiddler; + + var invokeActions = function(actions) { + info.widgetNode.invokeActionString(actions,info.widgetNode,null,{ + currentTiddler: TEST_TIDDLER_TITLE, + }); + }; + + var action = generateActionWikitext(condition,field); + + invokeActions(action); + + var testContext = generateTestContext(action,originalTiddler); + + var tiddler = info.wiki.getTiddler(TEST_TIDDLER_TITLE); + if(originalTiddler) { + // assert that the tiddler doesn't have the target field anymore + expect(tiddler.hasField(field)).withContext(testContext).toBeFalsy(); + + var targetFieldWasPresent = originalTiddler.hasField(field); + var updateTimestamps = condition.timestampArgument !== "no"; + + // "created" should exist if it did beforehand, or if the tiddler changed and we asked the widget to update timestamps + var createdFieldShouldExist = originalTiddler.hasField("created") || (targetFieldWasPresent && updateTimestamps); + + // "created" should change only if it didn't exist beforehand and the tiddler changed and we asked the widget to update timestamps + var createdFieldShouldChange = !originalTiddler.hasField("created") && (targetFieldWasPresent && updateTimestamps); + + // "modified" should exist if it did beforehand, or if the tiddler changed and we asked the widget to update timestamps + var modifiedFieldShouldExist = originalTiddler.hasField("modified") || (targetFieldWasPresent && updateTimestamps); + + // "modified" should change if the tiddler changed and we asked the widget to update timestamps + var modifiedFieldShouldChange = targetFieldWasPresent && updateTimestamps; + + expect(tiddler.hasField("created")).withContext(testContext).toBe(createdFieldShouldExist); + expect(tiddler.hasField("modified")).withContext(testContext).toBe(modifiedFieldShouldExist); + + if(createdFieldShouldChange) { + expect(tiddler.fields.created).withContext(testContext).not.toEqual(originalTiddler.fields.created); + } else { + expect(tiddler.fields.created).withContext(testContext).toEqual(originalTiddler.fields.created); + } + + if(modifiedFieldShouldChange) { + expect(tiddler.fields.modified).withContext(testContext).not.toEqual(originalTiddler.fields.modified); + } else { + expect(tiddler.fields.modified).withContext(testContext).toEqual(originalTiddler.fields.modified); + } + } else { + // assert that the tiddler didn't get created if it didn't exist already + expect(tiddler).withContext(testContext).toBeUndefined(); + } + }); + }); +}); + +}); + +})(); diff --git a/editions/tw5.com/tiddlers/widgets/ActionDeleteFieldWidget.tid b/editions/tw5.com/tiddlers/widgets/ActionDeleteFieldWidget.tid index 2855804fd..5b797232b 100644 --- a/editions/tw5.com/tiddlers/widgets/ActionDeleteFieldWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/ActionDeleteFieldWidget.tid @@ -16,6 +16,7 @@ The ''action-deletefield'' widget is invisible. Any content within it is ignored |!Attribute |!Description | |$tiddler |The title of the tiddler whose fields are to be modified (if not provided defaults to the [[current tiddler|Current Tiddler]]) | |$field |Optional name of a field to delete | +|$timestamp |<<.from-version "5.3.4">> Specifies whether the timestamp(s) of the target tiddler will be updated (''modified'' and ''modifier'', plus ''created'' and ''creator'' for newly created tiddlers). Can be "yes" (the default) or "no" | |//{any attributes not starting with $}// |Each attribute name specifies a field to be deleted. The attribute value is ignored and need not be specified | ! Examples From 1fb9098c762015ea9f6f6305a998377c6ef33253 Mon Sep 17 00:00:00 2001 From: andjar <2013988+andjar@users.noreply.github.com> Date: Tue, 9 Apr 2024 23:22:18 +0200 Subject: [PATCH 021/306] Update cla-individual.md (#8133) Signing the CLA --- licenses/cla-individual.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/licenses/cla-individual.md b/licenses/cla-individual.md index 5db3cddfc..ce6f2fd1a 100644 --- a/licenses/cla-individual.md +++ b/licenses/cla-individual.md @@ -564,4 +564,6 @@ Ed Holsinger, @eschlon, 2024/02/08 Kim I. McKinley, @PotOfCoffee2Go, 2024/03/16 -@Jinix6, 2024/03/31 \ No newline at end of file +@Jinix6, 2024/03/31 + +Anders Jarmund, @andjar, 2024/04/05 From df8731f760e7b561ff4a0bce2569481e3e2c0c15 Mon Sep 17 00:00:00 2001 From: Cameron Fischer Date: Wed, 10 Apr 2024 05:52:22 -0400 Subject: [PATCH 022/306] Made library boot module requirements consistent (#8083) --- core/templates/external-js/save-all-external-js.tid | 2 +- core/templates/external-js/save-offline-external-js.tid | 2 +- core/templates/save-all.tid | 2 +- core/templates/save-empty.tid | 2 +- core/templates/save-lazy-all.tid | 2 +- core/templates/save-lazy-images.tid | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/templates/external-js/save-all-external-js.tid b/core/templates/external-js/save-all-external-js.tid index ff5bbc851..1f4908878 100644 --- a/core/templates/external-js/save-all-external-js.tid +++ b/core/templates/external-js/save-all-external-js.tid @@ -3,7 +3,7 @@ title: $:/core/save/all-external-js \whitespace trim \import [subfilter{$:/core/config/GlobalImportFilter}] \define saveTiddlerFilter() -[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$ +[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$ \end diff --git a/core/templates/external-js/save-offline-external-js.tid b/core/templates/external-js/save-offline-external-js.tid index 564a34948..70cb8bbc0 100644 --- a/core/templates/external-js/save-offline-external-js.tid +++ b/core/templates/external-js/save-offline-external-js.tid @@ -3,7 +3,7 @@ title: $:/core/save/offline-external-js \whitespace trim \import [subfilter{$:/core/config/GlobalImportFilter}] \define saveTiddlerFilter() -[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$ +[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$ \end \define defaultCoreURL() tiddlywikicore-$(version)$.js <$let coreURL={{{ [[coreURL]is[variable]thenelse] }}}> diff --git a/core/templates/save-all.tid b/core/templates/save-all.tid index d7473ba5b..a316d1954 100644 --- a/core/templates/save-all.tid +++ b/core/templates/save-all.tid @@ -2,6 +2,6 @@ title: $:/core/save/all \import [subfilter{$:/core/config/GlobalImportFilter}] \define saveTiddlerFilter() -[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$ +[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$ \end {{$:/core/templates/tiddlywiki5.html}} diff --git a/core/templates/save-empty.tid b/core/templates/save-empty.tid index 6f0da4822..0b1c33b59 100644 --- a/core/templates/save-empty.tid +++ b/core/templates/save-empty.tid @@ -1,6 +1,6 @@ title: $:/core/save/empty \define saveTiddlerFilter() -[is[system]] -[prefix[$:/state/popup/]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] +[is[system]] -[prefix[$:/state/popup/]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] \end {{$:/core/templates/tiddlywiki5.html}} diff --git a/core/templates/save-lazy-all.tid b/core/templates/save-lazy-all.tid index a4b5cd6e9..da4353fba 100644 --- a/core/templates/save-lazy-all.tid +++ b/core/templates/save-lazy-all.tid @@ -1,7 +1,7 @@ title: $:/core/save/lazy-all \define saveTiddlerFilter() -[is[system]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] [is[tiddler]type[application/javascript]] +[sort[title]] +[is[system]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] [is[tiddler]type[application/javascript]] +[sort[title]] \end \define skinnySaveTiddlerFilter() [!is[system]] -[type[application/javascript]] diff --git a/core/templates/save-lazy-images.tid b/core/templates/save-lazy-images.tid index 0a4a84295..b23b348f0 100644 --- a/core/templates/save-lazy-images.tid +++ b/core/templates/save-lazy-images.tid @@ -1,7 +1,7 @@ title: $:/core/save/lazy-images \define saveTiddlerFilter() -[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[!is[system]is[image]] +[sort[title]] +[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[!is[system]is[image]] +[sort[title]] \end \define skinnySaveTiddlerFilter() [!is[system]is[image]] From 9167b190d2116cfb7dcd33b106c2bea719d6d0f2 Mon Sep 17 00:00:00 2001 From: Joshua Fontany Date: Thu, 11 Apr 2024 11:23:32 -0700 Subject: [PATCH 023/306] Fix bug 8138: server cache-control (#8141) * cache-control no-store by default * clarify comment spec reference * comment typo * fix else formatting * Update server.js allow route definitions to set their own cache-control --- core/modules/server/server.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/modules/server/server.js b/core/modules/server/server.js index 258ddfa31..d3c98f8fc 100644 --- a/core/modules/server/server.js +++ b/core/modules/server/server.js @@ -140,6 +140,11 @@ function sendResponse(request,response,statusCode,headers,data,encoding) { return; } } + } else { + // RFC 7231, 6.1. Overview of Status Codes: + // Browser clients may cache 200, 203, 204, 206, 300, 301, + // 404, 405, 410, 414, and 501 unless given explicit cache controls + headers["Cache-Control"] = headers["Cache-Control"] || "no-store"; } /* If the gzip=yes is set, check if the user agent permits compression. If so, From 5f74f4c2fa520b0c7a639cd0dcd5cc450b63418d Mon Sep 17 00:00:00 2001 From: Joshua Fontany Date: Thu, 11 Apr 2024 13:54:46 -0700 Subject: [PATCH 024/306] Fix bug 7878: Save command (#8140) * first pass at fixing bug 7878, needs testing * clarify default behaviour in comment * fix property typo, tested and works as intended * remove debugger --- core/modules/commands/save.js | 4 +++- core/modules/utils/filesystem.js | 23 +++++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/core/modules/commands/save.js b/core/modules/commands/save.js index 9769cec69..3cb7ef08c 100644 --- a/core/modules/commands/save.js +++ b/core/modules/commands/save.js @@ -43,7 +43,9 @@ Saves individual tiddlers in their raw text or binary format to the specified fi directory: path.resolve(self.commander.outputPath), pathFilters: [filenameFilter], wiki: wiki, - fileInfo: {} + fileInfo: { + overwrite: true + } }); if(self.commander.verbose) { console.log("Saving \"" + title + "\" to \"" + fileInfo.filepath + "\""); diff --git a/core/modules/utils/filesystem.js b/core/modules/utils/filesystem.js index 1ba34323e..5319e0481 100644 --- a/core/modules/utils/filesystem.js +++ b/core/modules/utils/filesystem.js @@ -316,11 +316,13 @@ Options include: 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 + fileInfo.overwrite: if true, turns off filename clash numbers (defaults to false) */ exports.generateTiddlerFilepath = function(title,options) { var directory = options.directory || "", extension = options.extension || "", originalpath = (options.fileInfo && options.fileInfo.originalpath) ? options.fileInfo.originalpath : "", + overwrite = options.fileInfo && options.fileInfo.overwrite || false, filepath; // Check if any of the pathFilters applies if(options.pathFilters && options.wiki) { @@ -381,19 +383,20 @@ exports.generateTiddlerFilepath = function(title,options) { filepath += char.charCodeAt(0).toString(); }); } - // Add a uniquifier if the file already exists - var fullPath, oldPath = (options.fileInfo) ? options.fileInfo.filepath : undefined, + // Add a uniquifier if the file already exists (default) + var fullPath = path.resolve(directory, filepath + extension); + if (!overwrite) { + var 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)); + do { + fullPath = path.resolve(directory,filepath + (count ? "_" + count : "") + extension); + if(oldPath && oldPath == fullPath) break; + count++; + } while(fs.existsSync(fullPath)); + } // If the last write failed with an error, or if path does not start with: // the resolved options.directory, the resolved wikiPath directory, the wikiTiddlersPath directory, - // or the 'originalpath' directory, then $tw.utils.encodeURIComponentExtended() and resolve to tiddler directory. + // or the 'originalpath' directory, then $tw.utils.encodeURIComponentExtended() and resolve to options.directory. var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath,fullPath), encode = (options.fileInfo || {writeError: false}).writeError == true; if(!encode) { From d3722a6602254a619fa655f6777f74ac75ec09bf Mon Sep 17 00:00:00 2001 From: Joshua Fontany Date: Sat, 13 Apr 2024 02:08:40 -0700 Subject: [PATCH 025/306] Docs for use-browser-cache (#8142) * docs for use-browser-cache * Update WebServer Parameter_ use-browse-cache.tid remove timestamps * revert last change * move to webserver folder * clarify, typos * dedupe --- ...Using the external JavaScript template.tid | 4 +-- ...sing the integrated static file server.tid | 19 ++++++++++++-- .../WebServer Parameter_ use-browse-cache.tid | 25 +++++++++++++++++++ .../tw5.com/tiddlers/webserver/WebServer.tid | 2 +- 4 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 editions/tw5.com/tiddlers/webserver/WebServer Parameter_ use-browse-cache.tid diff --git a/editions/tw5.com/tiddlers/webserver/Using the external JavaScript template.tid b/editions/tw5.com/tiddlers/webserver/Using the external JavaScript template.tid index 75b5f1484..75d38cc29 100644 --- a/editions/tw5.com/tiddlers/webserver/Using the external JavaScript template.tid +++ b/editions/tw5.com/tiddlers/webserver/Using the external JavaScript template.tid @@ -1,5 +1,5 @@ created: 20180905075846391 -modified: 20230319130830880 +modified: 20240413045138914 tags: [[WebServer Guides]] title: Using the external JavaScript template type: text/vnd.tiddlywiki @@ -20,7 +20,7 @@ The remaining inefficiency when working in the client server configuration is th ! Using the external ~JavaScript template with the client-server configuration -The mechanism is activated by setting the [[root-tiddler|WebServer Parameter: root-tiddler]] parameter to `$:/core/save/all-external-js`. This template externalises ~TiddlyWiki's core ~JavaScript into a separate file. For example, the following command will start your server with caching enabled. It will transfer the wiki with two GET requests, and the core can be cached by the browser. +The mechanism is activated by setting the [[root-tiddler|WebServer Parameter: root-tiddler]] parameter to `$:/core/save/all-external-js`. This template externalises ~TiddlyWiki's core ~JavaScript into a separate file. For example, the following command will [[start your server with caching enabled|WebServer Parameter: use-browser-cache]]. It will transfer the wiki with two GET requests, and the core can be cached by the browser. ``` tiddlywiki YOUR_WIKI_FOLDER --listen 'root-tiddler=$:/core/save/all-external-js' use-browser-cache=yes diff --git a/editions/tw5.com/tiddlers/webserver/Using the integrated static file server.tid b/editions/tw5.com/tiddlers/webserver/Using the integrated static file server.tid index 515730a3b..91544551e 100644 --- a/editions/tw5.com/tiddlers/webserver/Using the integrated static file server.tid +++ b/editions/tw5.com/tiddlers/webserver/Using the integrated static file server.tid @@ -1,5 +1,5 @@ created: 20180703095630828 -modified: 20180703100445719 +modified: 20240413045124764 tags: [[WebServer Guides]] title: Using the integrated static file server type: text/vnd.tiddlywiki @@ -13,4 +13,19 @@ Static files can be referenced directly: * `[ext[./files/a-big-document.pdf]]` - to make a link to a PDF * `[img[./files/a-big-image.png]]` - to embed an image -Alternatively, the ''_canonical_uri'' field can be used to reference the files as [[external tiddlers|ExternalImages]]. \ No newline at end of file +Alternatively, the ''_canonical_uri'' field can be used to reference the files as [[external tiddlers|ExternalImages]]. + +If [[WebServer Parameter: use-browser-cache]] is used, these files will be cached by the client's browser to save on bandwidth. In this case, the `cache busting strategy` can be used to make sure the client always has the latest updated files. + + +<<< +https://javascript.plainenglish.io/what-is-cache-busting-55366b3ac022 + +!! Cache Busting + +There are a couple different ways of changing the names of files so that they will load when they change. One way is to use version numbers and have them somewhere in the file name when loading. You could have a subdirectory for every version, `v1/index.js` `v2/index.css` . You could also have the version in queries in the URLs, `index.js?v1` , `index.css?v2` . + +Another way is to change the name of the file, `index.v1.js` , `index.v2.css` . These ways are not as manageable because this can become very hard once you have a ton of files that are being changed. + +A more popular and manageable way is to keep hashes inside the file names. Hashes, if you don’t know, are fixed length character representations of any content and they are irreversible, meaning you can get the hash from the file but you can’t get the file from the hash. Hashes are perfect for this, because when a file changes its hash will change, so if we keep the hash inside the filename `index.[someHashHere].js` browsers will detect it and load it instead of an old file. +<<< diff --git a/editions/tw5.com/tiddlers/webserver/WebServer Parameter_ use-browse-cache.tid b/editions/tw5.com/tiddlers/webserver/WebServer Parameter_ use-browse-cache.tid new file mode 100644 index 000000000..2d0693aa2 --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/WebServer Parameter_ use-browse-cache.tid @@ -0,0 +1,25 @@ +caption: use-browse-cache +created: 20240413042652008 +modified: 20240413050841387 +tags: [[WebServer Parameters]] +title: WebServer Parameter: use-browser-cache +type: text/vnd.tiddlywiki + +The [[web server configuration parameter|WebServer Parameters]] ''use-browser-cache=yes'' activates 200 OK browser caching via the `Cache-Control` header and a smart a Etag header: + +* The server javascript creates an MD5 `hash` object. +* Adds the data of the current `request:response` (for example: json text or an image binary) to the hash object. +* Adds the current `headers` of the response to the hash object. +* If the response data has an `encoding` value, adds the encoding to the hash object. +* Calculates the final MD5 hash string as a `contentDigest` javascript variable, and saves it as an `Etag: "<>"` header. + +If the incoming request contains a header named `if-none-match`, then the server will check the generated Etag against all values. + +If any `if-none-match` value DOES match the current Etag, the server will send a `304 NOT MODIFIED` response with the current response headers, instead of the data with a `200 OK` response. + +This saves bandwidth, as the client can be sure they have already received the exact data and has it in their current cache. + +If ''use-browser-cache=no'' (or any other value including null), then the server will return a `Cache-Control: no-store` header by default. + +If any customer server route module defines custom `Cache-Control` header behavior, then the server will pass that header through instead of the default. + diff --git a/editions/tw5.com/tiddlers/webserver/WebServer.tid b/editions/tw5.com/tiddlers/webserver/WebServer.tid index c1ab5ae2a..afa3fe749 100644 --- a/editions/tw5.com/tiddlers/webserver/WebServer.tid +++ b/editions/tw5.com/tiddlers/webserver/WebServer.tid @@ -1,5 +1,5 @@ created: 20180626150526207 -modified: 20181216181934282 +modified: 20240413043741157 tags: ListenCommand ServerCommand Features title: WebServer type: text/vnd.tiddlywiki From 1d48909012f98806cd1894b2d998fb4031a9a2d9 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 16 Apr 2024 10:34:49 +0100 Subject: [PATCH 026/306] Docs: Remove reference to restrictions on field names Fixes #8146 --- editions/tw5.com/tiddlers/concepts/TiddlerFields.tid | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editions/tw5.com/tiddlers/concepts/TiddlerFields.tid b/editions/tw5.com/tiddlers/concepts/TiddlerFields.tid index 0f9b830a7..342c04280 100644 --- a/editions/tw5.com/tiddlers/concepts/TiddlerFields.tid +++ b/editions/tw5.com/tiddlers/concepts/TiddlerFields.tid @@ -1,11 +1,11 @@ created: 20130825213300000 -modified: 20220109101407050 +modified: 20240416103247799 tags: Concepts title: TiddlerFields type: text/vnd.tiddlywiki \define lingo-base() $:/language/Docs/Fields/ -~TiddlerFields are name:value pairs that make up a [[tiddler|Tiddlers]]. Field names must be lowercase letters, digits or the characters `-` (dash), `_` (underscore) and `.` (period). +~TiddlerFields are name:value pairs that make up a [[tiddler|Tiddlers]]. Field names may contain any combination of characters (prior to [[v5.2.0|Release 5.2.0]], fields were constrained to be lowercase letters, digits or the characters `-` (dash), `_` (underscore) and `.` (period)). The standard fields are: From a081e58273da9b7974eac1e860193e371a32e69c Mon Sep 17 00:00:00 2001 From: Matt Lauber Date: Tue, 16 Apr 2024 11:24:53 -0400 Subject: [PATCH 027/306] HTTP Client: Return success calls for all 2XX response codes (#8150) APIs especially use 2XX response codes outside of 200, 201, 204 for responding to responses. Treat all "Successful" response codes (i.e. anything between 200-299) as successes, and pass the responseText. --- core/modules/utils/dom/http.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/utils/dom/http.js b/core/modules/utils/dom/http.js index 05879e5a9..ddb1e17c4 100644 --- a/core/modules/utils/dom/http.js +++ b/core/modules/utils/dom/http.js @@ -283,7 +283,7 @@ exports.httpRequest = function(options) { // Set up the state change handler request.onreadystatechange = function() { if(this.readyState === 4) { - if(this.status === 200 || this.status === 201 || this.status === 204) { + if(this.status >= 200 && this.status < 300) { // Success! options.callback(null,this[returnProp],this); return; From 67845f8ebeb24aabfdc50c94b01c7c147ea85e9c Mon Sep 17 00:00:00 2001 From: FSpark Date: Fri, 26 Apr 2024 00:29:09 +0800 Subject: [PATCH 028/306] Fix: some plugin subtiddlers do not have title in savewikifolder command (#8151) * fix: some plugin subtiddlers do not have title in savewikifolder command * fix: following coding style --- core/modules/commands/savewikifolder.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/modules/commands/savewikifolder.js b/core/modules/commands/savewikifolder.js index c0fccd775..461ff6f04 100644 --- a/core/modules/commands/savewikifolder.js +++ b/core/modules/commands/savewikifolder.js @@ -176,7 +176,10 @@ WikiFolderMaker.prototype.saveCustomPlugin = function(pluginTiddler) { this.saveJSONFile(directory + path.sep + "plugin.info",pluginInfo); self.log("Writing " + directory + path.sep + "plugin.info: " + JSON.stringify(pluginInfo,null,$tw.config.preferences.jsonSpaces)); var pluginTiddlers = $tw.utils.parseJSONSafe(pluginTiddler.fields.text).tiddlers; // A hashmap of tiddlers in the plugin - $tw.utils.each(pluginTiddlers,function(tiddler) { + $tw.utils.each(pluginTiddlers,function(tiddler,title) { + if(!tiddler.title) { + tiddler.title = title; + } self.saveTiddler(directory,new $tw.Tiddler(tiddler)); }); }; From b4e0a9b28bc7f0e2bfedc16023aecf2be61c0056 Mon Sep 17 00:00:00 2001 From: sarna Date: Sun, 28 Apr 2024 19:22:58 +0200 Subject: [PATCH 029/306] Signing the CLA (#8171) --- licenses/cla-individual.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/licenses/cla-individual.md b/licenses/cla-individual.md index ce6f2fd1a..e73a46e35 100644 --- a/licenses/cla-individual.md +++ b/licenses/cla-individual.md @@ -567,3 +567,5 @@ Kim I. McKinley, @PotOfCoffee2Go, 2024/03/16 @Jinix6, 2024/03/31 Anders Jarmund, @andjar, 2024/04/05 + +@sarna, 2024/04/28 From 07a048975d430f1e7f9a48665832959ab6c86b20 Mon Sep 17 00:00:00 2001 From: sarna Date: Sun, 28 Apr 2024 19:23:31 +0200 Subject: [PATCH 030/306] Improve Polish date translation (#8170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make month and weekday names lowercase * Replace AM and PM with Polish words * Adhere to recommendations wrt short weekday names https://sjp.pwn.pl/poradnia/haslo/dni-tygodnia-i-inne-roznosci;1788.html * Fix a typo * Inflect month names I assume they're always used as part of the full date, and in this case months are always inflected in Polish. * Use roman numerals in place of short month names I could not find any actual use of short month names in Polish. The only mentions are from people trying to translate English conventions into Polish - typically in software. In https://sjp.pwn.pl/poradnia/haslo/dni-tygodnia-i-inne-roznosci;1788.html Mr. Bańko answered (translation mine): Abbreviations of month names are less common, numbers are used instead. Such abbreviations can be created [...]. However, one must take into account that the reader will not understand them. I decided to go with a convention that's in actual use, rather than to force an English convention which is alien to non-software dev Poles. --- languages/pl-PL/Dates.multids | 82 +++++++++++++++++------------------ 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/languages/pl-PL/Dates.multids b/languages/pl-PL/Dates.multids index f1c2d3a1b..0c12a366f 100644 --- a/languages/pl-PL/Dates.multids +++ b/languages/pl-PL/Dates.multids @@ -31,46 +31,46 @@ Date/DaySuffix/28: . Date/DaySuffix/29: . Date/DaySuffix/30: . Date/DaySuffix/31: . -Date/Long/Day/0: Niedziela -Date/Long/Day/1: Poniedziałek -Date/Long/Day/2: Wtorek -Date/Long/Day/3: Środa -Date/Long/Day/4: Czwartek -Date/Long/Day/5: Piątek -Date/Long/Day/6: Sobota -Date/Long/Month/1: Styczeń -Date/Long/Month/2: Luty -Date/Long/Month/3: Marzec -Date/Long/Month/4: Kwiecień -Date/Long/Month/5: Maj -Date/Long/Month/6: Czerwiec -Date/Long/Month/7: Lipiec -Date/Long/Month/8: Sierpień -Date/Long/Month/9: Wrzesień -Date/Long/Month/10: Październik -Date/Long/Month/11: Listopad -Date/Long/Month/12: Grudzień -Date/Period/am: AM -Date/Period/pm: PM -Date/Short/Day/0: nd -Date/Short/Day/1: pn -Date/Short/Day/2: wt -Date/Short/Day/3: śr -Date/Short/Day/4: cz -Date/Short/Day/5: pt -Date/Short/Day/6: sb -Date/Short/Month/1: st -Date/Short/Month/2: lut -Date/Short/Month/3: mrz -Date/Short/Month/4: kw -Date/Short/Month/5: maj -Date/Short/Month/6: cz -Date/Short/Month/7: lip -Date/Short/Month/8: sier -Date/Short/Month/9: wrz -Date/Short/Month/10: paź -Date/Short/Month/11: lis -Date/Short/Month/12: gr +Date/Long/Day/0: niedziela +Date/Long/Day/1: poniedziałek +Date/Long/Day/2: wtorek +Date/Long/Day/3: środa +Date/Long/Day/4: czwartek +Date/Long/Day/5: piątek +Date/Long/Day/6: sobota +Date/Long/Month/1: stycznia +Date/Long/Month/2: lutego +Date/Long/Month/3: marca +Date/Long/Month/4: kwietnia +Date/Long/Month/5: maja +Date/Long/Month/6: czerwca +Date/Long/Month/7: lipca +Date/Long/Month/8: sierpnia +Date/Long/Month/9: września +Date/Long/Month/10: października +Date/Long/Month/11: listopada +Date/Long/Month/12: grudnia +Date/Period/am: rano +Date/Period/pm: po południu +Date/Short/Day/0: niedz. +Date/Short/Day/1: pon. +Date/Short/Day/2: wt. +Date/Short/Day/3: śr. +Date/Short/Day/4: czw. +Date/Short/Day/5: pt. +Date/Short/Day/6: sob. +Date/Short/Month/1: I +Date/Short/Month/2: II +Date/Short/Month/3: III +Date/Short/Month/4: IV +Date/Short/Month/5: V +Date/Short/Month/6: VI +Date/Short/Month/7: VII +Date/Short/Month/8: VIII +Date/Short/Month/9: IX +Date/Short/Month/10: X +Date/Short/Month/11: XI +Date/Short/Month/12: XII RelativeDate/Future/Days: <> dni od teraz RelativeDate/Future/Hours: <> godzin od teraz RelativeDate/Future/Minutes: <> minut od teraz @@ -79,7 +79,7 @@ RelativeDate/Future/Second: 1 sekunda od teraz RelativeDate/Future/Seconds: <> sekund od teraz RelativeDate/Future/Years: <> lat od teraz RelativeDate/Past/Days: <> dni temu -RelativeDate/Past/Hours: <> godizn temu +RelativeDate/Past/Hours: <> godzin temu RelativeDate/Past/Minutes: <> minut temu RelativeDate/Past/Months: <> miesięcy temu RelativeDate/Past/Second: 1 sekundę temu From 64f5dd942cda4c0b6f332d2da30fa50e828fb265 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Thu, 2 May 2024 11:39:25 +0100 Subject: [PATCH 031/306] Update release note --- .../prerelease/tiddlers/Release 5.3.4.tid | 69 +++++++++++++++++-- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/editions/prerelease/tiddlers/Release 5.3.4.tid b/editions/prerelease/tiddlers/Release 5.3.4.tid index 562909a93..638afaaa2 100644 --- a/editions/prerelease/tiddlers/Release 5.3.4.tid +++ b/editions/prerelease/tiddlers/Release 5.3.4.tid @@ -10,12 +10,23 @@ description: Under development ! Major Improvements +<<.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 new features include: + +* The new Tour Plugin itself +* 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 ! Translation improvements Improvements to the following translations: -* +* Chinese +* Macedonian +* Polish ! Plugin Improvements @@ -23,23 +34,44 @@ Improvements to the following translations: ! Widget Improvements -* +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/8115">> ''$timestamp'' attribute to ActionDeleteFieldWidget + +! Filter Improvements + +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7966">> new [[backtranscludes Operator]] ! Usability Improvements -* +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/issues/8121">> new keyboard shortcut for refreshing the page ! Hackability Improvements -* +* <<.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 ! Bug Fixes -* +* <<.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/issues/3460">> parsing bug with empty procedures/macros +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7907">> functions to use variables set by filter runs +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7943">> edit widget not refreshing when the editor type changes +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7922">> editor preview width +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/9bf3c0602d4fd3fe5ac7411db697b51f87a79056">> [[WidgetMessage: tm-http-request]] not returning data in the event of an error +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/8150">> [[WidgetMessage: tm-http-request]] incorrectly interpreting 2XX status codes +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7949">> processing of path separators in `tiddlywiki.files` files on Windows +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7975">> incorrect state reference in advanced search +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7985">> clipping of popups in preview pane +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/8039">> JavaScript error when attempting to export missing tiddlers to a CSV file +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7909">> imported procedures defaulting to `\whitespace trim` +* <<.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/7945">> theme font size settings to open in new window CSS ! Node.js Improvements -* +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/8141">> usage of "Cache-Control" header +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7878">> SaveCommand not overwriting files when required ! Performance Improvements @@ -58,4 +90,29 @@ Improvements to the following translations: [[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki: <<.contributors """ +andjar +AnthonyMuscio +bimlas +BramChen +btheado +BurningTreeC +catter-fly +eschlon +etardiff +flibbles +FSpark +hoelzro +jinix6 +joshuafontany +linonetwo +mateuszwilczek +mklauber +oeyoews +pmario +PotOfCoffee2Go +rmunn +saqimtiaz +sarna +Telumire +yaisog """>> From 24dceb1bced9f4c49dc688c9bb6b865da8ac26dc Mon Sep 17 00:00:00 2001 From: twMat Date: Tue, 14 May 2024 09:38:30 +0200 Subject: [PATCH 032/306] Update Filter Run Prefix.tid (#8188) add relevant links --- editions/tw5.com/tiddlers/filters/syntax/Filter Run Prefix.tid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editions/tw5.com/tiddlers/filters/syntax/Filter Run Prefix.tid b/editions/tw5.com/tiddlers/filters/syntax/Filter Run Prefix.tid index 4387ba9cb..5eb487b6d 100644 --- a/editions/tw5.com/tiddlers/filters/syntax/Filter Run Prefix.tid +++ b/editions/tw5.com/tiddlers/filters/syntax/Filter Run Prefix.tid @@ -4,7 +4,7 @@ tags: [[Filter Expression]] title: Filter Run Prefix type: text/vnd.tiddlywiki -There are 2 types of filter run prefixes that are interchangeable. Named prefixes and shortcut prefixes. +There are 2 types of filter run prefixes that are interchangeable; [[named prefixes|Named Filter Run Prefix]] and [[shortcut prefixes|Shortcut Filter Run Prefix]]. <$railroad text=""" \start none From f1299120a6a62a7ca5fb7d224c1d2bd758bd7595 Mon Sep 17 00:00:00 2001 From: Joshua Fontany Date: Wed, 15 May 2024 04:25:02 -0700 Subject: [PATCH 033/306] Block Quotes - fix parsing error with spaces before reEndString (#8186) * fix parsing error with spaces before reEndString, update docs to clarify block mode inside block quotes. * additional advanced example * oops, convert spaces back to tabs. * reset indentation * final tabs * missed some * wikitext classes are appended to other leading wikitext, no need to skip whitespace here. --- .../parsers/wikiparser/rules/quoteblock.js | 30 ++--------------- .../wikitext/Block Quotes in WikiText.tid | 33 ++++++++++++++++++- .../wikitext/Hard Linebreaks in WikiText.tid | 10 ++++-- .../wikitext/parser/Block Mode WikiText.tid | 4 +-- 4 files changed, 44 insertions(+), 33 deletions(-) diff --git a/core/modules/parsers/wikiparser/rules/quoteblock.js b/core/modules/parsers/wikiparser/rules/quoteblock.js index 71b689680..787b7e30f 100644 --- a/core/modules/parsers/wikiparser/rules/quoteblock.js +++ b/core/modules/parsers/wikiparser/rules/quoteblock.js @@ -3,30 +3,7 @@ title: $:/core/modules/parsers/wikiparser/rules/quoteblock.js type: application/javascript module-type: wikirule -Wiki text rule for quote blocks. For example: - -``` - <<<.optionalClass(es) optional cited from - a quote - <<< - - <<<.optionalClass(es) - a quote - <<< optional cited from -``` - -Quotes can be quoted by putting more 0) { tree.unshift({ diff --git a/editions/tw5.com/tiddlers/wikitext/Block Quotes in WikiText.tid b/editions/tw5.com/tiddlers/wikitext/Block Quotes in WikiText.tid index 181779fe9..5e2a368f4 100644 --- a/editions/tw5.com/tiddlers/wikitext/Block Quotes in WikiText.tid +++ b/editions/tw5.com/tiddlers/wikitext/Block Quotes in WikiText.tid @@ -1,6 +1,6 @@ caption: Block Quotes created: 20131206154636572 -modified: 20170417165145317 +modified: 20240512000910702 tags: WikiText title: Block Quotes in WikiText type: text/vnd.tiddlywiki @@ -72,3 +72,34 @@ You can also mix block quotes with other list items. For example: **> Another quote * List Three ">> + +! Advanced Wikitext and Block Quotes +You can also mix block quotes with paragraphs and other block wikitext. Be mindful of block mode - if other quoted content follows a paragraph, end it with a blank line. The final paragraph in the quote does not need to end with a blank line. If using indentation, make sure __not to indent the blank lines__. The parser will interpret this as additional inline content and not return to block mode. For example: + +< A quote +""" +A poem +with line beaks +needs to have +a blank line after +the final quotes +if followed +by other content +""" + + <<<< Deep Block Quote + A paragraph before other //wikitext//, which ends with a blank line. + + ! A Header + Another paragraph, which needs to end with a blank line. + + !! Sub Header + A final paragraph, which __does not__ need to end with a blank line as the Block Quote ends. + <<<< +<<< +'>> \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/wikitext/Hard Linebreaks in WikiText.tid b/editions/tw5.com/tiddlers/wikitext/Hard Linebreaks in WikiText.tid index c49b866ce..b7f05756f 100644 --- a/editions/tw5.com/tiddlers/wikitext/Hard Linebreaks in WikiText.tid +++ b/editions/tw5.com/tiddlers/wikitext/Hard Linebreaks in WikiText.tid @@ -1,9 +1,9 @@ +caption: Hard Linebreaks created: 20131214165710101 -modified: 20131214170106553 +modified: 20240512001649319 tags: WikiText title: Hard Linebreaks in WikiText type: text/vnd.tiddlywiki -caption: Hard Linebreaks The usual handling of [[paragraphs in wikitext|Paragraphs in WikiText]] causes single line breaks to be ignored, and double linebreaks to be interpreted as the end of a paragraph. @@ -15,4 +15,8 @@ and this is a new line while this is yet another line and this is the final one apart from this one -"""'>> +""" + +'>> + +<<.tip 'Note: Hard Linebreaks in ~WikiText require an extra blank line after the trailing `"""` before the parser will return to [[block mode|Block Mode WikiText]].'>>. \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/wikitext/parser/Block Mode WikiText.tid b/editions/tw5.com/tiddlers/wikitext/parser/Block Mode WikiText.tid index 9501f672c..b0e00cfaf 100644 --- a/editions/tw5.com/tiddlers/wikitext/parser/Block Mode WikiText.tid +++ b/editions/tw5.com/tiddlers/wikitext/parser/Block Mode WikiText.tid @@ -1,6 +1,6 @@ caption: block parser mode created: 20220110234234616 -modified: 20220122182842032 +modified: 20240512001555383 tags: [[WikiText Parser Modes]] title: Block Mode WikiText type: text/vnd.tiddlywiki @@ -28,7 +28,7 @@ Common characteristics of such block mode WikiText: The above WikiText types are only recognised in ''block mode''. However, the text <<.em enclosed>> by most of them will be parsed in ''inline mode'' ([[Block Quotes in WikiText]] and [[Styles and Classes in WikiText]] are the two exceptions in which the parser will continue in ''block mode''). While in ''inline mode'' the parser may encounter something which moves it to ''block mode'' (see [[WikiText parser mode transitions]]). At the end of the terminating line, the parser will return to ''block mode''. -<<.tip 'Note: [[Hard Linebreaks in WikiText]] require an extra blank line after the trailing `"""` before the parser will return to block mode'>>. +<<.tip 'Note: [[Hard Linebreaks in WikiText]] require an extra blank line after the trailing `"""` before the parser will return to block mode.'>> If the punctuation for the above types of WikiText is encountered while the parser is in ''inline mode'', it will be //ignored// and output as-is. From ece8b0ee01f04f9a88066d48500f41bc3765dfff Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Mon, 20 May 2024 11:30:30 +0100 Subject: [PATCH 034/306] Add <$testcase> widget (#7817) * Initial Commit * Add note to preview build * Fix whitespace and indenting Thanks @pmario * Fix crash with unset $tiddler attribute on <$data> widget Thanks @CodaCodr * Don't duplicate "description" field in test cases * Use different background colours for nested testcase widgets * Extend the testcase widget to run tests * Add testcases to control panel * Add a view template body template to render testcase tiddlers * Test edition should display testcases * Whitespace fixes * Make testcase tiddler tempalte link to itself * Styling tweaks * Docs improvements * Styling tweaks * Run the new tw5.com testcases in the test edition * Update data widget to display its content in JSON * Add testcase convenience procedure * Clearer testcases for data widget, and docs tweaks * Don't expect our intentionally failing test to pass * Extend testcase default template so that the display format can be chosen It is selected by setting the variable "displayFormat" * DataWidget docs typo * Fix data widget not refreshing * Links in testcase output switch to the tab containing that tiddler Thanks to @btheado for the suggestion * Docs update for 648855e8a50b1ee3bef3120b64b5713b69190c9b * Wording tweak * Add support for narrative tiddlers in test cases * Documentation improvements * Cleanup comments * Remove obsolete code comments * Simplify template * Docs update * Rename $:/core/ui/testcases/DefaultTemplate/SourceTabs from $:/core/ui/testcases/DefaultTemplate/Source * Use the view template body for failing tests * Don't reference the geospatial plugin * "Test case" should be two words * Fix handling of currentTiddler variable Fixes problem reported by @btheado in https://github.com/Jermolene/TiddlyWiki5/pull/7817#issuecomment-2103704468 * Prepare for merging --- core/language/en-GB/ControlPanel.multids | 6 + .../en-GB/Docs/PaletteColours.multids | 3 + core/modules/widgets/data.js | 145 ++++++++++++++++ core/modules/widgets/testcase.js | 160 ++++++++++++++++++ core/modules/widgets/widget.js | 15 ++ core/palettes/Vanilla.tid | 3 + core/ui/ControlPanel/TestCases.tid | 10 ++ core/ui/ControlPanel/TestCasesAll.tid | 24 +++ core/ui/ControlPanel/TestCasesFailed.tid | 15 ++ core/ui/TestCaseTemplate.tid | 18 ++ core/ui/TestCases/DefaultTemplate.tid | 64 +++++++ .../TestCases/DefaultTemplateSourceTabs.tid | 24 +++ core/ui/TestCases/RawJSONTemplate.tid | 4 + .../config/ViewTemplateBodyFilters.multids | 1 + core/wiki/macros/testcase.tid | 10 ++ core/wiki/tags/ViewTemplateBodyFilter.tid | 2 +- editions/test/tiddlers/HelloThere.tid | 4 + .../tests/from-tw5.com/tiddlywiki.files | 5 + .../tiddlers/concepts/CompoundTiddlers.tid | 31 ++++ .../tiddlers/concepts/TestCaseTiddlers.tid | 27 +++ .../tiddlers/hellothere/HelloThere.tid | 2 +- .../testcases/DataWidget/ImportCompound.tid | 33 ++++ .../testcases/DataWidget/ImportedFilter.tid | 49 ++++++ .../testcases/DataWidget/ImportedTiddler.tid | 29 ++++ .../testcases/DataWidget/Refreshing.tid | 30 ++++ .../testcases/DataWidget/SimpleTiddler.tid | 22 +++ .../testcases/TestCaseWidget/FailingTest.tid | 15 ++ .../TestCaseWidget/currentTiddler.tid | 16 ++ .../TranscludeWidget/SimpleTransclusion.tid | 23 +++ .../tw5.com/tiddlers/widgets/DataWidget.tid | 42 +++++ .../tiddlers/widgets/TestCaseWidget.tid | 101 +++++++++++ plugins/tiddlywiki/innerwiki/anchor.js | 17 ++ plugins/tiddlywiki/innerwiki/data.js | 58 ------- plugins/tiddlywiki/innerwiki/innerwiki.js | 72 +------- .../jasmine/run-wiki-based-tests.js | 8 +- themes/tiddlywiki/vanilla/base.tid | 152 ++++++++++++++++- 36 files changed, 1109 insertions(+), 131 deletions(-) create mode 100644 core/modules/widgets/data.js create mode 100644 core/modules/widgets/testcase.js create mode 100644 core/ui/ControlPanel/TestCases.tid create mode 100644 core/ui/ControlPanel/TestCasesAll.tid create mode 100644 core/ui/ControlPanel/TestCasesFailed.tid create mode 100644 core/ui/TestCaseTemplate.tid create mode 100644 core/ui/TestCases/DefaultTemplate.tid create mode 100644 core/ui/TestCases/DefaultTemplateSourceTabs.tid create mode 100644 core/ui/TestCases/RawJSONTemplate.tid create mode 100644 core/wiki/macros/testcase.tid create mode 100644 editions/test/tiddlers/tests/from-tw5.com/tiddlywiki.files create mode 100644 editions/tw5.com/tiddlers/concepts/CompoundTiddlers.tid create mode 100644 editions/tw5.com/tiddlers/concepts/TestCaseTiddlers.tid create mode 100644 editions/tw5.com/tiddlers/testcases/DataWidget/ImportCompound.tid create mode 100644 editions/tw5.com/tiddlers/testcases/DataWidget/ImportedFilter.tid create mode 100644 editions/tw5.com/tiddlers/testcases/DataWidget/ImportedTiddler.tid create mode 100644 editions/tw5.com/tiddlers/testcases/DataWidget/Refreshing.tid create mode 100644 editions/tw5.com/tiddlers/testcases/DataWidget/SimpleTiddler.tid create mode 100644 editions/tw5.com/tiddlers/testcases/TestCaseWidget/FailingTest.tid create mode 100644 editions/tw5.com/tiddlers/testcases/TestCaseWidget/currentTiddler.tid create mode 100644 editions/tw5.com/tiddlers/testcases/TranscludeWidget/SimpleTransclusion.tid create mode 100644 editions/tw5.com/tiddlers/widgets/DataWidget.tid create mode 100644 editions/tw5.com/tiddlers/widgets/TestCaseWidget.tid create mode 100644 plugins/tiddlywiki/innerwiki/anchor.js delete mode 100644 plugins/tiddlywiki/innerwiki/data.js diff --git a/core/language/en-GB/ControlPanel.multids b/core/language/en-GB/ControlPanel.multids index d8321edbf..93cfc3c10 100644 --- a/core/language/en-GB/ControlPanel.multids +++ b/core/language/en-GB/ControlPanel.multids @@ -206,6 +206,12 @@ Stylesheets/Caption: Stylesheets Stylesheets/Expand/Caption: Expand All Stylesheets/Hint: This is the rendered CSS of the current stylesheet tiddlers tagged with <> Stylesheets/Restore/Caption: Restore +TestCases/Caption: Test Cases +TestCases/Hint: Test cases are self contained examples for testing and learning +TestCases/All/Caption: All Test Cases +TestCases/All/Hint: All Test Cases +TestCases/Failed/Caption: Failed Test Cases +TestCases/Failed/Hint: Only Failed Test Cases Theme/Caption: Theme Theme/Prompt: Current theme: TiddlerFields/Caption: Tiddler Fields diff --git a/core/language/en-GB/Docs/PaletteColours.multids b/core/language/en-GB/Docs/PaletteColours.multids index 98addbf85..1c671a67c 100644 --- a/core/language/en-GB/Docs/PaletteColours.multids +++ b/core/language/en-GB/Docs/PaletteColours.multids @@ -65,6 +65,9 @@ sidebar-tab-foreground-selected: Sidebar tab foreground for selected tabs sidebar-tab-foreground: Sidebar tab foreground sidebar-tiddler-link-foreground-hover: Sidebar tiddler link foreground hover sidebar-tiddler-link-foreground: Sidebar tiddler link foreground +testcase-accent-level-1: Test case accent colour with no nesting +testcase-accent-level-2: Test case accent colour with 2nd level nesting +testcase-accent-level-3: Test case accent colour with 3rd level nesting or higher site-title-foreground: Site title foreground static-alert-foreground: Static alert foreground tab-background-selected: Tab background for selected tabs diff --git a/core/modules/widgets/data.js b/core/modules/widgets/data.js new file mode 100644 index 000000000..c46dd1fb8 --- /dev/null +++ b/core/modules/widgets/data.js @@ -0,0 +1,145 @@ +/*\ +title: $:/core/modules/widgets/data.js +type: application/javascript +module-type: widget + +Widget to dynamically represent one or more tiddlers + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +var Widget = require("$:/core/modules/widgets/widget.js").widget; + +var DataWidget = function(parseTreeNode,options) { + this.dataWidgetTag = parseTreeNode.type; + this.initialise(parseTreeNode,options); +}; + +/* +Inherit from the base widget class +*/ +DataWidget.prototype = new Widget(); + +/* +Render this widget into the DOM +*/ +DataWidget.prototype.render = function(parent,nextSibling) { + this.parentDomNode = parent; + this.computeAttributes(); + this.execute(); + var jsonPayload = JSON.stringify(this.readDataTiddlerValues(),null,4); + var textNode = this.document.createTextNode(jsonPayload); + parent.insertBefore(textNode,nextSibling); + this.domNodes.push(textNode); +}; + +/* +Compute the internal state of the widget +*/ +DataWidget.prototype.execute = function() { + // Construct the child widgets + this.makeChildWidgets(); +}; + +/* +Read the tiddler value(s) from a data widget – must be called after the .render() method +*/ +DataWidget.prototype.readDataTiddlerValues = function() { + var self = this; + // Start with a blank object + var item = Object.create(null); + // Read any attributes not prefixed with $ + $tw.utils.each(this.attributes,function(value,name) { + if(name.charAt(0) !== "$") { + item[name] = value; + } + }); + item = new $tw.Tiddler(item); + // Deal with $tiddler, $filter or $compound-tiddler attributes + var tiddlers = [],title; + if(this.hasAttribute("$tiddler")) { + title = this.getAttribute("$tiddler"); + if(title) { + var tiddler = this.wiki.getTiddler(title); + if(tiddler) { + tiddlers.push(tiddler); + } + } + } + if(this.hasAttribute("$filter")) { + var filter = this.getAttribute("$filter"); + if(filter) { + var titles = this.wiki.filterTiddlers(filter); + $tw.utils.each(titles,function(title) { + var tiddler = self.wiki.getTiddler(title); + tiddlers.push(tiddler); + }); + } + } + if(this.hasAttribute("$compound-tiddler")) { + title = this.getAttribute("$compound-tiddler"); + if(title) { + tiddlers.push.apply(tiddlers,this.extractCompoundTiddler(title)); + } + } + // Convert the literal item to field strings + item = item.getFieldStrings(); + if(tiddlers.length === 0) { + if(Object.keys(item).length > 0 && !!item.title) { + return [item]; + } else { + return []; + } + } else { + var results = []; + $tw.utils.each(tiddlers,function(tiddler,index) { + var fields = tiddler.getFieldStrings(); + results.push($tw.utils.extend({},fields,item)); + }); + return results; + } +}; + +/* +Helper to extract tiddlers from text/vnd.tiddlywiki-multiple tiddlers +*/ +DataWidget.prototype.extractCompoundTiddler = function(title) { + var tiddler = this.wiki.getTiddler(title); + if(tiddler && tiddler.fields.type === "text/vnd.tiddlywiki-multiple") { + var text = tiddler.fields.text || "", + rawTiddlers = text.split(/\r?\n\+\r?\n/), + tiddlers = []; + $tw.utils.each(rawTiddlers,function(rawTiddler) { + var fields = Object.create(null), + split = rawTiddler.split(/\r?\n\r?\n/mg); + if(split.length >= 1) { + fields = $tw.utils.parseFields(split[0],fields); + } + if(split.length >= 2) { + fields.text = split.slice(1).join("\n\n"); + } + tiddlers.push(new $tw.Tiddler(fields)); + }); + return tiddlers; + } else { + return []; + } +}; + +/* +Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering +*/ +DataWidget.prototype.refresh = function(changedTiddlers) { + // It would be expensive to calculate whether the changedTiddlers impact the filter + // identified by the $filter attribute so we just refresh ourselves unconditionally + this.refreshSelf(); + return true; +}; + +exports.data = DataWidget; + +})(); diff --git a/core/modules/widgets/testcase.js b/core/modules/widgets/testcase.js new file mode 100644 index 000000000..abb8f03f6 --- /dev/null +++ b/core/modules/widgets/testcase.js @@ -0,0 +1,160 @@ +/*\ +title: $:/core/modules/widgets/testcase.js +type: application/javascript +module-type: widget + +Widget to display a test case + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +var Widget = require("$:/core/modules/widgets/widget.js").widget; + +var TestCaseWidget = function(parseTreeNode,options) { + this.initialise(parseTreeNode,options); +}; + +/* +Inherit from the base widget class +*/ +TestCaseWidget.prototype = new Widget(); + +/* +Render this widget into the DOM +*/ +TestCaseWidget.prototype.render = function(parent,nextSibling) { + var self = this; + this.parentDomNode = parent; + this.computeAttributes(); + this.execute(); + // Create container DOM node + var domNode = this.document.createElement("div"); + this.domNodes.push(domNode); + parent.insertBefore(domNode,nextSibling); + // Render the children into a hidden DOM node + var parser = { + tree: [{ + type: "widget", + attributes: {}, + orderedAttributes: [], + children: this.parseTreeNode.children || [] + }] + }; + this.contentRoot = this.wiki.makeWidget(parser,{ + document: $tw.fakeDocument, + parentWidget: this + }); + this.contentContainer = $tw.fakeDocument.createElement("div"); + this.contentRoot.render(this.contentContainer,null); + // Create a wiki + this.testcaseWiki = new $tw.Wiki(); + // Always load the core plugin + var loadTiddler = function(title) { + var tiddler = self.wiki.getTiddler(title); + if(tiddler) { + self.testcaseWiki.addTiddler(tiddler); + } + } + loadTiddler("$:/core"); + loadTiddler("$:/plugins/tiddlywiki/codemirror"); + // Load tiddlers from child data widgets + var tiddlers = []; + this.findChildrenDataWidgets(this.contentRoot.children,"data",function(widget) { + Array.prototype.push.apply(tiddlers,widget.readDataTiddlerValues()); + }); + var jsonPayload = JSON.stringify(tiddlers); + this.testcaseWiki.addTiddlers(tiddlers); + // Unpack plugin tiddlers + this.testcaseWiki.readPluginInfo(); + this.testcaseWiki.registerPluginTiddlers("plugin"); + this.testcaseWiki.unpackPluginTiddlers(); + this.testcaseWiki.addIndexersToWiki(); + // Generate a `transclusion` variable that depends on the values of the payload tiddlers so that the template can easily make unique state tiddlers + this.setVariable("transclusion",$tw.utils.hashString(jsonPayload)); + // Generate a `payloadTiddlers` variable that contains the payload in JSON format + this.setVariable("payloadTiddlers",jsonPayload); + // Render the test rendering if required + if(this.testcaseTestOutput && this.testcaseTestExpectedResult) { + var testcaseOutputContainer = $tw.fakeDocument.createElement("div"); + var testcaseOutputWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTestOutput,{ + document: $tw.fakeDocument, + parseAsInline: false, + parentWidget: this, + variables: { + currentTiddler: this.testcaseTestOutput + } + }); + testcaseOutputWidget.render(testcaseOutputContainer); + } + // Clear changes queue + this.testcaseWiki.clearTiddlerEventQueue(); + // Run the actions if provided + if(this.testcaseWiki.tiddlerExists(this.testcaseTestActions)) { + testcaseOutputWidget.invokeActionString(this.testcaseWiki.getTiddlerText(this.testcaseTestActions)); + testcaseOutputWidget.refresh(this.testcaseWiki.changedTiddlers,testcaseOutputContainer); + } + // Set up the test result variables + var testResult = "", + outputHTML = "", + expectedHTML = ""; + if(this.testcaseTestOutput && this.testcaseTestExpectedResult) { + outputHTML = testcaseOutputContainer.children[0].innerHTML; + expectedHTML = this.testcaseWiki.getTiddlerText(this.testcaseTestExpectedResult); + if(outputHTML === expectedHTML) { + testResult = "pass"; + } else { + testResult = "fail"; + } + this.setVariable("outputHTML",outputHTML); + this.setVariable("expectedHTML",expectedHTML); + this.setVariable("testResult",testResult); + this.setVariable("currentTiddler",this.testcaseTestOutput); + } + // Don't display anything if testHideIfPass is "yes" and the tests have passed + if(this.testcaseHideIfPass === "yes" && testResult === "pass") { + return; + } + // Render the page root template of the subwiki + var rootWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTemplate,{ + document: this.document, + parseAsInline: false, + parentWidget: this + }); + rootWidget.render(domNode); + // Trap changes in the wiki and refresh the rendering + this.testcaseWiki.addEventListener("change",function(changes) { + rootWidget.refresh(changes,domNode); + }); +}; + +/* +Compute the internal state of the widget +*/ +TestCaseWidget.prototype.execute = function() { + this.testcaseTemplate = this.getAttribute("template","$:/core/ui/testcases/DefaultTemplate"); + this.testcaseTestOutput = this.getAttribute("testOutput"); + this.testcaseTestActions = this.getAttribute("testActions"); + this.testcaseTestExpectedResult = this.getAttribute("testExpectedResult"); + this.testcaseHideIfPass = this.getAttribute("testHideIfPass"); +}; + +/* +Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering +*/ +TestCaseWidget.prototype.refresh = function(changedTiddlers) { + var changedAttributes = this.computeAttributes(); + if($tw.utils.count(changedAttributes) > 0) { + this.refreshSelf(); + return true; + } else { + return this.contentRoot.refresh(changedTiddlers); + } +}; + +exports["testcase"] = TestCaseWidget; + +})(); diff --git a/core/modules/widgets/widget.js b/core/modules/widgets/widget.js index ea300ca0e..69f63a684 100755 --- a/core/modules/widgets/widget.js +++ b/core/modules/widgets/widget.js @@ -813,6 +813,21 @@ Widget.prototype.allowActionPropagation = function() { return true; }; +/* +Find child <$data> widgets recursively. The tag name allows aliased versions of the widget to be found too +*/ +Widget.prototype.findChildrenDataWidgets = function(children,tag,callback) { + var self = this; + $tw.utils.each(children,function(child) { + if(child.dataWidgetTag === tag) { + callback(child); + } + if(child.children) { + self.findChildrenDataWidgets(child.children,tag,callback); + } + }); +}; + /* Evaluate a variable with parameters. This is a static convenience method that attempts to evaluate a variable as a function, returning an array of strings */ diff --git a/core/palettes/Vanilla.tid b/core/palettes/Vanilla.tid index 4c660e912..c7c800046 100644 --- a/core/palettes/Vanilla.tid +++ b/core/palettes/Vanilla.tid @@ -95,6 +95,9 @@ table-footer-background: #a8a8a8 table-header-background: #f0f0f0 tag-background: #ec6 tag-foreground: #ffffff +testcase-accent-level-1: #84C5E6 +testcase-accent-level-2: #E3B740 +testcase-accent-level-3: #5FD564 tiddler-background: <> tiddler-border: <> tiddler-controls-foreground-hover: #888888 diff --git a/core/ui/ControlPanel/TestCases.tid b/core/ui/ControlPanel/TestCases.tid new file mode 100644 index 000000000..401e14113 --- /dev/null +++ b/core/ui/ControlPanel/TestCases.tid @@ -0,0 +1,10 @@ +title: $:/core/ui/ControlPanel/TestCases +tags: $:/tags/ControlPanel/Advanced +caption: {{$:/language/ControlPanel/TestCases/Caption}} + +\whitespace trim +{{$:/language/ControlPanel/TestCases/Hint}} + +
+<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/TestCases]!has[draft.of]]" default="$:/core/ui/ControlPanel/TestCases/All"/> +
diff --git a/core/ui/ControlPanel/TestCasesAll.tid b/core/ui/ControlPanel/TestCasesAll.tid new file mode 100644 index 000000000..571fb93c2 --- /dev/null +++ b/core/ui/ControlPanel/TestCasesAll.tid @@ -0,0 +1,24 @@ +title: $:/core/ui/ControlPanel/TestCases/All +tags: $:/tags/ControlPanel/TestCases +caption: {{$:/language/ControlPanel/TestCases/All/Caption}} + +\define lingo-base() $:/language/ControlPanel/ +<> + +<$list filter="[all[tiddlers+shadows]tag[$:/tags/wiki-test-spec]type[text/vnd.tiddlywiki-multiple]] [all[tiddlers+shadows]tag[$:/tags/wiki-test-spec-failing]type[text/vnd.tiddlywiki-multiple]]"> + +

+ +<$link> + +<$text text=<>/> + + + +

+ +<$transclude + $tiddler="$:/core/ui/TestCaseTemplate" +/> + + diff --git a/core/ui/ControlPanel/TestCasesFailed.tid b/core/ui/ControlPanel/TestCasesFailed.tid new file mode 100644 index 000000000..4ab2d062d --- /dev/null +++ b/core/ui/ControlPanel/TestCasesFailed.tid @@ -0,0 +1,15 @@ +title: $:/core/ui/ControlPanel/TestCases/Failed +tags: $:/tags/ControlPanel/TestCases +caption: {{$:/language/ControlPanel/TestCases/Failed/Caption}} + +\define lingo-base() $:/language/ControlPanel/ +<> + +<$list filter="[all[tiddlers+shadows]tag[$:/tags/wiki-test-spec]type[text/vnd.tiddlywiki-multiple]] [all[tiddlers+shadows]tag[$:/tags/wiki-test-spec-failing]type[text/vnd.tiddlywiki-multiple]]"> + +<$transclude + $tiddler="$:/core/ui/TestCaseTemplate" + hideIfPass="yes" +/> + + diff --git a/core/ui/TestCaseTemplate.tid b/core/ui/TestCaseTemplate.tid new file mode 100644 index 000000000..74b6ab27d --- /dev/null +++ b/core/ui/TestCaseTemplate.tid @@ -0,0 +1,18 @@ +title: $:/core/ui/TestCaseTemplate + +\parameters (hideIfPass:"no") +\whitespace trim +<$let + linkTarget="yes" + displayFormat={{!!display-format}} +> + <$testcase + testOutput="Output" + testExpectedResult="ExpectedResult" + testActions="Actions" + testHideIfPass=<> + > + <$data $compound-tiddler=<>/> + <$data title="Description" text={{!!description}}/> + + diff --git a/core/ui/TestCases/DefaultTemplate.tid b/core/ui/TestCases/DefaultTemplate.tid new file mode 100644 index 000000000..679620969 --- /dev/null +++ b/core/ui/TestCases/DefaultTemplate.tid @@ -0,0 +1,64 @@ +title: $:/core/ui/testcases/DefaultTemplate + +\whitespace trim +\procedure linkcatcherActions() +<%if [has[title]] %> + <$qualify title=<> name="qualifiedState"> + <$action-setfield $tiddler=<> text=<>/> + +<%endif%> +\end + +<$let + state={{{ [] }}} +> +
+
+

+ <$genesis $type={{{ [!match[]then[$link]else[div]] }}}> + <%if [!match[]] %> + !match[fail]then[tc-test-case-result-icon-pass]] [match[fail]then[tc-test-case-result-icon-fail]] +[join[ ]] }}}> + <%if [!match[fail]] %> + {{$:/core/images/done-button}} + <%else%> + {{$:/core/images/close-button}} + <%endif%> + + <%endif%> + <$view tiddler="Description" mode="inline"/> + +

+
+ <%if [[Narrative]is[tiddler]] %> +
+ <$transclude $tiddler="Narrative" mode="block"/> +
+ <%endif%> + <%if [match[fail]] %> +
+
+ TEST FAILED +
+
+ <$diff-text source=<> dest=<>/> +
+
+ <%endif%> +
+
+ <$macrocall $name="tabs" tabsList="[all[tiddlers]sort[]] -[prefix] -Description -Narrative -ExpectedResult -Output Output +[putfirst[]] -[has[plugin-type]]" state=<> default="Output" template="$:/core/ui/testcases/DefaultTemplate/SourceTabs"/> +
+
+
+
+ <%if [!match[]else[wikitext]match[plaintext]] %> +
<$view tiddler="Output" format="plainwikified" mode="block"/>
+ <%else%> + <$linkcatcher actions=<>> + <$transclude $tiddler="Output" $mode="block"/> + + <%endif%> +
+
+
+ diff --git a/core/ui/TestCases/DefaultTemplateSourceTabs.tid b/core/ui/TestCases/DefaultTemplateSourceTabs.tid new file mode 100644 index 000000000..68c62c1f6 --- /dev/null +++ b/core/ui/TestCases/DefaultTemplateSourceTabs.tid @@ -0,0 +1,24 @@ +title: $:/core/ui/testcases/DefaultTemplate/SourceTabs + +\whitespace trim +\procedure body() +<$list filter="[fields[]] -text +[limit[1]]" variable="ignore"> + + + <$list filter="[fields[]sort[]] -text -title title +[putfirst[]]" variable="fieldName"> + + + + + + +
+ <$text text=<>/> + + <$view tiddler=<> field=<>/> +
+ +<$edit class="tc-edit-texteditor" tiddler=<>/> +\end + +<$transclude $variable="body" $mode="inline"/> diff --git a/core/ui/TestCases/RawJSONTemplate.tid b/core/ui/TestCases/RawJSONTemplate.tid new file mode 100644 index 000000000..fe9c583e8 --- /dev/null +++ b/core/ui/TestCases/RawJSONTemplate.tid @@ -0,0 +1,4 @@ +title: $:/core/ui/testcases/RawJSONTemplate + +\whitespace trim +<$text text=<>/> diff --git a/core/wiki/config/ViewTemplateBodyFilters.multids b/core/wiki/config/ViewTemplateBodyFilters.multids index ff9fe7250..e1dd62880 100644 --- a/core/wiki/config/ViewTemplateBodyFilters.multids +++ b/core/wiki/config/ViewTemplateBodyFilters.multids @@ -1,6 +1,7 @@ title: $:/config/ViewTemplateBodyFilters/ tags: $:/tags/ViewTemplateBodyFilter +testcase: [tag[$:/tags/wiki-test-spec]type[text/vnd.tiddlywiki-multiple]then[$:/core/ui/TestCaseTemplate]] [tag[$:/tags/wiki-test-spec-failing]type[text/vnd.tiddlywiki-multiple]then[$:/core/ui/TestCaseTemplate]] stylesheet: [tag[$:/tags/Stylesheet]then[$:/core/ui/ViewTemplate/body/rendered-plain-text]] core-ui-tags: [tag[$:/tags/PageTemplate]] [tag[$:/tags/EditTemplate]] [tag[$:/tags/ViewTemplate]] [tag[$:/tags/KeyboardShortcut]] [tag[$:/tags/ImportPreview]] [tag[$:/tags/EditPreview]][tag[$:/tags/EditorToolbar]] [tag[$:/tags/Actions]] :then[[$:/core/ui/ViewTemplate/body/code]] system: [prefix[$:/boot/]] [prefix[$:/config/]] [prefix[$:/core/macros]] [prefix[$:/core/save/]] [prefix[$:/core/templates/]] [prefix[$:/info/]] [prefix[$:/language/]] [prefix[$:/languages/]] [prefix[$:/snippets/]] [prefix[$:/state/]] [prefix[$:/status/]] [prefix[$:/info/]] [prefix[$:/temp/]] +[!is[image]limit[1]then[$:/core/ui/ViewTemplate/body/code]] diff --git a/core/wiki/macros/testcase.tid b/core/wiki/macros/testcase.tid new file mode 100644 index 000000000..a04cb540d --- /dev/null +++ b/core/wiki/macros/testcase.tid @@ -0,0 +1,10 @@ +title: $:/core/macros/testcase +tags: $:/tags/Macro $:/tags/Global + +\whitespace trim + +\procedure testcase(tiddler) +<$tiddler tiddler=<>> +<$transclude $tiddler="$:/core/ui/TestCaseTemplate"> + +\end diff --git a/core/wiki/tags/ViewTemplateBodyFilter.tid b/core/wiki/tags/ViewTemplateBodyFilter.tid index 7b9fb7fd8..0143c1f88 100644 --- a/core/wiki/tags/ViewTemplateBodyFilter.tid +++ b/core/wiki/tags/ViewTemplateBodyFilter.tid @@ -1,2 +1,2 @@ title: $:/tags/ViewTemplateBodyFilter -list: $:/config/ViewTemplateBodyFilters/hide-body $:/config/ViewTemplateBodyFilters/code-body $:/config/ViewTemplateBodyFilters/stylesheet $:/config/ViewTemplateBodyFilters/core-ui-advanced-search $:/config/ViewTemplateBodyFilters/core-ui-tags $:/config/ViewTemplateBodyFilters/system $:/config/ViewTemplateBodyFilters/import $:/config/ViewTemplateBodyFilters/plugin $:/config/ViewTemplateBodyFilters/default \ No newline at end of file +list: $:/config/ViewTemplateBodyFilters/testcase $:/config/ViewTemplateBodyFilters/hide-body $:/config/ViewTemplateBodyFilters/code-body $:/config/ViewTemplateBodyFilters/stylesheet $:/config/ViewTemplateBodyFilters/core-ui-advanced-search $:/config/ViewTemplateBodyFilters/core-ui-tags $:/config/ViewTemplateBodyFilters/system $:/config/ViewTemplateBodyFilters/import $:/config/ViewTemplateBodyFilters/plugin $:/config/ViewTemplateBodyFilters/default \ No newline at end of file diff --git a/editions/test/tiddlers/HelloThere.tid b/editions/test/tiddlers/HelloThere.tid index d41f45fe2..74ea616e5 100644 --- a/editions/test/tiddlers/HelloThere.tid +++ b/editions/test/tiddlers/HelloThere.tid @@ -3,3 +3,7 @@ title: HelloThere This is TiddlyWiki's browser-based test runner for version <>. See the bottom of this page for the test results. https://tiddlywiki.com/ + +! Test Cases + +{{$:/core/ui/ControlPanel/TestCases}} diff --git a/editions/test/tiddlers/tests/from-tw5.com/tiddlywiki.files b/editions/test/tiddlers/tests/from-tw5.com/tiddlywiki.files new file mode 100644 index 000000000..c8ce1656e --- /dev/null +++ b/editions/test/tiddlers/tests/from-tw5.com/tiddlywiki.files @@ -0,0 +1,5 @@ +{ + "directories": [ + "../../../../tw5.com/tiddlers/testcases" + ] +} \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/concepts/CompoundTiddlers.tid b/editions/tw5.com/tiddlers/concepts/CompoundTiddlers.tid new file mode 100644 index 000000000..c4a049a6a --- /dev/null +++ b/editions/tw5.com/tiddlers/concepts/CompoundTiddlers.tid @@ -0,0 +1,31 @@ +title: CompoundTiddlers +modified: 20240507221902644 +created: 20240507221902644 +tags: Concepts + +Compound tiddlers are a special type of tiddler that can store one or more payload tiddlers. The tiddlers within a compound tiddler are only accessible via special operations, typically with the TestCaseWidget. + +The compound tiddler format is extremely simple, and includes the notable flaw that it does not permit tiddlers that contain a plus sign (`+`) on a line by itself. It is not intended as a general purpose way of storing tiddler data. + +Compound tiddlers are identified by having their type field set to `text/vnd.tiddlywiki-multiple`. + +The content of a compound tiddler consists of a sequence of tiddlers separated by a plus sign (`+`) on a line by itself. Each tiddler uses the same format as [[.tid files|TiddlerFiles]]. + +For example: + +``` +title: First +tags: one two + +This is the first tiddler ++ +title: Second +tags: three four + +This is the second tiddler ++ +title: third +tags: five six + +This is the third tiddler +``` diff --git a/editions/tw5.com/tiddlers/concepts/TestCaseTiddlers.tid b/editions/tw5.com/tiddlers/concepts/TestCaseTiddlers.tid new file mode 100644 index 000000000..ff84d6800 --- /dev/null +++ b/editions/tw5.com/tiddlers/concepts/TestCaseTiddlers.tid @@ -0,0 +1,27 @@ +title: TestCaseTiddlers +modified: 20240507221902644 +created: 20240507221902644 +tags: Concepts + +Test case tiddlers encapsulate one or more tiddlers that can be displayed as a [[test case|TestCaseWidget]]: an independent embedded wiki that can be used for testing or learning purposes. + +Test case tiddlers are formatted as CompoundTiddlers, allowing them to contain multiple tiddlers packed into one. + +Test case tiddlers have the following fields: + +|!Field |!Description | +|<<.field type>> | Should be set to `text/vnd.tiddlywiki-multiple` | +|<<.field tags>> | Test cases are tagged [[$:/tags/wiki-test-spec]]. Test cases that intentionally fail are tagged [[$:/tags/wiki-test-spec-failing]] | +|<<.field description>> |Descriptive heading for the test, intended to make it easy to identify the test | +|<<.field display-format>> |Optional, defaults to `wikitext`. Set to `plaintext` to cause the output to be rended as plain text | + +Test case tiddlers with the appropriate tag are shown in $:/ControlPanel + +Some payload tiddlers are set aside for special purposes: + +|!Tiddler |!Description | +|''Narrative'' |Narrative description of the test, intended to explain the purpose and operation of the test | +|''Output'' |The tiddler that produces the test output | +|''~ExpectedResult'' |HTML of expected result of rendering the ''Output'' tiddler | + + diff --git a/editions/tw5.com/tiddlers/hellothere/HelloThere.tid b/editions/tw5.com/tiddlers/hellothere/HelloThere.tid index 91ee04e2f..956deec8c 100644 --- a/editions/tw5.com/tiddlers/hellothere/HelloThere.tid +++ b/editions/tw5.com/tiddlers/hellothere/HelloThere.tid @@ -5,7 +5,7 @@ tags: TableOfContents title: HelloThere type: text/vnd.tiddlywiki - !!.tc-hero-heading ''Welcome to TiddlyWiki, a unique [[non-linear|Philosophy of Tiddlers]] notebook for [[capturing|Creating and editing tiddlers]], [[organising|Structuring TiddlyWiki]] and [[sharing|Sharing your tiddlers with others]] complex information'' +!!.tc-hero-heading ''Welcome to TiddlyWiki, a unique [[non-linear|Philosophy of Tiddlers]] notebook for [[capturing|Creating and editing tiddlers]], [[organising|Structuring TiddlyWiki]] and [[sharing|Sharing your tiddlers with others]] complex information'' Use it to keep your [[to-do list|TaskManagementExample]], to plan an [[essay or novel|"TiddlyWiki for Scholars" by Alberto Molina]], or to organise your wedding. Record every thought that crosses your brain, or build a flexible and responsive website. diff --git a/editions/tw5.com/tiddlers/testcases/DataWidget/ImportCompound.tid b/editions/tw5.com/tiddlers/testcases/DataWidget/ImportCompound.tid new file mode 100644 index 000000000..20e967316 --- /dev/null +++ b/editions/tw5.com/tiddlers/testcases/DataWidget/ImportCompound.tid @@ -0,0 +1,33 @@ +title: TestCases/DataWidget/ImportCompound +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] +description: Importing a compound payload tiddler and adding custom fields +display-format: plaintext + +title: Narrative + +Using the data widget to import a tiddler stored in a compound tiddler ++ +title: Output + +<$data $compound-tiddler="Compound" custom="Alpha"/> ++ +title: Compound +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Payload Tiddler +tags: Alpha Beta Gamma + +This is a payload tiddler from a compound tiddler ++ +title: ExpectedResult + +

[ + { + "title": "Payload Tiddler", + "tags": "Alpha Beta Gamma", + "text": "This is a payload tiddler from a compound tiddler", + "custom": "Alpha" + } +]

\ No newline at end of file diff --git a/editions/tw5.com/tiddlers/testcases/DataWidget/ImportedFilter.tid b/editions/tw5.com/tiddlers/testcases/DataWidget/ImportedFilter.tid new file mode 100644 index 000000000..3e7416fe3 --- /dev/null +++ b/editions/tw5.com/tiddlers/testcases/DataWidget/ImportedFilter.tid @@ -0,0 +1,49 @@ +title: TestCases/DataWidget/ImportedFilter +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] +description: Imported filter definition +display-format: plaintext + +title: Narrative + +Using the data widget to create copies of all the tiddlers with the title prefix "Day: T", adding the field "custom" set to "Beta" ++ +title: Output + +<$data $filter="[prefix[Day: T]]" custom="Beta"/> ++ +title: Day: Monday +text: Today is Monday ++ +title: Day: Tuesday +text: Today is Tuesday ++ +title: Day: Wednesday +text: Today is Wednesday ++ +title: Day: Thursday +text: Today is Thursday ++ +title: Day: Friday +text: Today is Friday ++ +title: Day: Saturday +text: Today is Saturday ++ +title: Day: Sunday +text: Today is Sunday ++ +title: ExpectedResult + +

[ + { + "title": "Day: Thursday", + "text": "Today is Thursday", + "custom": "Beta" + }, + { + "title": "Day: Tuesday", + "text": "Today is Tuesday", + "custom": "Beta" + } +]

\ No newline at end of file diff --git a/editions/tw5.com/tiddlers/testcases/DataWidget/ImportedTiddler.tid b/editions/tw5.com/tiddlers/testcases/DataWidget/ImportedTiddler.tid new file mode 100644 index 000000000..02b89726c --- /dev/null +++ b/editions/tw5.com/tiddlers/testcases/DataWidget/ImportedTiddler.tid @@ -0,0 +1,29 @@ +title: TestCases/DataWidget/ImportedTiddler +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] +description: Imported tiddler definition +display-format: plaintext + +title: Narrative + +Using the data widget to create a tiddler that is a copy of the tiddler "Hello" with the addition of the field "custom" set to "Alpha" ++ +title: Output + +<$data $tiddler="Hello" custom="Alpha"/> ++ +title: Hello +modifier: JoeBloggs + +This is the Hello tiddler ++ +title: ExpectedResult + +

[ + { + "title": "Hello", + "modifier": "JoeBloggs", + "text": "This is the Hello tiddler", + "custom": "Alpha" + } +]

\ No newline at end of file diff --git a/editions/tw5.com/tiddlers/testcases/DataWidget/Refreshing.tid b/editions/tw5.com/tiddlers/testcases/DataWidget/Refreshing.tid new file mode 100644 index 000000000..92fc32090 --- /dev/null +++ b/editions/tw5.com/tiddlers/testcases/DataWidget/Refreshing.tid @@ -0,0 +1,30 @@ +title: TestCases/DataWidget/Refreshing +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] +description: Refreshing the data widget +display-format: plaintext + +title: Narrative + +Verifying that the JSON output of the data widget is correctly refreshed when the data changes ++ +title: Output + +<$data title="Epsilon" text={{Subject}}/> ++ +title: Subject + +Nothing ++ +title: Actions + +<$action-setfield $tiddler="Subject" text="Theta"/> ++ +title: ExpectedResult + +

[ + { + "title": "Epsilon", + "text": "Theta" + } +]

\ No newline at end of file diff --git a/editions/tw5.com/tiddlers/testcases/DataWidget/SimpleTiddler.tid b/editions/tw5.com/tiddlers/testcases/DataWidget/SimpleTiddler.tid new file mode 100644 index 000000000..633ecb0b8 --- /dev/null +++ b/editions/tw5.com/tiddlers/testcases/DataWidget/SimpleTiddler.tid @@ -0,0 +1,22 @@ +title: TestCases/DataWidget/SimpleTiddler +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] +description: Simple tiddler definition +display-format: plaintext + +title: Narrative + +Using the data widget to create a tiddler with the title "Epsilon" and the text "Theta" ++ +title: Output + +<$data title="Epsilon" text="Theta"/> ++ +title: ExpectedResult + +

[ + { + "title": "Epsilon", + "text": "Theta" + } +]

\ No newline at end of file diff --git a/editions/tw5.com/tiddlers/testcases/TestCaseWidget/FailingTest.tid b/editions/tw5.com/tiddlers/testcases/TestCaseWidget/FailingTest.tid new file mode 100644 index 000000000..bd9126e03 --- /dev/null +++ b/editions/tw5.com/tiddlers/testcases/TestCaseWidget/FailingTest.tid @@ -0,0 +1,15 @@ +title: TestCases/TestCaseWidget/FailingTest +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec-failing]] +description: An example of a failing test + +title: Narrative + +This test case intentionally fails to show how failures are displayed. ++ +title: Output + +The sum is <$text text={{{ [[2]add[2]] }}}/>. ++ +title: ExpectedResult +text:

The sum is not 8.

diff --git a/editions/tw5.com/tiddlers/testcases/TestCaseWidget/currentTiddler.tid b/editions/tw5.com/tiddlers/testcases/TestCaseWidget/currentTiddler.tid new file mode 100644 index 000000000..824a2b17f --- /dev/null +++ b/editions/tw5.com/tiddlers/testcases/TestCaseWidget/currentTiddler.tid @@ -0,0 +1,16 @@ +description: currentTiddler should be properly set +tags: $:/tags/wiki-test-spec +title: TestCases/TestCaseTiddler/currentTiddler +type: text/vnd.tiddlywiki-multiple + +title: Narrative + +currentTiddler variable in Output tiddler should be "Output" ++ +title: Output + +<$text text=<>> ++ +title: ExpectedResult + +

Output

\ No newline at end of file diff --git a/editions/tw5.com/tiddlers/testcases/TranscludeWidget/SimpleTransclusion.tid b/editions/tw5.com/tiddlers/testcases/TranscludeWidget/SimpleTransclusion.tid new file mode 100644 index 000000000..e7ef05e6d --- /dev/null +++ b/editions/tw5.com/tiddlers/testcases/TranscludeWidget/SimpleTransclusion.tid @@ -0,0 +1,23 @@ +title: TestCases/TranscludeWidget/SimpleTransclusion +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] +description: Simple transclusion + +title: Narrative + +This test case demonstrates transclusion of and links to other tiddlers. ++ +title: Output + +Good morning, my [[name|Name]] is {{Name}} and I [[live in|Address]] {{Address}} ++ +title: Name + +Robert Rabbit ++ +title: Address + +14 Carrot Street, Vegetabletown ++ +title: ExpectedResult +text:

Good morning, my name is Robert Rabbit and I live in 14 Carrot Street, Vegetabletown

diff --git a/editions/tw5.com/tiddlers/widgets/DataWidget.tid b/editions/tw5.com/tiddlers/widgets/DataWidget.tid new file mode 100644 index 000000000..8aaf1efaf --- /dev/null +++ b/editions/tw5.com/tiddlers/widgets/DataWidget.tid @@ -0,0 +1,42 @@ +caption: data +created: 20240507221902644 +modified: 20240507221902644 +tags: Widgets +title: DataWidget +type: text/vnd.tiddlywiki + +! Introduction + +The data widget is used with the <<.wlink TestCaseWidget>> widget and the [[Innerwiki Plugin]] to specify payload tiddlers that are to be included in the test case or innerwiki. + +! Content and Attributes + +The content of the data widget is ignored. It supports the following attributes: + +|!Attribute |!Description | +|<<.attr $tiddler>> |Optional title of a tiddler to be used as a payload tiddler (optional) | +|<<.attr $filter>> |Optional filter string identifying tiddlers to be used as payload tiddlers (optional) | +|<<.attr $compound-tiddler>> |Optional title of a tiddler containing payload tiddlers in `text/vnd.tiddlywiki-multiple` format (see below) | +|//any attribute
not starting
with $// |Field values to be assigned to the payload tiddler(s) | + +The data widget is not rendered when used within the <<.wlink TestCaseWidget>> widget or the [[Innerwiki Plugin]] but for ease of testing, when used elsewhere it renders a JSON representation of the payload tiddlers. + +Without any of the attributes <<.attr $tiddler>>, <<.attr $filter>> or <<.attr $compound-tiddler>>, any attributes whose name does not start with $ are used as the field values for creating a single new tiddler. + +<> + +If any of the attributes <<.attr $tiddler>>, <<.attr $filter>> or <<.attr $compound-tiddler>> are specified then they are used to generate base tiddlers that are then modified with the addition of fields derived from any attributes whose name does not start with $. + +The attribute <<.attr $tiddler>> is used to ingest a single tiddler from the wiki containing the data widget: + +<> + +The attribute <<.attr $filter>> is used to ingest multiple tiddlers from the wiki containing the data widget: + +<> + +! Compound Tiddlers + +[[Compound tiddlers|CompoundTiddlers]] provide a way to easily create multiple tiddlers from within a single tiddler. They are contained in tiddlers of type `text/vnd.tiddlywiki-multiple`. The text field consists of a series of tiddlers in the same format as `.tid` files, each separated by a line containing a single `+` character. + +<> diff --git a/editions/tw5.com/tiddlers/widgets/TestCaseWidget.tid b/editions/tw5.com/tiddlers/widgets/TestCaseWidget.tid new file mode 100644 index 000000000..a73403890 --- /dev/null +++ b/editions/tw5.com/tiddlers/widgets/TestCaseWidget.tid @@ -0,0 +1,101 @@ +caption: testcase +created: 20240507221902644 +modified: 20240507221902644 +tags: Widgets +title: TestCaseWidget +type: text/vnd.tiddlywiki + +! Introduction + +The <<.wid testcase>> widget is designed to present interactive example test cases that are useful for learning and testing. It functions by creating an independent subwiki loaded with the specified payload tiddlers and then rendering a specified template from within the subwiki. The <<.wid testcase>> widget can optionally also be used to run and verify test results within the subwiki. + +This makes it possible to run independent tests that also serve as documentation examples. + +The <<.wid testcase>> widget can be used directly as documented below, but it is generally easier to create [[TestCaseTiddlers]]. These are special CompoundTiddlers that can contain multiple payload tiddlers making up a test case. + +!! Features + +Here is an example of a test case showing the default split view with the source tiddlers on the left and the tiddler titled `Output` rendered on the right. + +<> + +Notice also that clicking on links within the output pane will switch to the tab containing that tiddler. + +The text of the payload tiddlers listed on the left are editable, with the results being immediately reflected in the preview pane on the right. However, if the <<.wid testcase>> widget is refreshed then the modifications are lost. + +The green tick at the top left of a test case indicates that a test has been set up and that it passes. + +If the test fails, a red cross is shown, and there is a display of the differences between the actual results and the expected results: + +<> + +! Limitations + +The <<.wid testcase>> widget creates a lightweight TiddlyWiki environment that is a parasite of the main wiki. Because it is not a full, independent TiddlyWiki environment, there are some important limitations: + +* Output is rendered into a DIV, and so cannot be styled independently of the host wiki +* Any changes to the wiki made interactively by the user are volatile, and are lost when the <<.wid testcase>> widget is refreshed +* Startup actions are not supported +* Only plugins available in the host wiki can be included in the test case + +If these limitations are a problem, the [[Innerwiki Plugin]] offers the ability to embed a fully independent subwiki via an `