equipment 0.1.0 → 1.4.84
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +9 -0
- data/LICENSE +340 -0
- data/README +29 -12
- data/Rakefile +157 -0
- data/TODO +14 -0
- data/doc/structure.dia +0 -0
- data/doc/structure.png +0 -0
- data/lib/camping_ext.rb +72 -0
- data/lib/equipment.rb +39 -116
- data/lib/ext.rb +33 -0
- data/lib/ext/active_record.rb +146 -0
- data/lib/ext/basic_auth.rb +15 -15
- data/lib/ext/controls.rb +16 -14
- data/lib/ext/flash.rb +35 -17
- data/lib/ext/form_helpers.rb +46 -0
- data/lib/ext/forward.rb +44 -15
- data/lib/ext/js_helpers.rb +66 -19
- data/lib/ext/logging.rb +61 -0
- data/lib/ext/mount.rb +33 -27
- data/lib/ext/negociate_content.rb +90 -0
- data/lib/ext/og.rb +18 -10
- data/lib/ext/og_scaffold.rb +5 -8
- data/lib/ext/resource.rb +127 -0
- data/lib/ext/security.rb +66 -31
- data/lib/ext/sendfile.rb +3 -4
- data/lib/ext/settings.rb +243 -0
- data/lib/ext/template_view.rb +9 -37
- data/lib/ext/use_helper.rb +6 -10
- data/lib/ext/view.rb +98 -0
- data/lib/ext/view_slot.rb +60 -0
- data/lib/mimetype_ext.rb +12 -0
- data/lib/more/typecast.rb +288 -0
- data/lib/ruby_ext.rb +126 -0
- data/share/js/date_ext.js +234 -0
- data/share/js/es-confirm.js +23 -0
- data/share/js/event-selector.js +145 -0
- data/share/js/jquery.js +1793 -0
- data/share/js/prototype.js +2012 -0
- metadata +50 -35
- data/ProjectInfo +0 -55
- data/examples/basicauthtest.rb +0 -59
- data/examples/erubytest.rb +0 -36
- data/examples/flashtest.rb +0 -46
- data/examples/index.erb +0 -9
- data/examples/mounttest.rb +0 -34
- data/examples/ogtest.rb +0 -41
- data/examples/patchestest.rb +0 -40
- data/examples/sendfiletest.rb +0 -29
- data/lib/ext/forms.rb +0 -22
- data/lib/ext/patches.rb +0 -130
- data/lib/ext/ressource.rb +0 -88
data/lib/ruby_ext.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# Some core ruby extensions
|
2
|
+
|
3
|
+
class Module
|
4
|
+
|
5
|
+
# Utility method to transfer all classes of a module into another. It is
|
6
|
+
# useful when you write Camping extensions. cf. other equipments.
|
7
|
+
#
|
8
|
+
# I'm using this to override ServerError and NotFound controllers.
|
9
|
+
def transfer_classes_to(dest, force=false)
|
10
|
+
constants.each do |str|
|
11
|
+
k = const_get(str)
|
12
|
+
if k.kind_of? Class
|
13
|
+
dest.send :remove_const, str if force and dest.const_defined? str
|
14
|
+
dest.const_set str, k.dup unless dest.const_defined? str
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# WARNING : This is a dangerous method
|
20
|
+
#
|
21
|
+
# It's like include but changes the order so that the new module is
|
22
|
+
# before the older one.
|
23
|
+
def insert(new_mod)
|
24
|
+
new_mod = new_mod.dup
|
25
|
+
old_mod = self
|
26
|
+
mod_name = self.basename
|
27
|
+
|
28
|
+
new_mod.module_eval do
|
29
|
+
include old_mod
|
30
|
+
end
|
31
|
+
|
32
|
+
(nesting[-2] || Object).module_eval do
|
33
|
+
remove_const mod_name
|
34
|
+
const_set mod_name, new_mod
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# From the Facets package
|
39
|
+
#
|
40
|
+
# Returns an array of all the parents in the namespace name.
|
41
|
+
#
|
42
|
+
# ex. YourApp::Models::Page #=> [YourApp::Models::Page,
|
43
|
+
# YourApp::Models, YourApp]
|
44
|
+
def nesting
|
45
|
+
n = []
|
46
|
+
name.split(/::/).inject(self){ |mod, name| c = mod.const_get(name) ; n << c ; c }
|
47
|
+
return n
|
48
|
+
end
|
49
|
+
|
50
|
+
# From the Facets package
|
51
|
+
#
|
52
|
+
# returns the name of the class or module without the namespace
|
53
|
+
# prefix.
|
54
|
+
#
|
55
|
+
def basename
|
56
|
+
if name and not name.empty?
|
57
|
+
name.gsub(/^.*::/, '')
|
58
|
+
else
|
59
|
+
nil #inspect.gsub('#<','').gsub('>','').sub(':', '_')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
class Object
|
66
|
+
|
67
|
+
# Sets all instance variables of an object to another
|
68
|
+
#
|
69
|
+
# if force is set to true, existing instance variables will be overwritten
|
70
|
+
def instance_variables_send(obj, force=false)
|
71
|
+
instance_variables.each do |v|
|
72
|
+
if force or not obj.instance_variables.include? v
|
73
|
+
obj.instance_variable_set(v, instance_variable_get(v))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
obj
|
77
|
+
end
|
78
|
+
alias :ivs_send :instance_variables_send
|
79
|
+
|
80
|
+
# Does what its name says
|
81
|
+
def extend_once(*mods)
|
82
|
+
mods.each do |mod|
|
83
|
+
extend mod unless metaclass.ancestors.include? mod
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Does what its name says
|
88
|
+
def include_once(*mods)
|
89
|
+
mods.each do |mod|
|
90
|
+
include mod unless ancestors.include? mod
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class String
|
96
|
+
# From the Facets package.
|
97
|
+
#
|
98
|
+
# Changes a module name in a method compatible name.
|
99
|
+
def methodize
|
100
|
+
to_s.gsub(/([A-Z])/, '_\1').downcase.gsub(/^_/,'').gsub(/(::|\/)_?/, '__')
|
101
|
+
end
|
102
|
+
|
103
|
+
# From the Facets package.
|
104
|
+
#
|
105
|
+
# Changes a method name in a module compatible name.
|
106
|
+
def modulize
|
107
|
+
to_s.gsub(/(__|\/)(.?)/){ "::" + $2.upcase }.gsub(/(^|_)(.)/){ $2.upcase }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class Symbol
|
112
|
+
# Seen on
|
113
|
+
# http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Tech/Ruby/ToProc.rdoc
|
114
|
+
def to_proc
|
115
|
+
proc { |obj, *args| obj.send(self, *args) }
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
module Kernel
|
120
|
+
# Checks if a module is loaded without triggering autoload
|
121
|
+
def using?(sym)
|
122
|
+
return false if Object.autoload?(sym)
|
123
|
+
return Object.const_defined?(sym)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
@@ -0,0 +1,234 @@
|
|
1
|
+
|
2
|
+
// BEGIN: DATE OBJECT PATCHES
|
3
|
+
|
4
|
+
/** Adds the number of days array to the Date object. */
|
5
|
+
Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
|
6
|
+
|
7
|
+
/** Constants used for time computations */
|
8
|
+
Date.SECOND = 1000 /* milliseconds */;
|
9
|
+
Date.MINUTE = 60 * Date.SECOND;
|
10
|
+
Date.HOUR = 60 * Date.MINUTE;
|
11
|
+
Date.DAY = 24 * Date.HOUR;
|
12
|
+
Date.WEEK = 7 * Date.DAY;
|
13
|
+
|
14
|
+
Date.parseDate = function(str, fmt) {
|
15
|
+
var today = new Date();
|
16
|
+
var y = 0;
|
17
|
+
var m = -1;
|
18
|
+
var d = 0;
|
19
|
+
var a = str.split(/\W+/);
|
20
|
+
var b = fmt.match(/%./g);
|
21
|
+
var i = 0, j = 0;
|
22
|
+
var hr = 0;
|
23
|
+
var min = 0;
|
24
|
+
for (i = 0; i < a.length; ++i) {
|
25
|
+
if (!a[i])
|
26
|
+
continue;
|
27
|
+
switch (b[i]) {
|
28
|
+
case "%d":
|
29
|
+
case "%e":
|
30
|
+
d = parseInt(a[i], 10);
|
31
|
+
break;
|
32
|
+
|
33
|
+
case "%m":
|
34
|
+
m = parseInt(a[i], 10) - 1;
|
35
|
+
break;
|
36
|
+
|
37
|
+
case "%Y":
|
38
|
+
case "%y":
|
39
|
+
y = parseInt(a[i], 10);
|
40
|
+
(y < 100) && (y += (y > 29) ? 1900 : 2000);
|
41
|
+
break;
|
42
|
+
|
43
|
+
case "%b":
|
44
|
+
case "%B":
|
45
|
+
for (j = 0; j < 12; ++j) {
|
46
|
+
if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
|
47
|
+
}
|
48
|
+
break;
|
49
|
+
|
50
|
+
case "%H":
|
51
|
+
case "%I":
|
52
|
+
case "%k":
|
53
|
+
case "%l":
|
54
|
+
hr = parseInt(a[i], 10);
|
55
|
+
break;
|
56
|
+
|
57
|
+
case "%P":
|
58
|
+
case "%p":
|
59
|
+
if (/pm/i.test(a[i]) && hr < 12)
|
60
|
+
hr += 12;
|
61
|
+
else if (/am/i.test(a[i]) && hr >= 12)
|
62
|
+
hr -= 12;
|
63
|
+
break;
|
64
|
+
|
65
|
+
case "%M":
|
66
|
+
min = parseInt(a[i], 10);
|
67
|
+
break;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
if (isNaN(y)) y = today.getFullYear();
|
71
|
+
if (isNaN(m)) m = today.getMonth();
|
72
|
+
if (isNaN(d)) d = today.getDate();
|
73
|
+
if (isNaN(hr)) hr = today.getHours();
|
74
|
+
if (isNaN(min)) min = today.getMinutes();
|
75
|
+
if (y != 0 && m != -1 && d != 0)
|
76
|
+
return new Date(y, m, d, hr, min, 0);
|
77
|
+
y = 0; m = -1; d = 0;
|
78
|
+
for (i = 0; i < a.length; ++i) {
|
79
|
+
if (a[i].search(/[a-zA-Z]+/) != -1) {
|
80
|
+
var t = -1;
|
81
|
+
for (j = 0; j < 12; ++j) {
|
82
|
+
if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
|
83
|
+
}
|
84
|
+
if (t != -1) {
|
85
|
+
if (m != -1) {
|
86
|
+
d = m+1;
|
87
|
+
}
|
88
|
+
m = t;
|
89
|
+
}
|
90
|
+
} else if (parseInt(a[i], 10) <= 12 && m == -1) {
|
91
|
+
m = a[i]-1;
|
92
|
+
} else if (parseInt(a[i], 10) > 31 && y == 0) {
|
93
|
+
y = parseInt(a[i], 10);
|
94
|
+
(y < 100) && (y += (y > 29) ? 1900 : 2000);
|
95
|
+
} else if (d == 0) {
|
96
|
+
d = a[i];
|
97
|
+
}
|
98
|
+
}
|
99
|
+
if (y == 0)
|
100
|
+
y = today.getFullYear();
|
101
|
+
if (m != -1 && d != 0)
|
102
|
+
return new Date(y, m, d, hr, min, 0);
|
103
|
+
return today;
|
104
|
+
};
|
105
|
+
|
106
|
+
/** Returns the number of days in the current month */
|
107
|
+
Date.prototype.getMonthDays = function(month) {
|
108
|
+
var year = this.getFullYear();
|
109
|
+
if (typeof month == "undefined") {
|
110
|
+
month = this.getMonth();
|
111
|
+
}
|
112
|
+
if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
|
113
|
+
return 29;
|
114
|
+
} else {
|
115
|
+
return Date._MD[month];
|
116
|
+
}
|
117
|
+
};
|
118
|
+
|
119
|
+
/** Returns the number of day in the year. */
|
120
|
+
Date.prototype.getDayOfYear = function() {
|
121
|
+
var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
|
122
|
+
var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
|
123
|
+
var time = now - then;
|
124
|
+
return Math.floor(time / Date.DAY);
|
125
|
+
};
|
126
|
+
|
127
|
+
/** Returns the number of the week in year, as defined in ISO 8601. */
|
128
|
+
Date.prototype.getWeekNumber = function() {
|
129
|
+
var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
|
130
|
+
var DoW = d.getDay();
|
131
|
+
d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
|
132
|
+
var ms = d.valueOf(); // GMT
|
133
|
+
d.setMonth(0);
|
134
|
+
d.setDate(4); // Thu in Week 1
|
135
|
+
return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
|
136
|
+
};
|
137
|
+
|
138
|
+
/** Checks date and time equality */
|
139
|
+
Date.prototype.equalsTo = function(date) {
|
140
|
+
return ((this.getFullYear() == date.getFullYear()) &&
|
141
|
+
(this.getMonth() == date.getMonth()) &&
|
142
|
+
(this.getDate() == date.getDate()) &&
|
143
|
+
(this.getHours() == date.getHours()) &&
|
144
|
+
(this.getMinutes() == date.getMinutes()));
|
145
|
+
};
|
146
|
+
|
147
|
+
/** Set only the year, month, date parts (keep existing time) */
|
148
|
+
Date.prototype.setDateOnly = function(date) {
|
149
|
+
var tmp = new Date(date);
|
150
|
+
this.setDate(1);
|
151
|
+
this.setFullYear(tmp.getFullYear());
|
152
|
+
this.setMonth(tmp.getMonth());
|
153
|
+
this.setDate(tmp.getDate());
|
154
|
+
};
|
155
|
+
|
156
|
+
/** Prints the date in a string according to the given format. */
|
157
|
+
Date.prototype.print = function (str) {
|
158
|
+
var m = this.getMonth();
|
159
|
+
var d = this.getDate();
|
160
|
+
var y = this.getFullYear();
|
161
|
+
var wn = this.getWeekNumber();
|
162
|
+
var w = this.getDay();
|
163
|
+
var s = {};
|
164
|
+
var hr = this.getHours();
|
165
|
+
var pm = (hr >= 12);
|
166
|
+
var ir = (pm) ? (hr - 12) : hr;
|
167
|
+
var dy = this.getDayOfYear();
|
168
|
+
if (ir == 0)
|
169
|
+
ir = 12;
|
170
|
+
var min = this.getMinutes();
|
171
|
+
var sec = this.getSeconds();
|
172
|
+
// s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
|
173
|
+
// s["%A"] = Calendar._DN[w]; // full weekday name
|
174
|
+
// s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
|
175
|
+
// s["%B"] = Calendar._MN[m]; // full month name
|
176
|
+
// FIXME: %c : preferred date and time representation for the current locale
|
177
|
+
s["%C"] = 1 + Math.floor(y / 100); // the century number
|
178
|
+
s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
|
179
|
+
s["%e"] = d; // the day of the month (range 1 to 31)
|
180
|
+
// FIXME: %D : american date style: %m/%d/%y
|
181
|
+
// FIXME: %E, %F, %G, %g, %h (man strftime)
|
182
|
+
s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
|
183
|
+
s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
|
184
|
+
s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
|
185
|
+
s["%k"] = hr; // hour, range 0 to 23 (24h format)
|
186
|
+
s["%l"] = ir; // hour, range 1 to 12 (12h format)
|
187
|
+
s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
|
188
|
+
s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
|
189
|
+
s["%n"] = "\n"; // a newline character
|
190
|
+
s["%p"] = pm ? "PM" : "AM";
|
191
|
+
s["%P"] = pm ? "pm" : "am";
|
192
|
+
// FIXME: %r : the time in am/pm notation %I:%M:%S %p
|
193
|
+
// FIXME: %R : the time in 24-hour notation %H:%M
|
194
|
+
s["%s"] = Math.floor(this.getTime() / 1000);
|
195
|
+
s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
|
196
|
+
s["%t"] = "\t"; // a tab character
|
197
|
+
// FIXME: %T : the time in 24-hour notation (%H:%M:%S)
|
198
|
+
s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
|
199
|
+
s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON)
|
200
|
+
s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN)
|
201
|
+
// FIXME: %x : preferred date representation for the current locale without the time
|
202
|
+
// FIXME: %X : preferred time representation for the current locale without the date
|
203
|
+
s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
|
204
|
+
s["%Y"] = y; // year with the century
|
205
|
+
s["%%"] = "%"; // a literal '%' character
|
206
|
+
|
207
|
+
var re = /%./g;
|
208
|
+
// if (!Calendar.is_ie5 && !Calendar.is_khtml)
|
209
|
+
// return str.replace(re, function (par) { return s[par] || par; });
|
210
|
+
|
211
|
+
var a = str.match(re);
|
212
|
+
for (var i = 0; i < a.length; i++) {
|
213
|
+
var tmp = s[a[i]];
|
214
|
+
if (tmp) {
|
215
|
+
re = new RegExp(a[i], 'g');
|
216
|
+
str = str.replace(re, tmp);
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
return str;
|
221
|
+
};
|
222
|
+
|
223
|
+
Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear;
|
224
|
+
Date.prototype.setFullYear = function(y) {
|
225
|
+
var d = new Date(this);
|
226
|
+
d.__msh_oldSetFullYear(y);
|
227
|
+
if (d.getMonth() != this.getMonth())
|
228
|
+
this.setDate(28);
|
229
|
+
this.__msh_oldSetFullYear(y);
|
230
|
+
};
|
231
|
+
|
232
|
+
// END: DATE OBJECT PATCHES
|
233
|
+
|
234
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
// TODO : Fix some bug here
|
2
|
+
function confirm_event(elem, event) {
|
3
|
+
var source = Event.element(event);
|
4
|
+
var message = ''
|
5
|
+
if (source.value) {
|
6
|
+
message = source.value
|
7
|
+
} else {
|
8
|
+
message = source.innerHTML
|
9
|
+
}
|
10
|
+
|
11
|
+
var answer = confirm('Are you sure you want to ' + message + ' ?')
|
12
|
+
if (!answer) {
|
13
|
+
Event.stop(event);
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
EventSelector.register({
|
18
|
+
'FORM.confirm:submit': confirm_event,
|
19
|
+
'A.confirm:click': confirm_event,
|
20
|
+
'INPUT.confirm:click': confirm_event,
|
21
|
+
'BUTTON.confirm:click': confirm_event
|
22
|
+
})
|
23
|
+
|
@@ -0,0 +1,145 @@
|
|
1
|
+
// EventSelector
|
2
|
+
|
3
|
+
// This is a modified version for Equipment
|
4
|
+
|
5
|
+
// Copyright (c) 2005-2006 Justin Palmer (http://encytemedia.com)
|
6
|
+
// Examples and documentation (http://encytemedia.com/event-selectors)
|
7
|
+
//
|
8
|
+
// EventSelectors allow you access to Javascript events using a CSS style syntax.
|
9
|
+
// It goes one step beyond Javascript events to also give you :loaded, which allows
|
10
|
+
// you to wait until an item is loaded in the document before you begin to interact
|
11
|
+
// with it.
|
12
|
+
//
|
13
|
+
// Inspired by the work of Ben Nolan's Behaviour (http://bennolan.com/behaviour)
|
14
|
+
//
|
15
|
+
// Permission is hereby granted, free of charge, to any person obtaining
|
16
|
+
// a copy of this software and associated documentation files (the
|
17
|
+
// "Software"), to deal in the Software without restriction, including
|
18
|
+
// without limitation the rights to use, copy, modify, merge, publish,
|
19
|
+
// distribute, sublicense, and/or sell copies of the Software, and to
|
20
|
+
// permit persons to whom the Software is furnished to do so, subject to
|
21
|
+
// the following conditions:
|
22
|
+
//
|
23
|
+
// The above copyright notice and this permission notice shall be
|
24
|
+
// included in all copies or substantial portions of the Software.
|
25
|
+
//
|
26
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
27
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
28
|
+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
29
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
30
|
+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
31
|
+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
32
|
+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
33
|
+
//
|
34
|
+
|
35
|
+
if (!Ajax) {
|
36
|
+
throw "The Prototype library is not available for EventSelector. Please include that first."
|
37
|
+
}
|
38
|
+
|
39
|
+
var clone = function(obj) {
|
40
|
+
for(var key in obj) { this[key] = obj[key] }
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
var EventSelector = {
|
45
|
+
version: '1.0_pre',
|
46
|
+
cache: {},
|
47
|
+
started: false,
|
48
|
+
rules: {},
|
49
|
+
|
50
|
+
start: function() {
|
51
|
+
this.timer = new Array();
|
52
|
+
this.started = true;
|
53
|
+
this.register(this.rules);
|
54
|
+
},
|
55
|
+
|
56
|
+
reload: function(){
|
57
|
+
this.register(this.rules);
|
58
|
+
},
|
59
|
+
|
60
|
+
register: function(rules){
|
61
|
+
this._extendRules(new clone(rules))._each(
|
62
|
+
function(rule) { this.assign(rule.key, rule.value); }.bind(this)
|
63
|
+
);
|
64
|
+
},
|
65
|
+
|
66
|
+
unregister: function(rules){
|
67
|
+
this._extendRules(new clone(rules))._each(
|
68
|
+
function(rule) { this.deassign(rule.key); }.bind(this)
|
69
|
+
);
|
70
|
+
},
|
71
|
+
|
72
|
+
assign: function(key, value) {
|
73
|
+
this.deassign(key);
|
74
|
+
this.rules[key] = value;
|
75
|
+
|
76
|
+
if (this.started) {
|
77
|
+
var rule = [key, value];
|
78
|
+
rule.key = key; rule.value = value;
|
79
|
+
|
80
|
+
var observer = null;
|
81
|
+
var selectors = $A(rule.key.split(','));
|
82
|
+
selectors.each(function(selector) {
|
83
|
+
var pair = selector.split(':');
|
84
|
+
var event = pair[1];
|
85
|
+
$$(pair[0]).each(function(element) {
|
86
|
+
if(pair[1] == '' || pair.length == 1) return rule.value(element);
|
87
|
+
if(event.toLowerCase() == 'loaded') {
|
88
|
+
this.timer[pair[0]] = setInterval(this._checkLoaded.bind(this, element, pair[0], rule), 15);
|
89
|
+
} else {
|
90
|
+
observer = function(event) {
|
91
|
+
var element = Event.element(event);
|
92
|
+
if (element.nodeType == 3) // Safari Bug (Fixed in Webkit)
|
93
|
+
element = element.parentNode;
|
94
|
+
rule.value($(element), event);
|
95
|
+
}
|
96
|
+
this.cache[key] || (this.cache[key] = []);
|
97
|
+
this.cache[key].push([element, event, observer]);
|
98
|
+
Event.observe(element, event, observer);
|
99
|
+
}
|
100
|
+
}.bind(this));
|
101
|
+
}.bind(this));
|
102
|
+
}
|
103
|
+
},
|
104
|
+
|
105
|
+
deassign: function(key) {
|
106
|
+
if (!this.cache || !this.cache[key]) return;
|
107
|
+
for (var i = 0; i < this.cache[key].length; i++) {
|
108
|
+
Event.stopObserving.apply(this, this.cache[key][i]);
|
109
|
+
}
|
110
|
+
delete this.cache[key];
|
111
|
+
delete this.rules[key];
|
112
|
+
},
|
113
|
+
|
114
|
+
_checkLoaded: function(element, timer, rule) {
|
115
|
+
var node = $(element);
|
116
|
+
if(element.tagName != 'undefined') {
|
117
|
+
clearInterval(this.timer[timer]);
|
118
|
+
rule.value(node);
|
119
|
+
}
|
120
|
+
},
|
121
|
+
|
122
|
+
_extendRules: function(rules) {
|
123
|
+
return Object.extend(rules, {
|
124
|
+
_each: function(iterator) {
|
125
|
+
for (var key in this) {
|
126
|
+
if(key == '_each') continue;
|
127
|
+
var value = this[key];
|
128
|
+
var pair = [key, value];
|
129
|
+
pair.key = key;
|
130
|
+
pair.value = value;
|
131
|
+
iterator(pair);
|
132
|
+
}
|
133
|
+
}
|
134
|
+
});
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
// Remove/Comment this if you do not wish to reapply Rules automatically
|
139
|
+
// on Ajax request.
|
140
|
+
Ajax.Responders.register({
|
141
|
+
onComplete: function() { EventSelector.reload() }
|
142
|
+
});
|
143
|
+
|
144
|
+
Event.observe(window, 'load', function() { EventSelector.start() })
|
145
|
+
|