1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-07-06 20:12:49 +00:00

Refactored renderer logic to call refreshInDom on macros unconditionally

This allows the macro itself to decide whether it wants to perform an
update or not
This commit is contained in:
Jeremy Ruston 2012-03-30 16:45:24 +01:00
parent 1deb23b82d
commit a7b905cf88
4 changed files with 98 additions and 88 deletions

View File

@ -288,12 +288,12 @@ MacroNode.prototype.refresh = function(changes) {
MacroNode.prototype.refreshInDom = function(changes) { MacroNode.prototype.refreshInDom = function(changes) {
var t, var t,
self = this; self = this;
// Check if any of the dependencies of this macro node have changed // Ask the macro to rerender itself if it can
if(this.dependencies.hasChanged(changes,this.tiddlerTitle)) { if(this.macro.refreshInDom) {
// Ask the macro to rerender itself if it can this.macro.refreshInDom.call(this,changes);
if(this.macro.refreshInDom) { } else {
this.macro.refreshInDom.call(this,changes); // Check if any of the dependencies of this macro node have changed
} else { if(this.dependencies.hasChanged(changes,this.tiddlerTitle)) {
// Manually reexecute and rerender this macro // Manually reexecute and rerender this macro
while(this.domNode.hasChildNodes()) { while(this.domNode.hasChildNodes()) {
this.domNode.removeChild(this.domNode.firstChild); this.domNode.removeChild(this.domNode.firstChild);
@ -302,11 +302,11 @@ MacroNode.prototype.refreshInDom = function(changes) {
for(t=0; t<this.content.length; t++) { for(t=0; t<this.content.length; t++) {
this.content[t].renderInDom(this.domNode); this.content[t].renderInDom(this.domNode);
} }
} } else {
} else { // Refresh any children
// Refresh any children for(t=0; t<this.content.length; t++) {
for(t=0; t<this.content.length; t++) { this.content[t].refreshInDom(changes);
this.content[t].refreshInDom(changes); }
} }
} }
}; };

View File

@ -91,17 +91,19 @@ exports.macro = {
return [editor]; return [editor];
}, },
refreshInDom: function(changes) { refreshInDom: function(changes) {
// Don't refresh the editor if it contains the caret or selection if(this.dependencies.hasChanged(changes,this.tiddlerTitle)) {
if(!window.getSelection().containsNode(this.domNode, true)) { // Don't refresh the editor if it contains the caret or selection
// Remove the previous content if(!window.getSelection().containsNode(this.domNode, true)) {
while(this.domNode.hasChildNodes()) { // Remove the previous content
this.domNode.removeChild(this.domNode.firstChild); while(this.domNode.hasChildNodes()) {
} this.domNode.removeChild(this.domNode.firstChild);
// Execute the new content }
this.execute(this.parents,this.tiddlerTitle); // Execute the new content
// Render to the DOM this.execute(this.parents,this.tiddlerTitle);
for(var t=0; t<this.content.length; t++) { // Render to the DOM
this.content[t].renderInDom(this.domNode); for(var t=0; t<this.content.length; t++) {
this.content[t].renderInDom(this.domNode);
}
} }
} }
} }

View File

@ -145,27 +145,29 @@ exports.macro = {
return [content]; return [content];
}, },
refreshInDom: function(changes) { refreshInDom: function(changes) {
var needContentRefresh = true; // Avoid refreshing the content nodes if we don't need to if(this.dependencies.hasChanged(changes,this.tiddlerTitle)) {
// If the state tiddler has changed then reset the open state var needContentRefresh = true; // Avoid refreshing the content nodes if we don't need to
if(this.hasParameter("state") && changes.hasOwnProperty(this.params.state)) { // If the state tiddler has changed then reset the open state
this.isOpen = getOpenState(this); if(this.hasParameter("state") && changes.hasOwnProperty(this.params.state)) {
} this.isOpen = getOpenState(this);
// Render the content if the slider is open and we don't have any content yet }
if(this.isOpen && this.content[0].children[1].children.length === 0) { // Render the content if the slider is open and we don't have any content yet
// Remove the existing dom node for the body if(this.isOpen && this.content[0].children[1].children.length === 0) {
this.content[0].domNode.removeChild(this.content[0].children[1].domNode); // Remove the existing dom node for the body
// Get the slider content and execute it this.content[0].domNode.removeChild(this.content[0].children[1].domNode);
this.content[0].children[1].children = getSliderContent(this); // Get the slider content and execute it
this.content[0].children[1].execute(this.parents,this.tiddlerTitle); this.content[0].children[1].children = getSliderContent(this);
this.content[0].children[1].renderInDom(this.content[0].domNode,null); this.content[0].children[1].execute(this.parents,this.tiddlerTitle);
needContentRefresh = false; // Don't refresh the children if we've just created them this.content[0].children[1].renderInDom(this.content[0].domNode,null);
} needContentRefresh = false; // Don't refresh the children if we've just created them
// Set the visibility of the slider content }
this.content[0].children[1].domNode.style.display = this.isOpen ? "block" : "none"; // Set the visibility of the slider content
// Refresh any children this.content[0].children[1].domNode.style.display = this.isOpen ? "block" : "none";
if(needContentRefresh) { // Refresh any children
for(var t=0; t<this.content.length; t++) { if(needContentRefresh) {
this.content[t].refreshInDom(changes); for(var t=0; t<this.content.length; t++) {
this.content[t].refreshInDom(changes);
}
} }
} }
} }

View File

@ -97,58 +97,64 @@ exports.macro = {
}, },
refreshInDom: function(changes) { refreshInDom: function(changes) {
/*jslint browser: true */ /*jslint browser: true */
// Get the tiddlers we're supposed to be displaying if(this.dependencies.hasChanged(changes,this.tiddlerTitle)) {
var self = this, // Get the tiddlers we're supposed to be displaying
story = JSON.parse(this.store.getTiddlerText(this.params.story)), var self = this,
template = this.params.template, story = JSON.parse(this.store.getTiddlerText(this.params.story)),
t,n,domNode, template = this.params.template,
findTiddler = function (childIndex,tiddlerTitle,templateTitle) { t,n,domNode,
while(childIndex < self.content.length) { findTiddler = function (childIndex,tiddlerTitle,templateTitle) {
var params = self.content[childIndex].params; while(childIndex < self.content.length) {
if(params.target === tiddlerTitle) { var params = self.content[childIndex].params;
if(!templateTitle || params.template === templateTitle) { if(params.target === tiddlerTitle) {
return childIndex; if(!templateTitle || params.template === templateTitle) {
return childIndex;
}
} }
childIndex++;
} }
childIndex++; return null;
} };
return null; for(t=0; t<story.tiddlers.length; t++) {
}; // See if the node we want is already there
for(t=0; t<story.tiddlers.length; t++) { var tiddlerNode = findTiddler(t,story.tiddlers[t].title,story.tiddlers[t].template);
// See if the node we want is already there if(tiddlerNode === null) {
var tiddlerNode = findTiddler(t,story.tiddlers[t].title,story.tiddlers[t].template); // If not, render the tiddler
if(tiddlerNode === null) { var m = Renderer.MacroNode("tiddler",
// If not, render the tiddler {target: story.tiddlers[t].title,template: story.tiddlers[t].template},
var m = Renderer.MacroNode("tiddler", null,
{target: story.tiddlers[t].title,template: story.tiddlers[t].template}, this.store);
null, m.execute(this.parents,this.tiddlerTitle);
this.store); m.renderInDom(this.domNode,this.domNode.childNodes[t]);
m.execute(this.parents,story.tiddlers[t].title); this.content.splice(t,0,m);
m.renderInDom(this.domNode,this.domNode.childNodes[t]); } else {
this.content.splice(t,0,m); // Delete any nodes preceding the one we want
} else { if(tiddlerNode > t) {
// Delete any nodes preceding the one we want // First delete the DOM nodes
if(tiddlerNode > t) { for(n=t; n<tiddlerNode; n++) {
// First delete the DOM nodes domNode = this.content[n].domNode;
for(n=t; n<tiddlerNode; n++) { domNode.parentNode.removeChild(domNode);
domNode = this.content[n].domNode; }
domNode.parentNode.removeChild(domNode); // Then delete the actual renderer nodes
this.content.splice(t,tiddlerNode-t);
} }
// Then delete the actual renderer nodes // Refresh the DOM node we're reusing
this.content.splice(t,tiddlerNode-t); this.content[t].refreshInDom(changes);
} }
// Refresh the DOM node we're reusing }
// Remove any left over nodes
if(this.content.length > story.tiddlers.length) {
for(t=story.tiddlers.length; t<this.content.length; t++) {
domNode = this.content[t].domNode;
domNode.parentNode.removeChild(domNode);
}
this.content.splice(story.tiddlers.length,this.content.length-story.tiddlers.length);
}
} else {
for(t=0; t<this.content.length; t++) {
this.content[t].refreshInDom(changes); this.content[t].refreshInDom(changes);
} }
} }
// Remove any left over nodes
if(this.content.length > story.tiddlers.length) {
for(t=story.tiddlers.length; t<this.content.length; t++) {
domNode = this.content[t].domNode;
domNode.parentNode.removeChild(domNode);
}
this.content.splice(story.tiddlers.length,this.content.length-story.tiddlers.length);
}
} }
}; };