mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-29 12:59:56 +00:00
Alternate fix for inconsistent list template syntax (#7827)
* Alternate fix for inconsistent list template syntax First attempt, which fails on the ListWidget/WithMissingTemplate test. * Make WithMissingTemplate test pass, inefficiently Unfortunately, this ends up being very inefficient, because the clone-and-mutate logic is repeated for every list item. Not ideal. * More efficient way to do it This also makes the failing test pass, but far more efficiently. * Improve performance of list template discovery Since parse tree nodes never change after widget creation (whereas attribute values *can* change), we can safely search for the explicit list templtaes only once, at widget creation time. This saves time as the search doesn't have to be done on each re-render, and also allows us to safely do a clone-and-mutate step to extract the list widget's body (if any) without any `$list-empty` or other items. That, in turn, allows using the list widget's body as the template even if `$list-empty` is specified inside the widget body.
This commit is contained in:
parent
6567843927
commit
758089cbb3
@ -28,6 +28,18 @@ Inherit from the base widget class
|
|||||||
*/
|
*/
|
||||||
ListWidget.prototype = new Widget();
|
ListWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
ListWidget.prototype.initialise = function(parseTreeNode,options) {
|
||||||
|
// Bail if parseTreeNode is undefined, meaning that the ListWidget constructor was called without any arguments so that it can be subclassed
|
||||||
|
if(parseTreeNode === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// First call parent constructor to set everything else up
|
||||||
|
Widget.prototype.initialise.call(this,parseTreeNode,options);
|
||||||
|
// Now look for <$list-template> and <$list-empty> widgets as immediate child widgets
|
||||||
|
// This is safe to do during initialization because parse trees never change after creation
|
||||||
|
this.findExplicitTemplates();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Render this widget into the DOM
|
Render this widget into the DOM
|
||||||
*/
|
*/
|
||||||
@ -68,8 +80,6 @@ ListWidget.prototype.execute = function() {
|
|||||||
this.counterName = this.getAttribute("counter");
|
this.counterName = this.getAttribute("counter");
|
||||||
this.storyViewName = this.getAttribute("storyview");
|
this.storyViewName = this.getAttribute("storyview");
|
||||||
this.historyTitle = this.getAttribute("history");
|
this.historyTitle = this.getAttribute("history");
|
||||||
// Look for <$list-template> and <$list-empty> widgets as immediate child widgets
|
|
||||||
this.findExplicitTemplates();
|
|
||||||
// Compose the list elements
|
// Compose the list elements
|
||||||
this.list = this.getTiddlerList();
|
this.list = this.getTiddlerList();
|
||||||
var members = [],
|
var members = [],
|
||||||
@ -92,6 +102,7 @@ ListWidget.prototype.findExplicitTemplates = function() {
|
|||||||
var self = this;
|
var self = this;
|
||||||
this.explicitListTemplate = null;
|
this.explicitListTemplate = null;
|
||||||
this.explicitEmptyTemplate = null;
|
this.explicitEmptyTemplate = null;
|
||||||
|
this.hasTemplateInBody = false;
|
||||||
var searchChildren = function(childNodes) {
|
var searchChildren = function(childNodes) {
|
||||||
$tw.utils.each(childNodes,function(node) {
|
$tw.utils.each(childNodes,function(node) {
|
||||||
if(node.type === "list-template") {
|
if(node.type === "list-template") {
|
||||||
@ -100,6 +111,8 @@ ListWidget.prototype.findExplicitTemplates = function() {
|
|||||||
self.explicitEmptyTemplate = node.children;
|
self.explicitEmptyTemplate = node.children;
|
||||||
} else if(node.type === "element" && node.tag === "p") {
|
} else if(node.type === "element" && node.tag === "p") {
|
||||||
searchChildren(node.children);
|
searchChildren(node.children);
|
||||||
|
} else {
|
||||||
|
self.hasTemplateInBody = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -160,11 +173,11 @@ ListWidget.prototype.makeItemTemplate = function(title,index) {
|
|||||||
// Check for a <$list-item> widget
|
// Check for a <$list-item> widget
|
||||||
if(this.explicitListTemplate) {
|
if(this.explicitListTemplate) {
|
||||||
templateTree = this.explicitListTemplate;
|
templateTree = this.explicitListTemplate;
|
||||||
} else if (!this.explicitEmptyTemplate) {
|
} else if(this.hasTemplateInBody) {
|
||||||
templateTree = this.parseTreeNode.children;
|
templateTree = this.parseTreeNode.children;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!templateTree) {
|
if(!templateTree || templateTree.length === 0) {
|
||||||
// Default template is a link to the title
|
// Default template is a link to the title
|
||||||
templateTree = [{type: "element", tag: this.parseTreeNode.isBlock ? "div" : "span", children: [{type: "link", attributes: {to: {type: "string", value: title}}, children: [
|
templateTree = [{type: "element", tag: this.parseTreeNode.isBlock ? "div" : "span", children: [{type: "link", attributes: {to: {type: "string", value: title}}, children: [
|
||||||
{type: "text", text: title}
|
{type: "text", text: title}
|
||||||
@ -414,4 +427,27 @@ ListItemWidget.prototype.refresh = function(changedTiddlers) {
|
|||||||
|
|
||||||
exports.listitem = ListItemWidget;
|
exports.listitem = ListItemWidget;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Make <$list-template> and <$list-empty> widgets that do nothing
|
||||||
|
*/
|
||||||
|
var ListTemplateWidget = function(parseTreeNode,options) {
|
||||||
|
// Main initialisation inherited from widget.js
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
ListTemplateWidget.prototype = new Widget();
|
||||||
|
ListTemplateWidget.prototype.render = function() {}
|
||||||
|
ListTemplateWidget.prototype.refresh = function() { return false; }
|
||||||
|
|
||||||
|
exports["list-template"] = ListTemplateWidget;
|
||||||
|
|
||||||
|
var ListEmptyWidget = function(parseTreeNode,options) {
|
||||||
|
// Main initialisation inherited from widget.js
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
ListEmptyWidget.prototype = new Widget();
|
||||||
|
ListEmptyWidget.prototype.render = function() {}
|
||||||
|
ListEmptyWidget.prototype.refresh = function() { return false; }
|
||||||
|
|
||||||
|
exports["list-empty"] = ListEmptyWidget;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
Loading…
Reference in New Issue
Block a user