6 * @license MIT License
\r
7 * @author Harald Kirschner <mail [at] digitarald.de>
\r
8 * @copyright 2008 Author
\r
11 History.implement(new Options());
\r
21 register: function(route) {
\r
22 if (this.routes.push(route) == 1) this.addEvent('changed', this.match);
\r
25 unregister: function(route) {
\r
26 this.routes.remove(route);
\r
29 match: function(state, previous, manual) {
\r
30 if (!manual) this.routes.each(Function.methodize('match', this.state));
\r
33 generate: function() {
\r
34 return this.routes.map(Function.methodize('generate')).clean().join(this.options.separator);
\r
37 update: function() {
\r
38 return this.setState(this.generate());
\r
43 History.Route = new Class({
\r
45 Implements: [Events, Options],
\r
48 * pattern: Regular expression that matches the string updated from onGenerate
\r
49 * defaults: Default values array, initially empty.
\r
50 * flags: When regexp is a String, this is the second argument for new RegExp.
\r
51 * skipDefaults: default true; generate is not called when current values are similar to the default values.
\r
52 * generate: Should return the string for the state string, values are first argument
\r
53 * onMatch: Will be called when the regexp matches, with the new values as argument.
\r
60 generate: function(values) {
\r
66 initialize: function(options){
\r
67 this.setOptions(options);
\r
68 this.pattern = this.options.pattern || '(.*)';
\r
69 if ($type(this.pattern) == 'string') this.pattern = new RegExp(this.pattern, this.options.flags);
\r
70 this.values = this.defaults = this.options.defaults.slice();
\r
71 History.register(this);
\r
75 setValues: function(values) {
\r
76 if (this.values.toString() == values.toString()) return this;
\r
77 this.values = values;
\r
82 setValue: function(index, value) {
\r
83 if (this.values[index] == value) return this;
\r
84 this.values[index] = value;
\r
89 build: function(values) {
\r
90 var tmp = this.values.slice();
\r
91 this.values = values;
\r
92 var state = History.generate();
\r
97 destroy: function() {
\r
98 History.unregister(this);
\r
101 generate: function() {
\r
102 if (this.options.skipDefaultMatch && (String(this.values) == String(this.defaults))) return null;
\r
103 return this.options.generate.call(this, this.values);
\r
106 match: function(state) {
\r
107 var bits = state.match(this.pattern);
\r
108 var defaults = this.defaults;
\r
111 for (var i = 0, j = bits.length; i < j; i++) bits[i] = $pick(bits[i], defaults[i] || null);
\r
112 if (String(bits) != String(defaults)) this.values = bits;
\r
114 this.values = this.defaults.slice();
\r
116 this.fireEvent('onMatch', [this.values, this.defaults]);
\r
121 Function.methodize = function(name) {
\r
122 var args = Array.slice(arguments, 1);
\r
123 return function(obj) {
\r
124 return obj[name].apply(obj, args);
\r