1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-08-06 22:04:19 +00:00

Improve refreshing of the data widget

This commit is contained in:
Jeremy Ruston 2024-05-31 12:43:21 +01:00
parent 7a50b2b554
commit ac855b0065

View File

@ -31,34 +31,49 @@ DataWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent; this.parentDomNode = parent;
this.computeAttributes(); this.computeAttributes();
this.execute(); this.execute();
var jsonPayload = JSON.stringify(this.readDataTiddlerValues(),null,4); this.dataPayload = this.computeDataTiddlerValues(); // Array of $tw.Tiddler objects
var textNode = this.document.createTextNode(jsonPayload); this.domNode = this.document.createTextNode(this.readDataTiddlerValuesAsJson());
parent.insertBefore(textNode,nextSibling); parent.insertBefore(this.domNode,nextSibling);
this.domNodes.push(textNode); this.domNodes.push(this.domNode);
}; };
/* /*
Compute the internal state of the widget Compute the internal state of the widget
*/ */
DataWidget.prototype.execute = function() { DataWidget.prototype.execute = function() {
// Construct the child widgets // Nothing to do here
this.makeChildWidgets();
}; };
/* /*
Read the tiddler value(s) from a data widget must be called after the .render() method Read the tiddler value(s) from a data widget as an array of tiddler field objects (not $tw.Tiddler objects)
*/ */
DataWidget.prototype.readDataTiddlerValues = function() { DataWidget.prototype.readDataTiddlerValues = function() {
var results = [];
$tw.utils.each(this.dataPayload,function(tiddler,index) {
results.push(tiddler.getFieldStrings());
});
return results;
};
/*
Read the tiddler value(s) from a data widget as an array of tiddler field objects (not $tw.Tiddler objects)
*/
DataWidget.prototype.readDataTiddlerValuesAsJson = function() {
return JSON.stringify(this.readDataTiddlerValues(),null,4);
};
/*
Compute list of tiddlers from a data widget
*/
DataWidget.prototype.computeDataTiddlerValues = function() {
var self = this; var self = this;
// Start with a blank object
var item = Object.create(null);
// Read any attributes not prefixed with $ // Read any attributes not prefixed with $
var item = Object.create(null);
$tw.utils.each(this.attributes,function(value,name) { $tw.utils.each(this.attributes,function(value,name) {
if(name.charAt(0) !== "$") { if(name.charAt(0) !== "$") {
item[name] = value; item[name] = value;
} }
}); });
item = new $tw.Tiddler(item);
// Deal with $tiddler, $filter or $compound-tiddler attributes // Deal with $tiddler, $filter or $compound-tiddler attributes
var tiddlers = [],title; var tiddlers = [],title;
if(this.hasAttribute("$tiddler")) { if(this.hasAttribute("$tiddler")) {
@ -86,21 +101,22 @@ DataWidget.prototype.readDataTiddlerValues = function() {
tiddlers.push.apply(tiddlers,this.extractCompoundTiddler(title)); tiddlers.push.apply(tiddlers,this.extractCompoundTiddler(title));
} }
} }
// Convert the literal item to field strings // Return the literal item if none of the special attributes were used
item = item.getFieldStrings(); if(!this.hasAttribute("$tiddler") && !this.hasAttribute("$filter") && !this.hasAttribute("$compound-tiddler")) {
if(tiddlers.length === 0) {
if(Object.keys(item).length > 0 && !!item.title) { if(Object.keys(item).length > 0 && !!item.title) {
return [item]; return [new $tw.Tiddler(item)];
} else { } else {
return []; return [];
} }
} else { } else {
var results = []; // Apply the item fields to each of the tiddlers
$tw.utils.each(tiddlers,function(tiddler,index) { delete item.title; // Do not overwrite the title
var fields = tiddler.getFieldStrings(); if(Object.keys(item).length > 0) {
results.push($tw.utils.extend({},fields,item)); $tw.utils.each(tiddlers,function(tiddler,index) {
}); tiddlers[index] = new $tw.Tiddler(tiddler,item);
return results; });
}
return tiddlers;
} }
}; };
@ -134,12 +150,33 @@ DataWidget.prototype.extractCompoundTiddler = function(title) {
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/ */
DataWidget.prototype.refresh = function(changedTiddlers) { DataWidget.prototype.refresh = function(changedTiddlers) {
// It would be expensive to calculate whether the changedTiddlers impact the filter var changedAttributes = this.computeAttributes();
// identified by the $filter attribute so we just refresh ourselves unconditionally var newPayload = this.computeDataTiddlerValues();
this.refreshSelf(); if(hasPayloadChanged(this.dataPayload,newPayload)) {
return true; this.dataPayload = newPayload;
this.domNode.textContent = this.readDataTiddlerValuesAsJson();
return true;
} else {
return false;
}
}; };
/*
Compare two arrays of tiddlers and return true if they are different
*/
function hasPayloadChanged(a,b) {
if(a.length === b.length) {
for(var t=0; t<a.length; t++) {
if(!(a[t].isEqual(b[t]))) {
return true;
}
}
return false;
} else {
return true;
}
}
exports.data = DataWidget; exports.data = DataWidget;
})(); })();