mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-27 12:07:19 +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:
parent
79530dea49
commit
52f59a4eb4
@ -19,8 +19,7 @@ exports.info = {
|
||||
popup: {byName: true, type: "tiddler"},
|
||||
qualifyTiddlerTitles: {byName: true, type: "text"},
|
||||
"class": {byName: true, type: "text"}
|
||||
},
|
||||
events: ["click", "tw-cancel-popup"]
|
||||
}
|
||||
};
|
||||
|
||||
exports.dispatchMessage = function(event) {
|
||||
@ -44,12 +43,12 @@ exports.triggerPopup = function(event,cancel) {
|
||||
value = "";
|
||||
} else {
|
||||
// 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)) {
|
||||
value = "";
|
||||
} else {
|
||||
// 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
|
||||
@ -68,7 +67,7 @@ exports.handleEvent = function(event) {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
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);
|
||||
}
|
||||
break;
|
||||
@ -87,7 +86,10 @@ exports.executeMacro = function() {
|
||||
for(var t=0; t<this.content.length; t++) {
|
||||
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
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
||||
|
@ -15,8 +15,7 @@ Zooming chooser macro
|
||||
exports.info = {
|
||||
name: "chooser",
|
||||
params: {
|
||||
},
|
||||
events: ["touchstart","touchmove","touchend","mouseover","mousemove","mouseup","mouseout"]
|
||||
}
|
||||
};
|
||||
|
||||
exports.showChooser = function() {
|
||||
@ -172,7 +171,10 @@ exports.executeMacro = function() {
|
||||
}
|
||||
return $tw.Tree.Element("div",wrapperAttributes,[
|
||||
$tw.Tree.Element("div",innerAttributes,[])
|
||||
]);
|
||||
],{
|
||||
events: ["touchstart","touchmove","touchend","mouseover","mousemove","mouseup","mouseout"],
|
||||
eventHandler: this
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
||||
|
@ -19,8 +19,7 @@ exports.info = {
|
||||
type: {byName: true, type: "text"},
|
||||
"filename": {byName: true, type: "text"},
|
||||
"label": {byName: true, type: "text"}
|
||||
},
|
||||
events: ["click"]
|
||||
}
|
||||
};
|
||||
|
||||
exports.handleEvent = function(event) {
|
||||
@ -50,7 +49,10 @@ exports.executeMacro = function() {
|
||||
if(this.classes) {
|
||||
attributes["class"] = this.classes.slice(0);
|
||||
}
|
||||
return $tw.Tree.Element("button",attributes,content);
|
||||
return $tw.Tree.Element("button",attributes,content,{
|
||||
events: ["click"],
|
||||
eventHandler: this
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
||||
|
@ -40,12 +40,6 @@ exports.executeMacro = function() {
|
||||
return child;
|
||||
};
|
||||
|
||||
exports.addEventHandlers = function() {
|
||||
if(this.editor.addEventHandlers) {
|
||||
this.editor.addEventHandlers();
|
||||
}
|
||||
};
|
||||
|
||||
exports.postRenderInDom = function() {
|
||||
if(this.editor.postRenderInDom) {
|
||||
this.editor.postRenderInDom();
|
||||
@ -66,8 +60,6 @@ exports.refreshInDom = function(changes) {
|
||||
this.execute(this.parents,this.tiddlerTitle);
|
||||
// Render to the DOM
|
||||
this.child.renderInDom(parent,nextSibling);
|
||||
this.domNode = this.child.domNode;
|
||||
this.addEventHandlers();
|
||||
}
|
||||
} else {
|
||||
// Refresh any children
|
||||
|
@ -19,7 +19,10 @@ function BitmapEditor(macroNode) {
|
||||
BitmapEditor.prototype.getChild = function() {
|
||||
return $tw.Tree.Element("canvas",{
|
||||
"class": ["tw-edit-field"]
|
||||
},[]);
|
||||
},[],{
|
||||
events: ["touchstart","touchmove","touchend","mousedown","mousemove","mouseup"],
|
||||
eventHandler: this
|
||||
});
|
||||
};
|
||||
|
||||
BitmapEditor.prototype.postRenderInDom = function() {
|
||||
@ -43,57 +46,54 @@ BitmapEditor.prototype.postRenderInDom = function() {
|
||||
ctx.drawImage(currImage,0,0);
|
||||
};
|
||||
|
||||
BitmapEditor.prototype.addEventHandlers = function() {
|
||||
var self = this;
|
||||
this.macroNode.child.domNode.addEventListener("touchstart",function(event) {
|
||||
self.brushDown = true;
|
||||
self.strokeStart(event.touches[0].clientX,event.touches[0].clientY);
|
||||
BitmapEditor.prototype.handleEvent = function(event) {
|
||||
switch(event.type) {
|
||||
case "touchstart":
|
||||
this.brushDown = true;
|
||||
this.strokeStart(event.touches[0].clientX,event.touches[0].clientY);
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
},false);
|
||||
this.macroNode.child.domNode.addEventListener("touchmove",function(event) {
|
||||
if(self.brushDown) {
|
||||
self.strokeMove(event.touches[0].clientX,event.touches[0].clientY);
|
||||
case "touchmove":
|
||||
if(this.brushDown) {
|
||||
this.strokeMove(event.touches[0].clientX,event.touches[0].clientY);
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
},false);
|
||||
this.macroNode.child.domNode.addEventListener("touchend",function(event) {
|
||||
if(self.brushDown) {
|
||||
self.brushDown = false;
|
||||
self.strokeEnd();
|
||||
case "touchend":
|
||||
if(this.brushDown) {
|
||||
this.brushDown = false;
|
||||
this.strokeEnd();
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
},false);
|
||||
this.macroNode.child.domNode.addEventListener("mousedown",function(event) {
|
||||
self.strokeStart(event.clientX,event.clientY);
|
||||
self.brushDown = true;
|
||||
case "mousedown":
|
||||
this.strokeStart(event.clientX,event.clientY);
|
||||
this.brushDown = true;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
},false);
|
||||
this.macroNode.child.domNode.addEventListener("mousemove",function(event) {
|
||||
if(self.brushDown) {
|
||||
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();
|
||||
case "mousemove":
|
||||
if(this.brushDown) {
|
||||
this.strokeMove(event.clientX,event.clientY);
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
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) {
|
||||
|
@ -55,12 +55,10 @@ TextEditor.prototype.getChild = function() {
|
||||
attributes.value = value;
|
||||
}
|
||||
// Wrap the editor control in a div
|
||||
return $tw.Tree.Element("div",{},[$tw.Tree.Element(tagName,attributes,content)]);
|
||||
};
|
||||
|
||||
TextEditor.prototype.addEventHandlers = function() {
|
||||
this.macroNode.child.domNode.addEventListener("focus",this,false);
|
||||
this.macroNode.child.domNode.addEventListener("keyup",this,false);
|
||||
return $tw.Tree.Element("div",{},[$tw.Tree.Element(tagName,attributes,content)],{
|
||||
events: ["focus","keyup"],
|
||||
eventHandler: this
|
||||
});
|
||||
};
|
||||
|
||||
TextEditor.prototype.handleEvent = function(event) {
|
||||
|
@ -22,8 +22,7 @@ exports.info = {
|
||||
params: {
|
||||
to: {byName: "default", type: "tiddler", skinny: true},
|
||||
space: {byName: true, type: "text"}
|
||||
},
|
||||
events: ["click"]
|
||||
}
|
||||
};
|
||||
|
||||
exports.handleEvent = function (event) {
|
||||
@ -80,7 +79,7 @@ exports.executeMacro = function() {
|
||||
if(linkInfo.suppressLink) {
|
||||
child = $tw.Tree.Element("span",{},this.content);
|
||||
} 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);
|
||||
return child;
|
||||
|
@ -21,8 +21,7 @@ exports.info = {
|
||||
qualifyTiddlerTitles: {byName: true, type: "text"},
|
||||
"default": {byName: true, type: "text"},
|
||||
"class": {byName: true, type: "text"}
|
||||
},
|
||||
events: ["click"]
|
||||
}
|
||||
};
|
||||
|
||||
exports.readState = function() {
|
||||
@ -95,7 +94,10 @@ exports.executeMacro = function() {
|
||||
break;
|
||||
}
|
||||
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);
|
||||
return child;
|
||||
};
|
||||
@ -105,7 +107,7 @@ exports.refreshInDom = function(changes) {
|
||||
t;
|
||||
// If the state tiddler has changed then reset the open state
|
||||
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
|
||||
if(this.isOpen && this.child.children.length === 0) {
|
||||
|
@ -48,8 +48,7 @@ exports.info = {
|
||||
tooltip: {byPos: 3, type: "text"},
|
||||
"default": {byName: true, type: "text"},
|
||||
"class": {byName: true, type: "text"}
|
||||
},
|
||||
events: ["click"]
|
||||
}
|
||||
};
|
||||
|
||||
exports.getOpenState = function() {
|
||||
@ -142,7 +141,10 @@ exports.executeMacro = function() {
|
||||
},
|
||||
sliderChildren
|
||||
)
|
||||
]
|
||||
],{
|
||||
events: ["click"],
|
||||
eventHandler: this
|
||||
}
|
||||
);
|
||||
child.execute(this.parents,this.tiddlerTitle);
|
||||
return child;
|
||||
|
@ -27,8 +27,7 @@ exports.info = {
|
||||
defaultViewTemplate: {byName: true, type: "tiddler"},
|
||||
defaultEditTemplate: {byName: true, type: "tiddler"},
|
||||
storyview: {byName: true, type: "text"}
|
||||
},
|
||||
events: ["tw-navigate","tw-EditTiddler","tw-SaveTiddler"]
|
||||
}
|
||||
};
|
||||
|
||||
exports.getStory = function() {
|
||||
@ -162,7 +161,10 @@ exports.executeMacro = function() {
|
||||
if(this.classes) {
|
||||
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() {
|
||||
|
@ -15,8 +15,7 @@ Zooming navigator macro
|
||||
exports.info = {
|
||||
name: "zoomer",
|
||||
params: {
|
||||
},
|
||||
events: ["touchstart","touchmove","touchend"]
|
||||
}
|
||||
};
|
||||
|
||||
exports.startZoomer = function(x,y) {
|
||||
@ -112,7 +111,10 @@ exports.executeMacro = function() {
|
||||
if(this.classes) {
|
||||
attributes["class"] = this.classes.slice(0);
|
||||
}
|
||||
return $tw.Tree.Element("div",attributes,[]);
|
||||
return $tw.Tree.Element("div",attributes,[],{
|
||||
events: ["touchstart","touchmove","touchend"],
|
||||
eventHandler: this
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
||||
|
@ -14,13 +14,16 @@ Element nodes
|
||||
|
||||
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) {
|
||||
this.type = type;
|
||||
this.attributes = attributes || {};
|
||||
this.children = children;
|
||||
this.events = options.events;
|
||||
this.eventHandler = options.eventHandler;
|
||||
} 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());
|
||||
}
|
||||
}
|
||||
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) {
|
||||
@ -87,7 +93,9 @@ Element.prototype.render = function(type) {
|
||||
};
|
||||
|
||||
Element.prototype.renderInDom = function(parentDomNode,insertBefore) {
|
||||
// Create the element
|
||||
var element = document.createElement(this.type);
|
||||
// Assign the attributes
|
||||
if(this.attributes) {
|
||||
for(var a in this.attributes) {
|
||||
var v = this.attributes[a];
|
||||
@ -104,12 +112,21 @@ Element.prototype.renderInDom = function(parentDomNode,insertBefore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Insert it into the DOM tree
|
||||
if(insertBefore) {
|
||||
parentDomNode.insertBefore(element,insertBefore);
|
||||
} else {
|
||||
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;
|
||||
// Render any child nodes
|
||||
if(this.children) {
|
||||
for(var t=0; t<this.children.length; t++) {
|
||||
this.children[t].renderInDom(element);
|
||||
|
@ -175,27 +175,13 @@ Macro.prototype.render = function(type) {
|
||||
};
|
||||
|
||||
Macro.prototype.renderInDom = function(parentDomNode,insertBefore) {
|
||||
this.parentDomNode = parentDomNode;
|
||||
if(this.child) {
|
||||
this.child.renderInDom(parentDomNode,insertBefore);
|
||||
this.domNode = this.child.domNode;
|
||||
this.addEventHandlers();
|
||||
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() {
|
||||
// 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) {
|
||||
var t,
|
||||
self = this;
|
||||
// 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);
|
||||
}
|
||||
if(this.child) {
|
||||
this.child.refreshInDom(changes);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user