1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-06-30 01:03:16 +00:00

Refactor data widget implementation

To avoid code duplication
This commit is contained in:
jeremy@jermolene.com 2023-04-13 08:42:18 +01:00
parent 3aac8e1c8a
commit b6181e1cb1
4 changed files with 60 additions and 130 deletions

View File

@ -42,6 +42,42 @@ DataWidget.prototype.execute = function() {
this.makeChildWidgets(); this.makeChildWidgets();
}; };
/*
Read the tiddler value(s) from a data widget must be called after the .render() method
*/
DataWidget.prototype.readDataTiddlerValues = function() {
var self = this;
// Start with a blank object
var item = Object.create(null);
// Read any attributes not prefixed with $
$tw.utils.each(this.attributes,function(value,name) {
if(name.charAt(0) !== "$") {
item[name] = value;
}
});
// Deal with $tiddler or $filter attributes
var titles;
if(this.hasAttribute("$tiddler")) {
titles = [this.getAttribute("$tiddler")];
} else if(this.hasAttribute("$filter")) {
titles = this.wiki.filterTiddlers(this.getAttribute("$filter"));
}
if(titles) {
var results = [];
$tw.utils.each(titles,function(title,index) {
var tiddler = self.wiki.getTiddler(title),
fields;
if(tiddler) {
fields = tiddler.getFieldStrings();
}
results.push($tw.utils.extend({},fields,item));
})
return results;
} else {
return [item];
}
};
/* /*
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
*/ */

View File

@ -48,7 +48,10 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) {
// Create a wiki // Create a wiki
this.testcaseWiki = new $tw.Wiki(); this.testcaseWiki = new $tw.Wiki();
// Load tiddlers from child data widgets // Load tiddlers from child data widgets
var tiddlers = this.readTiddlerDataWidgets(this.contentRoot.children); var tiddlers = [];
this.findChildrenDataWidgets(this.contentRoot.children,"data",function(widget) {
Array.prototype.push.apply(tiddlers,widget.readDataTiddlerValues());
});
this.testcaseWiki.addTiddlers(tiddlers); this.testcaseWiki.addTiddlers(tiddlers);
// Load tiddlers from the optional testcaseTiddler // Load tiddlers from the optional testcaseTiddler
if(this.testcaseTiddler) { if(this.testcaseTiddler) {
@ -119,70 +122,6 @@ TestCaseWidget.prototype.testcaseRawTiddler = function(parent,nextSibling,title,
parent.insertBefore(this.document.createTextNode(text),nextSibling); parent.insertBefore(this.document.createTextNode(text),nextSibling);
}; };
/*
Find child data widgets
*/
TestCaseWidget.prototype.findDataWidgets = function(children,tag,callback) {
var self = this;
$tw.utils.each(children,function(child) {
if(child.dataWidgetTag === tag) {
callback(child);
}
if(child.children) {
self.findDataWidgets(child.children,tag,callback);
}
});
};
/*
Find the child data widgets
*/
TestCaseWidget.prototype.readTiddlerDataWidgets = function(children) {
var self = this,
results = [];
this.findDataWidgets(children,"data",function(widget) {
Array.prototype.push.apply(results,self.readTiddlerDataWidget(widget));
});
return results;
};
/*
Read the value(s) from a data widget
*/
TestCaseWidget.prototype.readTiddlerDataWidget = function(dataWidget) {
var self = this;
// Start with a blank object
var item = Object.create(null);
// Read any attributes not prefixed with $
$tw.utils.each(dataWidget.attributes,function(value,name) {
if(name.charAt(0) !== "$") {
item[name] = value;
}
});
// Deal with $tiddler or $filter attributes
var titles;
if(dataWidget.hasAttribute("$tiddler")) {
titles = [dataWidget.getAttribute("$tiddler")];
} else if(dataWidget.hasAttribute("$filter")) {
titles = this.wiki.filterTiddlers(dataWidget.getAttribute("$filter"));
}
if(titles) {
var self = this;
var results = [];
$tw.utils.each(titles,function(title,index) {
var tiddler = self.wiki.getTiddler(title),
fields;
if(tiddler) {
fields = tiddler.getFieldStrings();
}
results.push($tw.utils.extend({},fields,item));
})
return results;
} else {
return [item];
}
};
/* /*
Compute the internal state of the widget Compute the internal state of the widget
*/ */

View File

@ -829,6 +829,21 @@ Widget.prototype.allowActionPropagation = function() {
return true; return true;
}; };
/*
Find child <$data> widgets recursively. The tag name allows aliased versions of the widget to be found too
*/
Widget.prototype.findChildrenDataWidgets = function(children,tag,callback) {
var self = this;
$tw.utils.each(children,function(child) {
if(child.dataWidgetTag === tag) {
callback(child);
}
if(child.children) {
self.findChildrenDataWidgets(child.children,tag,callback);
}
});
};
exports.widget = Widget; exports.widget = Widget;
})(); })();

View File

@ -143,7 +143,7 @@ Create the anchors
*/ */
InnerWikiWidget.prototype.createAnchors = function() { InnerWikiWidget.prototype.createAnchors = function() {
var self = this; var self = this;
this.findDataWidgets(this.children,"anchor",function(widget) { this.findChildrenDataWidgets(this.children,"anchor",function(widget) {
var anchorWidth = 40, var anchorWidth = 40,
anchorHeight = 40, anchorHeight = 40,
getAnchorCoordinate = function(name) { getAnchorCoordinate = function(name) {
@ -233,76 +233,16 @@ InnerWikiWidget.prototype.createInnerHTML = function() {
IMPLANT_PREFIX = "<" + "script>\n$tw.preloadTiddlerArray(", IMPLANT_PREFIX = "<" + "script>\n$tw.preloadTiddlerArray(",
IMPLANT_SUFFIX = ");\n</" + "script>\n", IMPLANT_SUFFIX = ");\n</" + "script>\n",
parts = html.split(SPLIT_MARKER), parts = html.split(SPLIT_MARKER),
tiddlers = this.readTiddlerDataWidgets(this.children); tiddlers = [];
this.findChildrenDataWidgets(this.children,"data",function(widget) {
Array.prototype.push.apply(tiddlers,widget.readDataTiddlerValues());
});
if(parts.length === 2) { if(parts.length === 2) {
html = parts[0] + IMPLANT_PREFIX + JSON.stringify(tiddlers) + IMPLANT_SUFFIX + SPLIT_MARKER + parts[1]; html = parts[0] + IMPLANT_PREFIX + JSON.stringify(tiddlers) + IMPLANT_SUFFIX + SPLIT_MARKER + parts[1];
} }
return html; return html;
}; };
/*
Find child data widgets
*/
InnerWikiWidget.prototype.findDataWidgets = function(children,tag,callback) {
var self = this;
$tw.utils.each(children,function(child) {
if(child.dataWidgetTag === tag) {
callback(child);
}
if(child.children) {
self.findDataWidgets(child.children,tag,callback);
}
});
};
/*
Find the child data widgets
*/
InnerWikiWidget.prototype.readTiddlerDataWidgets = function(children) {
var self = this,
results = [];
this.findDataWidgets(children,"data",function(widget) {
Array.prototype.push.apply(results,self.readTiddlerDataWidget(widget));
});
return results;
};
/*
Read the value(s) from a data widget
*/
InnerWikiWidget.prototype.readTiddlerDataWidget = function(dataWidget) {
// Start with a blank object
var item = Object.create(null);
// Read any attributes not prefixed with $
$tw.utils.each(dataWidget.attributes,function(value,name) {
if(name.charAt(0) !== "$") {
item[name] = value;
}
});
// Deal with $tiddler or $filter attributes
var titles;
if(dataWidget.hasAttribute("$tiddler")) {
titles = [dataWidget.getAttribute("$tiddler")];
} else if(dataWidget.hasAttribute("$filter")) {
titles = this.wiki.filterTiddlers(dataWidget.getAttribute("$filter"));
}
if(titles) {
var self = this;
var results = [];
$tw.utils.each(titles,function(title,index) {
var tiddler = self.wiki.getTiddler(title),
fields;
if(tiddler) {
fields = tiddler.getFieldStrings();
}
results.push($tw.utils.extend({},fields,item));
})
return results;
} else {
return [item];
}
};
/* /*
Compute the internal state of the widget Compute the internal state of the widget
*/ */