Created
August 5, 2009 11:00
-
-
Save obeattie/162642 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Implements an anchor-based permalink system, with handlers assigned to a component. | |
* The format used is "/page/#key1:(value1,value2),key2:(value3,value4)[...]" | |
*/ | |
var PermalinkManager = new Class({ | |
Implements: [Events, Class.Binds], | |
Binds: ['processHash'], | |
initialize: function() { | |
this.handlers = new Hash(); | |
this.permalink = new Hash(); | |
}, | |
processHash: function() { | |
// Split the permalink into parts | |
var parts = window.location.hash.split(/(\w+:\([^\)]+\)),?/).filter($chk); | |
parts.each(function(part){ | |
part = part.split(/^(\w+):\(([^\)]+)\)$/).filter($chk); | |
if (part.length == 2) { | |
part[1] = part[1].split(',').filter($chk); | |
if (!this.permalink.has(part[0])){ | |
// The key has not been entered into the Hash yet | |
this.permalink.set(part[0], part[1]); | |
} else { | |
// Extend the values already there | |
this.permalink.get(part[0]).extend(part[1]); | |
} | |
// Finally, call defined handlers for each value | |
if (this.handlers.has(part[0])){ | |
part[1].each(this.handlers.get(part[0])); | |
} | |
} | |
}, this); | |
}, | |
resetHash: function() { | |
var template = '{key}:({values})'; | |
// Get a substitution template for each permalink part | |
var parts = this.permalink.map(function(value, key){ | |
return { | |
'key': key, | |
'values': value.join(',') | |
}; | |
}, this); | |
// Render the template for each part | |
parts = parts.map(function(part){ | |
return template.substitute(part); | |
}, this).getValues(); | |
// And set the hash to the keys, seperated by commas | |
window.location.hash = parts.join(','); | |
}, | |
addHandler: function(key, callback) { | |
if (!this.handlers.has(key)){ | |
this.handlers.set(key, callback); | |
// Call the callbacks for anything already in the permalink which can be handled | |
// by the new handler | |
if (this.permalink.has(key)){ | |
this.permalink.get(key).each(callback); | |
} | |
} | |
}, | |
addPart: function(key, value) { | |
// Values must be strings | |
value = value.toString(); | |
if (this.permalink.has(key)){ | |
// Add the value to the pre-existing key | |
this.permalink.get(key).push(value); | |
} else { | |
// Create a new key | |
this.permalink.set(key, [value]); | |
} | |
this.resetHash(); | |
}, | |
removePart: function(key, value) { | |
if (!$defined(value)) { | |
// Erase the key itself if no value was passed | |
this.permalink.erase(key); | |
} else if (this.permalink.has(key)) { | |
// Values must be strings | |
value = value.toString(); | |
// Remove the value specified from the key | |
this.permalink.set(key, this.permalink.get(key).erase(value)); | |
if (this.permalink.get(key).length == 0) { | |
// Remove the key entirely from the permalink, since no values remain | |
this.permalink.erase(key); | |
} | |
} | |
this.resetHash(); | |
} | |
}); | |
// We just need a global instance of this | |
PermalinkManager = new PermalinkManager(); | |
// Process everything on domready | |
window.addEvent('domready', PermalinkManager.processHash); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment