Add support for full refreshing of action widgets

Fixes #5791
new-json-store-area
jeremy@jermolene.com 2021-07-02 14:33:38 +01:00
rodzic f87b3bfcdb
commit 3094e06236
2 zmienionych plików z 53 dodań i 7 usunięć

Wyświetl plik

@ -568,10 +568,15 @@ Widget.prototype.invokeActions = function(triggeringWidget,event) {
var handled = false;
// For each child widget
for(var t=0; t<this.children.length; t++) {
var child = this.children[t];
// Invoke the child if it is an action widget
if(child.invokeAction) {
var child = this.children[t],
childIsActionWidget = !!child.invokeAction,
actionRefreshPolicy = child.getVariable("tv-action-refresh-policy");
// Refresh the child if required
if(childIsActionWidget || actionRefreshPolicy === "always") {
child.refreshSelf();
}
// Invoke the child if it is an action widget
if(childIsActionWidget) {
if(child.invokeAction(triggeringWidget,event)) {
handled = true;
}

Wyświetl plik

@ -1,5 +1,5 @@
created: 20141008134425548
modified: 20160429165240169
modified: 20210630163127249
tags: Widgets
title: ActionWidgets
type: text/vnd.tiddlywiki
@ -12,10 +12,10 @@ The following action widgets are provided:
There are two ways to use action widgets:
* Using the `actions` attribute of the triggering widget (this is the preferred way)
* Placing them within an action string attribute (typically called `actions`) on the triggering widget (this is the preferred way)
* Embedding the actions within the triggering widget (an older technique that is now deprecated)
!! Assigning action widgets with the `actions` attribute
!! Using action string attributes
The action widgets are passed as a string to the `actions` attribute of the triggering widget. Usually, it is more convenient to use a macro to assign the action widgets to a variable. For example, here is a button that triggers two actions of sending different messages:
@ -30,7 +30,7 @@ Click me!
</$button>
```
!! Assigning action widgets by embedding
!! Directly embedding action widgets
The action widgets need not be immediate children of their triggering widget, but they must be descendents of it. The actions are performed in sequence. Here is the above example rewritten to use embedding:
@ -42,3 +42,44 @@ Click me!
</$button>
```
! Action Execution Modes
<<.from-version "5.1.24">> The default behaviour of action widgets has some peculiarities that often cause confusion. There is now an improved mode that simplifies how things work, but due to BackwardsCompatibility constraints, it must be explicitly engaged in order to take advantage of it.
The peculiarities relate to the way that the results of previous action widgets are available to subsequent action widgets. By default, action widgets are refreshed before each execution which ensure that they reflect the results of previous actions. However, ordinary widgets are not updated in the same way. Thus, the following example fails:
<$macrocall $name='wikitext-example-without-html'
src='\define actions()
<$action-setfield $tiddler="ActionTestTiddler" $field="text" $value="FOO"/>
<$set name="newvalue" value={{{ [{ActionTestTiddler}lowercase[]] }}}>
<$action-setfield $tiddler="ActionTestTiddler" $field="text" $value=<<newvalue>>/>
</$set>
\end
Current value of ActionTestTiddler: {{ActionTestTiddler}}
<$button actions=<<actions>>>
Click me
</$button>'/>
The new behaviour avoids these problems by refreshing all widgets before execution, not just action widgets. It is engaged by setting the variable `tv-action-refresh-policy` to the value `always`. This can be done within an action string, or via a local variable declaration.
<<.warning "Do not attempt to set `tv-action-refresh-policy` globally. The core will not work correctly">>
The example above works as expected with the addition of `tv-action-refresh-policy`:
<$macrocall $name='wikitext-example-without-html'
src='\define tv-action-refresh-policy() always
\define actions()
<$action-setfield $tiddler="ActionTestTiddler" $field="text" $value="FOO"/>
<$set name="newvalue" value={{{ [{ActionTestTiddler}lowercase[]] }}}>
<$action-setfield $tiddler="ActionTestTiddler" $field="text" $value=<<newvalue>>/>
</$set>
\end
Current value of ActionTestTiddler: {{ActionTestTiddler}}
<$button actions=<<actions>>>
Click me
</$button>'/>