1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-12-10 10:48:05 +00:00

Refactor rendertree to simplify context handling

Get rid of the separate renderContext stack and instead have a parent
pointer on renderer nodes. This lets us walk back up the render tree to
resolve context references
This commit is contained in:
Jeremy Ruston
2013-05-15 17:32:17 +01:00
parent 32dc09d8ac
commit 8564602256
42 changed files with 175 additions and 183 deletions

View File

@@ -48,21 +48,21 @@ ButtonWidget.prototype.generate = function() {
// Set the return element
this.tag = "button";
this.attributes ={"class": classes.join(" ")};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,this.renderer.parseTreeNode.children);
this.children = this.renderer.renderTree.createRenderers(this.renderer,this.renderer.parseTreeNode.children);
this.events = events;
};
ButtonWidget.prototype.dispatchMessage = function(event) {
$tw.utils.dispatchCustomEvent(event.target,this.message,{
param: this.param,
tiddlerTitle: this.renderer.getContextTiddlerTitle()
tiddlerTitle: this.renderer.tiddlerTitle
});
};
ButtonWidget.prototype.triggerPopup = function(event) {
var title = this.popup;
if(this.qualifyTiddlerTitles) {
title = title + "-" + this.renderer.getContextScopeId();
title = title + "-" + this.renderer.renderTree.getContextScopeId(this.renderer.parentRenderer);
}
$tw.popup.triggerPopup({
domNode: this.renderer.domNode,
@@ -74,7 +74,7 @@ ButtonWidget.prototype.triggerPopup = function(event) {
ButtonWidget.prototype.isSelected = function() {
var title = this.set;
if(this.qualifyTiddlerTitles) {
title = title + "-" + this.renderer.getContextScopeId();
title = title + "-" + this.renderer.renderTree.getContextScopeId(this.renderer.parentRenderer);
}
var tiddler = this.renderer.renderTree.wiki.getTiddler(title);
return tiddler ? tiddler.fields.text === this.setTo : false;
@@ -83,7 +83,7 @@ ButtonWidget.prototype.isSelected = function() {
ButtonWidget.prototype.setTiddler = function() {
var title = this.set;
if(this.qualifyTiddlerTitles) {
title = title + "-" + this.renderer.getContextScopeId();
title = title + "-" + this.renderer.renderTree.getContextScopeId(this.renderer.parentRenderer);
}
var tiddler = this.renderer.renderTree.wiki.getTiddler(title);
this.renderer.renderTree.wiki.addTiddler(new $tw.Tiddler(tiddler,{title: title, text: this.setTo}));
@@ -120,7 +120,7 @@ ButtonWidget.prototype.refreshInDom = function(changedAttributes,changedTiddlers
var setTitle = this.set,
popupTitle = this.popup;
if(this.qualifyTiddlerTitles) {
var scopeId = this.renderer.getContextScopeId();
var scopeId = this.renderer.renderTree.getContextScopeId(this.renderer.parentRenderer);
if(setTitle) {
setTitle = setTitle + "-" + scopeId;
}

View File

@@ -31,7 +31,7 @@ var CheckboxWidget = function(renderer) {
CheckboxWidget.prototype.generate = function() {
// Get the parameters from the attributes
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.getContextTiddlerTitle());
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.tiddlerTitle);
this.tagName = this.renderer.getAttribute("tag");
this["class"] = this.renderer.getAttribute("class");
// Compute classes
@@ -59,7 +59,7 @@ CheckboxWidget.prototype.generate = function() {
// Set the return element
this.tag = "label";
this.attributes ={"class": classes.join(" ")};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[nodeCheckbox,nodeSpan]);
this.children = this.renderer.renderTree.createRenderers(this.renderer,[nodeCheckbox,nodeSpan]);
this.events = [{name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"}];
};

View File

@@ -26,7 +26,7 @@ var EditWidget = function(renderer) {
EditWidget.prototype.generate = function() {
// Get parameters from our attributes
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.getContextTiddlerTitle());
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.tiddlerTitle);
this.fieldName = this.renderer.getAttribute("field","text");
// Choose the editor to use
// TODO: Tiddler field modules should be able to specify a field type from which the editor is derived

View File

@@ -88,7 +88,7 @@ TextEditor.prototype.render = function() {
this.editWidget.attributes.style = this.editWidget.attributes.style || "";
this.editWidget.attributes.style += this.editWidget.renderer.parseTreeNode.attributes.style.value;
}
this.editWidget.children = this.editWidget.renderer.renderTree.createRenderers(this.editWidget.renderer.renderContext,[node]);
this.editWidget.children = this.editWidget.renderer.renderTree.createRenderers(this.editWidget.renderer,[node]);
this.editWidget.events = [
{name: "focus", handlerObject: this},
{name: "blur", handlerObject: this},

View File

@@ -40,7 +40,7 @@ EncryptWidget.prototype.generate = function() {
// Set the return element
this.tag = "pre";
this.attributes ={"class": "tw-encrypt"};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[{
this.children = this.renderer.renderTree.createRenderers(this.renderer,[{
type: "text",
text: encryptedText
}]);

View File

@@ -26,7 +26,7 @@ ErrorWidget.prototype.generate = function() {
this.attributes = {
"class": "tw-error-widget"
};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[{
this.children = this.renderer.renderTree.createRenderers(this.renderer,[{
type: "text",
text: this.errorMessage
}]);

View File

@@ -21,7 +21,7 @@ var FieldGridWidget = function(renderer) {
FieldGridWidget.prototype.generate = function() {
// Get attributes
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.getContextTiddlerTitle());
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.tiddlerTitle);
this.exclude = this.renderer.getAttribute("exclude");
this["class"] = this.renderer.getAttribute("class");
// Set up the exclusion array
@@ -73,7 +73,7 @@ FieldGridWidget.prototype.generate = function() {
// Return the table element
this.tag = "table";
this.attributes ={"class": classes.join(" ")};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[{
this.children = this.renderer.renderTree.createRenderers(this.renderer,[{
type: "element",
tag: "tbody",
children: rows

View File

@@ -21,7 +21,7 @@ var FieldsWidget = function(renderer) {
FieldsWidget.prototype.generate = function() {
// Get parameters from our attributes
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.getContextTiddlerTitle());
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.tiddlerTitle);
this.template = this.renderer.getAttribute("template");
this.exclude = this.renderer.getAttribute("exclude");
this.stripTitlePrefix = this.renderer.getAttribute("stripTitlePrefix","no") === "yes";
@@ -75,7 +75,7 @@ FieldsWidget.prototype.generate = function() {
this.attributes.title = this.renderer.getAttribute("tooltip");
}
// Create the renderers for the wrapper and the children
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[{
this.children = this.renderer.renderTree.createRenderers(this.renderer,[{
type: "text",
text: text.join("")
}]);

View File

@@ -60,7 +60,7 @@ ImportWidget.prototype.generate = function() {
this.attributes = {
"class": classes.join(" ")
};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[fileInput,container]);
this.children = this.renderer.renderTree.createRenderers(this.renderer,[fileInput,container]);
};
ImportWidget.prototype.handleChangeEvent = function(event) {

View File

@@ -25,7 +25,7 @@ InfoWidget.types = {
InfoWidget.prototype.generate = function() {
// Get attributes
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.getContextTiddlerTitle());
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.tiddlerTitle);
this.type = this.renderer.getAttribute("type","changecount");
// Get the appropriate value for the current tiddler
var value = "",
@@ -39,7 +39,7 @@ InfoWidget.prototype.generate = function() {
// Set the element
this.tag = "span";
this.attributes = {};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[{
this.children = this.renderer.renderTree.createRenderers(this.renderer,[{
type: "text",
text: value
}]);

View File

@@ -31,7 +31,7 @@ LinkWidget.prototype.generate = function() {
this.qualifyHoverTitles = this.renderer.getAttribute("qualifyHoverTitles");
// Qualify the hover tiddler title if needed
if(this.qualifyHoverTitles) {
this.hover = this.hover + "-" + this.renderer.getContextScopeId();
this.hover = this.hover + "-" + this.renderer.renderTree.getContextScopeId(this.renderer.parentRenderer);
}
// Determine the default link characteristics
this.isExternal = isLinkExternal(this.to);
@@ -66,7 +66,7 @@ LinkWidget.prototype.generate = function() {
events.push({name: "mouseout", handlerObject: this, handlerMethod: "handleMouseOverOrOutEvent"});
}
// Get the value of the tw-wikilinks configuration macro
var wikiLinksMacro = this.renderer.findMacroDefinition("tw-wikilinks"),
var wikiLinksMacro = this.renderer.renderTree.findMacroDefinition(this.renderer.parentRenderer,"tw-wikilinks"),
useWikiLinks = wikiLinksMacro ? !(wikiLinksMacro.text.trim() === "no") : true;
// Set up the element
if(useWikiLinks) {
@@ -77,7 +77,7 @@ LinkWidget.prototype.generate = function() {
if(this.isExternal) {
this.attributes.href = this.to;
} else {
var wikiLinkTemplateMacro = this.renderer.findMacroDefinition("tw-wikilink-template"),
var wikiLinkTemplateMacro = this.renderer.renderTree.findMacroDefinition(this.renderer.parentRenderer,"tw-wikilink-template"),
wikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.text.trim() : "$uri_encoded$";
this.wikiLinkText = wikiLinkTemplate.replace("$uri_encoded$",encodeURIComponent(this.to));
this.wikiLinkText = this.wikiLinkText.replace("$uri_doubleencoded$",encodeURIComponent(encodeURIComponent(this.to)));
@@ -87,7 +87,7 @@ LinkWidget.prototype.generate = function() {
} else {
this.tag = "span";
}
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,this.renderer.parseTreeNode.children);
this.children = this.renderer.renderTree.createRenderers(this.renderer,this.renderer.parseTreeNode.children);
};
LinkWidget.prototype.handleClickEvent = function(event) {

View File

@@ -29,7 +29,7 @@ LinkCatcherWidget.prototype.generate = function() {
this.attributes = {
"class": "tw-linkcatcher"
};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,this.renderer.parseTreeNode.children);
this.children = this.renderer.renderTree.createRenderers(this.renderer,this.renderer.parseTreeNode.children);
this.events = [
{name: "tw-navigate", handlerObject: this, handlerMethod: "handleNavigateEvent"}
];
@@ -47,7 +47,7 @@ LinkCatcherWidget.prototype.refreshInDom = function(changedAttributes,changedTid
// Navigate to a specified tiddler
LinkCatcherWidget.prototype.handleNavigateEvent = function(event) {
if(this.to) {
this.renderer.renderTree.wiki.setTextReference(this.to,event.navigateTo,this.renderer.getContextTiddlerTitle());
this.renderer.renderTree.wiki.setTextReference(this.to,event.navigateTo,this.renderer.tiddlerTitle);
}
event.stopPropagation();
return false;

View File

@@ -59,7 +59,7 @@ ListWidget.prototype.generate = function() {
this.attributes = {
"class": "tw-list-frame"
};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,listMembers);
this.children = this.renderer.renderTree.createRenderers(this.renderer,listMembers);
};
ListWidget.prototype.getTiddlerList = function() {
@@ -72,7 +72,7 @@ ListWidget.prototype.getTiddlerList = function() {
if(!filter) {
filter = "[!is[system]]";
}
this.list = this.renderer.renderTree.wiki.filterTiddlers(filter,this.renderer.getContextTiddlerTitle());
this.list = this.renderer.renderTree.wiki.filterTiddlers(filter,this.renderer.tiddlerTitle);
};
/*
@@ -253,7 +253,7 @@ ListWidget.prototype.handleListChanges = function(changedTiddlers) {
this.removeListElement(t);
}
// Insert the empty message
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[this.getEmptyMessage()]);
this.children = this.renderer.renderTree.createRenderers(this.renderer,[this.getEmptyMessage()]);
$tw.utils.each(this.children,function(node) {
if(node.renderInDom) {
self.renderer.domNode.appendChild(node.renderInDom());
@@ -273,7 +273,7 @@ ListWidget.prototype.handleListChanges = function(changedTiddlers) {
var index = this.findListElementByTitle(t,this.list[t]);
if(index === undefined) {
// The list element isn't there, so we need to insert it
this.children.splice(t,0,this.renderer.renderTree.createRenderer(this.renderer.renderContext,this.createListElement(this.list[t])));
this.children.splice(t,0,this.renderer.renderTree.createRenderer(this.renderer,this.createListElement(this.list[t])));
this.renderer.domNode.insertBefore(this.children[t].renderInDom(),this.renderer.domNode.childNodes[t]);
// Ask the listview to animate the insertion
if(this.listview && this.listview.insert) {

View File

@@ -28,7 +28,7 @@ NavigatorWidget.prototype.generate = function() {
this.attributes = {
"class": "tw-navigator"
};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,this.renderer.parseTreeNode.children);
this.children = this.renderer.renderTree.createRenderers(this.renderer,this.renderer.parseTreeNode.children);
this.events = [
{name: "tw-navigate", handlerObject: this, handlerMethod: "handleNavigateEvent"},
{name: "tw-edit-tiddler", handlerObject: this, handlerMethod: "handleEditTiddlerEvent"},

View File

@@ -31,7 +31,7 @@ RevealWidget.prototype.generate = function() {
// Compute the title of the state tiddler and read it
this.stateTitle = this.state;
if(this.qualifyTiddlerTitles) {
this.stateTitle = this.stateTitle + "-" + this.renderer.getContextScopeId();
this.stateTitle = this.stateTitle + "-" + this.renderer.renderTree.getContextScopeId(this.renderer.parentRenderer);
}
this.readState();
// Set up the element attributes
@@ -53,7 +53,7 @@ RevealWidget.prototype.generate = function() {
"class": classes.join(" "),
style: styles.join("")
};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,this.isOpen ? this.renderer.parseTreeNode.children : []);
this.children = this.renderer.renderTree.createRenderers(this.renderer,this.isOpen ? this.renderer.parseTreeNode.children : []);
this.events = [{name: "click", handlerObject: this, handlerMethod: "handleClickEvent"}];
};
@@ -63,7 +63,7 @@ Read the state tiddler
RevealWidget.prototype.readState = function() {
// Read the information from the state tiddler
if(this.stateTitle) {
var state = this.renderer.renderTree.wiki.getTextReference(this.stateTitle,this["default"],this.renderer.getContextTiddlerTitle());
var state = this.renderer.renderTree.wiki.getTextReference(this.stateTitle,this["default"],this.renderer.tiddlerTitle);
switch(this.type) {
case "popup":
this.readPopupState(state);
@@ -129,7 +129,7 @@ RevealWidget.prototype.refreshInDom = function(changedAttributes,changedTiddlers
this.readState();
// Construct the child nodes if required
if(this.isOpen && this.children.length === 0) {
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,this.renderer.parseTreeNode.children);
this.children = this.renderer.renderTree.createRenderers(this.renderer,this.renderer.parseTreeNode.children);
var parentNode = this.renderer.domNode;
$tw.utils.each(this.children,function(child) {
parentNode.appendChild(child.renderInDom());

View File

@@ -32,7 +32,7 @@ SetStyleWidget.prototype.generate = function() {
if(this["class"]) {
this.attributes["class"] = this["class"];
}
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,this.renderer.parseTreeNode.children);
this.children = this.renderer.renderTree.createRenderers(this.renderer,this.renderer.parseTreeNode.children);
};
exports.setstyle = SetStyleWidget;

View File

@@ -56,7 +56,7 @@ var TranscludeWidget = function(renderer) {
TranscludeWidget.prototype.generate = function() {
var tr, templateParseTree, templateTiddler;
// Get the render target details
this.targetTitle = this.renderer.getAttribute("target",this.renderer.getContextTiddlerTitle());
this.targetTitle = this.renderer.getAttribute("target",this.renderer.tiddlerTitle);
this.targetField = this.renderer.getAttribute("field");
this.targetIndex = this.renderer.getAttribute("index");
// Get the render tree for the template
@@ -67,7 +67,7 @@ TranscludeWidget.prototype.generate = function() {
} else {
this.templateTitle = this.renderer.getAttribute("template",this.targetTitle);
// Check for recursion
if(this.renderer.checkContextRecursion({
if(this.renderer.renderTree.checkContextRecursion(this.renderer.parentRenderer,{
tiddlerTitle: this.targetTitle,
templateTitle: this.templateTitle
})) {
@@ -101,11 +101,10 @@ TranscludeWidget.prototype.generate = function() {
if(!this.renderer.renderTree.wiki.tiddlerExists(this.targetTitle) && !this.renderer.renderTree.wiki.isShadowTiddler(this.targetTitle)) {
$tw.utils.pushTop(classes,"tw-tiddler-missing");
}
// Create the renderers for the wrapper and the children
var newRenderContext = {
// Save the context for this renderer node
this.renderer.context = {
tiddlerTitle: this.targetTitle,
templateTitle: this.templateTitle,
parentContext: this.renderer.renderContext
templateTitle: this.templateTitle
};
// Set the element
this.tag = this.renderer.parseTreeNode.isBlock ? "div" : "span";
@@ -119,7 +118,7 @@ TranscludeWidget.prototype.generate = function() {
if(this.renderer.hasAttribute("tooltip")) {
this.attributes.title = this.renderer.getAttribute("tooltip");
}
this.children = this.renderer.renderTree.createRenderers(newRenderContext,templateParseTree);
this.children = this.renderer.renderTree.createRenderers(this.renderer,templateParseTree);
};
TranscludeWidget.prototype.refreshInDom = function(changedAttributes,changedTiddlers) {

View File

@@ -23,7 +23,7 @@ VersionWidget.prototype.generate = function() {
// Set the element
this.tag = "span";
this.attributes = {};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[{
this.children = this.renderer.renderTree.createRenderers(this.renderer,[{
type: "text",
text: $tw.version
}]);

View File

@@ -57,7 +57,7 @@ VideoWidget.prototype.generate = function() {
default:
this.tag = "div";
this.attributes = {};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[{
this.children = this.renderer.renderTree.createRenderers(this.renderer,[{
type: "text",
text: "Unknown video type"
}]);

View File

@@ -54,7 +54,7 @@ var ViewWidget = function(renderer) {
ViewWidget.prototype.generate = function() {
// Get parameters from our attributes
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.getContextTiddlerTitle());
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.tiddlerTitle);
this.fieldName = this.renderer.getAttribute("field","text");
this.format = this.renderer.getAttribute("format","text");
// Get the value to display

View File

@@ -30,7 +30,7 @@ DateViewer.prototype.render = function() {
this.viewWidget.attributes = {
"class": "tw-view-date"
};
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer.renderContext,[{
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer,[{
type: "text",
text: value
}]);

View File

@@ -33,7 +33,7 @@ HtmlEncodedViewer.prototype.render = function() {
this.viewWidget.attributes = {
"class": "tw-view-htmlencoded"
};
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer.renderContext,[{
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer,[{
type: "text",
text: $tw.utils.htmlEncode(value)
}]);

View File

@@ -21,20 +21,17 @@ var HtmlWikifiedViewer = function(viewWidget,tiddler,field,value) {
HtmlWikifiedViewer.prototype.render = function() {
// Parse the field text
var newRenderContext = {
parentContext: this.viewWidget.renderer.renderContext
};
var wiki = this.viewWidget.renderer.renderTree.wiki,
parser = wiki.parseText("text/vnd.tiddlywiki",this.value),
renderTree = new $tw.WikiRenderTree(parser,{wiki: wiki});
renderTree.execute(newRenderContext);
renderTree.execute();
var text = renderTree.render("text/html");
// Set the element details
this.viewWidget.tag = "pre";
this.viewWidget.attributes = {
"class": "tw-view-htmlwikified"
};
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer.renderContext,[{
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer,[{
type: "text",
text: text
}]);

View File

@@ -33,7 +33,7 @@ JsEncodedViewer.prototype.render = function() {
this.viewWidget.attributes = {
"class": "tw-view-jsencoded"
};
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer.renderContext,[{
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer,[{
type: "text",
text: $tw.utils.stringify(value)
}]);

View File

@@ -26,7 +26,7 @@ LinkViewer.prototype.render = function() {
this.viewWidget.attributes = {
"class": "tw-view-link"
};
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer.renderContext,[{
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer,[{
type: "element",
tag: "$link",
attributes: {

View File

@@ -30,7 +30,7 @@ RelativeDateViewer.prototype.render = function() {
this.viewWidget.attributes = {
"class": "tw-view-date"
};
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer.renderContext,[{
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer,[{
type: "text",
text: value
}]);

View File

@@ -35,7 +35,7 @@ WikifiedViewer.prototype.render = function() {
if(this.tiddler && this.tiddler.fields.title) {
node.attributes.target = {type: "string", value: this.tiddler.fields.title}
}
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer.renderContext,[node]);
this.viewWidget.children = this.viewWidget.renderer.renderTree.createRenderers(this.viewWidget.renderer,[node]);
};
exports.wikified = WikifiedViewer;