From a463783283179db449a6d2950aea736e1ca1493c Mon Sep 17 00:00:00 2001 From: lin onetwo Date: Sun, 26 May 2024 09:56:25 -0500 Subject: [PATCH 01/19] Fix/sjcl variable (#8099) * refactor: use files to add prefix * fix: always use $tw.sjcl * refactor: move sjcl to lib/sjcl * fix: require sjcl in lib/ * refactor: move sjcl.js back into /boot --- boot/sjcl.js.meta | 3 --- boot/tiddlywiki.files | 35 +++++++++++++++++++++++++++++++++++ core/modules/utils/utils.js | 2 +- 3 files changed, 36 insertions(+), 4 deletions(-) delete mode 100644 boot/sjcl.js.meta create mode 100644 boot/tiddlywiki.files diff --git a/boot/sjcl.js.meta b/boot/sjcl.js.meta deleted file mode 100644 index f32b4df93..000000000 --- a/boot/sjcl.js.meta +++ /dev/null @@ -1,3 +0,0 @@ -title: $:/library/sjcl.js -type: application/javascript -library: yes diff --git a/boot/tiddlywiki.files b/boot/tiddlywiki.files new file mode 100644 index 000000000..5e9c3d393 --- /dev/null +++ b/boot/tiddlywiki.files @@ -0,0 +1,35 @@ +{ + "tiddlers": [ + { + "file": "sjcl.js", + "fields": { + "title": "$:/library/sjcl.js", + "type": "application/javascript", + "library": "yes" + }, + "prefix": "(function(define) {\n", + "suffix": "\n})(function (_,defined){window.sjcl = defined()})\n" + }, + { + "file": "boot.js", + "fields": { + "title": "$:/boot/boot.js", + "type": "application/javascript" + } + }, + { + "file": "bootprefix.js", + "fields": { + "title": "$:/boot/bootprefix.js", + "type": "application/javascript" + } + }, + { + "file": "boot.css.tid", + "fields": { + "title": "$:/boot/boot.css", + "type": "text/css" + } + } + ] +} \ No newline at end of file diff --git a/core/modules/utils/utils.js b/core/modules/utils/utils.js index 42b3bd05c..878f83fbb 100644 --- a/core/modules/utils/utils.js +++ b/core/modules/utils/utils.js @@ -825,7 +825,7 @@ options.length .. number of characters returned defaults to 64 */ exports.sha256 = function(str, options) { options = options || {} - return sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(str)).substr(0,options.length || 64); + return $tw.sjcl.codec.hex.fromBits($tw.sjcl.hash.sha256.hash(str)).substr(0,options.length || 64); } /* From dbe912ba5d6b51e542abd8a94db0d49cc7eee04e Mon Sep 17 00:00:00 2001 From: lin onetwo Date: Mon, 27 May 2024 06:45:29 -0500 Subject: [PATCH 02/19] Fix boot.css bug from #8099 (#8214) --- boot/{boot.css.tid => boot.css} | 3 --- boot/tiddlywiki.files | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) rename boot/{boot.css.tid => boot.css} (96%) diff --git a/boot/boot.css.tid b/boot/boot.css similarity index 96% rename from boot/boot.css.tid rename to boot/boot.css index 27c8884cd..c0d15f1e3 100644 --- a/boot/boot.css.tid +++ b/boot/boot.css @@ -1,6 +1,3 @@ -title: $:/boot/boot.css -type: text/css - /* Basic styles used before we boot up the parsing engine */ diff --git a/boot/tiddlywiki.files b/boot/tiddlywiki.files index 5e9c3d393..38ab5adde 100644 --- a/boot/tiddlywiki.files +++ b/boot/tiddlywiki.files @@ -25,7 +25,7 @@ } }, { - "file": "boot.css.tid", + "file": "boot.css", "fields": { "title": "$:/boot/boot.css", "type": "text/css" From 2312cd33015d4d1aa930e8e60572d0b2f710a31a Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 28 May 2024 13:17:35 +0100 Subject: [PATCH 03/19] Improve wording for failing test See https://talk.tiddlywiki.org/t/introducing-the-testcase-widget/9847/11 --- .../tw5.com/tiddlers/testcases/TestCaseWidget/FailingTest.tid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editions/tw5.com/tiddlers/testcases/TestCaseWidget/FailingTest.tid b/editions/tw5.com/tiddlers/testcases/TestCaseWidget/FailingTest.tid index bd9126e03..5524a9852 100644 --- a/editions/tw5.com/tiddlers/testcases/TestCaseWidget/FailingTest.tid +++ b/editions/tw5.com/tiddlers/testcases/TestCaseWidget/FailingTest.tid @@ -5,7 +5,7 @@ description: An example of a failing test title: Narrative -This test case intentionally fails to show how failures are displayed. +This test case intentionally fails (in order to show how failures are displayed) + title: Output From b5bd4c96734bc76fe5380b05fd45d401ac602004 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 28 May 2024 13:22:44 +0100 Subject: [PATCH 04/19] Fix testcase heading link destination --- core/ui/TestCaseTemplate.tid | 1 + core/ui/TestCases/DefaultTemplate.tid | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core/ui/TestCaseTemplate.tid b/core/ui/TestCaseTemplate.tid index 74b6ab27d..9871a2904 100644 --- a/core/ui/TestCaseTemplate.tid +++ b/core/ui/TestCaseTemplate.tid @@ -5,6 +5,7 @@ title: $:/core/ui/TestCaseTemplate <$let linkTarget="yes" displayFormat={{!!display-format}} + testcaseTiddler=<> > <$testcase testOutput="Output" diff --git a/core/ui/TestCases/DefaultTemplate.tid b/core/ui/TestCases/DefaultTemplate.tid index 679620969..0e4692ebf 100644 --- a/core/ui/TestCases/DefaultTemplate.tid +++ b/core/ui/TestCases/DefaultTemplate.tid @@ -15,7 +15,7 @@ title: $:/core/ui/testcases/DefaultTemplate

- <$genesis $type={{{ [!match[]then[$link]else[div]] }}}> + <$genesis $type={{{ [!match[]then[$link]else[div]] }}} to=<>> <%if [!match[]] %> !match[fail]then[tc-test-case-result-icon-pass]] [match[fail]then[tc-test-case-result-icon-fail]] +[join[ ]] }}}> <%if [!match[fail]] %> From 613ee13294ce01d9098c647329d4b6fdc1caeba6 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 28 May 2024 13:37:50 +0100 Subject: [PATCH 05/19] Testcase docs: add note about description field overwriting Description payload tiddler --- editions/tw5.com/tiddlers/concepts/TestCaseTiddlers.tid | 3 +-- editions/tw5.com/tiddlers/widgets/TestCaseWidget.tid | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/editions/tw5.com/tiddlers/concepts/TestCaseTiddlers.tid b/editions/tw5.com/tiddlers/concepts/TestCaseTiddlers.tid index ff84d6800..cf42c67d7 100644 --- a/editions/tw5.com/tiddlers/concepts/TestCaseTiddlers.tid +++ b/editions/tw5.com/tiddlers/concepts/TestCaseTiddlers.tid @@ -23,5 +23,4 @@ Some payload tiddlers are set aside for special purposes: |''Narrative'' |Narrative description of the test, intended to explain the purpose and operation of the test | |''Output'' |The tiddler that produces the test output | |''~ExpectedResult'' |HTML of expected result of rendering the ''Output'' tiddler | - - +|''Description'' |Set to the text of the <<.field description>> field | diff --git a/editions/tw5.com/tiddlers/widgets/TestCaseWidget.tid b/editions/tw5.com/tiddlers/widgets/TestCaseWidget.tid index a73403890..608a964d6 100644 --- a/editions/tw5.com/tiddlers/widgets/TestCaseWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/TestCaseWidget.tid @@ -75,7 +75,7 @@ The test case wiki will inherit variables that are visible to the <<.wid testcas A custom template can be specified for special purposes. For example, the provided template $:/core/ui/testcases/RawJSONTemplate just displays the payload tiddlers in JSON, which can be used for debugging purposes. -! Test Czase Template Variables +! Test Case Template Variables The <<.wid testcase>> widget makes the following variables available within the rendered template: From 9756b79683d157ce1ee87ddaec0d273edc754ce7 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 28 May 2024 14:30:59 +0100 Subject: [PATCH 06/19] Fix currentTiddler in testcase renderings See https://github.com/Jermolene/TiddlyWiki5/commit/eb4e9d86ac02a0d29e63ab600a4fc93bf8f2f360#r142368175 --- core/ui/TestCases/DefaultTemplate.tid | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/ui/TestCases/DefaultTemplate.tid b/core/ui/TestCases/DefaultTemplate.tid index 0e4692ebf..3a68253e8 100644 --- a/core/ui/TestCases/DefaultTemplate.tid +++ b/core/ui/TestCases/DefaultTemplate.tid @@ -55,7 +55,9 @@ title: $:/core/ui/testcases/DefaultTemplate
<$view tiddler="Output" format="plainwikified" mode="block"/>
<%else%> <$linkcatcher actions=<>> - <$transclude $tiddler="Output" $mode="block"/> + <$tiddler tiddler="Output"> + <$transclude $tiddler="Output" $mode="block"/> + <%endif%>

From 1b6e8e1a7930115a0a9c90d4d03fb6c1b135484e Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 29 May 2024 08:28:34 +0100 Subject: [PATCH 07/19] Testcase widget should only run tests if expected results are specified Fixes #8218 --- core/modules/widgets/testcase.js | 9 +++++++-- .../testcases/TestCaseWidget/NoExpectedResults.tid | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 editions/tw5.com/tiddlers/testcases/TestCaseWidget/NoExpectedResults.tid diff --git a/core/modules/widgets/testcase.js b/core/modules/widgets/testcase.js index abb8f03f6..e80bbcaa3 100644 --- a/core/modules/widgets/testcase.js +++ b/core/modules/widgets/testcase.js @@ -77,8 +77,13 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) { this.setVariable("transclusion",$tw.utils.hashString(jsonPayload)); // Generate a `payloadTiddlers` variable that contains the payload in JSON format this.setVariable("payloadTiddlers",jsonPayload); + // Only run the tests if the testcase output and expected results were specified, and those tiddlers actually exist in the wiki + var shouldRunTests = false; + if(this.testcaseTestOutput && this.testcaseWiki.tiddlerExists(this.testcaseTestOutput) && this.testcaseTestExpectedResult && this.testcaseWiki.tiddlerExists(this.testcaseTestExpectedResult)) { + shouldRunTests = true; + } // Render the test rendering if required - if(this.testcaseTestOutput && this.testcaseTestExpectedResult) { + if(shouldRunTests) { var testcaseOutputContainer = $tw.fakeDocument.createElement("div"); var testcaseOutputWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTestOutput,{ document: $tw.fakeDocument, @@ -101,7 +106,7 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) { var testResult = "", outputHTML = "", expectedHTML = ""; - if(this.testcaseTestOutput && this.testcaseTestExpectedResult) { + if(shouldRunTests) { outputHTML = testcaseOutputContainer.children[0].innerHTML; expectedHTML = this.testcaseWiki.getTiddlerText(this.testcaseTestExpectedResult); if(outputHTML === expectedHTML) { diff --git a/editions/tw5.com/tiddlers/testcases/TestCaseWidget/NoExpectedResults.tid b/editions/tw5.com/tiddlers/testcases/TestCaseWidget/NoExpectedResults.tid new file mode 100644 index 000000000..a4dcee462 --- /dev/null +++ b/editions/tw5.com/tiddlers/testcases/TestCaseWidget/NoExpectedResults.tid @@ -0,0 +1,12 @@ +title: TestCases/TestCaseWidget/NoExpectedResults +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] +description: A testcase that does not specify expected results + +title: Narrative + +This testcase will display without the pass/fail icons because it does not include an `ExpectedResults` tiddler, and so will only be rendered, and not be executed as a test ++ +title: Output + +This is the output From 4274e8fd7fd7440cd92037b537843d5bd27981d6 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 29 May 2024 08:36:52 +0100 Subject: [PATCH 08/19] Fix tests broken in 1b6e8e1a7930115a0a9c90d4d03fb6c1b135484e --- .../jasmine/run-wiki-based-tests.js | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/plugins/tiddlywiki/jasmine/run-wiki-based-tests.js b/plugins/tiddlywiki/jasmine/run-wiki-based-tests.js index e22fe7378..90d4768e4 100644 --- a/plugins/tiddlywiki/jasmine/run-wiki-based-tests.js +++ b/plugins/tiddlywiki/jasmine/run-wiki-based-tests.js @@ -34,23 +34,22 @@ describe("Wiki-based tests", function() { if(!wiki.tiddlerExists("Output")) { throw "Missing 'Output' tiddler"; } - if(!wiki.tiddlerExists("ExpectedResult")) { - throw "Missing 'ExpectedResult' tiddler"; + if(wiki.tiddlerExists("ExpectedResult")) { + // Construct the widget node + var text = "{{Output}}\n\n"; + var widgetNode = createWidgetNode(parseText(text,wiki),wiki); + // Render the widget node to the DOM + var wrapper = renderWidgetNode(widgetNode); + // Clear changes queue + wiki.clearTiddlerEventQueue(); + // Run the actions if provided + if(wiki.tiddlerExists("Actions")) { + widgetNode.invokeActionString(wiki.getTiddlerText("Actions")); + refreshWidgetNode(widgetNode,wrapper); + } + // Test the rendering + expect(wrapper.innerHTML).toBe(wiki.getTiddlerText("ExpectedResult")); } - // Construct the widget node - var text = "{{Output}}\n\n"; - var widgetNode = createWidgetNode(parseText(text,wiki),wiki); - // Render the widget node to the DOM - var wrapper = renderWidgetNode(widgetNode); - // Clear changes queue - wiki.clearTiddlerEventQueue(); - // Run the actions if provided - if(wiki.tiddlerExists("Actions")) { - widgetNode.invokeActionString(wiki.getTiddlerText("Actions")); - refreshWidgetNode(widgetNode,wrapper); - } - // Test the rendering - expect(wrapper.innerHTML).toBe(wiki.getTiddlerText("ExpectedResult")); }); }); From 0f17ff0f6cf6c3baf97b92e6b054667b1a6b1b3b Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 29 May 2024 10:25:34 +0100 Subject: [PATCH 09/19] Testcase widget should treat test cases without a test as if they had passed --- core/modules/widgets/testcase.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/widgets/testcase.js b/core/modules/widgets/testcase.js index e80bbcaa3..0fd55531c 100644 --- a/core/modules/widgets/testcase.js +++ b/core/modules/widgets/testcase.js @@ -120,7 +120,7 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) { this.setVariable("currentTiddler",this.testcaseTestOutput); } // Don't display anything if testHideIfPass is "yes" and the tests have passed - if(this.testcaseHideIfPass === "yes" && testResult === "pass") { + if(this.testcaseHideIfPass === "yes" && testResult !== "fail") { return; } // Render the page root template of the subwiki From 15001020fe858da8398ca37d0dd02ef65545d415 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 29 May 2024 10:33:08 +0100 Subject: [PATCH 10/19] Update release note --- .../prerelease/tiddlers/Release 5.3.4.tid | 28 ++++++++++++++++--- .../testcases/TestCaseWidget/TwoPlusTwo.tid | 18 ++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 editions/tw5.com/tiddlers/testcases/TestCaseWidget/TwoPlusTwo.tid diff --git a/editions/prerelease/tiddlers/Release 5.3.4.tid b/editions/prerelease/tiddlers/Release 5.3.4.tid index 638afaaa2..b88a8feb8 100644 --- a/editions/prerelease/tiddlers/Release 5.3.4.tid +++ b/editions/prerelease/tiddlers/Release 5.3.4.tid @@ -1,6 +1,6 @@ caption: 5.3.4 -created: 20231223102229103 -modified: 20231223102229103 +created: 20240529100240232 +modified: 20240529100240232 tags: ReleaseNotes title: Release 5.3.4 type: text/vnd.tiddlywiki @@ -10,6 +10,8 @@ description: Under development ! Major Improvements +!! Tour Plugin + <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7734">> several new features that together allow interactive learning tours to be created and presented in TiddlyWiki. The demo TiddlyWiki interactive tour can be seen at https://tiddlywiki.com/prerelease/tour @@ -20,6 +22,20 @@ The new features include: * The new Confetti Plugin that allows animated bursts of confetti to be displayed * Improvements to the Dynannotate Plugin to add the ability to highlight screen elements using an animated spotlight effect +!! <<.wlink TestCaseWidget>> Widget + +<<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7817">> new <<.wlink TestCaseWidget>> widget that is intended to solve a problem with the examples that we feature in the documentation. The existing macros are workable for simple, self-contained examples, but can be hard to follow in cases where the examples use additional tiddlers. The <<.wlink TestCaseWidget>> widget displays complete, self-contained interactive examples showing the output together with a tabbed display of the constituent tiddlers that produce it: + +<> + +The payload tiddlers for a test case are specified with the <<.wlink DataWidget>> widget. Test cases are run as an independent, self-contained nested wiki in a similar way to the [[Innerwiki Plugin]], but are much more lightweight. The disadvantage is that test cases are rendered as part of the main page, and so any styling changes will leak out to the rest of the page. + +Test cases can also specify the raw HTML of the expected result which causes them to be executed as tests, with success or failure indicated by an icon: + +<> + +The easiest way to use the <<.wlink TestCaseWidget>> is by creating TestCaseTiddlers using the new CompoundTiddlers format. There are also many test cases to view in the TiddlyWiki test edition at https://tiddlywiki.com/prerelease/test.html + ! Translation improvements Improvements to the following translations: @@ -30,7 +46,7 @@ Improvements to the following translations: ! Plugin Improvements -* +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/8198">> badges to the core plugins to indicate their [[stability level|Plugin Stability]] from "deprecated", "experimental", "stable" and "legacy". These badges are shown in the plugin library and in the control panel ! Widget Improvements @@ -46,11 +62,13 @@ Improvements to the following translations: ! Hackability Improvements +* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7882">> infinite recursion handling using a custom exception * <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7966">> button to the JavaScript error popup allowing tiddlers to be saved to a local JSON file * <<.link-badge-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/8186">> nested [[Block Quotes in WikiText]] * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7933">> TiddlyWikiClassic build process * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/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 @@ -79,7 +97,8 @@ Improvements to the following translations: ! Developer Improvements -* +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8195">> issue with fakedom TW_Node inheritence +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8099">> SJCL library creating variables in global scope ! Infrastructure Improvements @@ -114,5 +133,6 @@ rmunn saqimtiaz sarna Telumire +twMat yaisog """>> diff --git a/editions/tw5.com/tiddlers/testcases/TestCaseWidget/TwoPlusTwo.tid b/editions/tw5.com/tiddlers/testcases/TestCaseWidget/TwoPlusTwo.tid new file mode 100644 index 000000000..d08260e68 --- /dev/null +++ b/editions/tw5.com/tiddlers/testcases/TestCaseWidget/TwoPlusTwo.tid @@ -0,0 +1,18 @@ +title: TestCases/TestCaseWidget/TwoPlusTwo +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec-failing]] +description: A testcase to calculate 2+2 + +title: Narrative + +This test case shows an elaborate way to calculate 2+2 involving multiple tiddlers ++ +title: Output + +The sum is <$text text={{{ [{FirstNumber}add{SecondNumber}] }}}/> ++ +title: FirstNumber +text: 2 ++ +title: SecondNumber +text: 2 From 5856bd834223b3eb008063bccacc706406ba9225 Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Wed, 29 May 2024 12:14:21 +0200 Subject: [PATCH 11/19] Fix get variable info params (#8179) * return params for every variable type * add tests for widget getVariableInfo.params * make param values different to names --- core/modules/widgets/widget.js | 2 + .../tests/test-widget-getVariableInfo.js | 95 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 editions/test/tiddlers/tests/test-widget-getVariableInfo.js diff --git a/core/modules/widgets/widget.js b/core/modules/widgets/widget.js index cb8e5e881..056529c20 100755 --- a/core/modules/widgets/widget.js +++ b/core/modules/widgets/widget.js @@ -163,6 +163,8 @@ Widget.prototype.getVariableInfo = function(name,options) { }); resultList = this.wiki.filterTiddlers(value,this.makeFakeWidgetWithVariables(variables),options.source); value = resultList[0] || ""; + } else { + params = variable.params; } return { text: value, diff --git a/editions/test/tiddlers/tests/test-widget-getVariableInfo.js b/editions/test/tiddlers/tests/test-widget-getVariableInfo.js new file mode 100644 index 000000000..7273a6dce --- /dev/null +++ b/editions/test/tiddlers/tests/test-widget-getVariableInfo.js @@ -0,0 +1,95 @@ +/*\ +title: test-widget-getVariableInfo.js +type: application/javascript +tags: [[$:/tags/test-spec]] + +Tests the wikitext rendering pipeline end-to-end. We also need tests that individually test parsers, rendertreenodes etc., but this gets us started. + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +describe("Widget module", function() { + + var widget = require("$:/core/modules/widgets/widget.js"); + + function createWidgetNode(parseTreeNode,wiki) { + return new widget.widget(parseTreeNode,{ + wiki: wiki, + document: $tw.fakeDocument + }); + } + + function parseText(text,wiki,options) { + var parser = wiki.parseText("text/vnd.tiddlywiki",text,options); + return parser ? {type: "widget", children: parser.tree} : undefined; + } + + function renderWidgetNode(widgetNode) { + $tw.fakeDocument.setSequenceNumber(0); + var wrapper = $tw.fakeDocument.createElement("div"); + widgetNode.render(wrapper,null); +// console.log(require("util").inspect(wrapper,{depth: 8})); + return wrapper; + } + + function refreshWidgetNode(widgetNode,wrapper,changes) { + var changedTiddlers = {}; + if(changes) { + $tw.utils.each(changes,function(title) { + changedTiddlers[title] = true; + }); + } + widgetNode.refresh(changedTiddlers,wrapper,null); +// console.log(require("util").inspect(wrapper,{depth: 8})); + } + + it("should make sure that getVariableInfo returns all expected parameters", function() { + var wiki = new $tw.Wiki(); + wiki.addTiddlers([ + {title: "A", text: "\\define macro(a:aa) aaa"}, + {title: "B", text: "\\function fn(f:ff) fff\n\\function x() []"}, + {title: "C", text: "\\procedure proc(p:pp) ppp"}, + {title: "D", text: "\\widget $my.widget(w:ww) www"} + ]); + var text = "\\import A B C D\n\n<$let abc=def>"; + var widgetNode = createWidgetNode(parseText(text,wiki),wiki); + // Render the widget node to the DOM + renderWidgetNode(widgetNode); + var childNode = widgetNode; + while(childNode.children.length > 0) { + childNode = childNode.children[0]; + } + + expect(childNode.getVariableInfo("macro",{allowSelfAssigned:true}).params).toEqual([{name:"a",value:"aa"}]); + + // function params + expect(childNode.getVariableInfo("fn", {allowSelfAssigned:true}).params).toEqual([{name:"f",value:"ff"}]); + // functions have a text and a value + expect(childNode.getVariableInfo("x", {allowSelfAssigned:true}).text).toBe("fff"); + expect(childNode.getVariableInfo("x", {allowSelfAssigned:true}).srcVariable.value).toBe("[]"); + + // procedures and widgets failed prior to v5.3.4 + expect(childNode.getVariableInfo("proc", {allowSelfAssigned:true}).params).toEqual([{name:"p",default:"pp"}]); + expect(childNode.getVariableInfo("$my.widget", {allowSelfAssigned:true}).params).toEqual([{name:"w",default:"ww"}]); + + // no params expected + expect(childNode.getVariableInfo("abc", {allowSelfAssigned:true})).toEqual({text:"def"}); + + // debugger; Find code in browser + + // Find values to be compated to + // console.log("macro", childNode.getVariableInfo("macro",{allowSelfAssigned:true})); + // console.log("function", childNode.getVariableInfo("fn",{allowSelfAssigned:true})); + // console.log("function x", childNode.getVariableInfo("x",{allowSelfAssigned:true})); + // console.log("procedure", childNode.getVariableInfo("proc",{allowSelfAssigned:true})); + // console.log("widget", childNode.getVariableInfo("$my.widget",{allowSelfAssigned:true})); + // console.log("let", childNode.getVariableInfo("abc",{allowSelfAssigned:true})); + }); + +}); + +})(); From cd2d4b3eb7b5a0eebd0d78c4dccdbd331a234976 Mon Sep 17 00:00:00 2001 From: yaisog Date: Wed, 29 May 2024 12:39:41 +0200 Subject: [PATCH 12/19] Clarify handling of title lists in ActionListopsWidget documentation (#8184) * Improve section on subfilter expressions * Further refinement of the info box. --- editions/tw5.com/tiddlers/widgets/ActionListopsWidget.tid | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/editions/tw5.com/tiddlers/widgets/ActionListopsWidget.tid b/editions/tw5.com/tiddlers/widgets/ActionListopsWidget.tid index 3771ab445..ec9faf68b 100644 --- a/editions/tw5.com/tiddlers/widgets/ActionListopsWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/ActionListopsWidget.tid @@ -1,6 +1,6 @@ caption: action-listops created: 20141025120850184 -modified: 20230805103548113 +modified: 20240509135041526 myfield: tags: ActionWidgets Widgets title: ActionListopsWidget @@ -35,10 +35,12 @@ The above widget will toggle the presence of the element <<.value "List Item">> Similarly, if an element is to always be removed when it is present, the `-` / `:except` [[filter run prefix|Filter Expression]] can be used. Both of the following yield the same result: ``` -<$action-listops $subfilter="-[[List Item]]"/> -<$action-listops $subfilter="+[remove[List Item]]"/> +<$action-listops $subfilter="-[[ListItem]]"/> +<$action-listops $subfilter="+[remove[ListItem]]"/> ``` +<<.infoBox """Note that the parameter of the [[remove Operator]] is a [[Title List]]. To remove one or more titles containing spaces the individual titles must be wrapped in double square brackets, usually via a soft [[Filter Parameter]]. See //Filtered List Variable Assignment// in the [[SetWidget]] documentation to learn more.""">> + Without any prefixes, the filter run output is simply [[dominantly appended|Dominant Append]] to the list. See also the [[Examples|ActionListopsWidget (Examples)]]. From 6910be795f6c578094a4fd781283bc49f83c43eb Mon Sep 17 00:00:00 2001 From: Matt Lauber Date: Wed, 29 May 2024 06:42:50 -0400 Subject: [PATCH 13/19] Add defaultHeaders flag that controls helpful default heders that can sometimes interfere with apis (#8152) * Add defaultHeaders flag that controls helpful default heders that can sometimes interfere with apis * Bump version number --- core/modules/startup/rootwidget.js | 1 + core/modules/utils/dom/http.js | 11 ++++++----- .../messages/WidgetMessage_ tm-http-request.tid | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/core/modules/startup/rootwidget.js b/core/modules/startup/rootwidget.js index 716275cda..733f1461f 100644 --- a/core/modules/startup/rootwidget.js +++ b/core/modules/startup/rootwidget.js @@ -39,6 +39,7 @@ exports.startup = function() { method: params.method, body: params.body, binary: params.binary, + defaultHeaders: params.defaultHeaders, oncompletion: params.oncompletion, onprogress: params.onprogress, bindStatus: params["bind-status"], diff --git a/core/modules/utils/dom/http.js b/core/modules/utils/dom/http.js index ddb1e17c4..bcd4ce73c 100644 --- a/core/modules/utils/dom/http.js +++ b/core/modules/utils/dom/http.js @@ -69,7 +69,7 @@ HttpClient.prototype.cancelAllHttpRequests = function() { for(var t=this.requests.length - 1; t--; t>=0) { var requestInfo = this.requests[t]; requestInfo.request.cancel(); - } + } } this.requests = []; this.updateRequestTracker(); @@ -112,6 +112,7 @@ function HttpClientRequest(options) { this.method = options.method || "GET"; this.body = options.body || ""; this.binary = options.binary || ""; + this.defaultHeaders = options.defaultHeaders || true, this.variables = options.variables; var url = options.url; $tw.utils.each(options.queryStrings,function(value,name) { @@ -231,7 +232,7 @@ Make an HTTP request. Options are: exports.httpRequest = function(options) { var type = options.type || "GET", url = options.url, - headers = options.headers || {accept: "application/json"}, + headers = options.headers || (options.defaultHeaders ? {accept: "application/json"} : {}), hasHeader = function(targetHeader) { targetHeader = targetHeader.toLowerCase(); var result = false; @@ -257,7 +258,7 @@ exports.httpRequest = function(options) { if(hasHeader("Content-Type") && ["application/x-www-form-urlencoded","multipart/form-data","text/plain"].indexOf(getHeader["Content-Type"]) === -1) { return false; } - return true; + return true; }, returnProp = options.returnProp || "responseText", request = new XMLHttpRequest(), @@ -307,10 +308,10 @@ exports.httpRequest = function(options) { request.setRequestHeader(headerTitle,header); }); } - if(data && !hasHeader("Content-Type")) { + if(data && !hasHeader("Content-Type") && options.defaultHeaders) { request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); } - if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers)) { + if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers) && options.defaultHeaders) { request.setRequestHeader("X-Requested-With","TiddlyWiki"); } // Send data 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 d2dd6eed7..880767ec0 100644 --- a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid @@ -19,6 +19,7 @@ The following parameters are used: |method |HTTP method (eg "GET", "POST") | |body |String data to be sent with the request | |binary |<<.from-version "5.3.1">> Set to "yes" to cause the response body to be treated as binary data and returned in base64 format | +|defaultHeaders |<<.from-version "5.3.4">> Defaults to true. Set to "false" to prevent default headers from being added. This can be helpful when dealing with apis that restrict header fields. | |query-* |Query string parameters with string values | |header-* |Headers with string values | |password-header-* |Headers with values taken from the password store | From 47029bac9ed8d1deac3830f46d2d93e065d5af03 Mon Sep 17 00:00:00 2001 From: lin onetwo Date: Wed, 29 May 2024 05:53:44 -0500 Subject: [PATCH 14/19] Fix/backlink binary (#8098) * fix: prevent check binary tiddler for backlink * refactor: test for backlink --- core/modules/indexers/back-indexer.js | 3 + .../test/tiddlers/tests/test-backlinks.js | 103 ++++++++++-------- 2 files changed, 61 insertions(+), 45 deletions(-) diff --git a/core/modules/indexers/back-indexer.js b/core/modules/indexers/back-indexer.js index 609d62bfc..b9daf3328 100644 --- a/core/modules/indexers/back-indexer.js +++ b/core/modules/indexers/back-indexer.js @@ -70,6 +70,9 @@ BackSubIndexer.prototype.rebuild = function() { * Get things that is being referenced in the text, e.g. tiddler names in the link syntax. */ BackSubIndexer.prototype._getTarget = function(tiddler) { + if(this.wiki.isBinaryTiddler(tiddler.fields.text)) { + return []; + } var parser = this.wiki.parseText(tiddler.fields.type, tiddler.fields.text, {}); if(parser) { return this.wiki[this.extractor](parser.tree); diff --git a/editions/test/tiddlers/tests/test-backlinks.js b/editions/test/tiddlers/tests/test-backlinks.js index 68ad18bbd..ea7c2b7b4 100644 --- a/editions/test/tiddlers/tests/test-backlinks.js +++ b/editions/test/tiddlers/tests/test-backlinks.js @@ -12,6 +12,24 @@ Tests the backlinks mechanism. "use strict"; describe('Backlinks tests', function() { + function setupWiki(wikiOptions) { + wikiOptions = wikiOptions || {}; + // Create a wiki + var wiki = new $tw.Wiki(wikiOptions); + wiki.addIndexersToWiki(); + + wiki.addTiddler({ + title: 'TestIncoming', + text: '', + }); + + wiki.addTiddler({ + title: 'TestOutgoing', + text: 'A link to [[TestIncoming]]', + }); + return wiki; + } + describe('a tiddler with no links to it', function() { var wiki = new $tw.Wiki(); @@ -25,15 +43,7 @@ describe('Backlinks tests', function() { }); describe('A tiddler added to the wiki with a link to it', function() { - var wiki = new $tw.Wiki(); - - wiki.addTiddler({ - title: 'TestIncoming', - text: ''}); - - wiki.addTiddler({ - title: 'TestOutgoing', - text: 'A link to [[TestIncoming]]'}); + var wiki = setupWiki(); it('should have a backlink', function() { expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing'); @@ -42,15 +52,7 @@ describe('Backlinks tests', function() { describe('A tiddler that has a link added to it later', function() { it('should have an additional backlink', function() { - var wiki = new $tw.Wiki(); - - wiki.addTiddler({ - title: 'TestIncoming', - text: ''}); - - wiki.addTiddler({ - title: 'TestOutgoing', - text: 'A link to [[TestIncoming]]'}); + var wiki = setupWiki(); wiki.addTiddler({ title: 'TestOutgoing2', @@ -67,15 +69,7 @@ describe('Backlinks tests', function() { }); describe('A tiddler that has a link remove from it later', function() { - var wiki = new $tw.Wiki(); - - wiki.addTiddler({ - title: 'TestIncoming', - text: ''}); - - wiki.addTiddler({ - title: 'TestOutgoing', - text: 'A link to [[TestIncoming]]'}); + var wiki = setupWiki(); it('should have one fewer backlink', function() { expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing'); @@ -89,15 +83,7 @@ describe('Backlinks tests', function() { }); describe('A tiddler linking to another that gets renamed', function() { - var wiki = new $tw.Wiki(); - - wiki.addTiddler({ - title: 'TestIncoming', - text: ''}); - - wiki.addTiddler({ - title: 'TestOutgoing', - text: 'A link to [[TestIncoming]]'}); + var wiki = setupWiki(); it('should have its name changed in the backlinks', function() { expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing'); @@ -109,15 +95,7 @@ describe('Backlinks tests', function() { }); describe('A tiddler linking to another that gets deleted', function() { - var wiki = new $tw.Wiki(); - - wiki.addTiddler({ - title: 'TestIncoming', - text: ''}); - - wiki.addTiddler({ - title: 'TestOutgoing', - text: 'A link to [[TestIncoming]]'}); + var wiki = setupWiki(); it('should be removed from backlinks', function() { expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe('TestOutgoing'); @@ -127,6 +105,41 @@ describe('Backlinks tests', function() { expect(wiki.filterTiddlers('TestIncoming +[backlinks[]]').join(',')).toBe(''); }); }); + + describe('Binary tiddlers should not be parsed', function() { + var wiki = setupWiki(); + + wiki.addTiddler({ + title: 'TestDoc.doc', + text: 'A link to [[TestOutgoing]]', + type: 'application/msword' + }); + + wiki.addTiddler({ + title: 'TestExcel.xls', + text: 'A link to [[TestOutgoing]]', + type: 'application/excel' + }); + + wiki.addTiddler({ + title: 'TestOutgoing', + text: 'Some links to [[TestDoc.doc]] and [[TestExcel.xls]].' + }); + + it('should ignore office files', function() { + expect(wiki.getIndexer("BackIndexer").subIndexers.link._getTarget(wiki.getTiddler('TestExcel.xls'))).toEqual([]); + + expect(wiki.filterTiddlers('[all[]] +[backlinks[]]').join(',')).toBe('TestOutgoing'); + + // make it tw5 tiddler + wiki.addTiddler({ + title: 'TestExcel.xls', + text: 'A link to [[TestOutgoing]]' + }); + + expect(wiki.filterTiddlers('[all[]] +[backlinks[]]').join(',')).toBe('TestOutgoing,TestExcel.xls'); + }); + }); }); })(); From 928f3fc413b97e5dee40eeb53691570b70e00197 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 29 May 2024 13:55:32 +0100 Subject: [PATCH 15/19] Revert "Add defaultHeaders flag that controls helpful default heders that can sometimes interfere with apis (#8152)" This reverts commit 6910be795f6c578094a4fd781283bc49f83c43eb. --- core/modules/startup/rootwidget.js | 1 - core/modules/utils/dom/http.js | 11 +++++------ .../messages/WidgetMessage_ tm-http-request.tid | 1 - 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/core/modules/startup/rootwidget.js b/core/modules/startup/rootwidget.js index 733f1461f..716275cda 100644 --- a/core/modules/startup/rootwidget.js +++ b/core/modules/startup/rootwidget.js @@ -39,7 +39,6 @@ exports.startup = function() { method: params.method, body: params.body, binary: params.binary, - defaultHeaders: params.defaultHeaders, oncompletion: params.oncompletion, onprogress: params.onprogress, bindStatus: params["bind-status"], diff --git a/core/modules/utils/dom/http.js b/core/modules/utils/dom/http.js index bcd4ce73c..ddb1e17c4 100644 --- a/core/modules/utils/dom/http.js +++ b/core/modules/utils/dom/http.js @@ -69,7 +69,7 @@ HttpClient.prototype.cancelAllHttpRequests = function() { for(var t=this.requests.length - 1; t--; t>=0) { var requestInfo = this.requests[t]; requestInfo.request.cancel(); - } + } } this.requests = []; this.updateRequestTracker(); @@ -112,7 +112,6 @@ function HttpClientRequest(options) { this.method = options.method || "GET"; this.body = options.body || ""; this.binary = options.binary || ""; - this.defaultHeaders = options.defaultHeaders || true, this.variables = options.variables; var url = options.url; $tw.utils.each(options.queryStrings,function(value,name) { @@ -232,7 +231,7 @@ Make an HTTP request. Options are: exports.httpRequest = function(options) { var type = options.type || "GET", url = options.url, - headers = options.headers || (options.defaultHeaders ? {accept: "application/json"} : {}), + headers = options.headers || {accept: "application/json"}, hasHeader = function(targetHeader) { targetHeader = targetHeader.toLowerCase(); var result = false; @@ -258,7 +257,7 @@ exports.httpRequest = function(options) { if(hasHeader("Content-Type") && ["application/x-www-form-urlencoded","multipart/form-data","text/plain"].indexOf(getHeader["Content-Type"]) === -1) { return false; } - return true; + return true; }, returnProp = options.returnProp || "responseText", request = new XMLHttpRequest(), @@ -308,10 +307,10 @@ exports.httpRequest = function(options) { request.setRequestHeader(headerTitle,header); }); } - if(data && !hasHeader("Content-Type") && options.defaultHeaders) { + if(data && !hasHeader("Content-Type")) { request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); } - if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers) && options.defaultHeaders) { + if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers)) { request.setRequestHeader("X-Requested-With","TiddlyWiki"); } // Send data 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 880767ec0..d2dd6eed7 100644 --- a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid @@ -19,7 +19,6 @@ The following parameters are used: |method |HTTP method (eg "GET", "POST") | |body |String data to be sent with the request | |binary |<<.from-version "5.3.1">> Set to "yes" to cause the response body to be treated as binary data and returned in base64 format | -|defaultHeaders |<<.from-version "5.3.4">> Defaults to true. Set to "false" to prevent default headers from being added. This can be helpful when dealing with apis that restrict header fields. | |query-* |Query string parameters with string values | |header-* |Headers with string values | |password-header-* |Headers with values taken from the password store | From 78fb4a2c1dbb638b50a716e2df92d115a60ce687 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 29 May 2024 15:06:33 +0100 Subject: [PATCH 16/19] Custom copy clipboard notifications (#8211) * Initial Commit * Improve plugin tests Fixes #8209 * Fix RSOE * Fix extraneous copy to clipboard at startup --- core/modules/startup/rootwidget.js | 5 ++- core/modules/startup/story.js | 18 +++++++-- core/modules/utils/dom/dom.js | 4 +- editions/test/tiddlers/tests/test-plugins.js | 38 +++++++++++-------- .../WidgetMessage_ tm-copy-to-clipboard.tid | 4 +- .../messages/WidgetMessage_ tm-permalink.tid | 4 +- .../messages/WidgetMessage_ tm-permaview.tid | 4 +- 7 files changed, 53 insertions(+), 24 deletions(-) diff --git a/core/modules/startup/rootwidget.js b/core/modules/startup/rootwidget.js index 716275cda..512fc580a 100644 --- a/core/modules/startup/rootwidget.js +++ b/core/modules/startup/rootwidget.js @@ -68,7 +68,10 @@ exports.startup = function() { }); // Install the copy-to-clipboard mechanism $tw.rootWidget.addEventListener("tm-copy-to-clipboard",function(event) { - $tw.utils.copyToClipboard(event.param); + $tw.utils.copyToClipboard(event.param,{ + successNotification: event.paramObject.successNotification, + failureNotification: event.paramObject.failureNotification + }); }); // Install the tm-focus-selector message $tw.rootWidget.addEventListener("tm-focus-selector",function(event) { diff --git a/core/modules/startup/story.js b/core/modules/startup/story.js index 734f6ae76..c58c759c3 100644 --- a/core/modules/startup/story.js +++ b/core/modules/startup/story.js @@ -93,7 +93,9 @@ exports.startup = function() { updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permalink" : "none", updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(), targetTiddler: event.param || event.tiddlerTitle, - copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permalink" : "none" + copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permalink" : "none", + successNotification: event.paramObject && event.paramObject.successNotification, + failureNotification: event.paramObject && event.paramObject.failureNotification }); }); // Listen for the tm-permaview message @@ -102,7 +104,9 @@ exports.startup = function() { updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permaview" : "none", updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(), targetTiddler: event.param || event.tiddlerTitle, - copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permaview" : "none" + copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permaview" : "none", + successNotification: event.paramObject && event.paramObject.successNotification, + failureNotification: event.paramObject && event.paramObject.failureNotification }); }); } @@ -177,6 +181,8 @@ options.updateAddressBar: "permalink", "permaview" or "no" (defaults to "permavi options.updateHistory: "yes" or "no" (defaults to "no") options.copyToClipboard: "permalink", "permaview" or "no" (defaults to "no") options.targetTiddler: optional title of target tiddler for permalink +options.successNotification: optional title of tiddler to use as the notification in case of success +options.failureNotification: optional title of tiddler to use as the notification in case of failure */ function updateLocationHash(options) { // Get the story and the history stack @@ -205,14 +211,18 @@ function updateLocationHash(options) { break; } // Copy URL to the clipboard + var url = ""; switch(options.copyToClipboard) { case "permalink": - $tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler)); + url = $tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler); break; case "permaview": - $tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList))); + url = $tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList)); break; } + if(url) { + $tw.utils.copyToClipboard(url,{successNotification: options.successNotification, failureNotification: options.failureNotification}); + } // Only change the location hash if we must, thus avoiding unnecessary onhashchange events if($tw.utils.getLocationHash() !== $tw.locationHash) { if(options.updateHistory === "yes") { diff --git a/core/modules/utils/dom/dom.js b/core/modules/utils/dom/dom.js index 338d96280..4ba037ed5 100644 --- a/core/modules/utils/dom/dom.js +++ b/core/modules/utils/dom/dom.js @@ -292,7 +292,9 @@ exports.copyToClipboard = function(text,options) { } catch (err) { } if(!options.doNotNotify) { - $tw.notifier.display(succeeded ? "$:/language/Notifications/CopiedToClipboard/Succeeded" : "$:/language/Notifications/CopiedToClipboard/Failed"); + var successNotification = options.successNotification || "$:/language/Notifications/CopiedToClipboard/Succeeded", + failureNotification = options.failureNotification || "$:/language/Notifications/CopiedToClipboard/Failed" + $tw.notifier.display(succeeded ? successNotification : failureNotification); } document.body.removeChild(textArea); }; diff --git a/editions/test/tiddlers/tests/test-plugins.js b/editions/test/tiddlers/tests/test-plugins.js index 663192a9c..8e79efe24 100644 --- a/editions/test/tiddlers/tests/test-plugins.js +++ b/editions/test/tiddlers/tests/test-plugins.js @@ -22,22 +22,30 @@ if($tw.node) { describe("every plugin should have the required standard fields", function() { var titles = Object.keys(tiddlers); $tw.utils.each(titles,function(title) { - it("plugin " + title + " should have the required standard fields",function() { - var fields = tiddlers[title]; - expect(fields["plugin-type"]).toMatch(/^(?:plugin|language|theme)$/); - switch(fields["plugin-type"]) { - case "plugin": - expect(!!(fields.name && fields.description && fields.list)).toEqual(true); - expect(fields.stability).toMatch(/^(?:STABILITY_0_DEPRECATED|STABILITY_1_EXPERIMENTAL|STABILITY_2_STABLE|STABILITY_3_LEGACY)$/); - break; - case "language": - expect(!!(fields.name && fields.description)).toEqual(true); - break; - case "theme": - expect(!!(fields.name && fields.description)).toEqual(true); - break; - } + var fields = tiddlers[title]; + it("plugin should have a recognised plugin-type field",function() { + expect(["plugin","language","theme"].indexOf(fields["plugin-type"]) !== -1).toEqual(true); }); + switch(fields["plugin-type"]) { + case "plugin": + it("plugin " + title + " should have name, description and list fields",function() { + expect(!!(fields.name && fields.description && fields.list)).toBe(true); + }); + it("plugin " + title + " should have a valid stability field",function() { + expect(["STABILITY_0_DEPRECATED","STABILITY_1_EXPERIMENTAL","STABILITY_2_STABLE","STABILITY_3_LEGACY"].indexOf(fields.stability) !== -1).toBe(true); + }); + break; + case "language": + it("language " + title + " should have name and description fields",function() { + expect(!!(fields.name && fields.description)).toEqual(true); + }); + break; + case "theme": + it("theme " + title + " should have name and description fields",function() { + expect(!!(fields.name && fields.description)).toEqual(true); + }); + break; + } }); }); }); diff --git a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-copy-to-clipboard.tid b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-copy-to-clipboard.tid index 70cf2a24a..b9c07465a 100644 --- a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-copy-to-clipboard.tid +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-copy-to-clipboard.tid @@ -1,6 +1,6 @@ caption: tm-copy-to-clipboard created: 20171215150056004 -modified: 20171215150600888 +modified: 20240523174013095 tags: Messages title: WidgetMessage: tm-copy-to-clipboard type: text/vnd.tiddlywiki @@ -11,6 +11,8 @@ It requires the following properties on the `event` object: |!Name |!Description | |param |Text to be copied to the clipboard | +|successNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation succeeds | +|failureNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation fails | This message is usually generated with the ButtonWidget. It is handled by the TiddlyWiki core. diff --git a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-permalink.tid b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-permalink.tid index d2e17952b..60d9362a2 100644 --- a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-permalink.tid +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-permalink.tid @@ -1,5 +1,5 @@ created: 20140723103751357 -modified: 20140723103751357 +modified: 20240523174013095 tags: Messages title: WidgetMessage: tm-permalink type: text/vnd.tiddlywiki @@ -12,5 +12,7 @@ The permalink message supports the following properties on the `event` object: |!Name |!Description | |param |Title of the tiddler to be permalinked | |tiddlerTitle |The current tiddler (used by default if the tiddler title isn't specified in the `param`) | +|successNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation succeeds | +|failureNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation fails | The permalink message can be generated by the ButtonWidget, and is handled by the story mechanism. diff --git a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-permaview.tid b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-permaview.tid index 648cf9a7a..e2959c38e 100644 --- a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-permaview.tid +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-permaview.tid @@ -1,5 +1,5 @@ created: 20140723103751357 -modified: 20140723103751357 +modified: 20240523174013095 tags: Messages title: WidgetMessage: tm-permaview type: text/vnd.tiddlywiki @@ -12,5 +12,7 @@ The permaview message supports the following properties on the `event` object: |!Name |!Description | |param |Title of the tiddler to be navigated within the permaview | |tiddlerTitle |The current tiddler (used by default if the tiddler title isn't specified in the `param`) | +|successNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation succeeds | +|failureNotification |<<.from-version "5.3.4">> Optional title of tiddler containing notification to be used if the operation fails | The permaview message can be generated by the ButtonWidget, and is handled by the story mechanism. From f3614c1e47e6ac5d5fec221b060699e975cd5ef6 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 29 May 2024 15:14:13 +0100 Subject: [PATCH 17/19] Simplify splash screen --- editions/tw5.com/tiddlers/system/$__SplashScreen.tid | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/editions/tw5.com/tiddlers/system/$__SplashScreen.tid b/editions/tw5.com/tiddlers/system/$__SplashScreen.tid index a4301de46..6fe66dd2f 100644 --- a/editions/tw5.com/tiddlers/system/$__SplashScreen.tid +++ b/editions/tw5.com/tiddlers/system/$__SplashScreen.tid @@ -113,7 +113,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-Please wait while {{$:/SiteTitle}} is loading +{{$:/SiteTitle}} +
+is loading
From 3af2a0ae6f95cbe76381ab1125f4a29632cf4178 Mon Sep 17 00:00:00 2001 From: lin onetwo Date: Wed, 29 May 2024 10:47:52 -0500 Subject: [PATCH 18/19] Rename default layout to "Standard Layout" (#8172) * refactor: default PageTemplate -> DefaultLayout * refactor: DefaultLayout -> StandardLayout * i18n: Default ~PageTemplate -> Standard Layout --- core/images/{default-layout.tid => standard-layout.tid} | 4 ++-- core/language/en-GB/Misc.multids | 2 +- core/ui/{PageTemplate.tid => StandardLayout.tid} | 2 +- languages/zh-Hans/Misc.multids | 4 ++-- languages/zh-Hant/Misc.multids | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) rename core/images/{default-layout.tid => standard-layout.tid} (86%) rename core/ui/{PageTemplate.tid => StandardLayout.tid} (97%) diff --git a/core/images/default-layout.tid b/core/images/standard-layout.tid similarity index 86% rename from core/images/default-layout.tid rename to core/images/standard-layout.tid index 4e5295d76..1b83375c9 100644 --- a/core/images/default-layout.tid +++ b/core/images/standard-layout.tid @@ -1,7 +1,7 @@ -title: $:/core/images/default-layout +title: $:/core/images/standard-layout tags: $:/tags/Image \parameters (size:"22pt") -> height=<> class="tc-image-default-layout tc-image-button" viewBox="0 0 128 128"> +> height=<> class="tc-image-standard-layout tc-image-button" viewBox="0 0 128 128"> \ No newline at end of file diff --git a/core/language/en-GB/Misc.multids b/core/language/en-GB/Misc.multids index b5e6e2374..d8c091375 100644 --- a/core/language/en-GB/Misc.multids +++ b/core/language/en-GB/Misc.multids @@ -70,7 +70,7 @@ No: No OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library OfficialPluginLibrary/Hint: The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team. PageTemplate/Description: the default ~TiddlyWiki layout -PageTemplate/Name: Default ~PageTemplate +PageTemplate/Name: Standard Layout PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect RecentChanges/DateFormat: DDth MMM YYYY Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field diff --git a/core/ui/PageTemplate.tid b/core/ui/StandardLayout.tid similarity index 97% rename from core/ui/PageTemplate.tid rename to core/ui/StandardLayout.tid index 7e78f1e20..9989de6df 100644 --- a/core/ui/PageTemplate.tid +++ b/core/ui/StandardLayout.tid @@ -1,7 +1,7 @@ title: $:/core/ui/PageTemplate name: {{$:/language/PageTemplate/Name}} description: {{$:/language/PageTemplate/Description}} -icon: $:/core/images/default-layout +icon: $:/core/images/standard-layout code-body: yes \whitespace trim diff --git a/languages/zh-Hans/Misc.multids b/languages/zh-Hans/Misc.multids index edd508ecd..030e30c6a 100644 --- a/languages/zh-Hans/Misc.multids +++ b/languages/zh-Hans/Misc.multids @@ -69,8 +69,8 @@ MissingTiddler/Hint: 佚失条目 "<$text text=<>/>" - 点击 {{ No: 否 OfficialPluginLibrary: ~TiddlyWiki 官方插件库 OfficialPluginLibrary/Hint: 此为在 tiddlywiki.com 的 ~TiddlyWiki 官方插件库。由核心团队维护的插件、主题和语言包。 -PageTemplate/Description: 默认的 ~Tiddlywiki 布局 -PageTemplate/Name: 默认的 ~PageTemplate +PageTemplate/Description: 默认的太微布局 +PageTemplate/Name: 标准布局 PluginReloadWarning: 请保存 {{$:/core/ui/Buttons/save-wiki}} 并刷新页面 {{$:/core/ui/Buttons/refresh}} ,使 ~JavaScript 插件的更改生效 RecentChanges/DateFormat: YYYY年0MM月0DD日 Shortcuts/Input/Accept/Hint: 接受选取的项目 diff --git a/languages/zh-Hant/Misc.multids b/languages/zh-Hant/Misc.multids index 5ddb9f1a3..3c12ca9fd 100644 --- a/languages/zh-Hant/Misc.multids +++ b/languages/zh-Hant/Misc.multids @@ -70,7 +70,7 @@ No: 否 OfficialPluginLibrary: ~TiddlyWiki 官方插件程式庫 OfficialPluginLibrary/Hint: 此為在 tiddlywiki.com 的 ~TiddlyWiki 官方插件程式庫。由核心團隊維護的插件、主題和語言包。 PageTemplate/Description: 預設的 ~Tiddlywiki 佈局 -PageTemplate/Name: 預設的 ~PageTemplate +PageTemplate/Name: 標准佈局 PluginReloadWarning: 請儲存 {{$:/core/ui/Buttons/save-wiki}} 並刷新頁面 {{$:/core/ui/Buttons/refresh}} ,使 ~JavaScript 插件的更改生效 RecentChanges/DateFormat: YYYY年0MM月0DD日 Shortcuts/Input/Accept/Hint: 接受選取的項目 From e35793bc38023a8d46b9658aefb7035d638e9ad9 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 29 May 2024 21:29:47 +0100 Subject: [PATCH 19/19] Update release note --- editions/prerelease/tiddlers/Release 5.3.4.tid | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/editions/prerelease/tiddlers/Release 5.3.4.tid b/editions/prerelease/tiddlers/Release 5.3.4.tid index b88a8feb8..82f095720 100644 --- a/editions/prerelease/tiddlers/Release 5.3.4.tid +++ b/editions/prerelease/tiddlers/Release 5.3.4.tid @@ -59,12 +59,14 @@ Improvements to the following translations: ! Usability Improvements * <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/issues/8121">> new keyboard shortcut for refreshing the page +* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/commit/f3614c1e47e6ac5d5fec221b060699e975cd5ef6">> and simplified the splash screen for tiddlywiki.com. See [[Creating a splash screen]] for instructions on creating your own splash screen ! Hackability Improvements * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7882">> infinite recursion handling using a custom exception * <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7966">> button to the JavaScript error popup allowing tiddlers to be saved to a local JSON file * <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/issues/8120">> to latest version of modern-normalize 2.0.0 +* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/8211">> [[tm-permalink|WidgetMessage: tm-permalink]], [[tm-permaview|WidgetMessage: tm-permaview]] and [[tm-copy-to-clipboard|WidgetMessage: tm-copy-to-clipboard]] messages to allow the notification text to be customised ! Bug Fixes @@ -85,6 +87,7 @@ Improvements to the following translations: * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/801ed0ea1164aab4f88547322f9d73704388143f">> crash with [[cycle Operator]] if the the step size is larger than the number of operands * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/8095">> proper DOCTYPE for the open window template * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7945">> theme font size settings to open in new window CSS +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8098">> backlink parser to prevent it parsing binary tiddlers ! Node.js Improvements @@ -99,6 +102,7 @@ Improvements to the following translations: * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8195">> issue with fakedom TW_Node inheritence * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8099">> SJCL library creating variables in global scope +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/8179">> fix `widget.getVariableInfo()` to always return a `params` property ! Infrastructure Improvements