1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-11-30 13:29:56 +00:00

Medium-sized refactoring of macro architecture

Now event handlers are attached to element nodes, not to macro nodes.
This commit is contained in:
Jeremy Ruston 2012-06-14 17:15:38 +01:00
parent 79530dea49
commit 52f59a4eb4
13 changed files with 104 additions and 109 deletions

View File

@ -19,8 +19,7 @@ exports.info = {
popup: {byName: true, type: "tiddler"}, popup: {byName: true, type: "tiddler"},
qualifyTiddlerTitles: {byName: true, type: "text"}, qualifyTiddlerTitles: {byName: true, type: "text"},
"class": {byName: true, type: "text"} "class": {byName: true, type: "text"}
}, }
events: ["click", "tw-cancel-popup"]
}; };
exports.dispatchMessage = function(event) { exports.dispatchMessage = function(event) {
@ -44,12 +43,12 @@ exports.triggerPopup = function(event,cancel) {
value = ""; value = "";
} else { } else {
// Check if the popup is open by checking whether it matches "(<x>,<y>)" // Check if the popup is open by checking whether it matches "(<x>,<y>)"
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/; var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/;
if(popupLocationRegExp.test(value)) { if(popupLocationRegExp.test(value)) {
value = ""; value = "";
} else { } else {
// Set the position if we're opening it // Set the position if we're opening it
value = "(" + this.domNode.offsetLeft + "," + this.domNode.offsetTop + "," + this.domNode.offsetWidth + "," + this.domNode.offsetHeight + ")"; value = "(" + this.child.domNode.offsetLeft + "," + this.child.domNode.offsetTop + "," + this.child.domNode.offsetWidth + "," + this.child.domNode.offsetHeight + ")";
} }
} }
// Update the state tiddler // Update the state tiddler
@ -68,7 +67,7 @@ exports.handleEvent = function(event) {
event.preventDefault(); event.preventDefault();
return false; return false;
case "tw-cancel-popup": case "tw-cancel-popup":
if(this.hasParameter("popup") && this.domNode !== event.targetOfCancel && !$tw.utils.domContains(this.domNode,event.targetOfCancel)) { if(this.hasParameter("popup") && this.child.domNode !== event.targetOfCancel && !$tw.utils.domContains(this.child.domNode,event.targetOfCancel)) {
this.triggerPopup(event,true); this.triggerPopup(event,true);
} }
break; break;
@ -87,7 +86,10 @@ exports.executeMacro = function() {
for(var t=0; t<this.content.length; t++) { for(var t=0; t<this.content.length; t++) {
this.content[t].execute(this.parents,this.tiddlerTitle); this.content[t].execute(this.parents,this.tiddlerTitle);
} }
return $tw.Tree.Element("button",attributes,this.content); return $tw.Tree.Element("button",attributes,this.content,{
events: ["click","tw-cancel-popup"],
eventHandler: this
});
}; };
})(); })();

View File

@ -15,8 +15,7 @@ Zooming chooser macro
exports.info = { exports.info = {
name: "chooser", name: "chooser",
params: { params: {
}, }
events: ["touchstart","touchmove","touchend","mouseover","mousemove","mouseup","mouseout"]
}; };
exports.showChooser = function() { exports.showChooser = function() {
@ -172,7 +171,10 @@ exports.executeMacro = function() {
} }
return $tw.Tree.Element("div",wrapperAttributes,[ return $tw.Tree.Element("div",wrapperAttributes,[
$tw.Tree.Element("div",innerAttributes,[]) $tw.Tree.Element("div",innerAttributes,[])
]); ],{
events: ["touchstart","touchmove","touchend","mouseover","mousemove","mouseup","mouseout"],
eventHandler: this
});
}; };
})(); })();

View File

@ -19,8 +19,7 @@ exports.info = {
type: {byName: true, type: "text"}, type: {byName: true, type: "text"},
"filename": {byName: true, type: "text"}, "filename": {byName: true, type: "text"},
"label": {byName: true, type: "text"} "label": {byName: true, type: "text"}
}, }
events: ["click"]
}; };
exports.handleEvent = function(event) { exports.handleEvent = function(event) {
@ -50,7 +49,10 @@ exports.executeMacro = function() {
if(this.classes) { if(this.classes) {
attributes["class"] = this.classes.slice(0); attributes["class"] = this.classes.slice(0);
} }
return $tw.Tree.Element("button",attributes,content); return $tw.Tree.Element("button",attributes,content,{
events: ["click"],
eventHandler: this
});
}; };
})(); })();

View File

@ -40,12 +40,6 @@ exports.executeMacro = function() {
return child; return child;
}; };
exports.addEventHandlers = function() {
if(this.editor.addEventHandlers) {
this.editor.addEventHandlers();
}
};
exports.postRenderInDom = function() { exports.postRenderInDom = function() {
if(this.editor.postRenderInDom) { if(this.editor.postRenderInDom) {
this.editor.postRenderInDom(); this.editor.postRenderInDom();
@ -66,8 +60,6 @@ exports.refreshInDom = function(changes) {
this.execute(this.parents,this.tiddlerTitle); this.execute(this.parents,this.tiddlerTitle);
// Render to the DOM // Render to the DOM
this.child.renderInDom(parent,nextSibling); this.child.renderInDom(parent,nextSibling);
this.domNode = this.child.domNode;
this.addEventHandlers();
} }
} else { } else {
// Refresh any children // Refresh any children

View File

@ -19,7 +19,10 @@ function BitmapEditor(macroNode) {
BitmapEditor.prototype.getChild = function() { BitmapEditor.prototype.getChild = function() {
return $tw.Tree.Element("canvas",{ return $tw.Tree.Element("canvas",{
"class": ["tw-edit-field"] "class": ["tw-edit-field"]
},[]); },[],{
events: ["touchstart","touchmove","touchend","mousedown","mousemove","mouseup"],
eventHandler: this
});
}; };
BitmapEditor.prototype.postRenderInDom = function() { BitmapEditor.prototype.postRenderInDom = function() {
@ -43,57 +46,54 @@ BitmapEditor.prototype.postRenderInDom = function() {
ctx.drawImage(currImage,0,0); ctx.drawImage(currImage,0,0);
}; };
BitmapEditor.prototype.addEventHandlers = function() { BitmapEditor.prototype.handleEvent = function(event) {
var self = this; switch(event.type) {
this.macroNode.child.domNode.addEventListener("touchstart",function(event) { case "touchstart":
self.brushDown = true; this.brushDown = true;
self.strokeStart(event.touches[0].clientX,event.touches[0].clientY); this.strokeStart(event.touches[0].clientX,event.touches[0].clientY);
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
return false; return false;
},false); case "touchmove":
this.macroNode.child.domNode.addEventListener("touchmove",function(event) { if(this.brushDown) {
if(self.brushDown) { this.strokeMove(event.touches[0].clientX,event.touches[0].clientY);
self.strokeMove(event.touches[0].clientX,event.touches[0].clientY);
} }
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
return false; return false;
},false); case "touchend":
this.macroNode.child.domNode.addEventListener("touchend",function(event) { if(this.brushDown) {
if(self.brushDown) { this.brushDown = false;
self.brushDown = false; this.strokeEnd();
self.strokeEnd();
} }
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
return false; return false;
},false); case "mousedown":
this.macroNode.child.domNode.addEventListener("mousedown",function(event) { this.strokeStart(event.clientX,event.clientY);
self.strokeStart(event.clientX,event.clientY); this.brushDown = true;
self.brushDown = true;
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
return false; return false;
},false); case "mousemove":
this.macroNode.child.domNode.addEventListener("mousemove",function(event) { if(this.brushDown) {
if(self.brushDown) { this.strokeMove(event.clientX,event.clientY);
self.strokeMove(event.clientX,event.clientY);
event.preventDefault();
event.stopPropagation();
return false;
}
},false);
this.macroNode.child.domNode.addEventListener("mouseup",function(event) {
if(self.brushDown) {
self.brushDown = false;
self.strokeEnd();
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
return false; return false;
} }
return true; return true;
},false); case "mouseup":
if(this.brushDown) {
this.brushDown = false;
this.strokeEnd();
event.preventDefault();
event.stopPropagation();
return false;
}
return true;
}
return true;
}; };
BitmapEditor.prototype.adjustCoordinates = function(x,y) { BitmapEditor.prototype.adjustCoordinates = function(x,y) {

View File

@ -55,12 +55,10 @@ TextEditor.prototype.getChild = function() {
attributes.value = value; attributes.value = value;
} }
// Wrap the editor control in a div // Wrap the editor control in a div
return $tw.Tree.Element("div",{},[$tw.Tree.Element(tagName,attributes,content)]); return $tw.Tree.Element("div",{},[$tw.Tree.Element(tagName,attributes,content)],{
}; events: ["focus","keyup"],
eventHandler: this
TextEditor.prototype.addEventHandlers = function() { });
this.macroNode.child.domNode.addEventListener("focus",this,false);
this.macroNode.child.domNode.addEventListener("keyup",this,false);
}; };
TextEditor.prototype.handleEvent = function(event) { TextEditor.prototype.handleEvent = function(event) {

View File

@ -22,8 +22,7 @@ exports.info = {
params: { params: {
to: {byName: "default", type: "tiddler", skinny: true}, to: {byName: "default", type: "tiddler", skinny: true},
space: {byName: true, type: "text"} space: {byName: true, type: "text"}
}, }
events: ["click"]
}; };
exports.handleEvent = function (event) { exports.handleEvent = function (event) {
@ -80,7 +79,7 @@ exports.executeMacro = function() {
if(linkInfo.suppressLink) { if(linkInfo.suppressLink) {
child = $tw.Tree.Element("span",{},this.content); child = $tw.Tree.Element("span",{},this.content);
} else { } else {
child = $tw.Tree.Element("a",linkInfo.attributes,this.content); child = $tw.Tree.Element("a",linkInfo.attributes,this.content,{events: ["click"], eventHandler: this});
} }
child.execute(this.parents,this.tiddlerTitle); child.execute(this.parents,this.tiddlerTitle);
return child; return child;

View File

@ -21,8 +21,7 @@ exports.info = {
qualifyTiddlerTitles: {byName: true, type: "text"}, qualifyTiddlerTitles: {byName: true, type: "text"},
"default": {byName: true, type: "text"}, "default": {byName: true, type: "text"},
"class": {byName: true, type: "text"} "class": {byName: true, type: "text"}
}, }
events: ["click"]
}; };
exports.readState = function() { exports.readState = function() {
@ -95,7 +94,10 @@ exports.executeMacro = function() {
break; break;
} }
attributes.style = {display: this.isOpen ? "block" : "none"}; attributes.style = {display: this.isOpen ? "block" : "none"};
var child = $tw.Tree.Element("div",attributes,this.isOpen ? this.content : []); var child = $tw.Tree.Element("div",attributes,this.isOpen ? this.content : [],{
events: ["click"],
eventHandler: this
});
child.execute(this.parents,this.tiddlerTitle); child.execute(this.parents,this.tiddlerTitle);
return child; return child;
}; };
@ -105,7 +107,7 @@ exports.refreshInDom = function(changes) {
t; t;
// If the state tiddler has changed then reset the open state // If the state tiddler has changed then reset the open state
if($tw.utils.hop(changes,this.stateTitle)) { if($tw.utils.hop(changes,this.stateTitle)) {
this.readState(); this.readState();
} }
// Render the children if we're open and we don't have any children yet // Render the children if we're open and we don't have any children yet
if(this.isOpen && this.child.children.length === 0) { if(this.isOpen && this.child.children.length === 0) {

View File

@ -48,8 +48,7 @@ exports.info = {
tooltip: {byPos: 3, type: "text"}, tooltip: {byPos: 3, type: "text"},
"default": {byName: true, type: "text"}, "default": {byName: true, type: "text"},
"class": {byName: true, type: "text"} "class": {byName: true, type: "text"}
}, }
events: ["click"]
}; };
exports.getOpenState = function() { exports.getOpenState = function() {
@ -142,7 +141,10 @@ exports.executeMacro = function() {
}, },
sliderChildren sliderChildren
) )
] ],{
events: ["click"],
eventHandler: this
}
); );
child.execute(this.parents,this.tiddlerTitle); child.execute(this.parents,this.tiddlerTitle);
return child; return child;

View File

@ -27,8 +27,7 @@ exports.info = {
defaultViewTemplate: {byName: true, type: "tiddler"}, defaultViewTemplate: {byName: true, type: "tiddler"},
defaultEditTemplate: {byName: true, type: "tiddler"}, defaultEditTemplate: {byName: true, type: "tiddler"},
storyview: {byName: true, type: "text"} storyview: {byName: true, type: "text"}
}, }
events: ["tw-navigate","tw-EditTiddler","tw-SaveTiddler"]
}; };
exports.getStory = function() { exports.getStory = function() {
@ -162,7 +161,10 @@ exports.executeMacro = function() {
if(this.classes) { if(this.classes) {
attributes["class"] = this.classes.slice(0); attributes["class"] = this.classes.slice(0);
} }
return $tw.Tree.Element("div",attributes,[this.contentNode,this.storyNode]); return $tw.Tree.Element("div",attributes,[this.contentNode,this.storyNode],{
events: ["tw-navigate","tw-EditTiddler","tw-SaveTiddler"],
eventHandler: this
});
}; };
exports.postRenderInDom = function() { exports.postRenderInDom = function() {

View File

@ -15,8 +15,7 @@ Zooming navigator macro
exports.info = { exports.info = {
name: "zoomer", name: "zoomer",
params: { params: {
}, }
events: ["touchstart","touchmove","touchend"]
}; };
exports.startZoomer = function(x,y) { exports.startZoomer = function(x,y) {
@ -112,7 +111,10 @@ exports.executeMacro = function() {
if(this.classes) { if(this.classes) {
attributes["class"] = this.classes.slice(0); attributes["class"] = this.classes.slice(0);
} }
return $tw.Tree.Element("div",attributes,[]); return $tw.Tree.Element("div",attributes,[],{
events: ["touchstart","touchmove","touchend"],
eventHandler: this
});
}; };
})(); })();

View File

@ -14,13 +14,16 @@ Element nodes
var Node = require("./node.js").Node; var Node = require("./node.js").Node;
var Element = function(type,attributes,children) { var Element = function(type,attributes,children,options) {
options = options || {};
if(this instanceof Element) { if(this instanceof Element) {
this.type = type; this.type = type;
this.attributes = attributes || {}; this.attributes = attributes || {};
this.children = children; this.children = children;
this.events = options.events;
this.eventHandler = options.eventHandler;
} else { } else {
return new Element(type,attributes,children); return new Element(type,attributes,children,options);
} }
}; };
@ -35,7 +38,10 @@ Element.prototype.clone = function() {
childClones.push(this.children[t].clone()); childClones.push(this.children[t].clone());
} }
} }
return new Element(this.type,this.attributes,childClones); return new Element(this.type,this.attributes,childClones,{
events: this.events,
eventHandler: this.eventHandler
});
}; };
Element.prototype.execute = function(parents,tiddlerTitle) { Element.prototype.execute = function(parents,tiddlerTitle) {
@ -87,7 +93,9 @@ Element.prototype.render = function(type) {
}; };
Element.prototype.renderInDom = function(parentDomNode,insertBefore) { Element.prototype.renderInDom = function(parentDomNode,insertBefore) {
// Create the element
var element = document.createElement(this.type); var element = document.createElement(this.type);
// Assign the attributes
if(this.attributes) { if(this.attributes) {
for(var a in this.attributes) { for(var a in this.attributes) {
var v = this.attributes[a]; var v = this.attributes[a];
@ -104,12 +112,21 @@ Element.prototype.renderInDom = function(parentDomNode,insertBefore) {
} }
} }
} }
// Insert it into the DOM tree
if(insertBefore) { if(insertBefore) {
parentDomNode.insertBefore(element,insertBefore); parentDomNode.insertBefore(element,insertBefore);
} else { } else {
parentDomNode.appendChild(element); parentDomNode.appendChild(element);
} }
// Register event handlers
if(this.events) {
for(var e=0; e<this.events.length; e++) {
element.addEventListener(this.events[e],this.eventHandler,false);
}
}
// Save a reference to the DOM element
this.domNode = element; this.domNode = element;
// Render any child nodes
if(this.children) { if(this.children) {
for(var t=0; t<this.children.length; t++) { for(var t=0; t<this.children.length; t++) {
this.children[t].renderInDom(element); this.children[t].renderInDom(element);

View File

@ -175,27 +175,13 @@ Macro.prototype.render = function(type) {
}; };
Macro.prototype.renderInDom = function(parentDomNode,insertBefore) { Macro.prototype.renderInDom = function(parentDomNode,insertBefore) {
this.parentDomNode = parentDomNode;
if(this.child) { if(this.child) {
this.child.renderInDom(parentDomNode,insertBefore); this.child.renderInDom(parentDomNode,insertBefore);
this.domNode = this.child.domNode;
this.addEventHandlers();
this.postRenderInDom(); this.postRenderInDom();
} }
}; };
Macro.prototype.addEventHandlers = function() {
if(this.info.events && this.child) {
for(var t=0; t<this.info.events.length; t++) {
// Register this macro node to handle the event via the handleEvent() method
var info = this.info.events[t];
if(typeof info === "string") {
info = {type: info};
}
this.child.domNode.addEventListener(info.type,this,info.capture);
}
}
};
Macro.prototype.postRenderInDom = function() { Macro.prototype.postRenderInDom = function() {
// Do nothing, individual macros can override // Do nothing, individual macros can override
}; };
@ -215,23 +201,12 @@ Macro.prototype.refresh = function(changes) {
} }
}; };
/*
Macros that need special refreshing should override this function
*/
Macro.prototype.refreshInDom = function(changes) { Macro.prototype.refreshInDom = function(changes) {
var t, if(this.child) {
self = this; this.child.refreshInDom(changes);
// Check if any of the dependencies of this macro node have changed
if(this.dependencies.hasChanged(changes,this.tiddlerTitle)) {
// Manually reexecute and rerender this macro
var parent = this.child.domNode.parentNode,
nextSibling = this.child.domNode.nextSibling;
parent.removeChild(this.child.domNode);
this.execute(this.parents,this.tiddlerTitle);
this.child.renderInDom(parent,nextSibling);
this.domNode = this.child.domNode;
this.addEventHandlers();
} else {
if(this.child) {
this.child.refreshInDom(changes);
}
} }
}; };