File: History.Routing.js

package info (click to toggle)
tdiary-contrib 5.0.2-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 2,576 kB
  • ctags: 1,957
  • sloc: ruby: 16,900; lisp: 514; xml: 451; php: 61; sql: 40; sh: 35; makefile: 33
file content (126 lines) | stat: -rw-r--r-- 3,211 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
 * History.Routing
 *
 * @version		2.0
 *
 * @license		MIT License
 * @author		Harald Kirschner <mail [at] digitarald.de>
 * @copyright	2008 Author
 */

History.implement(new Options());

History.implement({

	options: {
		separator: ';'
	},

	routes: [],

	register: function(route) {
		if (this.routes.push(route) == 1) this.addEvent('changed', this.match);
	},

	unregister: function(route) {
		this.routes.remove(route);
	},

	match: function(state, previous, manual) {
		if (!manual) this.routes.each(Function.methodize('match', this.state));
	},

	generate: function() {
		return this.routes.map(Function.methodize('generate')).clean().join(this.options.separator);
	},

	update: function() {
		return this.setState(this.generate());
	}

});

History.Route = new Class({

	Implements: [Events, Options],

	/**
	 * pattern:				Regular expression that matches the string updated from onGenerate
	 * defaults:			Default values array, initially empty.
	 * flags:				When regexp is a String, this is the second argument for new RegExp.
	 * skipDefaults:		default true; generate is not called when current values are similar to the default values.
	 * generate:			Should return the string for the state string, values are first argument
	 * onMatch:				Will be called when the regexp matches, with the new values as argument.
	 */
	options: {
		skipDefaults: true,
		defaults: [],
		pattern: null,
		flags: '',
		generate: function(values) {
			return values[0];
		},
		onMatch: $empty
	},

	initialize: function(options){
		this.setOptions(options);
		this.pattern = this.options.pattern || '(.*)';
		if ($type(this.pattern) == 'string') this.pattern = new RegExp(this.pattern, this.options.flags);
		this.values = this.defaults = this.options.defaults.slice();
		History.register(this);
		return this;
	},

	setValues: function(values) {
		if (this.values.toString() == values.toString()) return this;
		this.values = values;
		History.update();
		return this;
	},

	setValue: function(index, value) {
		if (this.values[index] == value) return this;
		this.values[index] = value;
		History.update();
		return this;
	},

	build: function(values) {
		var tmp = this.values.slice();
		this.values = values;
		var state = History.generate();
		this.values = tmp;
		return state;
	},

	destroy: function() {
		History.unregister(this);
	},

	generate: function() {
		if (this.options.skipDefaultMatch && (String(this.values) == String(this.defaults))) return null;
		return this.options.generate.call(this, this.values);
	},

	match: function(state) {
		var bits = state.match(this.pattern);
		var defaults = this.defaults;
		if (bits) {
			bits.splice(0, 1);
			for (var i = 0, j = bits.length; i < j; i++) bits[i] = $pick(bits[i], defaults[i] || null);
			if (String(bits) != String(defaults)) this.values = bits;
		} else {
			this.values = this.defaults.slice();
		}
		this.fireEvent('onMatch', [this.values, this.defaults]);
	}

});

Function.methodize = function(name) {
	var args = Array.slice(arguments, 1);
	return function(obj) {
		return obj[name].apply(obj, args);
	};
};