diff --git a/.eslintrc.yml b/.eslintrc.yml index 049af59e4..0316b8385 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -231,7 +231,10 @@ rules: prefer-spread: 'off' prefer-template: 'off' quote-props: 'off' - quotes: 'off' + quotes: + - error + - double + - avoidEscape: true radix: 'off' require-atomic-updates: error require-await: error diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 1e644e161..286a842bc 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -21,7 +21,7 @@ body: attributes: label: To Reproduce description: "Steps to reproduce the behavior:" - value: | + placeholder: | 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -41,7 +41,7 @@ body: attributes: label: TiddlyWiki Configuration description: please complete the following information - value: | + placeholder: | - Version [e.g. v5.1.24] - Saving mechanism [e.g. Node.js, TiddlyDesktop, TiddlyHost etc] - Plugins installed [e.g. Freelinks, TiddlyMap] diff --git a/bin/readme-bld.sh b/bin/readme-bld.sh index 198c3abd0..e7c9df564 100755 --- a/bin/readme-bld.sh +++ b/bin/readme-bld.sh @@ -15,3 +15,11 @@ node $TW5_BUILD_TIDDLYWIKI \ --output . \ --build readmes \ || exit 1 + +# tw.org readmes +node $TW5_BUILD_TIDDLYWIKI \ + editions/tw.org \ + --verbose \ + --output . \ + --build readmes \ + || exit 1 diff --git a/boot/boot.js b/boot/boot.js index ea20c83fd..b4bdc00f2 100644 --- a/boot/boot.js +++ b/boot/boot.js @@ -386,8 +386,8 @@ $tw.utils.parseDate = function(value) { parseInt(value.substr(10,2)||"00",10), parseInt(value.substr(12,2)||"00",10), parseInt(value.substr(14,3)||"000",10))); - d.setUTCFullYear(year); // See https://stackoverflow.com/a/5870822 - return d; + d.setUTCFullYear(year); // See https://stackoverflow.com/a/5870822 + return d; } else if($tw.utils.isDate(value)) { return value; } else { diff --git a/code-of-conduct.md b/code-of-conduct.md new file mode 100644 index 000000000..e8e7664a7 --- /dev/null +++ b/code-of-conduct.md @@ -0,0 +1 @@ +

This community exists because TiddlyWiki is more useful when people share and work together.

This community is a beautiful but fragile thing: a collection of diverse people from all over the planet, united in their interest in the project, and their commitment to helping one another achieve and learn more.

We try to make the community as broad and welcoming as possible by remembering some basic principles of culture and behaviour.

These principles guide technical and non-technical decisions, and help contributors and leaders support our project and community.

Our discussions are in English. It is not the first language of many people in the community, nor do we all share the same cultural background and reference points. So we take care to use language that is clear and unambigous, and avoid cultural references or jokes that will not be widely understood.

It is not acceptable to make jokes or other comments that discriminate by race, gender, sexuality, or other protected characteristic.

As an inclusive community, we are committed to making sure that TiddlyWiki is an accessible tool that understands the needs of people with disabilities.

\ No newline at end of file diff --git a/core/images/discord.tid b/core/images/discord.tid new file mode 100644 index 000000000..7510babb4 --- /dev/null +++ b/core/images/discord.tid @@ -0,0 +1,5 @@ +title: $:/core/images/discord +tags: $:/tags/Image + +\parameters (size:"22pt") +> height=<> class="tc-image-discord tc-image-button" viewBox="0 -28.5 256 256"> \ No newline at end of file diff --git a/core/language/en-GB/Buttons.multids b/core/language/en-GB/Buttons.multids index 15273d18e..2fa732fd9 100644 --- a/core/language/en-GB/Buttons.multids +++ b/core/language/en-GB/Buttons.multids @@ -80,6 +80,7 @@ NewMarkdown/Caption: new Markdown tiddler NewMarkdown/Hint: Create a new Markdown tiddler NewTiddler/Caption: new tiddler NewTiddler/Hint: Create a new tiddler +OpenControlPanel/Hint: Open control panel OpenWindow/Caption: open in new window OpenWindow/Hint: Open tiddler in new window Palette/Caption: palette @@ -132,6 +133,7 @@ Excise/Caption/Replace/Link: link Excise/Caption/Replace/Transclusion: transclusion Excise/Caption/Tag: Tag new tiddler with the title of this tiddler Excise/Caption/TiddlerExists: Warning: tiddler already exists +Excise/DefaultTitle: New Excision Excise/Hint: Excise the selected text into a new tiddler Heading1/Caption: heading 1 Heading1/Hint: Apply heading level 1 formatting to lines containing selection diff --git a/core/language/en-GB/ControlPanel.multids b/core/language/en-GB/ControlPanel.multids index 93cfc3c10..a1b164c5c 100644 --- a/core/language/en-GB/ControlPanel.multids +++ b/core/language/en-GB/ControlPanel.multids @@ -198,6 +198,12 @@ Settings/TitleLinks/Yes/Description: Display tiddler titles as links Settings/MissingLinks/Caption: Wiki Links Settings/MissingLinks/Hint: Choose whether to link to tiddlers that do not exist yet Settings/MissingLinks/Description: Enable links to missing tiddlers +SocialCard/Caption: Social Media Card +SocialCard/Domain/Prompt: Domain name to display for the link (for example, ''tiddlywiki.com'') +SocialCard/Hint: This information is used by social and messaging services to display a preview card for links to this TiddlyWiki when hosted online +SocialCard/PreviewUrl/Prompt: Full URL to preview image for this TiddlyWiki +SocialCard/PreviewUrl/Preview: Preview image: +SocialCard/Url/Prompt: Full URL of this TiddlyWiki StoryTiddler/Caption: Story Tiddler StoryTiddler/Hint: This rule cascade is used to dynamically choose the template for displaying a tiddler in the story river. StoryView/Caption: Story View @@ -235,3 +241,7 @@ ViewTemplateBody/Caption: View Template Body ViewTemplateBody/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the body of a tiddler. ViewTemplateTitle/Caption: View Template Title ViewTemplateTitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler. +ViewTemplateSubtitle/Caption: View Template Subtitle +ViewTemplateSubtitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the subtitle of a tiddler. +ViewTemplateTags/Caption: View Template Tags +ViewTemplateTags/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the tags area of a tiddler. diff --git a/core/language/en-GB/EditTemplate.multids b/core/language/en-GB/EditTemplate.multids index c4bfa5e56..9b61f71ec 100644 --- a/core/language/en-GB/EditTemplate.multids +++ b/core/language/en-GB/EditTemplate.multids @@ -26,6 +26,7 @@ Tags/ClearInput/Caption: clear input Tags/ClearInput/Hint: Clear tag input Tags/Dropdown/Caption: tag list Tags/Dropdown/Hint: Show tag list +Tags/EmptyMessage: (no search result) Title/BadCharacterWarning: Warning: avoid using any of the characters <> in tiddler titles Title/Exists/Prompt: Target tiddler already exists Title/Relink/Prompt: Update ''<$text text=<>/>'' to ''<$text text=<>/>'' in the //tags// and //list// fields of other tiddlers diff --git a/core/language/en-GB/Search.multids b/core/language/en-GB/Search.multids index 2a57a6416..f5aa478bf 100644 --- a/core/language/en-GB/Search.multids +++ b/core/language/en-GB/Search.multids @@ -6,6 +6,8 @@ Filter/Hint: Search via a [[filter expression|https://tiddlywiki.com/static/Filt Filter/Matches: //<> matches// Matches: //<> matches// Matches/All: All matches: +Matches/NoMatch: //No match// +Matches/NoResult: //No search result// Matches/Title: Title matches: Search: Search Search/TooShort: Search text too short diff --git a/core/language/en-GB/Snippets/FunctionDefinition.tid b/core/language/en-GB/Snippets/FunctionDefinition.tid new file mode 100644 index 000000000..e000e38b1 --- /dev/null +++ b/core/language/en-GB/Snippets/FunctionDefinition.tid @@ -0,0 +1,7 @@ +title: $:/language/Snippets/FunctionDefinition +tags: $:/tags/TextEditor/Snippet +caption: Function definition + +\function f.name(param1,param2:"default value") [!is[blank]else] + +<> diff --git a/core/language/en-GB/Snippets/ProcedureDefinition.tid b/core/language/en-GB/Snippets/ProcedureDefinition.tid new file mode 100644 index 000000000..632abcc01 --- /dev/null +++ b/core/language/en-GB/Snippets/ProcedureDefinition.tid @@ -0,0 +1,7 @@ +title: $:/language/Snippets/ProcedureDefinition +tags: $:/tags/TextEditor/Snippet +caption: Procedure definition + +\procedure procName(param1:"default value",param2) +Your text comes here. +\end diff --git a/core/language/en-GB/Types/image_x-icon.tid b/core/language/en-GB/Types/image_x-icon.tid deleted file mode 100644 index 55420387a..000000000 --- a/core/language/en-GB/Types/image_x-icon.tid +++ /dev/null @@ -1,5 +0,0 @@ -title: $:/language/Docs/Types/image/x-icon -description: ICO icon -name: image/x-icon -group: Image -group-sort: 1 diff --git a/core/language/en-GB/Types/text_vnd.tiddlywiki_multiple.tid b/core/language/en-GB/Types/text_vnd.tiddlywiki_multiple.tid new file mode 100644 index 000000000..af15d7ac3 --- /dev/null +++ b/core/language/en-GB/Types/text_vnd.tiddlywiki_multiple.tid @@ -0,0 +1,5 @@ +title: $:/language/Docs/Types/text/vnd.tiddlywiki-multiple +description: Compound tiddler +name: text/vnd.tiddlywiki-multiple +group: Developer +group-sort: 2 diff --git a/core/modules/commands/render.js b/core/modules/commands/render.js index b396deef9..bd8b23171 100644 --- a/core/modules/commands/render.js +++ b/core/modules/commands/render.js @@ -45,17 +45,22 @@ Render individual tiddlers and save the results to the specified files variableList = variableList.slice(2); } $tw.utils.each(tiddlers,function(title) { - var filepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]); - if(self.commander.verbose) { - console.log("Rendering \"" + title + "\" to \"" + filepath + "\""); + var filenameResults = wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title])); + if(filenameResults.length > 0) { + var filepath = path.resolve(self.commander.outputPath,filenameResults[0]); + if(self.commander.verbose) { + console.log("Rendering \"" + title + "\" to \"" + filepath + "\""); + } + var parser = wiki.parseTiddler(template || title), + widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title,storyTiddler: title})}), + container = $tw.fakeDocument.createElement("div"); + widgetNode.render(container,null); + var text = type === "text/html" ? container.innerHTML : container.textContent; + $tw.utils.createFileDirectories(filepath); + fs.writeFileSync(filepath,text,"utf8"); + } else { + console.log("Not rendering \"" + title + "\" because the filename filter returned an empty result"); } - var parser = wiki.parseTiddler(template || title), - widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title,storyTiddler: title})}), - container = $tw.fakeDocument.createElement("div"); - widgetNode.render(container,null); - var text = type === "text/html" ? container.innerHTML : container.textContent; - $tw.utils.createFileDirectories(filepath); - fs.writeFileSync(filepath,text,"utf8"); }); return null; }; diff --git a/core/modules/editor/operations/text/excise.js b/core/modules/editor/operations/text/excise.js index ced771719..8cb3a8486 100644 --- a/core/modules/editor/operations/text/excise.js +++ b/core/modules/editor/operations/text/excise.js @@ -14,11 +14,12 @@ Text editor operation to excise the selection to a new tiddler exports["excise"] = function(event,operation) { var editTiddler = this.wiki.getTiddler(this.editTitle), - editTiddlerTitle = this.editTitle; + editTiddlerTitle = this.editTitle, + excisionBaseTitle = $tw.language.getString("Buttons/Excise/DefaultTitle"); if(editTiddler && editTiddler.fields["draft.of"]) { editTiddlerTitle = editTiddler.fields["draft.of"]; } - var excisionTitle = event.paramObject.title || this.wiki.generateNewTitle("New Excision"); + var excisionTitle = event.paramObject.title || this.wiki.generateNewTitle(excisionBaseTitle); this.wiki.addTiddler(new $tw.Tiddler( this.wiki.getCreationFields(), this.wiki.getModificationFields(), diff --git a/core/modules/parsers/wikiparser/rules/table.js b/core/modules/parsers/wikiparser/rules/table.js index 59aa81e91..fbdbb4f9d 100644 --- a/core/modules/parsers/wikiparser/rules/table.js +++ b/core/modules/parsers/wikiparser/rules/table.js @@ -93,11 +93,12 @@ var processRow = function(prevColumns) { } // Check whether this is a heading cell var cell; + var start = this.parser.pos; if(chr === "!") { this.parser.pos++; - cell = {type: "element", tag: "th", children: []}; + cell = {type: "element", tag: "th", start: start, children: []}; } else { - cell = {type: "element", tag: "td", children: []}; + cell = {type: "element", tag: "td", start: start, children: []}; } tree.push(cell); // Record information about this cell @@ -121,6 +122,7 @@ var processRow = function(prevColumns) { } // Move back to the closing `|` this.parser.pos--; + cell.end = this.parser.pos; } col++; cellRegExp.lastIndex = this.parser.pos; @@ -169,12 +171,13 @@ exports.parse = function() { rowContainer.children = this.parser.parseInlineRun(rowTermRegExp,{eatTerminator: true}); } else { // Create the row - var theRow = {type: "element", tag: "tr", children: []}; + var theRow = {type: "element", tag: "tr", children: [], start: rowMatch.index}; $tw.utils.addClassToParseTreeNode(theRow,rowCount%2 ? "oddRow" : "evenRow"); rowContainer.children.push(theRow); // Process the row theRow.children = processRow.call(this,prevColumns); this.parser.pos = rowMatch.index + rowMatch[0].length; + theRow.end = this.parser.pos; // Increment the row count rowCount++; } diff --git a/core/modules/savers/put.js b/core/modules/savers/put.js index a1ebef4bb..87fe5f710 100644 --- a/core/modules/savers/put.js +++ b/core/modules/savers/put.js @@ -55,7 +55,7 @@ var PutSaver = function(wiki) { callback: function(err,data,xhr) { // Check DAV header http://www.webdav.org/specs/rfc2518.html#rfc.section.9.1 if(!err) { - self.serverAcceptsPuts = xhr.status === 200 && !!xhr.getResponseHeader("dav"); + self.serverAcceptsPuts = xhr.status >= 200 && xhr.status < 300 && !!xhr.getResponseHeader("dav"); } } }); diff --git a/core/modules/storyviews/classic.js b/core/modules/storyviews/classic.js index 044cd97f0..a85e458c5 100644 --- a/core/modules/storyviews/classic.js +++ b/core/modules/storyviews/classic.js @@ -30,12 +30,8 @@ ClassicStoryView.prototype.navigateTo = function(historyInfo) { if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { return; } - if(duration) { - // Scroll the node into view - this.listWidget.dispatchEvent({type: "tm-scroll", target: targetElement}); - } else { - targetElement.scrollIntoView(); - } + // Scroll the node into view + this.listWidget.dispatchEvent({type: "tm-scroll", target: targetElement}); }; ClassicStoryView.prototype.insert = function(widget) { diff --git a/core/modules/upgraders/system.js b/core/modules/upgraders/system.js index a93a57712..a653a75b1 100644 --- a/core/modules/upgraders/system.js +++ b/core/modules/upgraders/system.js @@ -12,7 +12,7 @@ Upgrader module that suppresses certain system tiddlers that shouldn't be import /*global $tw: false */ "use strict"; -var DONT_IMPORT_LIST = ["$:/Import"], +var DONT_IMPORT_LIST = ["$:/Import", "$:/build"], UNSELECT_PREFIX_LIST = ["$:/temp/","$:/state/","$:/StoryList","$:/HistoryList"], WARN_IMPORT_PREFIX_LIST = ["$:/core/modules/"]; diff --git a/core/modules/utils/edition-info.js b/core/modules/utils/edition-info.js index f8a5cab06..b9d97f962 100644 --- a/core/modules/utils/edition-info.js +++ b/core/modules/utils/edition-info.js @@ -29,10 +29,14 @@ exports.getEditionInfo = function() { for(var entryIndex=0; entryIndex