1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-10-02 08:50:46 +00:00

Refactored navigation to use new macro event mechanism

Phew. This gets rid of a lot of hacks
This commit is contained in:
Jeremy Ruston 2012-02-02 18:00:42 +00:00
parent f576c86b41
commit 58ab36ef51
6 changed files with 22 additions and 168 deletions

View File

@ -16,9 +16,7 @@ var WikiStore = require("./WikiStore.js").WikiStore,
WikiTextParser = require("./WikiTextParser.js").WikiTextParser,
JSONParser = require("./JSONParser.js").JSONParser,
JavaScriptParser = require("./JavaScriptParser.js").JavaScriptParser,
ImageParser = require("./ImageParser.js").ImageParser,
Navigators = require("./Navigators.js").Navigators,
StoryNavigator = require("./StoryNavigator.js").StoryNavigator;
ImageParser = require("./ImageParser.js").ImageParser;
var App = function() {
var t;
@ -100,14 +98,6 @@ var App = function() {
this.store.installMacro(require("./macros/view.js").macro);
// Set up navigation if we're in the browser
if(this.isBrowser) {
// Install the standard navigators
var navigators = new Navigators({
document: document,
store: this.store
});
navigators.registerNavigator("StoryNavigator",new StoryNavigator(navigators));
// Use the story navigator for all links
navigators.install("a","StoryNavigator");
// Open the PageTemplate
var div = document.createElement("div");
this.store.renderTiddlerInNode(div,"PageTemplate");

View File

@ -1,56 +0,0 @@
/*\
title: js/Navigators.js
This browser component manages the available navigators that handle clicking on links to tiddlers.
\*/
(function(){
/*jslint node: true */
"use strict";
var util = require("util");
/*
Options hashmap has mandatory members:
document: the DOM document to use
store: the wiki store to use
*/
var Navigators = function(options) {
this.document = options.document;
this.store = options.store;
this.navigators = {};
};
Navigators.prototype.registerNavigator = function(name,nav) {
this.navigators[name] = nav;
};
Navigators.prototype.install = function(selector,navname) {
var nav = this.navigators[navname];
this.document.addEventListener("click",function(event) {
var el = event.target,
matchesSelector = el.matchesSelector || el.mozMatchesSelector ||
el.webkitMatchesSelector || el.oMatchesSelector || el.msMatchesSelector;
if(matchesSelector && matchesSelector.call(el,selector)) {
var r = nav.navigateTo(el.getAttribute("href"),event);
if(!r) {
event.preventDefault();
} else {
el.setAttribute("target","_blank");
}
return r;
}
},false);
};
Navigators.prototype.navigateTo = function(title,navname) {
var nav = this.navigators[navname];
if(nav) {
nav.navigateTo(title);
}
};
exports.Navigators = Navigators;
})();

View File

@ -1,34 +0,0 @@
/*\
title: js/StoryNavigator.js
This browser component manages navigating to new tiddlers in a TiddlyWiki classic story style
\*/
(function(){
/*jslint node: true, jquery: true */
"use strict";
var Tiddler = require("./Tiddler.js").Tiddler;
var StoryNavigator = function(navigators) {
this.navigators = navigators;
};
StoryNavigator.prototype.navigateTo = function(title,event) {
var store = this.navigators.store,
tiddler = store.getTiddler(title);
if(tiddler) {
store.invokeMacroMethod(event.target,"navigateTo",{
event: event,
target: title
});
return false;
} else {
return true;
}
};
exports.StoryNavigator = StoryNavigator;
})();

View File

@ -514,62 +514,6 @@ WikiStore.prototype.refreshDomNode = function(node,changes,renderer,tiddler) {
}
};
/*
Search up the parents of the specified node, looking for a macro that accepts the specified method
*/
WikiStore.prototype.invokeMacroMethod = function(node,method,args) {
// Walk up the DOM chain to get the context tiddler for each node
var contextStack = [],
macroStack = [],
nodeStack = [],
parentWalker = function(node) {
if(node.parentNode !== null) {
var parentContext = parentWalker(node.parentNode),
contextInfo = {tiddler: parentContext.tiddler, template: parentContext.template},
macroInfo = {};
if(node.getAttribute) {
if(node.hasAttribute("data-tw-render-tiddler")) {
contextInfo.tiddler = node.getAttribute("data-tw-render-tiddler");
contextInfo.template = node.getAttribute("data-tw-render-template");
}
macroInfo.macro = node.getAttribute("data-tw-macro");
macroInfo.step = node.getAttribute("data-tw-render-step");
}
nodeStack.push(node);
contextStack.push(contextInfo);
macroStack.push(macroInfo);
return contextInfo;
} else {
return {tiddler: null, template: null};
}
};
parentWalker(node);
// Walk back up the DOM chain to find a macro that can handle this method
var t;
for(t=nodeStack.length-1; t>=0; t--) {
var macro = macroStack[t].macro;
if(macro && this.macros[macro].hasOwnProperty(method)) {
var renderTitle = contextStack[t].tiddler,
renderTemplate = contextStack[t].template,
renderStep = macroStack[t].step;
if(typeof renderTemplate !== "string") {
renderTemplate = renderTitle;
}
var renderTiddler = this.getTiddler(renderTitle),
renderer = this.compileTiddler(renderTemplate,"text/html");
var ret = this.macros[macro][method](args,
nodeStack[t],
renderTiddler,
this,
renderer.renderSteps[renderStep].params(renderTiddler,renderer,this,utils));
if(ret) {
return true;
}
}
}
return false; // Didn't manage to dispatch it
};
exports.WikiStore = WikiStore;
})();

View File

@ -4,7 +4,7 @@ title: js/macros/link.js
\*/
(function(){
/*jslint node: true */
/*jslint node: true, browser: true */
"use strict";
var utils = require("../Utils.js");
@ -16,6 +16,16 @@ exports.macro = {
params: {
target: {byName: "default", type: "tiddler", optional: false}
},
events: {
click: function(event,node,tiddler,store,params) {
var navEvent = document.createEvent("Event");
navEvent.initEvent("tw-navigate",true,true);
navEvent.navigateTo = params.target;
node.dispatchEvent(navEvent);
event.preventDefault();
return false;
}
},
render: function(type,tiddler,store,params,content) {
if(type === "text/html") {
return utils.stitchElement("a",{

View File

@ -4,7 +4,7 @@ title: js/macros/story.js
\*/
(function(){
/*jslint node: true */
/*jslint node: true, jquery: true */
"use strict";
var Tiddler = require("../Tiddler.js").Tiddler,
@ -43,6 +43,15 @@ exports.macro = {
story: {byName: "default", type: "tiddler", optional: false},
template: {byName: true, type: "tiddler", optional: true}
},
events: {
"tw-navigate": function(event,node,tiddler,store,params) {
var storyTiddler = store.getTiddler(params.story);
store.addTiddler(new Tiddler(storyTiddler,{text: event.navigateTo + "\n" + storyTiddler.text}));
$("html,body").animate({
scrollTop: 0
}, 400);
}
},
render: function(type,tiddler,store,params) {
var tiddlers = parseStory(store.getTiddlerText(params.story)),
output = [];
@ -88,15 +97,6 @@ exports.macro = {
node.removeChild(currNode);
currNode = nextNode;
}
},
navigateTo: function(args,node,tiddler,store,params) {
/*jslint jquery: true */
var storyTiddler = store.getTiddler(params.story);
store.addTiddler(new Tiddler(storyTiddler,{text: args.target + "\n" + storyTiddler.text}));
$("html,body").animate({
scrollTop: 0
}, 400);
return true;
}
};