+
+
+```
+<$tiddlerfield/>
+```
+
+Renders as:
+
+<$tiddlerfield/>
+
+
+
+```
+<$view tiddler="test"/>
+```
+
+Renders as:
+
+<$view tiddler="test"/>
+
+
+$list>
+"""/>
+
+$innerwiki>
+$list>
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh demo II.tid b/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh demo II.tid
new file mode 100644
index 000000000..60997a9ca
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh demo II.tid
@@ -0,0 +1,40 @@
+created: 20190202032354223
+modified: 20190217005540498
+tags:
+title: Widget refresh demo II
+type: text/vnd.tiddlywiki
+
+
+<$list name=refresh filter=[[tiddlerfield.js]get[text]]>
+<$innerwiki width="600" height="400" style="width:100%;">
+ <$data title="$:/DefaultTiddlers" text="[[tiddler field widget]]"/>
+ <$data title="test" text="type new text here"/>
+ <$data $tiddler=tiddlerfield.js/>
+ <$data title="tiddler field widget" text="""
+<$edit-text focus=yes tiddler=test tag=input/>
+
+
+
+
+```
+<$tiddlerfield/>
+```
+
+Renders as:
+
+<$tiddlerfield/>
+
+
+
+```
+<$view tiddler="test"/>
+```
+
+Renders as:
+
+<$view tiddler="test"/>
+
+"""/>
+
+$innerwiki>
+$list>
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh demo III.tid b/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh demo III.tid
new file mode 100644
index 000000000..0c6fec3dd
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh demo III.tid
@@ -0,0 +1,50 @@
+created: 20190202122928187
+modified: 20190216191939585
+tags:
+title: Widget refresh demo III
+type: text/vnd.tiddlywiki
+
+
+<$list name=refresh filter=[[refreshcount.js]get[text]]>
+<$innerwiki width="600" height="400" style="width:100%;">
+ <$data title="$:/DefaultTiddlers" text="[[refresh count widget]]"/>
+ <$data title="test" text="Text field of tiddler='test'"/>
+ <$data $tiddler=refreshcount.js/>
+ <$data title="refresh count widget" text="""
+
+*<$button set="test!!test" setTo="hello">Modify a different tiddler$button>
+*<$button set="!!test" setTo="hello">Modify this tiddler$button>
+*<$edit-text focus=yes tiddler=test tag=input/>
+
+
+
+
+```
+<$refreshcount/>
+```
+
+Renders as:
+
+<$refreshcount/>
+
+
+
+
+```
+<$list filter="[[test]get[text]]">
+<>
+<$refreshcount/>
+$list>
+```
+
+Renders as:
+
+<$list filter="[[test]get[text]]">
+<>
+<$refreshcount/>
+$list>
+"""/>
+
+
+$innerwiki>
+$list>
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh tutorial part I.tid b/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh tutorial part I.tid
new file mode 100644
index 000000000..4665e6535
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh tutorial part I.tid
@@ -0,0 +1,47 @@
+created: 20190201232847949
+modified: 20221029203553291
+tags:
+title: Widget refresh tutorial part I
+type: text/vnd.tiddlywiki
+
+But what if we want to display dynamic content? How can we display information and keep it up to date as it changes? Let's display the content of a tiddler field.
+
+The [[tiddlerfield-norefresh.js]] which defines the `tiddlerfield` widget is almost the same as [[hello.js]] except for this part:
+
+```javascript
+MyWidget.prototype.render = function(parent,nextSibling) {
+ this.parentDomNode = parent;
+ var text = this.wiki.getTiddlerText("test", "
")
+ var textNode = this.document.createTextNode(text);
+ parent.insertBefore(textNode,nextSibling);
+ this.domNodes.push(textNode);
+};
+```
+
+Instead of creating the text dom node from a static string, the text field of the `test` tiddler is used. This is similar to using the view widget like this: `<$view tiddler="test"/>`
+
+Here's how it looks (see [[Widget refresh demo I]] to look at the code):
+
+{{Widget refresh demo I}}
+
+Notice if you change the text in the input box, the output from the `tiddlerfield` widget doesn't change, but the output of the `view` widget does. Only after the ''Force refresh'' button is clicked does the output of `tiddlerfield` update to match the input box contents.
+
+What's going on here? The render method of the widget code is only called by tiddlywiki core when the widget is first created. After that, it isn't called again unless the widget is completely destroyed and then created again.
+
+The tiddlywiki ~ViewWidget has a properly written `refresh` method so typing in the input box will cause its content to update. However, the `tiddlerfield` widget does not have a `refresh` method at all. It has no way of being notified that the `test` tiddler content has changed. Its output will not change until the ''Force refresh'' button is clicked.
+
+See the next example for an implementation of the `refresh` method for the `tiddlerfield` widget.
+
+The code for the refresh button looks like this:
+
+```
+<$button set="!!refresh" setTo={{test}}>Force refresh$button>
+```
+
+and the widgets are enclosed in a list widget like this:
+
+```
+<$list filter="[{!!refresh}]">...$list>
+```
+
+When the button is clicked the field `refresh` in the containing tiddler is modified and it causes the children of the list widget to be created from scratch. The render method is called and the output of the `tiddlerfield` widget updates.
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh tutorial part II.tid b/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh tutorial part II.tid
new file mode 100644
index 000000000..dfb86a640
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh tutorial part II.tid
@@ -0,0 +1,37 @@
+created: 20190201232910076
+modified: 20190217014335419
+tags:
+title: Widget refresh tutorial part II
+type: text/vnd.tiddlywiki
+
+This example is like [[Widget refresh tutorial part I]] except the widget output will be automatically refreshed when the tiddler field changes.
+
+[[tiddlerfield.js]] is the same as [[tiddlerfield-norefresh.js]], except this `refresh` method is added:
+
+```javascript
+/*
+A widget with optimized performance will selectively refresh, but here we refresh always
+*/
+MyWidget.prototype.refresh = function(changedTiddlers) {
+ // Regenerate and rerender the widget and
+ // replace the existing DOM node
+ this.refreshSelf();
+ return true;
+};
+```
+
+The `refreshSelf` method called above is implemented by the core widget class and it takes care of cleaning the old dom node and calling the render function.
+
+Here is the result ([[Widget refresh demo II]]):
+
+{{Widget refresh demo II}}
+
+And now any typing into the input box will cause both the `tiddlerfield` and the `view` widget output to refresh immediately.
+
+Note this is a naive version of `refresh`. It unconditionally refreshes itself. This is far from optimal since the `refresh` method for all visible widgets is called every time the tiddler store changes. But the way we've defined our widget, the output ONLY depends on the tiddler titled `text`.
+
+In tiddlywiki the tiddler store is used for everything and almost any interaction will result in an update to the store. This means almost any interaction will cause the refresh method to be called. If you type into the search box, for example, the `tiddlerfield` widget will be refreshed with every keystroke.
+
+Adding and removing dom elements is a relatively expensive operation, so if someone has used the list widget to create a few hundred instances of this widget, then such tiddlywiki interactions might gain a noticable lag. Therefore, it usually makes sense to avoid modifying the dom when possible by writing a smarter `refresh` method.
+
+''Exercise'' - change the refresh method above to only call `refreshSelf` when the `changedTiddlers` input array contains `test` as one of its entries (Hint: see the refresh method in $:/core/modules/widgets/view.js for an example).
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh tutorial part III.tid b/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh tutorial part III.tid
new file mode 100644
index 000000000..f8729b784
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/Widget refresh tutorial part III.tid
@@ -0,0 +1,26 @@
+created: 20190202034841184
+modified: 20221029201023638
+tags:
+title: Widget refresh tutorial part III
+type: text/vnd.tiddlywiki
+
+This tutorial is intended to demonstrate a few examples of when calls to the `refresh` method happen vs. when a widget is recreated from scratch.
+
+This is accomplished with a [[refreshcount.js]] widget which sets a counter to zero when the widget is created and increments the counter every time the `refresh` method is called. Here is the full code:
+
+{{refreshcount.js}}
+
+These are the key parts of the code from above:
+
+```javascript
+this.refreshCount = 0;
+this.document.createTextNode(this.refreshCount + " refreshes");
+this.refreshCount++;
+```
+
+In the following example (see [[Widget refresh demo III]] for the code), two instances of the `refreshcount` widget are created. One at the top level and the other inside a list widget whose filter results depend on the value in the `text` field of the `test` widget. The tiddler store can be modified in a few ways via two buttons and an input box:
+{{Widget refresh demo III}}
+
+* ''Modify a different tiddler'' - every time this button is clicked, both counters increment, indicating the `refresh` method is being called
+* ''Modify this tiddler'' - clicking this button modifies the tiddler itself. In earlier ~TiddlyWiki versions that caused both widgets to be recreated from scratch and the counters are thereby reset to zero. Since [[version 5.2.0|https://tiddlywiki.com/#Release%205.2.0]] modifying another field in this tiddler does not cause the widgets to be recreated and the counters are not reset.
+* ''Text field of tiddler='test''' - typing text into the input box causes the counter in the standalone `refreshcount` widget to be incremented. But the other instance of the widget is embedded inside a list widget whose filter output depends on the value of the tiddler field which is being modified. This causes it to recreate its children from scratch and the counter is reset every time. So with every keystroke, the counter on the left is incremented, but the counter on the right goes to/stays at zero.
\ No newline at end of file
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/domwidget.js b/editions/dev/tiddlers/javascript-widget-tutorial/domwidget.js
new file mode 100644
index 000000000..243839764
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/domwidget.js
@@ -0,0 +1,47 @@
+/*\
+
+Library function for creating widget using a dom creating function
+
+\*/
+(function() {
+
+/*jslint node: true, browser: true */
+/*global $tw: false */
+"use strict";
+
+var Widget = require("$:/core/modules/widgets/widget.js").widget;
+
+function createDomWidget(domCreatorFunction) {
+
+ var MyWidget = function(parseTreeNode, options) {
+ this.initialise(parseTreeNode, options);
+ };
+
+ /*
+ Inherit from the base widget class
+ */
+ MyWidget.prototype = new Widget();
+
+ /*
+ Render this widget into the DOM
+ */
+ MyWidget.prototype.render = function(parent, nextSibling) {
+ this.parentDomNode = parent;
+ var domNode = domCreatorFunction(this.document);
+ parent.insertBefore(domNode, nextSibling);
+ this.domNodes.push(domNode);
+ };
+
+ /*
+ A widget with optimized performance will selectively refresh, but here we refresh always
+ */
+ MyWidget.prototype.refresh = function(changedTiddlers) {
+ // Regenerate and rerender the widget and replace the existing DOM node
+ this.refreshSelf();
+ return true;
+ };
+
+ return MyWidget;
+}
+module.exports = createDomWidget;
+})();
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/domwidget.js.meta b/editions/dev/tiddlers/javascript-widget-tutorial/domwidget.js.meta
new file mode 100644
index 000000000..55235998f
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/domwidget.js.meta
@@ -0,0 +1,6 @@
+created: 20190201025244440
+modified: 20190201030708723
+module-type: library
+tags:
+title: domwidget.js
+type: application/javascript
\ No newline at end of file
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/donothing.js b/editions/dev/tiddlers/javascript-widget-tutorial/donothing.js
new file mode 100644
index 000000000..b1899b645
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/donothing.js
@@ -0,0 +1,16 @@
+/*\
+
+Do nothing widget
+
+\*/
+(function(){
+
+/*jslint node: true, browser: true */
+/*global $tw: false */
+"use strict";
+
+var Widget = require("$:/core/modules/widgets/widget.js").widget;
+
+exports.donothing = Widget;
+
+})();
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/donothing.js.meta b/editions/dev/tiddlers/javascript-widget-tutorial/donothing.js.meta
new file mode 100644
index 000000000..a8e70b03c
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/donothing.js.meta
@@ -0,0 +1,6 @@
+created: 20190201115945945
+modified: 20190201222441271
+module-type: widget
+tags:
+title: donothing.js
+type: application/javascript
\ No newline at end of file
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute-optimized.js b/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute-optimized.js
new file mode 100644
index 000000000..71cec1762
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute-optimized.js
@@ -0,0 +1,51 @@
+/*\
+
+Hello, World widget
+
+\*/
+(function() {
+
+/*jslint node: true, browser: true */
+/*global $tw: false */
+"use strict";
+
+var Widget = require("$:/core/modules/widgets/widget.js").widget;
+
+var MyWidget = function(parseTreeNode, options) {
+ this.initialise(parseTreeNode, options);
+};
+
+/*
+Inherit from the base widget class
+*/
+MyWidget.prototype = new Widget();
+
+/*
+Render this widget into the DOM
+*/
+MyWidget.prototype.render = function(parent, nextSibling) {
+ this.parentDomNode = parent;
+ this.computeAttributes();
+ var message = this.getAttribute("message", "World");
+ var textNode = this.document.createTextNode("Hello, " + message + "!");
+ parent.insertBefore(textNode, nextSibling);
+ this.domNodes.push(textNode);
+};
+
+/*
+Refresh if the attribute value changed since render
+*/
+MyWidget.prototype.refresh = function(changedTiddlers) {
+ // Find which attributes have changed
+ var changedAttributes = this.computeAttributes();
+ if (changedAttributes.message) {
+ this.refreshSelf();
+ return true;
+ } else {
+ return false;
+ }
+};
+
+exports.hello = MyWidget;
+
+})();
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute-optimized.js.meta b/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute-optimized.js.meta
new file mode 100644
index 000000000..e195f4bfa
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute-optimized.js.meta
@@ -0,0 +1,6 @@
+created: 20190205024846183
+modified: 20190205025110882
+module-type: widget
+tags:
+title: hello-attribute-optimized.js
+type: application/javascript
\ No newline at end of file
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute.js b/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute.js
new file mode 100644
index 000000000..3e91aa122
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute.js
@@ -0,0 +1,47 @@
+/*\
+
+Hello, World widget
+
+\*/
+(function() {
+
+/*jslint node: true, browser: true */
+/*global $tw: false */
+"use strict";
+
+var Widget = require("$:/core/modules/widgets/widget.js").widget;
+
+var MyWidget = function(parseTreeNode, options) {
+ this.initialise(parseTreeNode, options);
+};
+
+/*
+Inherit from the base widget class
+*/
+MyWidget.prototype = new Widget();
+
+/*
+Render this widget into the DOM
+*/
+MyWidget.prototype.render = function(parent, nextSibling) {
+ this.parentDomNode = parent;
+ this.computeAttributes();
+ var message = this.getAttribute("message", "World");
+ var textNode = this.document.createTextNode("Hello, " + message + "!");
+ parent.insertBefore(textNode, nextSibling);
+ this.domNodes.push(textNode);
+};
+
+/*
+A widget with optimized performance will selectively refresh, but here we refresh always
+*/
+MyWidget.prototype.refresh = function(changedTiddlers) {
+ // Regenerate and rerender the widget and
+ // replace the existing DOM node
+ this.refreshSelf();
+ return true;
+};
+
+exports.hello = MyWidget;
+
+})();
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute.js.meta b/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute.js.meta
new file mode 100644
index 000000000..008086c2a
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/hello-attribute.js.meta
@@ -0,0 +1,6 @@
+created: 20190204020011193
+modified: 20190204030332147
+module-type: widget
+tags:
+title: hello-attribute.js
+type: application/javascript
\ No newline at end of file
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/hello.js b/editions/dev/tiddlers/javascript-widget-tutorial/hello.js
new file mode 100644
index 000000000..91afbd8f4
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/hello.js
@@ -0,0 +1,35 @@
+/*\
+
+Hello, World widget
+
+\*/
+(function(){
+
+/*jslint node: true, browser: true */
+/*global $tw: false */
+"use strict";
+
+var Widget = require("$:/core/modules/widgets/widget.js").widget;
+
+var MyWidget = function(parseTreeNode,options) {
+ this.initialise(parseTreeNode,options);
+};
+
+/*
+Inherit from the base widget class
+*/
+MyWidget.prototype = new Widget();
+
+/*
+Render this widget into the DOM
+*/
+MyWidget.prototype.render = function(parent,nextSibling) {
+ this.parentDomNode = parent;
+ var textNode = this.document.createTextNode("Hello, World!");
+ parent.insertBefore(textNode,nextSibling);
+ this.domNodes.push(textNode);
+};
+
+exports.hello = MyWidget;
+
+})();
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/hello.js.meta b/editions/dev/tiddlers/javascript-widget-tutorial/hello.js.meta
new file mode 100644
index 000000000..2518f08ec
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/hello.js.meta
@@ -0,0 +1,6 @@
+created: 20190201114558816
+modified: 20190201224846870
+module-type: widget
+tags:
+title: hello.js
+type: application/javascript
\ No newline at end of file
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/refreshcount.js b/editions/dev/tiddlers/javascript-widget-tutorial/refreshcount.js
new file mode 100644
index 000000000..b8ee53d89
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/refreshcount.js
@@ -0,0 +1,43 @@
+/*\
+
+widget to count the number of times this widget refreshes
+
+\*/
+(function() {
+
+/*jslint node: true, browser: true */
+/*global $tw: false */
+"use strict";
+
+var Widget = require("$:/core/modules/widgets/widget.js").widget;
+
+var MyWidget = function(parseTreeNode, options) {
+ this.refreshCount = 0;
+ this.initialise(parseTreeNode, options);
+};
+
+/*
+Inherit from the base widget class
+*/
+MyWidget.prototype = new Widget();
+
+/*
+Render this widget into the DOM
+*/
+MyWidget.prototype.render = function(parent, nextSibling) {
+ this.parentDomNode = parent;
+ var textNode = this.document.createTextNode(this.refreshCount + " refreshes");
+ parent.insertBefore(textNode, nextSibling);
+ this.domNodes.push(textNode);
+};
+
+MyWidget.prototype.refresh = function(changedTiddlers) {
+ // Regenerate and rerender the widget and replace the existing DOM node
+ this.refreshCount++;
+ this.refreshSelf();
+ return true;
+};
+
+exports.refreshcount = MyWidget;
+
+})();
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/refreshcount.js.meta b/editions/dev/tiddlers/javascript-widget-tutorial/refreshcount.js.meta
new file mode 100644
index 000000000..86831cb85
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/refreshcount.js.meta
@@ -0,0 +1,6 @@
+created: 20190201005026324
+modified: 20190202143451303
+module-type: widget
+tags:
+title: refreshcount.js
+type: application/javascript
\ No newline at end of file
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield-norefresh.js b/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield-norefresh.js
new file mode 100644
index 000000000..59f179b5d
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield-norefresh.js
@@ -0,0 +1,36 @@
+/*\
+
+Hello, World widget
+
+\*/
+(function() {
+
+/*jslint node: true, browser: true */
+/*global $tw: false */
+"use strict";
+
+var Widget = require("$:/core/modules/widgets/widget.js").widget;
+
+var MyWidget = function(parseTreeNode, options) {
+ this.initialise(parseTreeNode, options);
+};
+
+/*
+Inherit from the base widget class
+*/
+MyWidget.prototype = new Widget();
+
+/*
+Render this widget into the DOM
+*/
+MyWidget.prototype.render = function(parent, nextSibling) {
+ this.parentDomNode = parent;
+ var text = this.wiki.getTiddlerText("test", "")
+ var textNode = this.document.createTextNode(text);
+ parent.insertBefore(textNode, nextSibling);
+ this.domNodes.push(textNode);
+};
+
+exports.tiddlerfield = MyWidget;
+
+})();
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield-norefresh.js.meta b/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield-norefresh.js.meta
new file mode 100644
index 000000000..bab1ed0cb
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield-norefresh.js.meta
@@ -0,0 +1,6 @@
+created: 20190201233714872
+modified: 20190202030615781
+module-type: widget
+tags:
+title: tiddlerfield-norefresh.js
+type: application/javascript
\ No newline at end of file
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield.js b/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield.js
new file mode 100644
index 000000000..c19e84f60
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield.js
@@ -0,0 +1,46 @@
+/*\
+
+Hello, World widget
+
+\*/
+(function() {
+
+/*jslint node: true, browser: true */
+/*global $tw: false */
+"use strict";
+
+var Widget = require("$:/core/modules/widgets/widget.js").widget;
+
+var MyWidget = function(parseTreeNode, options) {
+ this.initialise(parseTreeNode, options);
+};
+
+/*
+Inherit from the base widget class
+*/
+MyWidget.prototype = new Widget();
+
+/*
+Render this widget into the DOM
+*/
+MyWidget.prototype.render = function(parent, nextSibling) {
+ this.parentDomNode = parent;
+ var text = this.wiki.getTiddlerText("test", "")
+ var textNode = this.document.createTextNode(text);
+ parent.insertBefore(textNode, nextSibling);
+ this.domNodes.push(textNode);
+};
+
+/*
+A widget with optimized performance will selectively refresh, but here we refresh always
+*/
+MyWidget.prototype.refresh = function(changedTiddlers) {
+ // Regenerate and rerender the widget and
+ // replace the existing DOM node
+ this.refreshSelf();
+ return true;
+};
+
+exports.tiddlerfield = MyWidget;
+
+})();
diff --git a/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield.js.meta b/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield.js.meta
new file mode 100644
index 000000000..b5160e75a
--- /dev/null
+++ b/editions/dev/tiddlers/javascript-widget-tutorial/tiddlerfield.js.meta
@@ -0,0 +1,6 @@
+created: 20190202032530728
+modified: 20190202032700995
+module-type: widget
+tags:
+title: tiddlerfield.js
+type: application/javascript
\ No newline at end of file
diff --git a/editions/dev/tiddlywiki.info b/editions/dev/tiddlywiki.info
index 186ff45ee..1a8207f1e 100644
--- a/editions/dev/tiddlywiki.info
+++ b/editions/dev/tiddlywiki.info
@@ -5,7 +5,8 @@
"tiddlywiki/nodewebkitsaver",
"tiddlywiki/github-fork-ribbon",
"tiddlywiki/menubar",
- "tiddlywiki/internals"
+ "tiddlywiki/internals",
+ "tiddlywiki/innerwiki"
],
"themes": [
"tiddlywiki/vanilla",