From 2e695801b186cdadb888e6249375f19548bc058a Mon Sep 17 00:00:00 2001 From: Saq Imtiaz Date: Wed, 2 Jun 2021 14:58:30 +0200 Subject: [PATCH 01/55] Transclude widget: refresh selectively when needed (#5736) * Transclude widget: only refresh when transcluded text reference has changed, includes tests * Refactor wiki.parseTextReference so it is re-usable for getting the parser info * Re-arrange methods in wiki.js to improve diff readability --- core/modules/widgets/transclude.js | 9 +- core/modules/wiki.js | 56 +++++--- .../tiddlers/tests/test-parsetextreference.js | 123 ++++++++++++++++++ 3 files changed, 167 insertions(+), 21 deletions(-) create mode 100644 editions/test/tiddlers/tests/test-parsetextreference.js diff --git a/core/modules/widgets/transclude.js b/core/modules/widgets/transclude.js index 2acd8109b..18645cd27 100755 --- a/core/modules/widgets/transclude.js +++ b/core/modules/widgets/transclude.js @@ -60,6 +60,8 @@ TranscludeWidget.prototype.execute = function() { subTiddler: this.transcludeSubTiddler }), parseTreeNodes = parser ? parser.tree : this.parseTreeNode.children; + this.sourceText = parser ? parser.source : null; + this.parserType = parser? parser.type : null; // Set context variables for recursion detection var recursionMarker = this.makeRecursionMarker(); if(this.recursionMarker === "yes") { @@ -98,12 +100,17 @@ TranscludeWidget.prototype.makeRecursionMarker = function() { return output.join(""); }; +TranscludeWidget.prototype.parserNeedsRefresh = function() { + var parserInfo = this.wiki.getTextReferenceParserInfo(this.transcludeTitle,this.transcludeField,this.transcludeIndex,{subTiddler:this.transcludeSubTiddler}); + return (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType) +}; + /* Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering */ TranscludeWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); - if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedTiddlers[this.transcludeTitle]) { + if(($tw.utils.count(changedAttributes) > 0) || (changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) { this.refreshSelf(); return true; } else { diff --git a/core/modules/wiki.js b/core/modules/wiki.js index 072b76dbf..5401f7b8c 100755 --- a/core/modules/wiki.js +++ b/core/modules/wiki.js @@ -937,41 +937,57 @@ exports.parseTiddler = function(title,options) { }; exports.parseTextReference = function(title,field,index,options) { - var tiddler,text; - if(options.subTiddler) { - tiddler = this.getSubTiddler(title,options.subTiddler); - } else { + var tiddler, + text, + parserInfo; + if(!options.subTiddler) { tiddler = this.getTiddler(title); if(field === "text" || (!field && !index)) { this.getTiddlerText(title); // Force the tiddler to be lazily loaded return this.parseTiddler(title,options); } + } + parserInfo = this.getTextReferenceParserInfo(title,field,index,options); + if(parserInfo.sourceText !== null) { + return this.parseText(parserInfo.parserType,parserInfo.sourceText,options); + } else { + return null; + } +}; + +exports.getTextReferenceParserInfo = function(title,field,index,options) { + var tiddler, + parserInfo = { + sourceText : null, + parserType : "text/vnd.tiddlywiki" + }; + if(options.subTiddler) { + tiddler = this.getSubTiddler(title,options.subTiddler); + } else { + tiddler = this.getTiddler(title); } if(field === "text" || (!field && !index)) { if(tiddler && tiddler.fields) { - return this.parseText(tiddler.fields.type,tiddler.fields.text,options); - } else { - return null; + parserInfo.sourceText = tiddler.fields.text || ""; + if(tiddler.fields.type) { + parserInfo.parserType = tiddler.fields.type; + } } } else if(field) { if(field === "title") { - text = title; - } else { - if(!tiddler || !tiddler.hasField(field)) { - return null; - } - text = tiddler.fields[field]; + parserInfo.sourceText = title; + } else if(tiddler && tiddler.fields) { + parserInfo.sourceText = tiddler.fields[field] ? tiddler.fields[field].toString() : null; } - return this.parseText("text/vnd.tiddlywiki",text.toString(),options); } else if(index) { this.getTiddlerText(title); // Force the tiddler to be lazily loaded - text = this.extractTiddlerDataItem(tiddler,index,undefined); - if(text === undefined) { - return null; - } - return this.parseText("text/vnd.tiddlywiki",text,options); + parserInfo.sourceText = this.extractTiddlerDataItem(tiddler,index,null); } -}; + if(parserInfo.sourceText === null) { + parserInfo.parserType = null; + } + return parserInfo; +} /* Make a widget tree for a parse tree diff --git a/editions/test/tiddlers/tests/test-parsetextreference.js b/editions/test/tiddlers/tests/test-parsetextreference.js new file mode 100644 index 000000000..411f7a45b --- /dev/null +++ b/editions/test/tiddlers/tests/test-parsetextreference.js @@ -0,0 +1,123 @@ +/*\ +title: test-parsetextreference.js +type: application/javascript +tags: [[$:/tags/test-spec]] + +Tests for source attribute in parser returned from wiki.parseTextReference + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +describe("Wiki.parseTextReference tests", function() { + + // Create a wiki + var wiki = new $tw.Wiki(); + wiki.addTiddler({ + title: "TiddlerOne", + text: "The quick brown fox in $:/TiddlerTwo", + tags: ["one"], + authors: "Joe Bloggs", + modifier: "JoeBloggs", + modified: "201304152222"}); + wiki.addTiddler({ + title: "$:/TiddlerTwo", + tags: ["two"], + authors: "[[John Doe]]", + modifier: "John", + modified: "201304152211"}); + wiki.addTiddler({ + title: "Tiddler Three", + text: '{"oct":31,"nov":30,"dec":31}', + tags: ["one","two"], + type: "application/json", + modifier: "John", + modified: "201304162202"}); + wiki.addTiddler({ + title: "TiddlerFour", + text: "The quick brown fox in $:/TiddlerTwo", + tags: ["one"], + type: "text/vnd.tiddlywiki", + authors: "Joe Bloggs", + modifier: "JoeBloggs", + modified: "201304152222"}); + // Add a plugin containing some shadow tiddlers + var shadowTiddlers = { + tiddlers: { + "$:/TiddlerFive": { + title: "$:/TiddlerFive", + text: "Everything in federation", + tags: ["two"] + }, + "TiddlerSix": { + title: "TiddlerSix", + text: "Missing inaction from TiddlerOne", + filter: "[[one]] [[a a]] [subfilter{hasList!!list}]", + tags: [] + }, + "TiddlerSeventh": { + title: "TiddlerSeventh", + text: "", + list: "TiddlerOne [[Tiddler Three]] [[a fourth tiddler]] MissingTiddler", + tags: ["one"] + }, + "Tiddler8": { + title: "Tiddler8", + text: "Tidd", + tags: ["one"], + "test-field": "JoeBloggs" + } + } + }; + wiki.addTiddler({ + title: "$:/ShadowPlugin", + text: JSON.stringify(shadowTiddlers), + "plugin-type": "plugin", + type: "application/json"}); + wiki.addTiddler({ + title: "TiddlerNine", + text: "this is plain text", + type: "text/plain" + }); + + // Define a parsing shortcut for souce attribute of parser returned by wiki.parseTextReference + var parseAndGetSource = function(title,field,index,subTiddler) { + var parser = wiki.parseTextReference(title,field,index,{subTiddler: subTiddler}); + return parser ? parser.source : null; + }; + + it("should parse text references and return correct source attribute", function(){ + // Existing tiddler with a text field, no field argument specified + expect(parseAndGetSource("TiddlerOne")).toEqual("The quick brown fox in $:/TiddlerTwo"); + // Existing tiddler with a text field, field argument specified as text + expect(parseAndGetSource("TiddlerOne","text")).toEqual("The quick brown fox in $:/TiddlerTwo"); + // Existing tiddler with no text field + expect(parseAndGetSource("$:/TiddlerTwo")).toEqual(""); + // Existing tiddler, field argument specified as authors + expect(parseAndGetSource("TiddlerOne","authors")).toEqual("Joe Bloggs"); + // Non-existent tiddler, no field argument + expect(parseAndGetSource("MissingTiddler")).toEqual(null); + // Non-existent tiddler, field argument + expect(parseAndGetSource("MissingTiddler","missing-field")).toEqual(null); + // Non-existent tiddler, index specified + expect(parseAndGetSource("MissingTiddler",null,"missing-index")).toEqual(null); + // Existing tiddler with non existent field + expect(parseAndGetSource("TiddlerOne","missing-field")).toEqual(null); + // Data tiddler with index specified + expect(parseAndGetSource("Tiddler Three",null,"oct")).toEqual("31"); + // Existing tiddler with a text field, type set to vnd.tiddlywiki + expect(parseAndGetSource("TiddlerFour")).toEqual("The quick brown fox in $:/TiddlerTwo"); + // Existing subtiddler of a plugin + expect(parseAndGetSource("$:/ShadowPlugin","text",null,"Tiddler8")).toEqual("Tidd"); + // Non-existent subtiddler of a plugin + expect(parseAndGetSource("$:/ShadowPlugin","text",null,"MyMissingTiddler")).toEqual(null); + // Plain text tiddler + expect(parseAndGetSource("TiddlerNine")).toEqual(undefined); + }); + +}); + +})(); From 4f9dd50382b98239b8f611fb513e67146ab3d03a Mon Sep 17 00:00:00 2001 From: "jeremy@jermolene.com" Date: Wed, 2 Jun 2021 19:14:05 +0100 Subject: [PATCH 02/55] Revert "Transclude widget: refresh selectively when needed (#5736)" This reverts commit 2e695801b186cdadb888e6249375f19548bc058a. --- core/modules/widgets/transclude.js | 9 +- core/modules/wiki.js | 56 +++----- .../tiddlers/tests/test-parsetextreference.js | 123 ------------------ 3 files changed, 21 insertions(+), 167 deletions(-) delete mode 100644 editions/test/tiddlers/tests/test-parsetextreference.js diff --git a/core/modules/widgets/transclude.js b/core/modules/widgets/transclude.js index 18645cd27..2acd8109b 100755 --- a/core/modules/widgets/transclude.js +++ b/core/modules/widgets/transclude.js @@ -60,8 +60,6 @@ TranscludeWidget.prototype.execute = function() { subTiddler: this.transcludeSubTiddler }), parseTreeNodes = parser ? parser.tree : this.parseTreeNode.children; - this.sourceText = parser ? parser.source : null; - this.parserType = parser? parser.type : null; // Set context variables for recursion detection var recursionMarker = this.makeRecursionMarker(); if(this.recursionMarker === "yes") { @@ -100,17 +98,12 @@ TranscludeWidget.prototype.makeRecursionMarker = function() { return output.join(""); }; -TranscludeWidget.prototype.parserNeedsRefresh = function() { - var parserInfo = this.wiki.getTextReferenceParserInfo(this.transcludeTitle,this.transcludeField,this.transcludeIndex,{subTiddler:this.transcludeSubTiddler}); - return (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType) -}; - /* Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering */ TranscludeWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); - if(($tw.utils.count(changedAttributes) > 0) || (changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) { + if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedTiddlers[this.transcludeTitle]) { this.refreshSelf(); return true; } else { diff --git a/core/modules/wiki.js b/core/modules/wiki.js index 5401f7b8c..072b76dbf 100755 --- a/core/modules/wiki.js +++ b/core/modules/wiki.js @@ -937,57 +937,41 @@ exports.parseTiddler = function(title,options) { }; exports.parseTextReference = function(title,field,index,options) { - var tiddler, - text, - parserInfo; - if(!options.subTiddler) { + var tiddler,text; + if(options.subTiddler) { + tiddler = this.getSubTiddler(title,options.subTiddler); + } else { tiddler = this.getTiddler(title); if(field === "text" || (!field && !index)) { this.getTiddlerText(title); // Force the tiddler to be lazily loaded return this.parseTiddler(title,options); } - } - parserInfo = this.getTextReferenceParserInfo(title,field,index,options); - if(parserInfo.sourceText !== null) { - return this.parseText(parserInfo.parserType,parserInfo.sourceText,options); - } else { - return null; - } -}; - -exports.getTextReferenceParserInfo = function(title,field,index,options) { - var tiddler, - parserInfo = { - sourceText : null, - parserType : "text/vnd.tiddlywiki" - }; - if(options.subTiddler) { - tiddler = this.getSubTiddler(title,options.subTiddler); - } else { - tiddler = this.getTiddler(title); } if(field === "text" || (!field && !index)) { if(tiddler && tiddler.fields) { - parserInfo.sourceText = tiddler.fields.text || ""; - if(tiddler.fields.type) { - parserInfo.parserType = tiddler.fields.type; - } + return this.parseText(tiddler.fields.type,tiddler.fields.text,options); + } else { + return null; } } else if(field) { if(field === "title") { - parserInfo.sourceText = title; - } else if(tiddler && tiddler.fields) { - parserInfo.sourceText = tiddler.fields[field] ? tiddler.fields[field].toString() : null; + text = title; + } else { + if(!tiddler || !tiddler.hasField(field)) { + return null; + } + text = tiddler.fields[field]; } + return this.parseText("text/vnd.tiddlywiki",text.toString(),options); } else if(index) { this.getTiddlerText(title); // Force the tiddler to be lazily loaded - parserInfo.sourceText = this.extractTiddlerDataItem(tiddler,index,null); + text = this.extractTiddlerDataItem(tiddler,index,undefined); + if(text === undefined) { + return null; + } + return this.parseText("text/vnd.tiddlywiki",text,options); } - if(parserInfo.sourceText === null) { - parserInfo.parserType = null; - } - return parserInfo; -} +}; /* Make a widget tree for a parse tree diff --git a/editions/test/tiddlers/tests/test-parsetextreference.js b/editions/test/tiddlers/tests/test-parsetextreference.js deleted file mode 100644 index 411f7a45b..000000000 --- a/editions/test/tiddlers/tests/test-parsetextreference.js +++ /dev/null @@ -1,123 +0,0 @@ -/*\ -title: test-parsetextreference.js -type: application/javascript -tags: [[$:/tags/test-spec]] - -Tests for source attribute in parser returned from wiki.parseTextReference - -\*/ -(function(){ - -/*jslint node: true, browser: true */ -/*global $tw: false */ -"use strict"; - -describe("Wiki.parseTextReference tests", function() { - - // Create a wiki - var wiki = new $tw.Wiki(); - wiki.addTiddler({ - title: "TiddlerOne", - text: "The quick brown fox in $:/TiddlerTwo", - tags: ["one"], - authors: "Joe Bloggs", - modifier: "JoeBloggs", - modified: "201304152222"}); - wiki.addTiddler({ - title: "$:/TiddlerTwo", - tags: ["two"], - authors: "[[John Doe]]", - modifier: "John", - modified: "201304152211"}); - wiki.addTiddler({ - title: "Tiddler Three", - text: '{"oct":31,"nov":30,"dec":31}', - tags: ["one","two"], - type: "application/json", - modifier: "John", - modified: "201304162202"}); - wiki.addTiddler({ - title: "TiddlerFour", - text: "The quick brown fox in $:/TiddlerTwo", - tags: ["one"], - type: "text/vnd.tiddlywiki", - authors: "Joe Bloggs", - modifier: "JoeBloggs", - modified: "201304152222"}); - // Add a plugin containing some shadow tiddlers - var shadowTiddlers = { - tiddlers: { - "$:/TiddlerFive": { - title: "$:/TiddlerFive", - text: "Everything in federation", - tags: ["two"] - }, - "TiddlerSix": { - title: "TiddlerSix", - text: "Missing inaction from TiddlerOne", - filter: "[[one]] [[a a]] [subfilter{hasList!!list}]", - tags: [] - }, - "TiddlerSeventh": { - title: "TiddlerSeventh", - text: "", - list: "TiddlerOne [[Tiddler Three]] [[a fourth tiddler]] MissingTiddler", - tags: ["one"] - }, - "Tiddler8": { - title: "Tiddler8", - text: "Tidd", - tags: ["one"], - "test-field": "JoeBloggs" - } - } - }; - wiki.addTiddler({ - title: "$:/ShadowPlugin", - text: JSON.stringify(shadowTiddlers), - "plugin-type": "plugin", - type: "application/json"}); - wiki.addTiddler({ - title: "TiddlerNine", - text: "this is plain text", - type: "text/plain" - }); - - // Define a parsing shortcut for souce attribute of parser returned by wiki.parseTextReference - var parseAndGetSource = function(title,field,index,subTiddler) { - var parser = wiki.parseTextReference(title,field,index,{subTiddler: subTiddler}); - return parser ? parser.source : null; - }; - - it("should parse text references and return correct source attribute", function(){ - // Existing tiddler with a text field, no field argument specified - expect(parseAndGetSource("TiddlerOne")).toEqual("The quick brown fox in $:/TiddlerTwo"); - // Existing tiddler with a text field, field argument specified as text - expect(parseAndGetSource("TiddlerOne","text")).toEqual("The quick brown fox in $:/TiddlerTwo"); - // Existing tiddler with no text field - expect(parseAndGetSource("$:/TiddlerTwo")).toEqual(""); - // Existing tiddler, field argument specified as authors - expect(parseAndGetSource("TiddlerOne","authors")).toEqual("Joe Bloggs"); - // Non-existent tiddler, no field argument - expect(parseAndGetSource("MissingTiddler")).toEqual(null); - // Non-existent tiddler, field argument - expect(parseAndGetSource("MissingTiddler","missing-field")).toEqual(null); - // Non-existent tiddler, index specified - expect(parseAndGetSource("MissingTiddler",null,"missing-index")).toEqual(null); - // Existing tiddler with non existent field - expect(parseAndGetSource("TiddlerOne","missing-field")).toEqual(null); - // Data tiddler with index specified - expect(parseAndGetSource("Tiddler Three",null,"oct")).toEqual("31"); - // Existing tiddler with a text field, type set to vnd.tiddlywiki - expect(parseAndGetSource("TiddlerFour")).toEqual("The quick brown fox in $:/TiddlerTwo"); - // Existing subtiddler of a plugin - expect(parseAndGetSource("$:/ShadowPlugin","text",null,"Tiddler8")).toEqual("Tidd"); - // Non-existent subtiddler of a plugin - expect(parseAndGetSource("$:/ShadowPlugin","text",null,"MyMissingTiddler")).toEqual(null); - // Plain text tiddler - expect(parseAndGetSource("TiddlerNine")).toEqual(undefined); - }); - -}); - -})(); From 753bf8fe62189f551c4b7087c55b87a9bc3e481d Mon Sep 17 00:00:00 2001 From: "jeremy@jermolene.com" Date: Wed, 2 Jun 2021 21:45:06 +0100 Subject: [PATCH 03/55] Revert "Revert "Transclude widget: refresh selectively when needed (#5736)"" This reverts commit 4f9dd50382b98239b8f611fb513e67146ab3d03a. --- core/modules/widgets/transclude.js | 9 +- core/modules/wiki.js | 56 +++++--- .../tiddlers/tests/test-parsetextreference.js | 123 ++++++++++++++++++ 3 files changed, 167 insertions(+), 21 deletions(-) create mode 100644 editions/test/tiddlers/tests/test-parsetextreference.js diff --git a/core/modules/widgets/transclude.js b/core/modules/widgets/transclude.js index 2acd8109b..18645cd27 100755 --- a/core/modules/widgets/transclude.js +++ b/core/modules/widgets/transclude.js @@ -60,6 +60,8 @@ TranscludeWidget.prototype.execute = function() { subTiddler: this.transcludeSubTiddler }), parseTreeNodes = parser ? parser.tree : this.parseTreeNode.children; + this.sourceText = parser ? parser.source : null; + this.parserType = parser? parser.type : null; // Set context variables for recursion detection var recursionMarker = this.makeRecursionMarker(); if(this.recursionMarker === "yes") { @@ -98,12 +100,17 @@ TranscludeWidget.prototype.makeRecursionMarker = function() { return output.join(""); }; +TranscludeWidget.prototype.parserNeedsRefresh = function() { + var parserInfo = this.wiki.getTextReferenceParserInfo(this.transcludeTitle,this.transcludeField,this.transcludeIndex,{subTiddler:this.transcludeSubTiddler}); + return (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType) +}; + /* Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering */ TranscludeWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); - if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedTiddlers[this.transcludeTitle]) { + if(($tw.utils.count(changedAttributes) > 0) || (changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) { this.refreshSelf(); return true; } else { diff --git a/core/modules/wiki.js b/core/modules/wiki.js index 072b76dbf..5401f7b8c 100755 --- a/core/modules/wiki.js +++ b/core/modules/wiki.js @@ -937,41 +937,57 @@ exports.parseTiddler = function(title,options) { }; exports.parseTextReference = function(title,field,index,options) { - var tiddler,text; - if(options.subTiddler) { - tiddler = this.getSubTiddler(title,options.subTiddler); - } else { + var tiddler, + text, + parserInfo; + if(!options.subTiddler) { tiddler = this.getTiddler(title); if(field === "text" || (!field && !index)) { this.getTiddlerText(title); // Force the tiddler to be lazily loaded return this.parseTiddler(title,options); } + } + parserInfo = this.getTextReferenceParserInfo(title,field,index,options); + if(parserInfo.sourceText !== null) { + return this.parseText(parserInfo.parserType,parserInfo.sourceText,options); + } else { + return null; + } +}; + +exports.getTextReferenceParserInfo = function(title,field,index,options) { + var tiddler, + parserInfo = { + sourceText : null, + parserType : "text/vnd.tiddlywiki" + }; + if(options.subTiddler) { + tiddler = this.getSubTiddler(title,options.subTiddler); + } else { + tiddler = this.getTiddler(title); } if(field === "text" || (!field && !index)) { if(tiddler && tiddler.fields) { - return this.parseText(tiddler.fields.type,tiddler.fields.text,options); - } else { - return null; + parserInfo.sourceText = tiddler.fields.text || ""; + if(tiddler.fields.type) { + parserInfo.parserType = tiddler.fields.type; + } } } else if(field) { if(field === "title") { - text = title; - } else { - if(!tiddler || !tiddler.hasField(field)) { - return null; - } - text = tiddler.fields[field]; + parserInfo.sourceText = title; + } else if(tiddler && tiddler.fields) { + parserInfo.sourceText = tiddler.fields[field] ? tiddler.fields[field].toString() : null; } - return this.parseText("text/vnd.tiddlywiki",text.toString(),options); } else if(index) { this.getTiddlerText(title); // Force the tiddler to be lazily loaded - text = this.extractTiddlerDataItem(tiddler,index,undefined); - if(text === undefined) { - return null; - } - return this.parseText("text/vnd.tiddlywiki",text,options); + parserInfo.sourceText = this.extractTiddlerDataItem(tiddler,index,null); } -}; + if(parserInfo.sourceText === null) { + parserInfo.parserType = null; + } + return parserInfo; +} /* Make a widget tree for a parse tree diff --git a/editions/test/tiddlers/tests/test-parsetextreference.js b/editions/test/tiddlers/tests/test-parsetextreference.js new file mode 100644 index 000000000..411f7a45b --- /dev/null +++ b/editions/test/tiddlers/tests/test-parsetextreference.js @@ -0,0 +1,123 @@ +/*\ +title: test-parsetextreference.js +type: application/javascript +tags: [[$:/tags/test-spec]] + +Tests for source attribute in parser returned from wiki.parseTextReference + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +describe("Wiki.parseTextReference tests", function() { + + // Create a wiki + var wiki = new $tw.Wiki(); + wiki.addTiddler({ + title: "TiddlerOne", + text: "The quick brown fox in $:/TiddlerTwo", + tags: ["one"], + authors: "Joe Bloggs", + modifier: "JoeBloggs", + modified: "201304152222"}); + wiki.addTiddler({ + title: "$:/TiddlerTwo", + tags: ["two"], + authors: "[[John Doe]]", + modifier: "John", + modified: "201304152211"}); + wiki.addTiddler({ + title: "Tiddler Three", + text: '{"oct":31,"nov":30,"dec":31}', + tags: ["one","two"], + type: "application/json", + modifier: "John", + modified: "201304162202"}); + wiki.addTiddler({ + title: "TiddlerFour", + text: "The quick brown fox in $:/TiddlerTwo", + tags: ["one"], + type: "text/vnd.tiddlywiki", + authors: "Joe Bloggs", + modifier: "JoeBloggs", + modified: "201304152222"}); + // Add a plugin containing some shadow tiddlers + var shadowTiddlers = { + tiddlers: { + "$:/TiddlerFive": { + title: "$:/TiddlerFive", + text: "Everything in federation", + tags: ["two"] + }, + "TiddlerSix": { + title: "TiddlerSix", + text: "Missing inaction from TiddlerOne", + filter: "[[one]] [[a a]] [subfilter{hasList!!list}]", + tags: [] + }, + "TiddlerSeventh": { + title: "TiddlerSeventh", + text: "", + list: "TiddlerOne [[Tiddler Three]] [[a fourth tiddler]] MissingTiddler", + tags: ["one"] + }, + "Tiddler8": { + title: "Tiddler8", + text: "Tidd", + tags: ["one"], + "test-field": "JoeBloggs" + } + } + }; + wiki.addTiddler({ + title: "$:/ShadowPlugin", + text: JSON.stringify(shadowTiddlers), + "plugin-type": "plugin", + type: "application/json"}); + wiki.addTiddler({ + title: "TiddlerNine", + text: "this is plain text", + type: "text/plain" + }); + + // Define a parsing shortcut for souce attribute of parser returned by wiki.parseTextReference + var parseAndGetSource = function(title,field,index,subTiddler) { + var parser = wiki.parseTextReference(title,field,index,{subTiddler: subTiddler}); + return parser ? parser.source : null; + }; + + it("should parse text references and return correct source attribute", function(){ + // Existing tiddler with a text field, no field argument specified + expect(parseAndGetSource("TiddlerOne")).toEqual("The quick brown fox in $:/TiddlerTwo"); + // Existing tiddler with a text field, field argument specified as text + expect(parseAndGetSource("TiddlerOne","text")).toEqual("The quick brown fox in $:/TiddlerTwo"); + // Existing tiddler with no text field + expect(parseAndGetSource("$:/TiddlerTwo")).toEqual(""); + // Existing tiddler, field argument specified as authors + expect(parseAndGetSource("TiddlerOne","authors")).toEqual("Joe Bloggs"); + // Non-existent tiddler, no field argument + expect(parseAndGetSource("MissingTiddler")).toEqual(null); + // Non-existent tiddler, field argument + expect(parseAndGetSource("MissingTiddler","missing-field")).toEqual(null); + // Non-existent tiddler, index specified + expect(parseAndGetSource("MissingTiddler",null,"missing-index")).toEqual(null); + // Existing tiddler with non existent field + expect(parseAndGetSource("TiddlerOne","missing-field")).toEqual(null); + // Data tiddler with index specified + expect(parseAndGetSource("Tiddler Three",null,"oct")).toEqual("31"); + // Existing tiddler with a text field, type set to vnd.tiddlywiki + expect(parseAndGetSource("TiddlerFour")).toEqual("The quick brown fox in $:/TiddlerTwo"); + // Existing subtiddler of a plugin + expect(parseAndGetSource("$:/ShadowPlugin","text",null,"Tiddler8")).toEqual("Tidd"); + // Non-existent subtiddler of a plugin + expect(parseAndGetSource("$:/ShadowPlugin","text",null,"MyMissingTiddler")).toEqual(null); + // Plain text tiddler + expect(parseAndGetSource("TiddlerNine")).toEqual(undefined); + }); + +}); + +})(); From 056e6541a1e4e96b8ab03def25300a1891311e37 Mon Sep 17 00:00:00 2001 From: "jeremy@jermolene.com" Date: Wed, 2 Jun 2021 21:47:28 +0100 Subject: [PATCH 04/55] Revert 582b156d5f2b9b8b92f9289aa1288e1edb637450: Refresh non-action widgets before invocation --- core/modules/widgets/widget.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/modules/widgets/widget.js b/core/modules/widgets/widget.js index cf73cbca6..ce0102069 100755 --- a/core/modules/widgets/widget.js +++ b/core/modules/widgets/widget.js @@ -569,10 +569,9 @@ Widget.prototype.invokeActions = function(triggeringWidget,event) { // For each child widget for(var t=0; t Date: Fri, 4 Jun 2021 17:59:45 +0200 Subject: [PATCH 05/55] Make the insert- and remove-animations of storyviews work in new windows (#5755) * Make classic storyview work in new windows, too * Make pop storyview work in new windows, too * Make zoomin storyview insert and remove animation work in new windows, too --- core/modules/storyviews/classic.js | 6 +++--- core/modules/storyviews/pop.js | 4 ++-- core/modules/storyviews/zoomin.js | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/modules/storyviews/classic.js b/core/modules/storyviews/classic.js index fe6925b99..f33641cab 100644 --- a/core/modules/storyviews/classic.js +++ b/core/modules/storyviews/classic.js @@ -43,7 +43,7 @@ ClassicStoryView.prototype.insert = function(widget) { if(duration) { var targetElement = widget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(!(targetElement instanceof Element)) { + if(targetElement.nodeType === Node.TEXT_NODE) { return; } // Get the current height of the tiddler @@ -83,7 +83,7 @@ ClassicStoryView.prototype.remove = function(widget) { widget.removeChildDomNodes(); }; // Abandon if the list entry isn't a DOM element (it might be a text node) - if(!(targetElement instanceof Element)) { + if(targetElement.nodeType === Node.TEXT_NODE) { removeElement(); return; } @@ -118,4 +118,4 @@ ClassicStoryView.prototype.remove = function(widget) { exports.classic = ClassicStoryView; -})(); \ No newline at end of file +})(); diff --git a/core/modules/storyviews/pop.js b/core/modules/storyviews/pop.js index d0592cf18..6e4c54874 100644 --- a/core/modules/storyviews/pop.js +++ b/core/modules/storyviews/pop.js @@ -35,7 +35,7 @@ PopStoryView.prototype.insert = function(widget) { var targetElement = widget.findFirstDomNode(), duration = $tw.utils.getAnimationDuration(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(!(targetElement instanceof Element)) { + if(targetElement.nodeType === Node.TEXT_NODE) { return; } // Reset once the transition is over @@ -77,7 +77,7 @@ PopStoryView.prototype.remove = function(widget) { } }; // Abandon if the list entry isn't a DOM element (it might be a text node) - if(!(targetElement instanceof Element)) { + if(targetElement.nodeType === Node.TEXT_NODE) { removeElement(); return; } diff --git a/core/modules/storyviews/zoomin.js b/core/modules/storyviews/zoomin.js index be65b8e3a..a1b2e79e2 100644 --- a/core/modules/storyviews/zoomin.js +++ b/core/modules/storyviews/zoomin.js @@ -130,7 +130,7 @@ function findTitleDomNode(widget,targetClass) { ZoominListView.prototype.insert = function(widget) { var targetElement = widget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(!(targetElement instanceof Element)) { + if(targetElement.nodeType === Node.TEXT_NODE) { return; } // Make the newly inserted node position absolute and hidden @@ -147,7 +147,7 @@ ZoominListView.prototype.remove = function(widget) { widget.removeChildDomNodes(); }; // Abandon if the list entry isn't a DOM element (it might be a text node) - if(!(targetElement instanceof Element)) { + if(targetElement.nodeType === Node.TEXT_NODE) { removeElement(); return; } From afa4ea3d03b28c03d3eebbb2fa89bbabf8b4ab19 Mon Sep 17 00:00:00 2001 From: Simon Huber Date: Sun, 6 Jun 2021 11:47:19 +0200 Subject: [PATCH 06/55] Make navigation in new windows work for storyviews (#5759) --- core/modules/storyviews/classic.js | 6 +++--- core/modules/storyviews/pop.js | 6 +++--- core/modules/storyviews/zoomin.js | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/modules/storyviews/classic.js b/core/modules/storyviews/classic.js index f33641cab..653a7e437 100644 --- a/core/modules/storyviews/classic.js +++ b/core/modules/storyviews/classic.js @@ -27,7 +27,7 @@ ClassicStoryView.prototype.navigateTo = function(historyInfo) { var listItemWidget = this.listWidget.children[listElementIndex], targetElement = listItemWidget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(!(targetElement instanceof Element)) { + if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { return; } if(duration) { @@ -43,7 +43,7 @@ ClassicStoryView.prototype.insert = function(widget) { if(duration) { var targetElement = widget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement.nodeType === Node.TEXT_NODE) { + if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { return; } // Get the current height of the tiddler @@ -83,7 +83,7 @@ ClassicStoryView.prototype.remove = function(widget) { widget.removeChildDomNodes(); }; // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement.nodeType === Node.TEXT_NODE) { + if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { removeElement(); return; } diff --git a/core/modules/storyviews/pop.js b/core/modules/storyviews/pop.js index 6e4c54874..bb66606c5 100644 --- a/core/modules/storyviews/pop.js +++ b/core/modules/storyviews/pop.js @@ -24,7 +24,7 @@ PopStoryView.prototype.navigateTo = function(historyInfo) { var listItemWidget = this.listWidget.children[listElementIndex], targetElement = listItemWidget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(!(targetElement instanceof Element)) { + if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { return; } // Scroll the node into view @@ -35,7 +35,7 @@ PopStoryView.prototype.insert = function(widget) { var targetElement = widget.findFirstDomNode(), duration = $tw.utils.getAnimationDuration(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement.nodeType === Node.TEXT_NODE) { + if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { return; } // Reset once the transition is over @@ -77,7 +77,7 @@ PopStoryView.prototype.remove = function(widget) { } }; // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement.nodeType === Node.TEXT_NODE) { + if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { removeElement(); return; } diff --git a/core/modules/storyviews/zoomin.js b/core/modules/storyviews/zoomin.js index a1b2e79e2..9ece5823f 100644 --- a/core/modules/storyviews/zoomin.js +++ b/core/modules/storyviews/zoomin.js @@ -48,7 +48,7 @@ ZoominListView.prototype.navigateTo = function(historyInfo) { var listItemWidget = this.listWidget.children[listElementIndex], targetElement = listItemWidget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(!(targetElement instanceof Element)) { + if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { return; } // Make the new tiddler be position absolute and visible so that we can measure it @@ -130,7 +130,7 @@ function findTitleDomNode(widget,targetClass) { ZoominListView.prototype.insert = function(widget) { var targetElement = widget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement.nodeType === Node.TEXT_NODE) { + if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { return; } // Make the newly inserted node position absolute and hidden @@ -147,7 +147,7 @@ ZoominListView.prototype.remove = function(widget) { widget.removeChildDomNodes(); }; // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement.nodeType === Node.TEXT_NODE) { + if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { removeElement(); return; } From 2f1806ab6a2ebeb814c2034abff6c2f9d3f8b289 Mon Sep 17 00:00:00 2001 From: Simon Huber Date: Sun, 6 Jun 2021 12:03:08 +0200 Subject: [PATCH 07/55] Keyboard widget: don't refresh when class changes (#5758) --- core/modules/widgets/keyboard.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/core/modules/widgets/keyboard.js b/core/modules/widgets/keyboard.js index 035e4e351..bd980121b 100644 --- a/core/modules/widgets/keyboard.js +++ b/core/modules/widgets/keyboard.js @@ -40,9 +40,8 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) { // Create element var domNode = this.document.createElement(tag); // Assign classes - var classes = (this["class"] || "").split(" "); - classes.push("tc-keyboard"); - domNode.className = classes.join(" "); + this.domNode = domNode; + this.assignDomNodeClasses(); // Add a keyboard event handler $tw.utils.addEventListeners(domNode,[ {name: "keydown", handlerObject: this, handlerMethod: "handleChangeEvent"} @@ -90,7 +89,6 @@ KeyboardWidget.prototype.execute = function() { this.key = this.getAttribute("key",""); this.tag = this.getAttribute("tag",""); this.keyInfoArray = $tw.keyboardManager.parseKeyDescriptors(this.key); - this["class"] = this.getAttribute("class",""); if(this.key.substr(0,2) === "((" && this.key.substr(-2,2) === "))") { this.shortcutTiddlers = []; var name = this.key.substring(2,this.key.length -2); @@ -102,14 +100,22 @@ KeyboardWidget.prototype.execute = function() { this.makeChildWidgets(); }; +KeyboardWidget.prototype.assignDomNodeClasses = function() { + var classes = this.getAttribute("class","").split(" "); + classes.push("tc-keyboard"); + this.domNode.className = classes.join(" "); +}; + /* Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering */ KeyboardWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); - if(changedAttributes.message || changedAttributes.param || changedAttributes.key || changedAttributes["class"] || changedAttributes.tag) { + if(changedAttributes.message || changedAttributes.param || changedAttributes.key || changedAttributes.tag) { this.refreshSelf(); return true; + } else if(changedAttributes["class"]) { + this.assignDomNodeClasses(); } // Update the keyInfoArray if one of its shortcut-config-tiddlers has changed if(this.shortcutTiddlers && $tw.utils.hopArray(changedTiddlers,this.shortcutTiddlers)) { From c18b7527a761bd7da6c603444dd029cfcca55cdc Mon Sep 17 00:00:00 2001 From: Simon Huber Date: Sun, 6 Jun 2021 13:42:28 +0200 Subject: [PATCH 08/55] Fix #5760 - tm-focus-selector doesn't work in new windows (#5766) * Pass the original event to invokeActionString * Update rootwidget.js --- core/modules/keyboard.js | 2 +- core/modules/startup/rootwidget.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/modules/keyboard.js b/core/modules/keyboard.js index 1ae9ba482..1d818a25f 100644 --- a/core/modules/keyboard.js +++ b/core/modules/keyboard.js @@ -324,7 +324,7 @@ KeyboardManager.prototype.handleKeydownEvent = function(event) { if(key !== undefined) { event.preventDefault(); event.stopPropagation(); - $tw.rootWidget.invokeActionString(action,$tw.rootWidget); + $tw.rootWidget.invokeActionString(action,$tw.rootWidget,event); return true; } return false; diff --git a/core/modules/startup/rootwidget.js b/core/modules/startup/rootwidget.js index 6486cf6a2..8f119f02a 100644 --- a/core/modules/startup/rootwidget.js +++ b/core/modules/startup/rootwidget.js @@ -40,9 +40,10 @@ exports.startup = function() { // Install the tm-focus-selector message $tw.rootWidget.addEventListener("tm-focus-selector",function(event) { var selector = event.param || "", - element; + element, + doc = event.event ? event.event.target.ownerDocument : document; try { - element = document.querySelector(selector); + element = doc.querySelector(selector); } catch(e) { console.log("Error in selector: ",selector) } From 219beb13cc77bae54637e6d0d737153c9371da40 Mon Sep 17 00:00:00 2001 From: Simon Huber Date: Wed, 9 Jun 2021 11:18:15 +0200 Subject: [PATCH 09/55] Add test to storyviews if targetElement is null (#5767) * Update classic.js * Update pop.js * Update zoomin.js * simplify test in classic.js * simplify test in pop.js * simplify test in zoomin.js --- core/modules/storyviews/classic.js | 6 +++--- core/modules/storyviews/pop.js | 6 +++--- core/modules/storyviews/zoomin.js | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/modules/storyviews/classic.js b/core/modules/storyviews/classic.js index 653a7e437..c2848c435 100644 --- a/core/modules/storyviews/classic.js +++ b/core/modules/storyviews/classic.js @@ -27,7 +27,7 @@ ClassicStoryView.prototype.navigateTo = function(historyInfo) { var listItemWidget = this.listWidget.children[listElementIndex], targetElement = listItemWidget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { + if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { return; } if(duration) { @@ -43,7 +43,7 @@ ClassicStoryView.prototype.insert = function(widget) { if(duration) { var targetElement = widget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { + if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { return; } // Get the current height of the tiddler @@ -83,7 +83,7 @@ ClassicStoryView.prototype.remove = function(widget) { widget.removeChildDomNodes(); }; // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { + if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { removeElement(); return; } diff --git a/core/modules/storyviews/pop.js b/core/modules/storyviews/pop.js index bb66606c5..e2634e3d5 100644 --- a/core/modules/storyviews/pop.js +++ b/core/modules/storyviews/pop.js @@ -24,7 +24,7 @@ PopStoryView.prototype.navigateTo = function(historyInfo) { var listItemWidget = this.listWidget.children[listElementIndex], targetElement = listItemWidget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { + if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { return; } // Scroll the node into view @@ -35,7 +35,7 @@ PopStoryView.prototype.insert = function(widget) { var targetElement = widget.findFirstDomNode(), duration = $tw.utils.getAnimationDuration(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { + if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { return; } // Reset once the transition is over @@ -77,7 +77,7 @@ PopStoryView.prototype.remove = function(widget) { } }; // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { + if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { removeElement(); return; } diff --git a/core/modules/storyviews/zoomin.js b/core/modules/storyviews/zoomin.js index 9ece5823f..b2796e953 100644 --- a/core/modules/storyviews/zoomin.js +++ b/core/modules/storyviews/zoomin.js @@ -48,7 +48,7 @@ ZoominListView.prototype.navigateTo = function(historyInfo) { var listItemWidget = this.listWidget.children[listElementIndex], targetElement = listItemWidget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { + if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { return; } // Make the new tiddler be position absolute and visible so that we can measure it @@ -130,7 +130,7 @@ function findTitleDomNode(widget,targetClass) { ZoominListView.prototype.insert = function(widget) { var targetElement = widget.findFirstDomNode(); // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { + if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { return; } // Make the newly inserted node position absolute and hidden @@ -147,7 +147,7 @@ ZoominListView.prototype.remove = function(widget) { widget.removeChildDomNodes(); }; // Abandon if the list entry isn't a DOM element (it might be a text node) - if(targetElement === undefined || targetElement.nodeType === Node.TEXT_NODE) { + if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { removeElement(); return; } From 6dd1887f0bb79e5abb8fd4d7257ae830592b55bf Mon Sep 17 00:00:00 2001 From: Simon Huber Date: Fri, 11 Jun 2021 17:56:06 +0200 Subject: [PATCH 10/55] Use event.event.view.confirm for confirmation messages in navigator.js and action-confirm.js (#5776) --- core/modules/widgets/action-confirm.js | 7 ++++--- core/modules/widgets/navigator.js | 18 +++++++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/core/modules/widgets/action-confirm.js b/core/modules/widgets/action-confirm.js index eb762f050..5ad798663 100644 --- a/core/modules/widgets/action-confirm.js +++ b/core/modules/widgets/action-confirm.js @@ -58,9 +58,10 @@ Invoke the action associated with this widget */ ConfirmWidget.prototype.invokeAction = function(triggeringWidget,event) { var invokeActions = true, - handled = true; + handled = true, + win = event.event && event.event.view ? event.event.view : window; if(this.prompt) { - invokeActions = confirm(this.message); + invokeActions = win.confirm(this.message); } if(invokeActions) { handled = this.invokeActions(triggeringWidget,event); @@ -74,4 +75,4 @@ ConfirmWidget.prototype.allowActionPropagation = function() { exports["action-confirm"] = ConfirmWidget; -})(); \ No newline at end of file +})(); diff --git a/core/modules/widgets/navigator.js b/core/modules/widgets/navigator.js index 9df76acc4..6991d26e2 100755 --- a/core/modules/widgets/navigator.js +++ b/core/modules/widgets/navigator.js @@ -183,7 +183,8 @@ NavigatorWidget.prototype.handleCloseOtherTiddlersEvent = function(event) { // Place a tiddler in edit mode NavigatorWidget.prototype.handleEditTiddlerEvent = function(event) { - var editTiddler = $tw.hooks.invokeHook("th-editing-tiddler",event); + var editTiddler = $tw.hooks.invokeHook("th-editing-tiddler",event), + win = event.event && event.event.view ? event.event.view : window; if(!editTiddler) { return false; } @@ -192,7 +193,7 @@ NavigatorWidget.prototype.handleEditTiddlerEvent = function(event) { return self.wiki.isShadowTiddler(title) && !self.wiki.tiddlerExists(title); } function confirmEditShadow(title) { - return confirm($tw.language.getString( + return win.confirm($tw.language.getString( "ConfirmEditShadowTiddler", {variables: {title: title} @@ -225,7 +226,8 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) { storyList = this.getStoryList(), originalTitle = tiddler ? tiddler.fields["draft.of"] : "", originalTiddler = originalTitle ? this.wiki.getTiddler(originalTitle) : undefined, - confirmationTitle; + confirmationTitle, + win = event.event && event.event.view ? event.event.view : window; if(!tiddler) { return false; } @@ -238,7 +240,7 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) { confirmationTitle = title; } // Seek confirmation - if((this.wiki.getTiddler(originalTitle) || (tiddler.fields.text || "") !== "") && !confirm($tw.language.getString( + if((this.wiki.getTiddler(originalTitle) || (tiddler.fields.text || "") !== "") && !win.confirm($tw.language.getString( "ConfirmDeleteTiddler", {variables: {title: confirmationTitle} @@ -304,7 +306,8 @@ NavigatorWidget.prototype.generateDraftTitle = function(title) { NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) { var title = event.param || event.tiddlerTitle, tiddler = this.wiki.getTiddler(title), - storyList = this.getStoryList(); + storyList = this.getStoryList(), + win = event.event && event.event.view ? event.event.view : window; // Replace the original tiddler with the draft if(tiddler) { var draftTitle = (tiddler.fields["draft.title"] || "").trim(), @@ -313,7 +316,7 @@ NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) { var isRename = draftOf !== draftTitle, isConfirmed = true; if(isRename && this.wiki.tiddlerExists(draftTitle)) { - isConfirmed = confirm($tw.language.getString( + isConfirmed = win.confirm($tw.language.getString( "ConfirmOverwriteTiddler", {variables: {title: draftTitle} @@ -362,6 +365,7 @@ NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) { // Take a tiddler out of edit mode without saving the changes NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) { event = $tw.hooks.invokeHook("th-cancelling-tiddler", event); + var win = event.event && event.event.view ? event.event.view : window; // Flip the specified tiddler from draft back to the original var draftTitle = event.param || event.tiddlerTitle, draftTiddler = this.wiki.getTiddler(draftTitle), @@ -372,7 +376,7 @@ NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) { originalTiddler = this.wiki.getTiddler(originalTitle), storyList = this.getStoryList(); if(this.wiki.isDraftModified(draftTitle)) { - isConfirmed = confirm($tw.language.getString( + isConfirmed = win.confirm($tw.language.getString( "ConfirmCancelTiddler", {variables: {title: draftTitle} From b5db4884388c60accec9e456a3d4a798dbdd6f7b Mon Sep 17 00:00:00 2001 From: Odin <74539616+OdinJorna@users.noreply.github.com> Date: Fri, 11 Jun 2021 18:56:45 +0200 Subject: [PATCH 11/55] Update release notes 5.1.24 to 5.2.0 (#5754) --- .../prerelease/tiddlers/Release 5.1.24.tid | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/editions/prerelease/tiddlers/Release 5.1.24.tid b/editions/prerelease/tiddlers/Release 5.1.24.tid index 0eca552c9..aab85dde8 100644 --- a/editions/prerelease/tiddlers/Release 5.1.24.tid +++ b/editions/prerelease/tiddlers/Release 5.1.24.tid @@ -1,8 +1,8 @@ -caption: 5.1.24 +caption: 5.2.0 created: 20201229120443187 -modified: 20201229120443187 +modified: 20210604142913752 tags: ReleaseNotes -title: Release 5.1.24 +title: Release 5.2.0 type: text/vnd.tiddlywiki \define contributor(username) @@ -17,6 +17,7 @@ type: text/vnd.tiddlywiki * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/5362">> [[all Operator]] to use new linked list implementation * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/5369">> [[links Operator]] to use new linked list implementation * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5383">> unneeded escaping of double quotes in tiddler DIVs inside single file wikis (saving about 10% from the size of empty.html) +* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/5436">> Network performance for node.js ! Usability Improvements @@ -29,14 +30,26 @@ type: text/vnd.tiddlywiki * <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/commit/caec6bc3fea9155eb2b0aae64d577c565dd7b088">> SVG optimiser script * <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/c325380231a8c592a6e51d4498c1e6c3a241b539">> plus/minus SVG icons: <<.icon $:/core/images/plus-button>> and <<.icon $:/core/images/minus-button>> * <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5294">> support for [[dynamic toolbar buttons|How to create dynamic editor toolbar buttons]] -* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5612">> [[average Operator]], [[median Operator]], [[variance Operator]] and [[standard-deviation Operator]] for calculating the arithmetic mean of a list of numbers * <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/commit/cf56a17f28f1e44dcb62c5e161be4ac29e27c3f2">> unusedtitle macro to use the prefix parameter +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5672">> link to the existing tiddler when the warning Target tiddler already exists is displayed in EditTemplate +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5699">> (and again [[here|https://github.com/Jermolene/TiddlyWiki5/pull/5705]]) ability to drag 'n drop images in the editor to import and insert +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5707">> text operation [[insert-text|WidgetMessage: tm-edit-text-operation]] +* <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/pull/5467">> syncadaptor "save" "load" and "delete" methods +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5479">> possibility to import formerly blocked system tiddlers +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5720">> color-scheme field to all themes to differentiate between light and dark themes +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5727">> class to make tags in EditTemplate look like the tag-pills in the ViewTemplate +! Filter improvements + +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5612">> [[average Operator]], [[median Operator]], [[variance Operator]] and [[standard-deviation Operator]] for calculating the arithmetic mean of a list of numbers +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5673">> [[deserializers filter Operator|deserializers Operator]] +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5665">> [[format:titlelist operator|format Operator]] ! Hackability Improvements * <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/9eda02868f21e9dd1733ffe26352bd7ac96285b4">> new MessageCatcherWidget * <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/d25e540dd2f0decf61c52fdc665a28a5dfeda93f">> support for `image/vnd.microsoft.icon` content type +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5458">> Add throttling for changed tiddlers prefixed with $:/volatile/ ! Widget Improvements * <<.link-badge-modified "https://github.com/Jermolene/TiddlyWiki5/commit/b9647b2c48152dac069a1099a0822b32375a66cf">> [[FieldManglerWidget]] to ensure it doesn't propogate events that it traps @@ -49,6 +62,8 @@ type: text/vnd.tiddlywiki * <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/commit/07caa16e8714afe9a64eb202375e4a2f95da1508">> [[DropzoneWidget]] to also use the specified deserializer for strings either dropped or pasted on to the dropzone * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/44df6fe52f79bee88357afb4fc3d6f4800aa6dde">> issue with widget not being available to filter operator * <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/commit/3f986861538a3cc5c3c6da578b45d0d9138a6b2b">> [[ActionPopupWidget]] to create floating popups that must be manually cleared +* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/5648">> [[KeyboardWidget]] to allow for more flexibility +* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/commit/9faaa312998d48c56bd50335820b6b881266af4b">> [[ActionCreateTiddlerWidget]] to make new title available as a variable ! Client-server Improvements @@ -93,10 +108,13 @@ type: text/vnd.tiddlywiki * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/5377">> the Jasmine test suite output * <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/commit/9f9ce6595b08032a602981f82940ca113cff8211">> wikitext parser with a subclassing mechanism * <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/ef76349c37662e9706acfffc2c2edb51a920183d">> added support for ''utils-browser'' modules +* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5464">> th-before-importing hook mechanism to allow plugins to inspect or modify the `importTiddler` object ''before'' any tiddlers are imported ! Translation improvements * <<.link-badge-improved>> Chinese translations +* <<.link-badge-improved>> French translations +* <<.link-badge-improved>> Spanish translations ! Other Bug Fixes @@ -117,7 +135,17 @@ type: text/vnd.tiddlywiki * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/commit/d56e8764a1f02a214df5da1cc95191be2da2491b">> accessibility of button widget when controlling a popup * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/d6ea369f5ef9d3092a360a4286a99902df37782b">> EditTextWidget to use default text for missing fields * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5552">> css-escape-polyfill to work under Node.js - +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/dbd3f835bf8399ed1a3da7cc322ec9b6ab783d53">> crash when sorting by non-string fields +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5711">> some bugs in the [[EventCatcherWidget]] and introduced new `stopPorpagation` attribute +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5691">> CurrentTiddler variable consistency in subfilters and prefixes +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/485779f5b2136b7bcd739352b56188d94b0eb9e4">> crash when accessing variables in filters that don't have a widget context +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/8fbf52e419e71d726ea32b6c44e3ccfc4245d825">> unnecessary triggering reload warning when javascript tiddlers are not subsequently imported +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5521">> minor issue with import pragma +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5700">> leading and trailing whitespace in themes +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5469">> configuration list of HTML5 block elements +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5692">> shape and color for disabled button to work with `tc-btn-invisible` class +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5473">> inconsistent spacing of ViewToolbar items +* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/582b156d5f2b9b8b92f9289aa1288e1edb637450">> a [[bug|https://github.com/Jermolene/TiddlyWiki5/issues/5744]] where non-action widgets are not refreshed before invocation [[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki: From 4f33d2f35cd2c34ca5edfcf062f23bd1ca7ef177 Mon Sep 17 00:00:00 2001 From: Saq Imtiaz Date: Fri, 11 Jun 2021 19:15:07 +0200 Subject: [PATCH 12/55] Update release notes (#5780) --- editions/prerelease/tiddlers/Release 5.1.24.tid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editions/prerelease/tiddlers/Release 5.1.24.tid b/editions/prerelease/tiddlers/Release 5.1.24.tid index aab85dde8..4799ea95d 100644 --- a/editions/prerelease/tiddlers/Release 5.1.24.tid +++ b/editions/prerelease/tiddlers/Release 5.1.24.tid @@ -18,6 +18,7 @@ type: text/vnd.tiddlywiki * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/5369">> [[links Operator]] to use new linked list implementation * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5383">> unneeded escaping of double quotes in tiddler DIVs inside single file wikis (saving about 10% from the size of empty.html) * <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/5436">> Network performance for node.js +* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/5736">> refreshing of transclude widget. ! Usability Improvements @@ -145,7 +146,6 @@ type: text/vnd.tiddlywiki * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5469">> configuration list of HTML5 block elements * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5692">> shape and color for disabled button to work with `tc-btn-invisible` class * <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/5473">> inconsistent spacing of ViewToolbar items -* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/582b156d5f2b9b8b92f9289aa1288e1edb637450">> a [[bug|https://github.com/Jermolene/TiddlyWiki5/issues/5744]] where non-action widgets are not refreshed before invocation [[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki: From 960160b3a266a12d3d9d157e7edaef409c308462 Mon Sep 17 00:00:00 2001 From: felixhayashi <4307137+felixhayashi@users.noreply.github.com> Date: Mon, 14 Jun 2021 11:37:04 +0200 Subject: [PATCH 13/55] word break property when viewing field values (#1661) --- themes/tiddlywiki/vanilla/base.tid | 1 + 1 file changed, 1 insertion(+) diff --git a/themes/tiddlywiki/vanilla/base.tid b/themes/tiddlywiki/vanilla/base.tid index 30a65926a..ea1063f3d 100644 --- a/themes/tiddlywiki/vanilla/base.tid +++ b/themes/tiddlywiki/vanilla/base.tid @@ -1052,6 +1052,7 @@ button.tc-btn-invisible.tc-remove-tag-button { } .tc-view-field-value { + word-break: break-all; } @media (max-width: <>) { From f2e26927c12bcdac831b9b33180c0fe43d289cb0 Mon Sep 17 00:00:00 2001 From: Simon Huber Date: Mon, 14 Jun 2021 11:59:31 +0200 Subject: [PATCH 14/55] Add test for event.event.target being undefined in the tm-focus-selector listener (#5771) --- core/modules/startup/rootwidget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/startup/rootwidget.js b/core/modules/startup/rootwidget.js index 8f119f02a..721f84d5d 100644 --- a/core/modules/startup/rootwidget.js +++ b/core/modules/startup/rootwidget.js @@ -41,7 +41,7 @@ exports.startup = function() { $tw.rootWidget.addEventListener("tm-focus-selector",function(event) { var selector = event.param || "", element, - doc = event.event ? event.event.target.ownerDocument : document; + doc = event.event && event.event.target ? event.event.target.ownerDocument : document; try { element = doc.querySelector(selector); } catch(e) { From 3cd80de5bbadf5711c7c34342ad6bddf5565cf83 Mon Sep 17 00:00:00 2001 From: Simon Huber Date: Mon, 14 Jun 2021 12:01:00 +0200 Subject: [PATCH 15/55] Revert #5720 and fix #5770 by removing :root { color-scheme: ... } --- themes/tiddlywiki/vanilla/base.tid | 4 ---- 1 file changed, 4 deletions(-) diff --git a/themes/tiddlywiki/vanilla/base.tid b/themes/tiddlywiki/vanilla/base.tid index ea1063f3d..256152404 100644 --- a/themes/tiddlywiki/vanilla/base.tid +++ b/themes/tiddlywiki/vanilla/base.tid @@ -333,10 +333,6 @@ table tfoot tr td { height: 600px; } -:root { - color-scheme: {{{ [{$:/palette}get[color-scheme]] }}}; -} - /* ** Links */ From 8f9e8c1dee0942d30b34d3199fc7efea1a99e810 Mon Sep 17 00:00:00 2001 From: Saq Imtiaz Date: Mon, 14 Jun 2021 13:03:59 +0200 Subject: [PATCH 16/55] Keyboard widget: provide variable for shortcut descriptor to actions. (#5782) --- core/modules/keyboard.js | 16 ++++++++++++---- core/modules/widgets/keyboard.js | 6 +++++- .../tw5.com/tiddlers/widgets/KeyboardWidget.tid | 3 ++- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/core/modules/keyboard.js b/core/modules/keyboard.js index 1d818a25f..5e02a706d 100644 --- a/core/modules/keyboard.js +++ b/core/modules/keyboard.js @@ -179,7 +179,7 @@ Key descriptors have the following format: ctrl+enter ctrl+shift+alt+A */ -KeyboardManager.prototype.parseKeyDescriptor = function(keyDescriptor) { +KeyboardManager.prototype.parseKeyDescriptor = function(keyDescriptor,options) { var components = keyDescriptor.split(/\+|\-/), info = { keyCode: 0, @@ -206,6 +206,9 @@ KeyboardManager.prototype.parseKeyDescriptor = function(keyDescriptor) { info.keyCode = this.namedKeys[s]; } } + if(options.keyDescriptor) { + info.keyDescriptor = options.keyDescriptor; + } if(info.keyCode) { return info; } else { @@ -237,6 +240,7 @@ KeyboardManager.prototype.parseKeyDescriptors = function(keyDescriptors,options) lookupName = function(configName) { var keyDescriptors = wiki.getTiddlerText("$:/config/" + configName + "/" + name); if(keyDescriptors) { + options.keyDescriptor = keyDescriptor; result.push.apply(result,self.parseKeyDescriptors(keyDescriptors,options)); } }; @@ -245,7 +249,7 @@ KeyboardManager.prototype.parseKeyDescriptors = function(keyDescriptors,options) }); } } else { - result.push(self.parseKeyDescriptor(keyDescriptor)); + result.push(self.parseKeyDescriptor(keyDescriptor,options)); } }); return result; @@ -276,12 +280,16 @@ KeyboardManager.prototype.checkKeyDescriptor = function(event,keyInfo) { }; KeyboardManager.prototype.checkKeyDescriptors = function(event,keyInfoArray) { + return (this.getMatchingKeyDescriptor(event,keyInfoArray) !== null); +}; + +KeyboardManager.prototype.getMatchingKeyDescriptor = function(event,keyInfoArray) { for(var t=0; t` widget is rendered normally. The keyboard short |!Variables |!Description | |`event-key` |The <<.var event-key>> variable contains the character, if possible. eg: `1`. You can experiment with some settings at: [[Key Codes (Example)]] | |`event-code` |The <<.var event-code>> variable contains a character description. eg: `Digit1` instead of `1`. Or `Space` instead of an empty string ` `, which is hard to see| +|`event-key-descriptor` |The <<.var event-key-descriptor>> variable is available if the keyboard event captured was configured using a [[keyboard shortcut descriptor|Keyboard Shortcut Descriptor]] of the form `((my-shortcut))` which references a configuration tiddler. | |`modifier` |The [[modifier Variable]] contains the Modifier Key held during the event (can be normal, ctrl, shift, alt or combinations thereof) | ! Key Strings From 06318b7617dd2353e8dfdd57ade7bc37c4dfceac Mon Sep 17 00:00:00 2001 From: Saq Imtiaz Date: Mon, 14 Jun 2021 17:46:39 +0200 Subject: [PATCH 17/55] Pass reference to widget to CodeMirror (#5790) --- plugins/tiddlywiki/codemirror/engine.js | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/tiddlywiki/codemirror/engine.js b/plugins/tiddlywiki/codemirror/engine.js index 4d20b7733..e5e241a47 100755 --- a/plugins/tiddlywiki/codemirror/engine.js +++ b/plugins/tiddlywiki/codemirror/engine.js @@ -109,6 +109,7 @@ function CodeMirrorEngine(options) { if(this.widget.editTabIndex) { config["tabindex"] = this.widget.editTabIndex; } + config.editWidget = this.widget; // Create the CodeMirror instance this.cm = window.CodeMirror(function(cmDomNode) { // Note that this is a synchronous callback that is called before the constructor returns From 9c0d6a46ccfbb608312402fee111c7c0707fb282 Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Mon, 14 Jun 2021 18:39:56 +0200 Subject: [PATCH 18/55] Add "commentpragma" html style rule (#5726) * html-comment, that can be used in the pragma area * add commentpragma test * fix typo * fix typo and change comments ab bit * combine html-comment and pragma-comment and add some docs, how to use it * Make docs simpler by removing caching info * change h2 wording --- .../parsers/wikiparser/rules/commentblock.js | 8 ++++++- .../tiddlers/tests/test-wikitext-parser.js | 7 +++++++ .../tiddlers/wikitext/HTML in WikiText.tid | 21 +++++++++++++++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/core/modules/parsers/wikiparser/rules/commentblock.js b/core/modules/parsers/wikiparser/rules/commentblock.js index b7651c272..1c303f38f 100644 --- a/core/modules/parsers/wikiparser/rules/commentblock.js +++ b/core/modules/parsers/wikiparser/rules/commentblock.js @@ -7,6 +7,12 @@ Wiki text block rule for HTML comments. For example: ``` +\define macroX() + +xxxx +\end + + ``` Note that the syntax for comments is simplified to an opening "" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html) @@ -19,7 +25,7 @@ Note that the syntax for comments is simplified to an opening "\n\\define aMacro()\nnothing\n\\end\n")).toEqual( + + [ { type : 'set', attributes : { name : { type : 'string', value : 'aMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ ], isMacroDefinition : true } ] + + ); }); it("should parse inline macro calls", function() { diff --git a/editions/tw5.com/tiddlers/wikitext/HTML in WikiText.tid b/editions/tw5.com/tiddlers/wikitext/HTML in WikiText.tid index 412963adc..ec19e8a84 100644 --- a/editions/tw5.com/tiddlers/wikitext/HTML in WikiText.tid +++ b/editions/tw5.com/tiddlers/wikitext/HTML in WikiText.tid @@ -1,10 +1,12 @@ caption: HTML created: 20131205160816081 -modified: 20201125094415933 +modified: 20210614100305329 tags: WikiText title: HTML in WikiText type: text/vnd.tiddlywiki +! HTML tags and comments + HTML tags and comments can be used directly in WikiText. For example: ``` @@ -14,7 +16,22 @@ This is my nice and simple block of text. HelloThere ``` -[[Widgets share the same syntax as HTML tags|Widgets in WikiText]], and so the following information applies to them, too. +!! Pragma Comments + +<<.from-version 5.2.0>> Comments can now be freely intermixed with pragmas as well as within the main body of a block of wikitext. + +``` + +\define test() +some text +\end + +<> +``` + +! Important + +<<.tip """[[Widgets share the same syntax as HTML tags|Widgets in WikiText]], and so the following information applies to them, too.""">> ! Block mode versus Inline mode From 2da7ae0b735c45725802d813d15d0c807f95e65b Mon Sep 17 00:00:00 2001 From: "jeremy@jermolene.com" Date: Mon, 14 Jun 2021 18:13:51 +0100 Subject: [PATCH 19/55] Action-createtiddler: Ensure child widgets are refreshed before invocation Fixes #5791 --- core/modules/widgets/action-createtiddler.js | 1 + 1 file changed, 1 insertion(+) diff --git a/core/modules/widgets/action-createtiddler.js b/core/modules/widgets/action-createtiddler.js index 693c33282..b49eaad20 100644 --- a/core/modules/widgets/action-createtiddler.js +++ b/core/modules/widgets/action-createtiddler.js @@ -104,6 +104,7 @@ CreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) { } this.setVariable("createTiddler-title",title); this.setVariable("createTiddler-draftTitle",draftTitle); + this.refreshChildren(); return true; // Action was invoked }; From 0b56d5fd379e01a86b7faef8e8a70ef49d721d0e Mon Sep 17 00:00:00 2001 From: Mario Pietsch Date: Mon, 21 Jun 2021 13:14:36 +0200 Subject: [PATCH 20/55] update German translation (#5811) --- languages/de-DE/ControlPanel.multids | 6 +++++- languages/de-DE/Docs/ModuleTypes.multids | 1 + languages/de-DE/EditTemplate.multids | 2 ++ languages/de-DE/Help/listen.tid | 5 +++-- languages/de-DE/Help/render.tid | 3 ++- languages/de-DE/Import.multids | 5 +++++ languages/de-DE/Misc.multids | 11 ++++++++++- languages/de-DE/ThemeTweaks.multids | 4 ++-- languages/de-DE/TiddlerInfo.multids | 2 +- 9 files changed, 31 insertions(+), 8 deletions(-) diff --git a/languages/de-DE/ControlPanel.multids b/languages/de-DE/ControlPanel.multids index f7c9f46f4..ed5ef024d 100644 --- a/languages/de-DE/ControlPanel.multids +++ b/languages/de-DE/ControlPanel.multids @@ -17,6 +17,8 @@ Basics/NewJournal/Tags/Prompt: Tags des neuen Journal-Tiddlers Basics/NewTiddler/Title/Prompt: Titel des neuen Tiddlers Basics/NewTiddler/Tags/Prompt: Tags des neuen Tiddlers Basics/OverriddenShadowTiddlers/Prompt: Anzahl überschriebener Schatten-Tiddler +Basics/RemoveTags: Auf neues Format umstellen +Basics/RemoveTags/Hint: Die "tags" Konfiguration wird auf das aktuelle Format umgestellt Basics/ShadowTiddlers/Prompt: Anzahl Schatten-Tiddler Basics/Subtitle/Prompt: Untertitel Basics/SystemTiddlers/Prompt: Anzahl System-Tiddler @@ -44,6 +46,7 @@ KeyboardShortcuts/Platform/Linux: Nur Linux KeyboardShortcuts/Platform/NonLinux: Alle Plattformen, außer Linux KeyboardShortcuts/Platform/Windows: Nur Windows KeyboardShortcuts/Platform/NonWindows: Alle Plattformen, außer Windows +LayoutSwitcher/Caption: Layout LoadedModules/Caption: Geladene Module LoadedModules/Hint: Hier werden die geladenen Module und ihre Quelltext-Komponenten angezeigt. Kursiv hervorgehobene Tiddler haben keinen Quelltext. Sie werden während des Boot-Prozesses (Aufrufen des Tiddlywikis) erstellt. Palette/Caption: Palette @@ -120,11 +123,12 @@ Saving/TiddlySpot/BackupDir: Verzeichnis für das "Backup" Saving/TiddlySpot/ControlPanel: ~TiddlySpot Control Panel Saving/TiddlySpot/Backups: "Backups" Saving/TiddlySpot/Caption: Speichern auf ~TiddlySpot -Saving/TiddlySpot/Description: Diese Einstellungen sind nur für http://tiddlyspot.com und kompatible Server aktiv! +Saving/TiddlySpot/Description: Diese Einstellungen sind nur für [[TiddlySpot|http://tiddlyspot.com]], [[TiddlyHost|https://tiddlyhost.com]], und kompatible Server aktiv! [[Diese Beschreibung|https://github.com/simonbaird/tiddlyhost/wiki/TiddlySpot-Saver-configuration-for-Tiddlyhost-and-Tiddlyspot]] enthält weitergehende Informationen. Saving/TiddlySpot/Filename: Dateiname für den "Upload" Saving/TiddlySpot/Heading: ~TiddlySpot Saving/TiddlySpot/Hint: //Die Standard-Server-URL ist `http://.tiddlyspot.com/store.cgi` und kann im Feld 'Server-URL' verändert werden. zB: http://example.com/store.php// Saving/TiddlySpot/Password: Passwort +Saving/TiddlySpot/ReadOnly: ~TiddlySpot wurde durch https://tiddlyhost.com ersetzt. Neue Wikis können nur noch unter ~TiddlyHost erstellt werden. Bestehende Projekte können mit bekanntem Passwort gespeichert werden. Genaue Informationen finden Sie unter: http://tiddlyspot.com/ Saving/TiddlySpot/ServerURL: Server-URL Saving/TiddlySpot/UploadDir: Verzeichnis für den "Upload" Saving/TiddlySpot/UserName: Name des Wikis diff --git a/languages/de-DE/Docs/ModuleTypes.multids b/languages/de-DE/Docs/ModuleTypes.multids index 6e433d4f2..5b7738d84 100644 --- a/languages/de-DE/Docs/ModuleTypes.multids +++ b/languages/de-DE/Docs/ModuleTypes.multids @@ -23,6 +23,7 @@ tiddlerfield: Definiert das Verhalten, der unterschiedlichen Tiddler-Felder. tiddlermethod: Methoden werden dem `$tw.Tiddler` Prototypen hinzugefügt. upgrader: Führt spezifische Änderungen während des Upgrade- oder Import-prozesses durch. utils: Methoden werden `$tw.utils` hinzugefügt. +utils-browser: Browser-spezifische Methoden werden zu `$tw.utils` hinzugefügt. utils-node: Erweitert `$tw.utils` mit Methoden aus node.js. widget: Widgets verarbeiten das Rendern und Aktualisieren der Anzeige in der DOM. wikimethod: Methoden werden zu `$tw.Wiki` hinzugefügt. diff --git a/languages/de-DE/EditTemplate.multids b/languages/de-DE/EditTemplate.multids index 6fafba055..517d4334f 100644 --- a/languages/de-DE/EditTemplate.multids +++ b/languages/de-DE/EditTemplate.multids @@ -3,6 +3,8 @@ title: $:/language/EditTemplate/ Body/External/Hint: Dieser Tiddler zeigt den Inhalt einer Datei, die nicht im TW file gespeichert ist. Sie können die "Tags" und "Feld" Texte ändern, jedoch nicht den Inhalt des Tiddlers! Body/Placeholder: Geben Sie den Text für diesen Tiddler ein. Body/Preview/Type/Output: Anzeige +Body/Preview/Type/DiffShadow: Unterschiede zum Schatten-Tiddler (wenn vorhanden) +Body/Preview/Type/DiffCurrent: Unterschiede zum aktuellen Tiddler Field/Remove/Caption: Lösche Feld Field/Remove/Hint: Lösche Feld Field/Dropdown/Caption: Feld Liste diff --git a/languages/de-DE/Help/listen.tid b/languages/de-DE/Help/listen.tid index c1b71dda8..1d4760689 100644 --- a/languages/de-DE/Help/listen.tid +++ b/languages/de-DE/Help/listen.tid @@ -21,9 +21,10 @@ Mögliche Parameter: * ''username'' - Benutzername für die Basis-Authentifizierung * ''password'' - Passwort für die Basis-Authentifizierung * ''authenticated-user-header'' - HTTP Header-Name für vertrauenswürdige, authentifizierte Benutzer -* ''readers'' - Komma separierte Liste für Benutzer, mit Schreiberlaubnis -* ''writers'' - Komma separierte Liste für Benutzer, mit Leseerlaubnis +* ''readers'' - Komma-separierte Liste für Benutzer, mit Schreiberlaubnis +* ''writers'' - Komma-separierte Liste für Benutzer, mit Leseerlaubnis * ''csrf-disable'' - "yes" bedeutet, dass CSRF checks deaktiviert sind. (Standard: "no") +* ''sse-enabled'' - "yes" bedeuted, dass "Server-sent events" aktiv sind (Standard: "no") * ''root-tiddler'' - Tiddler, der für den "Root-Pfad" verwendet wird. (Standard: "$:/core/save/all") * ''root-render-type'' - Darstellungs-Type, die für den Root-Tiddler verwendet wird. (Standard: "text/plain") * ''root-serve-type'' - Inhalts-Type, die für den Root-Tiddler verwendet wird. (Standard: "text/html") diff --git a/languages/de-DE/Help/render.tid b/languages/de-DE/Help/render.tid index a35c59521..bb1b5cda8 100644 --- a/languages/de-DE/Help/render.tid +++ b/languages/de-DE/Help/render.tid @@ -8,7 +8,7 @@ Optionell kann eine Template-Datei angegeben werden. In diesem Fall wird nicht d Es können noch zusätzliche Variablen per Name und Wert gesetzt werden. ``` ---render [] [] [