Custom widgets and filter operator names must now contain a period

Fixes #7428
This commit is contained in:
jeremy@jermolene.com 2023-06-01 08:06:28 +01:00
parent f19e74900e
commit 68a7655396
11 changed files with 39 additions and 44 deletions

View File

@ -21,7 +21,7 @@ Export our filter function
*/
exports["[unknown]"] = function(source,operator,options) {
// Check for a user defined filter operator
if(operator.operator.charAt(0) === ".") {
if(operator.operator.indexOf(".") !== -1) {
var variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(operator.operator);
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
var list = options.widget.evaluateVariable(operator.operator,{params: operator.operands, source: source});

View File

@ -78,7 +78,7 @@ exports.parseTag = function(source,pos,options) {
orderedAttributes: []
};
// Define our regexps
var reTagName = /([a-zA-Z0-9\-\$]+)/g;
var reTagName = /([a-zA-Z0-9\-\$\.]+)/g;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for a less than sign
@ -138,7 +138,7 @@ exports.parseTag = function(source,pos,options) {
exports.findNextTag = function(source,pos,options) {
// A regexp for finding candidate HTML tags
var reLookahead = /<([a-zA-Z\-\$]+)/g;
var reLookahead = /<([a-zA-Z\-\$\.]+)/g;
// Find the next candidate
reLookahead.lastIndex = pos;
var match = reLookahead.exec(source);

View File

@ -546,8 +546,8 @@ Widget.prototype.makeChildWidget = function(parseTreeNode,options) {
var variableDefinitionName = "$" + parseTreeNode.type;
if(this.variables[variableDefinitionName]) {
var isOverrideable = function() {
// Widget is overrideable if it has a double dollar user defined name, or if it is an existing JS widget and we're not in safe mode
return parseTreeNode.type.charAt(0) === "$" || (!!self.widgetClasses[parseTreeNode.type] && !$tw.safeMode);
// Widget is overrideable if its name contains a period, or if it is an existing JS widget and we're not in safe mode
return parseTreeNode.type.indexOf(".") !== -1 || (!!self.widgetClasses[parseTreeNode.type] && !$tw.safeMode);
};
if(!parseTreeNode.isNotRemappable && isOverrideable()) {
var variableInfo = this.getVariableInfo(variableDefinitionName,{allowSelfAssigned: true});

View File

@ -12,15 +12,15 @@ title: Output
title: Actions
\whitespace trim
<!-- Define the <$$action-mywidget> widget by defining a transcludable variable with that name -->
\widget $$action-mywidget(one:'Jaguar')
<!-- Define the <$action.mywidget> widget by defining a transcludable variable with that name -->
\widget $action.mywidget(one:'Jaguar')
\whitespace trim
<$action-setfield $tiddler="Result" $field="text" $value=<<one>>/>
\end
<$$action-mywidget one="Dingo">
<$action.mywidget one="Dingo">
Crocodile
</$$action-mywidget>
</$action.mywidget>
+
title: ExpectedResult

View File

@ -12,21 +12,21 @@ title: Output
title: TiddlerOne
\whitespace trim
<!-- Define the <$$mywidget> widget by defining a transcludable variable with that name -->
\widget $$mywidget(one:'Jaguar')
<!-- Define the <$my.widget> widget by defining a transcludable variable with that name -->
\widget $my.widget(one:'Jaguar')
\whitespace trim
<$text text=<<one>>/>
<$slot $name="ts-raw">
Whale
</$slot>
\end
<$$mywidget one="Dingo">
<$my.widget one="Dingo">
Crocodile
</$$mywidget>
<$$mywidget one="BumbleBee">
</$my.widget>
<$my.widget one="BumbleBee">
Squirrel
</$$mywidget>
<$$mywidget/>
</$my.widget>
<$my.widget/>
+
title: ExpectedResult

View File

@ -6,13 +6,13 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\widget $$mywidget()
\widget $my.widget()
<$slot $name=ts-raw>the body is empty</$slot>
\end
#<$$mywidget/>
#<$$mywidget></$$mywidget>
#<$$mywidget>the body is not empty</$$mywidget>
#<$my.widget/>
#<$my.widget></$my.widget>
#<$my.widget>the body is not empty</$my.widget>
+
title: ExpectedResult

View File

@ -6,21 +6,21 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
\widget $$mywidget(one:'Jaguar')
\widget $my.widget(one:'Jaguar')
\whitespace trim
<$text text=<<one>>/>
<$slot $name="ts-stuff">
Whale
</$slot>
\end
<$$mywidget one="Dingo">
<$my.widget one="Dingo">
<$fill $name="ts-stuff">
Crocodile
</$fill>
</$$mywidget>
<$$mywidget one="BumbleBee">
</$my.widget>
<$my.widget one="BumbleBee">
Squirrel
</$$mywidget>
</$my.widget>
+
title: ExpectedResult

View File

@ -12,17 +12,17 @@ title: Output
title: TiddlerOne
\whitespace trim
<!-- Redefine the <$$mywidget> widget by defining a transcludable variable with that name -->
\widget $$mywidget($variable:'Jaguar')
<!-- Redefine the <$my.widget> widget by defining a transcludable variable with that name -->
\widget $my.widget($variable:'Jaguar')
\whitespace trim
<$text text=<<$variable>>/>
<$slot $name="ts-raw">
Whale
</$slot>
\end
<$$mywidget $variable="Dingo">
<$my.widget $variable="Dingo">
Crocodile
</$$mywidget>
</$my.widget>
+
title: ExpectedResult

View File

@ -21,7 +21,7 @@ Functions can be invoked in several ways:
* Directly transclude functions with the syntax `<<myfn param:"value">>`
* Assign functions to widget attributes with the syntax `<div class=<<myfn param:"value">>>`
* Invoke functions via the [[function Operator]] with the syntax `[function[myfn],[value],...]`
* Directly invoke functions whose names start with a period as custom filter operators with the syntax `[.myfn[value]]`
* Directly invoke functions whose names contain a period as custom filter operators with the syntax `[my.fn[value]]` or `[.myfn[value]]`
!! How Functions Work

View File

@ -150,5 +150,5 @@ Below is an example macro, procedure and function definition. All three forms o
*''tiddler titles'' - tiddlers are uniquely identified by their title. The namespace for tiddler titles and variable names are completely separate.
*''variables'' - \define, <<.wlink SetWidget>>, <<.wlink LetWidget>>, <<.wlink VarsWidget>>, \procedure, \widget, \function all create variables. If the same name is used, then later define will overwrite earlier defined
*''<<.op function>> filter operator parameter'' - only variables defined using \function can be called using the <<.olink function>> operator
*''filter operators'' - only the [[javascript defined filter operators|Filter Operators]] and variables defined using \function with name starting with a dot can be called
*''filter operators'' - only the [[javascript defined filter operators|Filter Operators]] and variables defined using \function with name containing a dot can be called
*''widgets'' - variables defined using \widget can be invoked using `<$widget/>` syntax ONLY if the name starts a dollar sign (to override existing javascript defined widgets) or double dollar sign (to define [[custom widgets|Custom Widgets]]). Without the dollar sign prefix, defining variables using \widget is no different than using \procedure.

View File

@ -15,26 +15,21 @@ Custom widgets can also be used to override built-in JavaScript widgets to custo
Custom widgets are usually defined with the [[Pragma: \widget]]:
```
\widget $$my-widget(attribute:"Default value")
\widget $my.widget(attribute:"Default value")
This is the widget, and the attribute is <<attribute>>.
\end
```
The name of the widget must start with one or two dollar signs:
* A ''single dollar sign'' is used to override existing core widgets
** for example, `$text` or `$codeblock`
* ''Double dollar signs'' are used to define a custom widget
** for example, `$$mywidget` or `$$acme-logger`
The name of the widget must start with a dollar sign. If it is a user defined widget that does not override an existing widget then it must include at least one period (dot) within the name (for example `$my.widget` or `$acme.logger`).
!! Using Custom Widgets
Custom widgets are called in the same way as ordinary built-in widgets:
```
<$my-widget/>
<$my.widget/>
<$my-widget attribute="The parameter"/>
<$my.widget attribute="The parameter"/>
```
The attributes that are specified in the widget call are made available as parameter variables.
@ -45,18 +40,18 @@ Within the definition of a custom widget the content of the calling widget is av
For example:
<<wikitext-example-without-html """\widget $$mywidget(one:'Jaguar')
<<wikitext-example-without-html """\widget $my.widget(one:'Jaguar')
<$text text=<<one>>/>
<$slot $name="ts-raw">
Whale
</$slot>
\end
<$$mywidget one="Dingo">
<$my.widget one="Dingo">
Crocodile
</$$mywidget>
</$my.widget>
<$$mywidget/>""">>
<$my.widget/>""">>
!! How Custom Widgets Work