From 43061e64a69a0c1b2c1c7f50521b7f46a406b5ab Mon Sep 17 00:00:00 2001 From: Simon Huber Date: Mon, 16 Nov 2020 17:54:29 +0100 Subject: [PATCH 1/3] Fix #5039 - Tag input, Type input and Fields inputs don't delete their state tiddlers on tiddler-cancel/delete (#5049) * Update EditTemplate.tid * Update EditTemplate.tid * Update EditTemplate.tid * Update tag-picker.tid * Update tag-picker.tid * Update type.tid * Update fields.tid * Update cancel.tid * Update delete.tid * Update type.tid * Update ViewTemplate.tid --- core/ui/EditTemplate.tid | 13 ++++++++----- core/ui/EditTemplate/fields.tid | 4 ++-- core/ui/EditTemplate/type.tid | 12 ++++++------ core/ui/EditToolbar/cancel.tid | 4 ++-- core/ui/EditToolbar/delete.tid | 4 ++-- core/ui/ViewTemplate.tid | 1 + core/wiki/macros/tag-picker.tid | 8 ++++++-- 7 files changed, 27 insertions(+), 19 deletions(-) diff --git a/core/ui/EditTemplate.tid b/core/ui/EditTemplate.tid index 1d342ef7b..bf99cd70c 100644 --- a/core/ui/EditTemplate.tid +++ b/core/ui/EditTemplate.tid @@ -1,17 +1,20 @@ title: $:/core/ui/EditTemplate +\define delete-edittemplate-state-tiddlers() <$action-deletetiddler $filter="[] [] [] [] [] [] [] [] []"/> \define save-tiddler-actions() <$action-sendmessage $message="tm-add-tag" $param={{{ [get[text]] }}}/> -<$action-deletetiddler $tiddler=<>/> <$action-sendmessage $message="tm-add-field" $name={{{ [get[text]] }}} $value={{{ [get[text]] }}}/> -<$action-deletetiddler $tiddler=<>/> -<$action-deletetiddler $tiddler=<>/> +<> <$action-sendmessage $message="tm-save-tiddler"/> \end +\define cancel-delete-tiddler-actions(message) +<> +<$action-sendmessage $message="tm-$message$-tiddler"/> +\end
> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-edit-frame [is[tiddler]then[tc-tiddler-exists]] [is[missing]!is[shadow]then[tc-tiddler-missing]] [is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [is[system]then[tc-tiddler-system]] [{!!class}] [tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}> <$fieldmangler> -<$vars storyTiddler=<> newTagNameTiddler=<> newFieldNameTiddler=<> newFieldValueTiddler=<>> -<$keyboard key="((cancel-edit-tiddler))" message="tm-cancel-tiddler"> +<$vars storyTiddler=<> newTagNameTiddler=<> newFieldNameTiddler=<> newFieldValueTiddler=<> newFieldNameInputTiddler=<> newFieldNameSelectionTiddler=<> newTagNameInputTiddler=<> newTagNameSelectionTiddler=<> typeInputTiddler=<> typeSelectionTiddler=<>> +<$keyboard key="((cancel-edit-tiddler))" actions=<>> <$keyboard key="((save-tiddler))" actions=<>> <$list filter="[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]" variable="listItem"> <$set name="tv-config-toolbar-class" filter="[] [encodeuricomponent[]addprefix[tc-btn-]]"> diff --git a/core/ui/EditTemplate/fields.tid b/core/ui/EditTemplate/fields.tid index 7c041d122..84f0baa68 100644 --- a/core/ui/EditTemplate/fields.tid +++ b/core/ui/EditTemplate/fields.tid @@ -23,7 +23,7 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$ \define delete-state-tiddlers() <$action-deletetiddler $filter="[] [] []"/> \define cancel-search-actions-inner() -<$list filter="[has[text]] [has[text]]" variable="ignore" emptyMessage="""<><$action-sendmessage $message="tm-cancel-tiddler"/>"""> +<$list filter="[has[text]] [has[text]]" variable="ignore" emptyMessage="""<>"""> <> \end @@ -87,7 +87,7 @@ $value={{{ [get[text]] }}}/> <> -<$vars refreshTitle=<> storeTitle=<> searchListState=<>> +<$vars refreshTitle=<> storeTitle=<> searchListState=<>>
<$macrocall $name="keyboard-driven-input" tiddler=<> storeTitle=<> refreshTitle=<> selectionStateTitle=<> tag="input" default="" placeholder={{$:/language/EditTemplate/Fields/Add/Name/Placeholder}} diff --git a/core/ui/EditTemplate/type.tid b/core/ui/EditTemplate/type.tid index 786a2ecd2..4b458aa5b 100644 --- a/core/ui/EditTemplate/type.tid +++ b/core/ui/EditTemplate/type.tid @@ -3,14 +3,14 @@ tags: $:/tags/EditTemplate first-search-filter: [all[shadows+tiddlers]prefix[$:/language/Docs/Types/]sort[description]sort[group-sort]removeprefix[$:/language/Docs/Types/]search] \define lingo-base() $:/language/EditTemplate/ -\define input-cancel-actions() <$list filter="[get[text]] [get[type]] +[limit[1]]" emptyMessage="""<$action-sendmessage $message="tm-cancel-tiddler"/>"""><$action-sendmessage $message="tm-remove-field" $param="type"/><$action-deletetiddler $filter="[] [] []"/> +\define input-cancel-actions() <$list filter="[get[text]] [get[type]] +[limit[1]]" emptyMessage="""<>"""><$action-sendmessage $message="tm-remove-field" $param="type"/><$action-deletetiddler $filter="[] [] []"/> \whitespace trim -<$vars storeTitle=<> refreshTitle=<> selectionStateTitle=<>> +<$set name="refreshTitle" value=<>>
<>
<$fieldmangler> -<$macrocall $name="keyboard-driven-input" tiddler=<> storeTitle=<> refreshTitle=<> selectionStateTitle=<> field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<> class="tc-edit-typeeditor tc-edit-texteditor tc-popup-handle" tabindex={{$:/config/EditTabIndex}} focus={{{ [{$:/config/AutoFocus}match[type]then[true]] ~[[false]] }}} cancelPopups="yes" configTiddlerFilter="[[$:/core/ui/EditTemplate/type]]" inputCancelActions=<>/><$button popup=<> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}<$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}<$action-deletetiddler $filter="[] [] []"/> +<$macrocall $name="keyboard-driven-input" tiddler=<> storeTitle=<> refreshTitle=<> selectionStateTitle=<> field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<> class="tc-edit-typeeditor tc-edit-texteditor tc-popup-handle" tabindex={{$:/config/EditTabIndex}} focus={{{ [{$:/config/AutoFocus}match[type]then[true]] ~[[false]] }}} cancelPopups="yes" configTiddlerFilter="[[$:/core/ui/EditTemplate/type]]" inputCancelActions=<>/><$button popup=<> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}<$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}<$action-deletetiddler $filter="[] [] []"/>
@@ -22,8 +22,8 @@ first-search-filter: [all[shadows+tiddlers]prefix[$:/language/Docs/Types/]sort[d
<$text text={{!!group}}/>
-<$set name="userInput" value={{{ [get[text]] }}}> -<$list filter="[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] +[sort[description]] +[removeprefix[$:/language/Docs/Types/]] +[search]">addsuffix[-primaryList]] -[get[text]] +[then[]else[tc-list-item-selected]] }}}><$link to={{{ [addprefix[$:/language/Docs/Types/]get[name]] }}}><$view tiddler={{{ [addprefix[$:/language/Docs/Types/]] }}} field="description"/> (<$view tiddler={{{ [addprefix[$:/language/Docs/Types/]] }}} field="name"/>) +<$set name="userInput" value={{{ [get[text]] }}}> +<$list filter="[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] +[sort[description]] +[removeprefix[$:/language/Docs/Types/]] +[search]">addsuffix[-primaryList]] -[get[text]] +[then[]else[tc-list-item-selected]] }}}><$link to={{{ [addprefix[$:/language/Docs/Types/]get[name]] }}}><$view tiddler={{{ [addprefix[$:/language/Docs/Types/]] }}} field="description"/> (<$view tiddler={{{ [addprefix[$:/language/Docs/Types/]] }}} field="name"/>) @@ -34,4 +34,4 @@ first-search-filter: [all[shadows+tiddlers]prefix[$:/language/Docs/Types/]sort[d
- + diff --git a/core/ui/EditToolbar/cancel.tid b/core/ui/EditToolbar/cancel.tid index 6b5aa56a1..341ae9d0b 100644 --- a/core/ui/EditToolbar/cancel.tid +++ b/core/ui/EditToolbar/cancel.tid @@ -3,11 +3,11 @@ tags: $:/tags/EditToolbar caption: {{$:/core/images/cancel-button}} {{$:/language/Buttons/Cancel/Caption}} description: {{$:/language/Buttons/Cancel/Hint}} -<$button message="tm-cancel-tiddler" tooltip={{$:/language/Buttons/Cancel/Hint}} aria-label={{$:/language/Buttons/Cancel/Caption}} class=<>> +<$button actions=<> tooltip={{$:/language/Buttons/Cancel/Hint}} aria-label={{$:/language/Buttons/Cancel/Caption}} class=<>> <$list filter="[match[yes]]"> {{$:/core/images/cancel-button}} <$list filter="[match[yes]]"> <$text text={{$:/language/Buttons/Cancel/Caption}}/> - \ No newline at end of file + diff --git a/core/ui/EditToolbar/delete.tid b/core/ui/EditToolbar/delete.tid index c6ce6b823..67e68c68b 100644 --- a/core/ui/EditToolbar/delete.tid +++ b/core/ui/EditToolbar/delete.tid @@ -3,11 +3,11 @@ tags: $:/tags/EditToolbar $:/tags/ViewToolbar caption: {{$:/core/images/delete-button}} {{$:/language/Buttons/Delete/Caption}} description: {{$:/language/Buttons/Delete/Hint}} -<$button message="tm-delete-tiddler" tooltip={{$:/language/Buttons/Delete/Hint}} aria-label={{$:/language/Buttons/Delete/Caption}} class=<>> +<$button actions=<> tooltip={{$:/language/Buttons/Delete/Hint}} aria-label={{$:/language/Buttons/Delete/Caption}} class=<>> <$list filter="[match[yes]]"> {{$:/core/images/delete-button}} <$list filter="[match[yes]]"> <$text text={{$:/language/Buttons/Delete/Caption}}/> - \ No newline at end of file + diff --git a/core/ui/ViewTemplate.tid b/core/ui/ViewTemplate.tid index 71303d3dd..e3ba249ee 100644 --- a/core/ui/ViewTemplate.tid +++ b/core/ui/ViewTemplate.tid @@ -3,6 +3,7 @@ title: $:/core/ui/ViewTemplate \define folded-state() $:/state/folded/$(currentTiddler)$ \end +\define cancel-delete-tiddler-actions(message) <$action-sendmessage $message="tm-$message$-tiddler"/> \import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]] <$vars storyTiddler=<> tiddlerInfoState=<>>
> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-view-frame [is[tiddler]then[tc-tiddler-exists]] [is[missing]!is[shadow]then[tc-tiddler-missing]] [is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [is[shadow]is[tiddler]then[tc-tiddler-overridden-shadow]] [is[system]then[tc-tiddler-system]] [{!!class}] [tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}><$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<>/>
diff --git a/core/wiki/macros/tag-picker.tid b/core/wiki/macros/tag-picker.tid index 30e0fc8ab..31d6c786d 100644 --- a/core/wiki/macros/tag-picker.tid +++ b/core/wiki/macros/tag-picker.tid @@ -34,7 +34,7 @@ $actions$ \end \define clear-tags-actions-inner() -<$list filter="[has[text]] [has[text]]" variable="ignore" emptyMessage="""<><$action-sendmessage $message="tm-cancel-tiddler"/>"""> +<$list filter="[has[text]] [has[text]]" variable="ignore" emptyMessage="""<>"""> <> \end @@ -49,7 +49,9 @@ $actions$ \define tag-picker-inner(actions,tagField:"tags") \whitespace trim -<$vars tagSelectionState=<> storeTitle=<> refreshTitle=<> nonSystemTagsFilter="[tags[]!is[system]search:titlesort[]]" systemTagsFilter="[tags[]is[system]search:titlesort[]]"> +<$vars newTagNameInputTiddlerQualified=<> newTagNameSelectionTiddlerQualified=<>> +<$vars storeTitle={{{ [!match[]] ~[] }}} tagSelectionState={{{ [!match[]] ~[] }}}> +<$vars refreshTitle=<> nonSystemTagsFilter="[tags[]!is[system]search:titlesort[]]" systemTagsFilter="[tags[]is[system]search:titlesort[]]">
@@ -95,6 +97,8 @@ $actions$
+ + \end \define tag-picker(actions,tagField:"tags") \whitespace trim From fc1721709ac5f473ee84fb0c1c0d16809155161d Mon Sep 17 00:00:00 2001 From: saqimtiaz Date: Mon, 16 Nov 2020 18:02:04 +0100 Subject: [PATCH 2/3] Cycle operator and refactored toggle operator (#5021) * Refactored toggle operator and added cycle operator * Better handling for operand case * Syntax/whitespace corrections --- core/modules/filters/x-listops.js | 59 ++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/core/modules/filters/x-listops.js b/core/modules/filters/x-listops.js index 73f19ccf5..5b3a9aba1 100644 --- a/core/modules/filters/x-listops.js +++ b/core/modules/filters/x-listops.js @@ -188,27 +188,44 @@ Extended filter operators to manipulate the current list. return set; }; - /* - Toggles an item in the current list. - */ - exports.toggle = function(source, operator) { - var results = prepare_results(source), - index = results.indexOf(operator.operand), - pairIndex = (operator.operands[1] ? results.indexOf(operator.operands[1]) : -1); - if(index === -1) { - if(pairIndex !== -1) { - results.splice(pairIndex,1,operator.operand); - } else { - results.push(operator.operand); - } - } else { - if(operator.operands[1]) { - results.splice(index,1,operator.operands[1]); - } else { - results.splice(index,1); + var cycleValueInArray = function(results,operands) { + var resultsIndex, + i = 0, + nextOperandIndex; + for(i; i < operands.length; i++) { + resultsIndex = results.indexOf(operands[i]); + if(resultsIndex !== -1) { + break; } } - return results; - }; + if(resultsIndex !== -1) { + i++; + nextOperandIndex = (i === operands.length ? 0 : i); + if(operands.length > 1) { + results.splice(resultsIndex,1,operands[nextOperandIndex]); + } else { + results.splice(resultsIndex,1,); + } + } else { + results.push(operands[0]); + } + return results; + } -})(); + /* + Toggles an item in the current list. + */ + exports.toggle = function(source,operator) { + return cycleValueInArray(prepare_results(source),operator.operands); + } + + exports.cycle = function(source,operator) { + var results = prepare_results(source), + operands = (operator.operand.length ? $tw.utils.parseStringArray(operator.operand, "true") : [""]); + if(operator.suffix === "reverse") { + operands.reverse(); + } + return cycleValueInArray(results,operands); + } + +})(); \ No newline at end of file From d6e055368d98f460b8f46d61e714b1e3977466b0 Mon Sep 17 00:00:00 2001 From: saqimtiaz Date: Mon, 16 Nov 2020 18:02:22 +0100 Subject: [PATCH 3/3] Added docs for action-confirm widget, added default message for widget and improved logic for disabling it. (#5047) --- core/language/en-GB/Misc.multids | 1 + core/modules/widgets/confirm.js | 6 +-- .../tiddlers/widgets/ActionConfirmWidget.tid | 40 +++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 editions/tw5.com/tiddlers/widgets/ActionConfirmWidget.tid diff --git a/core/language/en-GB/Misc.multids b/core/language/en-GB/Misc.multids index 61570f2af..a6655709d 100644 --- a/core/language/en-GB/Misc.multids +++ b/core/language/en-GB/Misc.multids @@ -10,6 +10,7 @@ ConfirmCancelTiddler: Do you wish to discard changes to the tiddler "<$text text ConfirmDeleteTiddler: Do you wish to delete the tiddler "<$text text=<>/>"? ConfirmOverwriteTiddler: Do you wish to overwrite the tiddler "<$text text=<<title>>/>"? ConfirmEditShadowTiddler: You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit "<$text text=<<title>>/>"? +ConfirmAction: Do you wish to proceed? Count: count DefaultNewTiddlerTitle: New Tiddler Diffs/CountMessage: <<diff-count>> differences diff --git a/core/modules/widgets/confirm.js b/core/modules/widgets/confirm.js index ffc506ec6..eb762f050 100644 --- a/core/modules/widgets/confirm.js +++ b/core/modules/widgets/confirm.js @@ -36,8 +36,8 @@ ConfirmWidget.prototype.render = function(parent,nextSibling) { Compute the internal state of the widget */ ConfirmWidget.prototype.execute = function() { - this.message = this.getAttribute("$message"); - this.prompt = (this.getAttribute("$prompt","yes") == "yes" ? true : false); + this.message = this.getAttribute("$message",$tw.language.getString("ConfirmAction")); + this.prompt = (this.getAttribute("$prompt","yes") == "no" ? false : true); this.makeChildWidgets(); }; @@ -59,7 +59,7 @@ Invoke the action associated with this widget ConfirmWidget.prototype.invokeAction = function(triggeringWidget,event) { var invokeActions = true, handled = true; - if(this.message && this.prompt) { + if(this.prompt) { invokeActions = confirm(this.message); } if(invokeActions) { diff --git a/editions/tw5.com/tiddlers/widgets/ActionConfirmWidget.tid b/editions/tw5.com/tiddlers/widgets/ActionConfirmWidget.tid new file mode 100644 index 000000000..5de11c755 --- /dev/null +++ b/editions/tw5.com/tiddlers/widgets/ActionConfirmWidget.tid @@ -0,0 +1,40 @@ +caption: action-confirm +created: 20201115150255011 +modified: 20201115160335288 +tags: Widgets ActionWidgets +title: ActionConfirmWidget +type: text/vnd.tiddlywiki + +! Introduction + +<<.from-version "5.1.23">>The ''action-confirm'' widget is an [[action widget|ActionWidgets]] that prompts the user for confirmation and invokes other action widgets contained within it only if the user confirms. ActionWidgets are used within triggering widgets such as the ButtonWidget. + +! Content and Attributes + +The ''action-confirm'' widget is invisible. Any content within it is only processed if the user confirms the action, or the confirmation has been disabled by the `$prompt` attribute. + +|!Attribute |!Description | +|$message |Optional message displayed to the user when asking for confirmation.| +|$prompt |Optional flag, set to "no" to disable the prompt for confirmation. Defaults to "yes" | + +! Examples + +Here is an example of a button that asks the user for confirmation, before deleting the caption and tags fields of the current tiddler: + +<$macrocall $name='wikitext-example-without-html' +src='<$button> +<$action-confirm $message="Do you wish to delete the caption and tags?"> +<$action-deletefield caption tags/> +Delete "caption" and "tags" +</$action-confirm> +</$button>'/> + +Here is an example of a button that uses the optional `$prompt` attribute to control whether to prompt the user before deleting the text field of the tiddler HelloThere: + +<$macrocall $name='wikitext-example-without-html' +src='<$button> +<$action-confirm $message="Do you wish to delete the text field?" $prompt={{$:/state/promptUser}}> +<$action-deletefield $tiddler="HelloThere" $field="text"/> +</$action-confirm> +Delete text from ~HelloThere +</$button>'/>