149 lines
4.8 KiB
JavaScript
149 lines
4.8 KiB
JavaScript
var Path = {
|
|
'version': "0.6.4",
|
|
'map': function (path) {
|
|
if (Path.routes.defined.hasOwnProperty(path)) {
|
|
return Path.routes.defined[path];
|
|
} else {
|
|
return new Path.core.route(path);
|
|
}
|
|
},
|
|
'root': function (path) {
|
|
Path.routes.root = path;
|
|
},
|
|
'rescue': function (fn) {
|
|
Path.routes.rescue = fn;
|
|
},
|
|
'match': function (path, parameterize) {
|
|
var params = {}, route = null, possible_routes, slice, i, j, compare;
|
|
for (route in Path.routes.defined) {
|
|
if (route !== null && route !== undefined) {
|
|
route = Path.routes.defined[route];
|
|
possible_routes = route.partition();
|
|
for (j = 0; j < possible_routes.length; j++) {
|
|
slice = possible_routes[j];
|
|
compare = path;
|
|
if (slice.search(/:/) > 0) {
|
|
for (i = 0; i < slice.split("/").length; i++) {
|
|
if ((i < compare.split("/").length) && (slice.split("/")[i][0] === ":")) {
|
|
params[slice.split('/')[i].replace(/:/, '')] = compare.split("/")[i];
|
|
compare = compare.replace(compare.split("/")[i], slice.split("/")[i]);
|
|
}
|
|
}
|
|
}
|
|
if (slice === compare) {
|
|
if (parameterize) {
|
|
route.params = params;
|
|
}
|
|
return route;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
'dispatch': function () {
|
|
var previous_route, matched_route;
|
|
if (Path.routes.current !== location.hash) {
|
|
Path.routes.previous = Path.routes.current;
|
|
Path.routes.current = location.hash;
|
|
matched_route = Path.match(location.hash, true);
|
|
|
|
if (Path.routes.previous) {
|
|
previous_route = Path.match(Path.routes.previous);
|
|
if (previous_route !== null && previous_route.do_exit !== null) {
|
|
previous_route.do_exit();
|
|
}
|
|
}
|
|
|
|
if (matched_route !== null) {
|
|
matched_route.run();
|
|
} else {
|
|
if (Path.routes.rescue !== null) {
|
|
Path.routes.rescue();
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'listen': function () {
|
|
if (location.hash === "") {
|
|
if (Path.routes.root !== null) {
|
|
location.hash = Path.routes.root;
|
|
// artistandarchitects:
|
|
// Added to init response on hashchange
|
|
Path.dispatch();
|
|
}
|
|
} else {
|
|
Path.dispatch();
|
|
}
|
|
|
|
if ("onhashchange" in window) {
|
|
window.onhashchange = Path.dispatch;
|
|
} else {
|
|
setInterval(Path.dispatch, 50);
|
|
}
|
|
},
|
|
'core': {
|
|
'route': function (path) {
|
|
this.path = path;
|
|
this.action = null;
|
|
this.do_enter = [];
|
|
this.do_exit = null;
|
|
this.params = {};
|
|
Path.routes.defined[path] = this;
|
|
}
|
|
},
|
|
'routes': {
|
|
'current': null,
|
|
'root': null,
|
|
'rescue': null,
|
|
'previous': null,
|
|
'defined': {}
|
|
}
|
|
};
|
|
Path.core.route.prototype = {
|
|
'to': function (fn) {
|
|
this.action = fn;
|
|
return this;
|
|
},
|
|
'enter': function (fns) {
|
|
if (fns instanceof Array) {
|
|
this.do_enter = this.do_enter.concat(fns);
|
|
} else {
|
|
this.do_enter.push(fns);
|
|
}
|
|
return this;
|
|
},
|
|
'exit': function (fn) {
|
|
this.do_exit = fn;
|
|
return this;
|
|
},
|
|
'partition': function () {
|
|
var parts = [], options = [], re = /\(([^}]+?)\)/g, text, i;
|
|
while (text = re.exec(this.path)) {
|
|
parts.push(text[1]);
|
|
}
|
|
options.push(this.path.split("(")[0]);
|
|
for (i = 0; i < parts.length; i++) {
|
|
options.push(options[options.length - 1] + parts[i]);
|
|
}
|
|
return options;
|
|
},
|
|
'run': function () {
|
|
var halt_execution = false, i, result, previous;
|
|
|
|
if (Path.routes.defined[this.path].hasOwnProperty("do_enter")) {
|
|
if (Path.routes.defined[this.path].do_enter.length > 0) {
|
|
for (i = 0; i < Path.routes.defined[this.path].do_enter.length; i++) {
|
|
result = Path.routes.defined[this.path].do_enter[i]();
|
|
if (result === false) {
|
|
halt_execution = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!halt_execution) {
|
|
Path.routes.defined[this.path].action();
|
|
}
|
|
}
|
|
}; |