right-rails 1.0.10 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +4 -4
- data/Rakefile +4 -4
- data/lib/right_rails.rb +1 -1
- data/public/javascripts/right/autocompleter-src.js +115 -106
- data/public/javascripts/right/autocompleter.js +3 -14
- data/public/javascripts/right/billboard-src.js +58 -38
- data/public/javascripts/right/billboard.js +3 -13
- data/public/javascripts/right/calendar-src.js +136 -133
- data/public/javascripts/right/calendar.js +4 -33
- data/public/javascripts/right/colorpicker-src.js +128 -125
- data/public/javascripts/right/colorpicker.js +4 -23
- data/public/javascripts/right/dialog-src.js +67 -37
- data/public/javascripts/right/dialog.js +3 -17
- data/public/javascripts/right/dnd-src.js +44 -43
- data/public/javascripts/right/dnd.js +3 -16
- data/public/javascripts/right/effects-src.js +125 -98
- data/public/javascripts/right/effects.js +3 -13
- data/public/javascripts/right/in-edit-src.js +54 -38
- data/public/javascripts/right/in-edit.js +4 -10
- data/public/javascripts/right/jquerysh-src.js +344 -20
- data/public/javascripts/right/jquerysh.js +3 -3
- data/public/javascripts/right/json-src.js +22 -35
- data/public/javascripts/right/json.js +4 -7
- data/public/javascripts/right/keys-src.js +87 -0
- data/public/javascripts/right/keys.js +7 -0
- data/public/javascripts/right/lightbox-src.js +76 -58
- data/public/javascripts/right/lightbox.js +3 -20
- data/public/javascripts/right/rails-src.js +108 -107
- data/public/javascripts/right/rails.js +4 -11
- data/public/javascripts/right/rater-src.js +47 -31
- data/public/javascripts/right/rater.js +3 -9
- data/public/javascripts/right/resizable-src.js +60 -33
- data/public/javascripts/right/resizable.js +3 -11
- data/public/javascripts/right/selectable-src.js +87 -51
- data/public/javascripts/right/selectable.js +3 -18
- data/public/javascripts/right/sizzle-src.js +15 -10
- data/public/javascripts/right/sizzle.js +4 -27
- data/public/javascripts/right/slider-src.js +49 -33
- data/public/javascripts/right/slider.js +3 -10
- data/public/javascripts/right/sortable-src.js +46 -32
- data/public/javascripts/right/sortable.js +4 -13
- data/public/javascripts/right/table-src.js +19 -10
- data/public/javascripts/right/table.js +4 -6
- data/public/javascripts/right/tabs-src.js +69 -47
- data/public/javascripts/right/tabs.js +4 -26
- data/public/javascripts/right/tooltips-src.js +78 -56
- data/public/javascripts/right/tooltips.js +4 -9
- data/public/javascripts/right/uploader-src.js +50 -34
- data/public/javascripts/right/uploader.js +3 -9
- data/public/javascripts/right-olds-src.js +528 -355
- data/public/javascripts/right-olds.js +4 -13
- data/public/javascripts/right-safe-src.js +4 -99
- data/public/javascripts/right-safe.js +3 -4
- data/public/javascripts/right-src.js +1618 -1245
- data/public/javascripts/right.js +4 -91
- metadata +8 -6
@@ -1,26 +1,29 @@
|
|
1
1
|
/**
|
2
|
-
*
|
2
|
+
* The old browsers support module for RightJS
|
3
3
|
*
|
4
|
-
*
|
4
|
+
* Released under the terms of the MIT license
|
5
5
|
* Visit http://rightjs.org for more details
|
6
6
|
*
|
7
|
-
* Copyright (C) 2008-
|
7
|
+
* Copyright (C) 2008-2011 Nikolay V. Nemshilov
|
8
8
|
*/
|
9
|
+
(function(RightJS) {
|
9
10
|
/**
|
10
11
|
* Old IE browser hacks
|
11
12
|
*
|
12
13
|
* Keep them in one place so they were more compact
|
13
14
|
*
|
14
|
-
* Copyright (C) 2009-
|
15
|
+
* Copyright (C) 2009-2011 Nikolay Nemshilov
|
15
16
|
*/
|
16
|
-
if (RightJS.Browser.OLD) {
|
17
|
+
if (RightJS.Browser.OLD && RightJS.Browser.IE) {
|
17
18
|
// loads DOM element extensions for selected elements
|
18
|
-
|
19
|
+
window.$ = RightJS.$ = (function(old_function) {
|
19
20
|
return function(id) {
|
20
21
|
var element = old_function(id);
|
21
22
|
|
22
23
|
// old IE browses match both, ID and NAME
|
23
|
-
if (element && element instanceof RightJS.Element &&
|
24
|
+
if (element && element instanceof RightJS.Element &&
|
25
|
+
RightJS.isString(id) && element._.id !== id
|
26
|
+
) {
|
24
27
|
element = RightJS.$(document).first('#'+ id);
|
25
28
|
}
|
26
29
|
|
@@ -30,17 +33,145 @@ if (RightJS.Browser.OLD) {
|
|
30
33
|
}
|
31
34
|
|
32
35
|
|
36
|
+
/**
|
37
|
+
* Making the 'submit' and 'change' events bubble under IE browsers
|
38
|
+
*
|
39
|
+
* Copyright (C) 2010-2011 Nikolay Nemshilov
|
40
|
+
*/
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Tests if there is the event support
|
44
|
+
*
|
45
|
+
* @param String event name
|
46
|
+
* @retrun Boolean check result
|
47
|
+
*/
|
48
|
+
function event_support_for(name, tag) {
|
49
|
+
var e = document.createElement(tag);
|
50
|
+
e.setAttribute(name, ';');
|
51
|
+
return isFunction(e[name]);
|
52
|
+
}
|
53
|
+
|
54
|
+
if (!event_support_for('onsubmit', 'form')) {
|
55
|
+
/**
|
56
|
+
* Emulates the 'submit' event bubbling for IE browsers
|
57
|
+
*
|
58
|
+
* @param raw dom-event
|
59
|
+
* @return void
|
60
|
+
*/
|
61
|
+
var submit_boobler = function(raw_event) {
|
62
|
+
var event = $(raw_event), element = event.target._,
|
63
|
+
type = element.type, form = element.form, parent;
|
64
|
+
|
65
|
+
if (form && (parent = $(form).parent()) && (
|
66
|
+
(raw_event.keyCode === 13 && (type === 'text' || type === 'password')) ||
|
67
|
+
(raw_event.type === 'click' && (type === 'submit' || type === 'image'))
|
68
|
+
)) {
|
69
|
+
event.type = 'submit';
|
70
|
+
event.target = $(form);
|
71
|
+
parent.fire(event);
|
72
|
+
}
|
73
|
+
};
|
74
|
+
|
75
|
+
document.attachEvent('onclick', submit_boobler);
|
76
|
+
document.attachEvent('onkeypress', submit_boobler);
|
77
|
+
}
|
78
|
+
|
79
|
+
if (!event_support_for('onchange', 'input')) {
|
80
|
+
|
81
|
+
var get_input_value = function(target) {
|
82
|
+
var element = target._,
|
83
|
+
type = element.type;
|
84
|
+
|
85
|
+
return type === 'radio' || type === 'checkbox' ?
|
86
|
+
element.checked : target.getValue();
|
87
|
+
},
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Emulates the 'change' event bubbling
|
91
|
+
*
|
92
|
+
* @param Event wrapped dom-event
|
93
|
+
* @param Input wrapped input element
|
94
|
+
* @return void
|
95
|
+
*/
|
96
|
+
change_boobler = function(event, target) {
|
97
|
+
var parent = target.parent(),
|
98
|
+
value = get_input_value(target);
|
99
|
+
|
100
|
+
if (parent && ''+target._prev_value !== ''+value) {
|
101
|
+
target._prev_value = value; // saving the value so it didn't fire up again
|
102
|
+
event.type = 'change';
|
103
|
+
parent.fire(event);
|
104
|
+
}
|
105
|
+
},
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Catches the input field changes
|
109
|
+
*
|
110
|
+
* @param raw dom-event
|
111
|
+
* @return void
|
112
|
+
*/
|
113
|
+
catch_inputs_access = function(raw_event) {
|
114
|
+
var event = $(raw_event),
|
115
|
+
target = event.target,
|
116
|
+
type = target._.type,
|
117
|
+
tag = target._.tagName,
|
118
|
+
input_is_radio = (type === 'radio' || type === 'checkbox');
|
119
|
+
|
120
|
+
if (
|
121
|
+
(event.type === 'click' && (input_is_radio || tag === 'SELECT')) ||
|
122
|
+
(event.type === 'keydown' && (
|
123
|
+
(event.keyCode == 13 && (tag !== 'TEXTAREA')) ||
|
124
|
+
type === 'select-multiple'
|
125
|
+
))
|
126
|
+
) {
|
127
|
+
change_boobler(event, target);
|
128
|
+
}
|
129
|
+
},
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Catch inputs blur
|
133
|
+
*
|
134
|
+
* @param raw dom-event
|
135
|
+
* @return void
|
136
|
+
*/
|
137
|
+
catch_input_left = function(raw_event) {
|
138
|
+
var event = $(raw_event),
|
139
|
+
target = event.target;
|
140
|
+
|
141
|
+
if (target instanceof Input) {
|
142
|
+
change_boobler(event, target);
|
143
|
+
}
|
144
|
+
};
|
145
|
+
|
146
|
+
document.attachEvent('onclick', catch_inputs_access);
|
147
|
+
document.attachEvent('onkeydown', catch_inputs_access);
|
148
|
+
document.attachEvent('onfocusout', catch_input_left);
|
149
|
+
|
150
|
+
/**
|
151
|
+
* storing the input element previous value, so we could figure out
|
152
|
+
* if it was changed later on
|
153
|
+
*/
|
154
|
+
document.attachEvent('onbeforeactivate', function(event) {
|
155
|
+
var element = $(event).target;
|
156
|
+
|
157
|
+
if (element instanceof Input) {
|
158
|
+
element._prev_value = get_input_value(element);
|
159
|
+
}
|
160
|
+
});
|
161
|
+
}
|
162
|
+
|
163
|
+
|
33
164
|
/**
|
34
165
|
* Konqueror browser fixes
|
35
166
|
*
|
36
|
-
* Copyright (C) 2009-
|
167
|
+
* Copyright (C) 2009-2011 Nikolay V. Nemshilov
|
37
168
|
*/
|
38
169
|
|
39
170
|
/**
|
40
171
|
* manual position calculator, it works for Konqueror and also
|
41
172
|
* for old versions of Opera and FF
|
42
173
|
*/
|
43
|
-
if (!RightJS.$E('p').getBoundingClientRect) {
|
174
|
+
if (!RightJS.$E('p')._.getBoundingClientRect) {
|
44
175
|
RightJS.Element.include({
|
45
176
|
position: function() {
|
46
177
|
var element = this._,
|
@@ -68,412 +199,454 @@ if (!RightJS.$E('p').getBoundingClientRect) {
|
|
68
199
|
* - Sizzle (http://sizzlejs.org) Copyright (C) John Resig
|
69
200
|
* - MooTools (http://mootools.net) Copyright (C) Valerio Proietti
|
70
201
|
*
|
71
|
-
* Copyright (C) 2009-
|
202
|
+
* Copyright (C) 2009-2011 Nikolay V. Nemshilov
|
72
203
|
*/
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
204
|
+
var has_native_css_selector = !!document.querySelector,
|
205
|
+
needs_css_engine_patch = !has_native_css_selector;
|
206
|
+
|
207
|
+
if (RightJS.Browser.IE8L) {
|
208
|
+
needs_css_engine_patch = true;
|
209
|
+
}
|
210
|
+
|
211
|
+
if (needs_css_engine_patch) {
|
212
|
+
/**
|
213
|
+
* The token searchers collection
|
214
|
+
*/
|
215
|
+
var search = {
|
216
|
+
// search for any descendant nodes
|
217
|
+
' ': function(element, tag) {
|
218
|
+
return RightJS.$A(element.getElementsByTagName(tag));
|
219
|
+
},
|
220
|
+
|
221
|
+
// search for immidate descendant nodes
|
222
|
+
'>': function(element, tag) {
|
223
|
+
var result = [], node = element.firstChild;
|
224
|
+
while (node) {
|
225
|
+
if (tag === '*' || node.tagName === tag) {
|
226
|
+
result.push(node);
|
92
227
|
}
|
93
|
-
|
94
|
-
}
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
228
|
+
node = node.nextSibling;
|
229
|
+
}
|
230
|
+
return result;
|
231
|
+
},
|
232
|
+
|
233
|
+
// search for immiate sibling nodes
|
234
|
+
'+': function(element, tag) {
|
235
|
+
while ((element = element.nextSibling)) {
|
236
|
+
if (element.tagName) {
|
237
|
+
return (tag === '*' || element.tagName === tag) ? [element] : [];
|
102
238
|
}
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
239
|
+
}
|
240
|
+
return [];
|
241
|
+
},
|
242
|
+
|
243
|
+
// search for late sibling nodes
|
244
|
+
'~': function(element, tag) {
|
245
|
+
var result = [];
|
246
|
+
while ((element = element.nextSibling)) {
|
247
|
+
if (tag === '*' || element.tagName === tag) {
|
248
|
+
result.push(element);
|
113
249
|
}
|
114
|
-
return result;
|
115
250
|
}
|
116
|
-
|
251
|
+
return result;
|
252
|
+
}
|
253
|
+
},
|
117
254
|
|
118
255
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
256
|
+
/**
|
257
|
+
* Collection of pseudo selector matchers
|
258
|
+
*/
|
259
|
+
pseudos = {
|
260
|
+
not: function(node, css_rule) {
|
261
|
+
return node.nodeType === 1 && !RightJS.$(node).match(css_rule);
|
262
|
+
},
|
126
263
|
|
127
|
-
|
128
|
-
|
129
|
-
|
264
|
+
checked: function(node) {
|
265
|
+
return node.checked === true;
|
266
|
+
},
|
130
267
|
|
131
|
-
|
132
|
-
|
133
|
-
|
268
|
+
enabled: function(node) {
|
269
|
+
return node.disabled === false;
|
270
|
+
},
|
134
271
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
if (node.tagName && (!tag_name || node.tagName == tag_name)) {
|
139
|
-
return false;
|
140
|
-
}
|
141
|
-
}
|
142
|
-
return true;
|
143
|
-
},
|
144
|
-
|
145
|
-
'first-of-type': function() {
|
146
|
-
return arguments[1]['first-child'].call(this, this.tagName);
|
147
|
-
},
|
148
|
-
|
149
|
-
'last-child': function(tag_name) {
|
150
|
-
var node = this;
|
151
|
-
while ((node = node.nextSibling)) {
|
152
|
-
if (node.tagName && (!tag_name || node.tagName == tag_name)) {
|
153
|
-
return false;
|
154
|
-
}
|
155
|
-
}
|
156
|
-
return true;
|
157
|
-
},
|
158
|
-
|
159
|
-
'last-of-type': function() {
|
160
|
-
return arguments[1]['last-child'].call(this, this.tagName);
|
161
|
-
},
|
162
|
-
|
163
|
-
'only-child': function(tag_name, matchers) {
|
164
|
-
return matchers['first-child'].call(this, tag_name) &&
|
165
|
-
matchers['last-child'].call(this, tag_name);
|
166
|
-
},
|
167
|
-
|
168
|
-
'only-of-type': function() {
|
169
|
-
return arguments[1]['only-child'].call(this, this.tagName, arguments[1]);
|
170
|
-
},
|
171
|
-
|
172
|
-
'nth-child': function(number, matchers, tag_name) {
|
173
|
-
if (!this.parentNode) { return false; }
|
174
|
-
number = number.toLowerCase();
|
175
|
-
|
176
|
-
if (number == 'n') { return true; }
|
177
|
-
|
178
|
-
if (number.include('n')) {
|
179
|
-
// parsing out the matching expression
|
180
|
-
var a = 0, b = 0;
|
181
|
-
if ((m = number.match(/^([+\-]?\d*)?n([+\-]?\d*)?$/))) {
|
182
|
-
a = m[1] == '-' ? -1 : parseInt(m[1], 10) || 1;
|
183
|
-
b = parseInt(m[2], 10) || 0;
|
184
|
-
}
|
272
|
+
disabled: function(node) {
|
273
|
+
return node.disabled === true;
|
274
|
+
},
|
185
275
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
if (node.tagName && (!tag_name || node.tagName == tag_name)) { index++; }
|
190
|
-
}
|
276
|
+
selected: function(node) {
|
277
|
+
return node.selected === true;
|
278
|
+
},
|
191
279
|
|
192
|
-
|
280
|
+
empty: function(node) {
|
281
|
+
return !node.firstChild;
|
282
|
+
},
|
193
283
|
|
194
|
-
|
195
|
-
|
284
|
+
'first-child': function(node, node_name) {
|
285
|
+
while ((node = node.previousSibling)) {
|
286
|
+
if (node.nodeType === 1 && (node_name === null || node.nodeName === node_name)) {
|
287
|
+
return false;
|
196
288
|
}
|
197
|
-
},
|
198
|
-
|
199
|
-
'nth-of-type': function(number) {
|
200
|
-
return arguments[1]['nth-child'].call(this, number, arguments[1], this.tagName);
|
201
|
-
},
|
202
|
-
|
203
|
-
// protected
|
204
|
-
index: function(number, matchers, tag_name) {
|
205
|
-
number = RightJS.isString(number) ? number.toInt() : number;
|
206
|
-
var node = this, count = 0;
|
207
|
-
while ((node = node.previousSibling)) {
|
208
|
-
if (node.tagName && (!tag_name || node.tagName == tag_name) && ++count > number) { return false; }
|
209
|
-
}
|
210
|
-
return count == number;
|
211
289
|
}
|
212
|
-
|
290
|
+
return true;
|
291
|
+
},
|
213
292
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
var tag_re = /^[\w\*]+/;
|
218
|
-
var class_re = /\.([\w\-\._]+)/;
|
219
|
-
var pseudo_re = /:([\w\-]+)(\((.+?)\))*$/;
|
220
|
-
var attrs_re = /\[((?:[\w\-]*:)?[\w\-]+)\s*(?:([!\^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/;
|
221
|
-
|
222
|
-
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
223
|
-
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
224
|
-
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
225
|
-
|
226
|
-
/**
|
227
|
-
* Builds an atom matcher
|
228
|
-
*
|
229
|
-
* @param String atom definition
|
230
|
-
* @return Object atom matcher
|
231
|
-
*/
|
232
|
-
var atoms_cache = {};
|
233
|
-
function build_atom(in_atom) {
|
234
|
-
if (!atoms_cache[in_atom]) {
|
235
|
-
var id, tag, classes, attrs, pseudo, values_of_pseudo, match, func, desc = {}, atom = in_atom;
|
236
|
-
|
237
|
-
// grabbing the attributes
|
238
|
-
while((match = atom.match(attrs_re))) {
|
239
|
-
attrs = attrs || {};
|
240
|
-
attrs[match[1]] = { o: match[2], v: match[5] || match[6] };
|
241
|
-
atom = atom.replace(match[0], '');
|
242
|
-
}
|
293
|
+
'first-of-type': function(node) {
|
294
|
+
return pseudos['first-child'](node, node.nodeName);
|
295
|
+
},
|
243
296
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
atom = atom.replace(match[0], '');
|
297
|
+
'last-child': function(node, node_name) {
|
298
|
+
while ((node = node.nextSibling)) {
|
299
|
+
if (node.nodeType === 1 && (node_name === null || node.nodeName === node_name)) {
|
300
|
+
return false;
|
249
301
|
}
|
302
|
+
}
|
303
|
+
return true;
|
304
|
+
},
|
250
305
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
classes = (atom.match(class_re) || [1, ''])[1].split('.').without('');
|
255
|
-
|
256
|
-
desc.tag = tag;
|
257
|
-
|
258
|
-
//
|
259
|
-
// HACK HACK HACK
|
260
|
-
//
|
261
|
-
// building the matcher function
|
262
|
-
//
|
263
|
-
// NOTE: we kinda compile a cutom filter function in here
|
264
|
-
// the point is to create a maximally optimized method
|
265
|
-
// that will make only this atom checks and will filter
|
266
|
-
// a list of elements in a single call
|
267
|
-
//
|
268
|
-
if (id || classes.length || attrs || pseudo) {
|
269
|
-
var filter = 'function(y){'+
|
270
|
-
'var e,r=[],z=0,x=y.length;'+
|
271
|
-
'for(;z<x;z++){'+
|
272
|
-
'e=y[z];_f_'+
|
273
|
-
'}return r}';
|
274
|
-
|
275
|
-
var patch_filter = function(code) {
|
276
|
-
filter = filter.replace('_f_', code + '_f_');
|
277
|
-
};
|
278
|
-
|
279
|
-
// adding the ID check conditions
|
280
|
-
if (id) { patch_filter('if(e.id!=i)continue;'); }
|
281
|
-
|
282
|
-
// adding the classes matching code
|
283
|
-
if (classes.length) { patch_filter(
|
284
|
-
'if(e.className){'+
|
285
|
-
'var n=e.className.split(" ");'+
|
286
|
-
'if(n.length==1&&c.indexOf(n[0])==-1)continue;'+
|
287
|
-
'else{'+
|
288
|
-
'for(var i=0,l=c.length,b=false;i<l;i++)'+
|
289
|
-
'if(n.indexOf(c[i])==-1){'+
|
290
|
-
'b=true;break;}'+
|
291
|
-
|
292
|
-
'if(b)continue;}'+
|
293
|
-
'}else continue;'
|
294
|
-
); }
|
295
|
-
|
296
|
-
// adding the attributes matching conditions
|
297
|
-
if (attrs) { patch_filter(
|
298
|
-
'var p,o,v,k,b=false;'+
|
299
|
-
'for (k in a){p=e.getAttribute(k)||"";o=a[k].o||"";v=a[k].v||"";'+
|
300
|
-
'if('+
|
301
|
-
'(o===""&&e.getAttributeNode(k)===null)||'+
|
302
|
-
'(o==="="&&p!=v)||'+
|
303
|
-
'(o==="*="&&!p.include(v))||'+
|
304
|
-
'(o==="^="&&!p.startsWith(v))||'+
|
305
|
-
'(o==="$="&&!p.endsWith(v))||'+
|
306
|
-
'(o==="~="&&!p.split(" ").include(v))||'+
|
307
|
-
'(o==="|="&&!p.split("-").include(v))'+
|
308
|
-
'){b=true;break;}'+
|
309
|
-
'}if(b){continue;}'
|
310
|
-
); }
|
311
|
-
|
312
|
-
// adding the pseudo matchers check
|
313
|
-
if (pseudo in pseudos) {
|
314
|
-
patch_filter('if(!S[P].call(e,V,S))continue;');
|
315
|
-
}
|
306
|
+
'last-of-type': function(node) {
|
307
|
+
return pseudos['last-child'](node, node.nodeName);
|
308
|
+
},
|
316
309
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
// and inside of the function, so that when this thing
|
322
|
-
// is optimized by the code compiler, it kept the necessary
|
323
|
-
// variable names intackt
|
324
|
-
//
|
325
|
-
desc.filter = eval(
|
326
|
-
"[function(i,t,c,a,P,V,S,s){return eval('['+s+']')[0]}]"
|
327
|
-
)[0](
|
328
|
-
id,tag,classes,attrs,pseudo,values_of_pseudo,pseudos,
|
329
|
-
filter.replace('_f_', 'r.push(e)')
|
330
|
-
);
|
331
|
-
}
|
310
|
+
'only-child': function(node, node_name) {
|
311
|
+
return pseudos['first-child'](node, node_name) &&
|
312
|
+
pseudos['last-child'](node, node_name);
|
313
|
+
},
|
332
314
|
|
333
|
-
|
334
|
-
|
315
|
+
'only-of-type': function(node) {
|
316
|
+
return pseudos['only-child'](node, node.nodeName);
|
317
|
+
},
|
335
318
|
|
336
|
-
|
337
|
-
|
319
|
+
'nth-child': function(node, number, node_name, reverse) {
|
320
|
+
var index = 1, a = number[0], b = number[1];
|
338
321
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
* @param Array of a single rule tokens
|
343
|
-
* @return Function selector
|
344
|
-
*/
|
345
|
-
var tokens_cache = {};
|
346
|
-
function build_selector(rule) {
|
347
|
-
var rule_key = rule.join('');
|
348
|
-
if (!tokens_cache[rule_key]) {
|
349
|
-
for (var i=0; i < rule.length; i++) {
|
350
|
-
rule[i][1] = build_atom(rule[i][1]);
|
322
|
+
while ((node = (reverse === true) ? node.nextSibling : node.previousSibling)) {
|
323
|
+
if (node.nodeType === 1 && (node_name === undefined || node.nodeName === node_name)) {
|
324
|
+
index++;
|
351
325
|
}
|
326
|
+
}
|
352
327
|
|
353
|
-
|
354
|
-
|
355
|
-
var uniq = function(elements) {
|
356
|
-
var uniq = [], uids = [], uid;
|
357
|
-
for (var i=0, length = elements.length; i < length; i++) {
|
358
|
-
uid = _uid(elements[i]);
|
359
|
-
if (!uids[uid]) {
|
360
|
-
uniq.push(elements[i]);
|
361
|
-
uids[uid] = true;
|
362
|
-
}
|
363
|
-
}
|
328
|
+
return (b === undefined ? (index === a) : ((index - b) % a === 0 && (index - b) / a >= 0));
|
329
|
+
},
|
364
330
|
|
365
|
-
|
366
|
-
|
331
|
+
'nth-of-type': function(node, number) {
|
332
|
+
return pseudos['nth-child'](node, number, node.nodeName);
|
333
|
+
},
|
367
334
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
return atom[1].filter ? atom[1].filter(result) : result;
|
372
|
-
};
|
335
|
+
'nth-last-child': function(node, number) {
|
336
|
+
return pseudos['nth-child'](node, number, undefined, true);
|
337
|
+
},
|
373
338
|
|
374
|
-
|
375
|
-
|
376
|
-
|
339
|
+
'nth-last-of-type': function(node, number) {
|
340
|
+
return pseudos['nth-child'](node, number, node.nodeName, true);
|
341
|
+
}
|
342
|
+
},
|
343
|
+
|
344
|
+
// the regexps collection
|
345
|
+
chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
|
346
|
+
id_re = /#([\w\-_]+)/,
|
347
|
+
tag_re = /^[\w\*]+/,
|
348
|
+
class_re = /\.([\w\-\._]+)/,
|
349
|
+
pseudo_re = /:([\w\-]+)(\((.+?)\))*$/,
|
350
|
+
attrs_re = /\[((?:[\w\-]*:)?[\w\-]+)\s*(?:([!\^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/,
|
351
|
+
|
352
|
+
///////////////////////////////////////////////////////////////////////////////
|
353
|
+
///////////////////////////////////////////////////////////////////////////////
|
354
|
+
///////////////////////////////////////////////////////////////////////////////
|
355
|
+
|
356
|
+
/**
|
357
|
+
* Builds an atom matcher
|
358
|
+
*
|
359
|
+
* @param String atom definition
|
360
|
+
* @return Object atom matcher
|
361
|
+
*/
|
362
|
+
atoms_cache = {},
|
363
|
+
build_atom = function(in_atom) {
|
364
|
+
if (!atoms_cache[in_atom]) {
|
365
|
+
var id, tag, classes, classes_length, attrs, pseudo,
|
366
|
+
values_of_pseudo, match, func, desc = {}, atom = in_atom;
|
367
|
+
|
368
|
+
// grabbing the attributes
|
369
|
+
while((match = atom.match(attrs_re))) {
|
370
|
+
attrs = attrs || {};
|
371
|
+
attrs[match[1]] = { o: match[2] || '', v: match[5] || match[6] || '' };
|
372
|
+
atom = atom.replace(match[0], '');
|
373
|
+
}
|
374
|
+
|
375
|
+
// extracting the pseudos
|
376
|
+
if ((match = atom.match(pseudo_re))) {
|
377
|
+
pseudo = match[1];
|
378
|
+
values_of_pseudo = match[3] === '' ? null : match[3];
|
377
379
|
|
378
|
-
|
379
|
-
|
380
|
-
|
380
|
+
if (pseudo.startsWith('nth')) {
|
381
|
+
// preparsing the nth-child pseoudo numbers
|
382
|
+
values_of_pseudo = values_of_pseudo.toLowerCase();
|
381
383
|
|
384
|
+
if (values_of_pseudo === 'n') {
|
385
|
+
// no need in the pseudo then
|
386
|
+
pseudo = null;
|
387
|
+
values_of_pseudo = null;
|
388
|
+
} else {
|
389
|
+
if (values_of_pseudo === 'odd') { values_of_pseudo = '2n+1'; }
|
390
|
+
if (values_of_pseudo === 'even') { values_of_pseudo = '2n'; }
|
391
|
+
|
392
|
+
var m = /^([+\-]?\d*)?n([+\-]?\d*)?$/.exec(values_of_pseudo);
|
393
|
+
if (m) {
|
394
|
+
values_of_pseudo = [
|
395
|
+
m[1] === '-' ? -1 : parseInt(m[1], 10) || 1,
|
396
|
+
parseInt(m[2], 10) || 0
|
397
|
+
];
|
382
398
|
} else {
|
383
|
-
|
399
|
+
values_of_pseudo = [parseInt(values_of_pseudo, 10), undefined];
|
400
|
+
}
|
401
|
+
}
|
402
|
+
}
|
403
|
+
|
404
|
+
atom = atom.replace(match[0], '');
|
405
|
+
}
|
406
|
+
|
407
|
+
// getting all the other options
|
408
|
+
id = (atom.match(id_re) || [1, null])[1];
|
409
|
+
tag = (atom.match(tag_re) || '*').toString().toUpperCase();
|
410
|
+
classes = (atom.match(class_re) || [1, ''])[1].split('.').without('');
|
411
|
+
classes_length = classes.length;
|
412
|
+
|
413
|
+
desc.tag = tag;
|
414
|
+
|
415
|
+
if (id || classes.length || attrs || pseudo) {
|
416
|
+
// optimizing a bit the values for quiker runtime checks
|
417
|
+
id = id || false;
|
418
|
+
attrs = attrs || false;
|
419
|
+
pseudo = pseudo in pseudos ? pseudos[pseudo] : false;
|
420
|
+
classes = classes_length ? classes : false;
|
421
|
+
|
422
|
+
desc.filter = function(elements) {
|
423
|
+
var node, result = [], i=0, j=0, l = elements.length, failed;
|
424
|
+
for (; i < l; i++) {
|
425
|
+
node = elements[i];
|
426
|
+
|
427
|
+
//////////////////////////////////////////////
|
428
|
+
// ID check
|
429
|
+
//
|
430
|
+
if (id !== false && node.id !== id) {
|
431
|
+
continue;
|
432
|
+
}
|
433
|
+
|
434
|
+
//////////////////////////////////////////////
|
435
|
+
// Class names check
|
436
|
+
if (classes !== false) {
|
437
|
+
var names = node.className.split(' '),
|
438
|
+
names_length = names.length,
|
439
|
+
x = 0; failed = false;
|
440
|
+
|
441
|
+
for (; x < classes_length; x++) {
|
442
|
+
for (var y=0, found = false; y < names_length; y++) {
|
443
|
+
if (classes[x] === names[y]) {
|
444
|
+
found = true;
|
445
|
+
break;
|
446
|
+
}
|
447
|
+
}
|
448
|
+
|
449
|
+
if (!found) {
|
450
|
+
failed = true;
|
451
|
+
break;
|
452
|
+
}
|
453
|
+
}
|
384
454
|
|
385
|
-
|
386
|
-
|
455
|
+
if (failed) { continue; }
|
456
|
+
}
|
387
457
|
|
388
|
-
|
389
|
-
|
458
|
+
///////////////////////////////////////////////
|
459
|
+
// Attributes check
|
460
|
+
if (attrs !== false) {
|
461
|
+
var key, attr, operand, value; failed = false;
|
462
|
+
for (key in attrs) {
|
463
|
+
attr = key === 'class' ? node.className : (node.getAttribute(key) || '');
|
464
|
+
operand = attrs[key].o;
|
465
|
+
value = attrs[key].v;
|
466
|
+
|
467
|
+
if (
|
468
|
+
(operand === '' && (key === 'class'|| key === 'lang' ?
|
469
|
+
(attr === '') : (node.getAttributeNode(key) === null))) ||
|
470
|
+
(operand === '=' && attr !== value) ||
|
471
|
+
(operand === '*=' && attr.indexOf(value) === -1) ||
|
472
|
+
(operand === '^=' && attr.indexOf(value) !== 0) ||
|
473
|
+
(operand === '$=' && attr.substring(attr.length - value.length) !== value) ||
|
474
|
+
(operand === '~=' && attr.split(' ').indexOf(value) === -1) ||
|
475
|
+
(operand === '|=' && attr.split('-').indexOf(value) === -1)
|
476
|
+
) { failed = true; break; }
|
477
|
+
}
|
390
478
|
|
391
|
-
|
479
|
+
if (failed) { continue; }
|
480
|
+
}
|
392
481
|
|
393
|
-
|
482
|
+
///////////////////////////////////////////////
|
483
|
+
// Pseudo selectors check
|
484
|
+
if (pseudo !== false) {
|
485
|
+
if (!pseudo(node, values_of_pseudo)) {
|
486
|
+
continue;
|
394
487
|
}
|
395
488
|
}
|
396
|
-
}
|
397
489
|
|
398
|
-
|
490
|
+
result[j++] = node;
|
491
|
+
}
|
492
|
+
return result;
|
399
493
|
};
|
400
494
|
}
|
401
|
-
|
495
|
+
|
496
|
+
atoms_cache[in_atom] = desc;
|
402
497
|
}
|
403
498
|
|
499
|
+
return atoms_cache[in_atom];
|
500
|
+
},
|
501
|
+
|
502
|
+
/**
|
503
|
+
* Builds a single selector out of a simple rule chunk
|
504
|
+
*
|
505
|
+
* @param Array of a single rule tokens
|
506
|
+
* @return Function selector
|
507
|
+
*/
|
508
|
+
tokens_cache = {},
|
509
|
+
build_selector = function(rule) {
|
510
|
+
var rule_key = rule.join('');
|
511
|
+
if (!tokens_cache[rule_key]) {
|
512
|
+
for (var i=0; i < rule.length; i++) {
|
513
|
+
rule[i][1] = build_atom(rule[i][1]);
|
514
|
+
}
|
515
|
+
|
516
|
+
// creates a list of uniq nodes
|
517
|
+
var _uid = RightJS.$uid;
|
518
|
+
var uniq = function(elements) {
|
519
|
+
var uniq = [], uids = [], uid;
|
520
|
+
for (var i=0, length = elements.length; i < length; i++) {
|
521
|
+
uid = _uid(elements[i]);
|
522
|
+
if (!uids[uid]) {
|
523
|
+
uniq.push(elements[i]);
|
524
|
+
uids[uid] = true;
|
525
|
+
}
|
526
|
+
}
|
527
|
+
|
528
|
+
return uniq;
|
529
|
+
};
|
404
530
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
*/
|
411
|
-
var selectors_cache = {}, chunks_cache = {};
|
412
|
-
function split_rule_to_selectors(css_rule) {
|
413
|
-
if (!selectors_cache[css_rule]) {
|
414
|
-
chunker.lastIndex = 0;
|
531
|
+
// performs the actual search of subnodes
|
532
|
+
var find_subnodes = function(element, atom) {
|
533
|
+
var result = search[atom[0]](element, atom[1].tag);
|
534
|
+
return atom[1].filter ? atom[1].filter(result) : result;
|
535
|
+
};
|
415
536
|
|
416
|
-
|
417
|
-
|
418
|
-
|
537
|
+
// building the actual selector function
|
538
|
+
tokens_cache[rule_key] = function(element) {
|
539
|
+
var founds, sub_founds;
|
540
|
+
|
541
|
+
for (var i=0, i_length = rule.length; i < i_length; i++) {
|
542
|
+
if (i === 0) {
|
543
|
+
founds = find_subnodes(element, rule[i]);
|
419
544
|
|
420
|
-
if (token == '+' || token == '>' || token == '~') {
|
421
|
-
rel = token;
|
422
545
|
} else {
|
423
|
-
|
424
|
-
|
425
|
-
|
546
|
+
if (i > 1) { founds = uniq(founds); }
|
547
|
+
|
548
|
+
for (var j=0; j < founds.length; j++) {
|
549
|
+
sub_founds = find_subnodes(founds[j], rule[i]);
|
426
550
|
|
427
|
-
|
428
|
-
|
429
|
-
|
551
|
+
sub_founds.unshift(1); // <- nuke the parent node out of the list
|
552
|
+
sub_founds.unshift(j); // <- position to insert the subresult
|
553
|
+
|
554
|
+
founds.splice.apply(founds, sub_founds);
|
555
|
+
|
556
|
+
j += sub_founds.length - 3;
|
557
|
+
}
|
430
558
|
}
|
431
559
|
}
|
432
|
-
rules.push(build_selector(rule));
|
433
560
|
|
434
|
-
|
435
|
-
}
|
436
|
-
return selectors_cache[css_rule];
|
561
|
+
return rule.length > 1 ? uniq(founds) : founds;
|
562
|
+
};
|
437
563
|
}
|
564
|
+
return tokens_cache[rule_key];
|
565
|
+
},
|
566
|
+
|
567
|
+
|
568
|
+
/**
|
569
|
+
* Builds the list of selectors for the css_rule
|
570
|
+
*
|
571
|
+
* @param String raw css-rule
|
572
|
+
* @return Array of selectors
|
573
|
+
*/
|
574
|
+
selectors_cache = {}, chunks_cache = {},
|
575
|
+
split_rule_to_selectors = function(css_rule) {
|
576
|
+
if (!selectors_cache[css_rule]) {
|
577
|
+
chunker.lastIndex = 0;
|
578
|
+
|
579
|
+
var rules = [], rule = [], rel = ' ', m, token;
|
580
|
+
while ((m = chunker.exec(css_rule))) {
|
581
|
+
token = m[1];
|
582
|
+
|
583
|
+
if (token === '+' || token === '>' || token === '~') {
|
584
|
+
rel = token;
|
585
|
+
} else {
|
586
|
+
rule.push([rel, token]);
|
587
|
+
rel = ' ';
|
588
|
+
}
|
438
589
|
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
*
|
444
|
-
* @param Element context
|
445
|
-
* @param String raw css-rule
|
446
|
-
* @return Array search result
|
447
|
-
*/
|
448
|
-
function select_all(element, css_rule) {
|
449
|
-
var selectors = split_rule_to_selectors(css_rule), result = [];
|
450
|
-
for (var i=0, length = selectors.length; i < length; i++) {
|
451
|
-
result = result.concat(selectors[i](element));
|
590
|
+
if (m[2]) {
|
591
|
+
rules.push(build_selector(rule));
|
592
|
+
rule = [];
|
593
|
+
}
|
452
594
|
}
|
595
|
+
rules.push(build_selector(rule));
|
453
596
|
|
454
|
-
|
597
|
+
selectors_cache[css_rule] = rules;
|
455
598
|
}
|
599
|
+
return selectors_cache[css_rule];
|
600
|
+
},
|
601
|
+
|
602
|
+
|
603
|
+
/**
|
604
|
+
* The top level method, it just goes throught the css-rule chunks
|
605
|
+
* collect and merge the results that's it
|
606
|
+
*
|
607
|
+
* @param Element context
|
608
|
+
* @param String raw css-rule
|
609
|
+
* @return Array search result
|
610
|
+
*/
|
611
|
+
select_all = function(element, css_rule) {
|
612
|
+
var selectors = split_rule_to_selectors(css_rule), result = [];
|
613
|
+
for (var i=0, length = selectors.length; i < length; i++) {
|
614
|
+
result = result.concat(selectors[i](element));
|
615
|
+
}
|
616
|
+
|
617
|
+
return result;
|
618
|
+
},
|
619
|
+
|
456
620
|
|
621
|
+
///////////////////////////////////////////////////////////////////////////////
|
622
|
+
///////////////////////////////////////////////////////////////////////////////
|
623
|
+
///////////////////////////////////////////////////////////////////////////////
|
457
624
|
|
458
|
-
|
459
|
-
|
460
|
-
|
625
|
+
// the previous dom-selection methods replacement
|
626
|
+
dom_extension = {
|
627
|
+
first: function(css_rule) {
|
628
|
+
return this.find(css_rule)[0];
|
629
|
+
},
|
461
630
|
|
462
|
-
|
463
|
-
|
464
|
-
first: function(css_rule) {
|
465
|
-
return this.find(css_rule)[0];
|
466
|
-
},
|
631
|
+
find: function(css_rule, raw) {
|
632
|
+
var result, rule = css_rule || '*', element = this._, tag = element.tagName;
|
467
633
|
|
468
|
-
|
469
|
-
|
634
|
+
if (has_native_css_selector) {
|
635
|
+
try { // trying to reuse native css-engine under IE8
|
636
|
+
result = $A(element.querySelectorAll(rule));
|
637
|
+
} catch(e) { // if it fails use our own engine
|
638
|
+
result = select_all(element, rule);
|
639
|
+
}
|
640
|
+
} else {
|
641
|
+
result = select_all(element, rule);
|
470
642
|
}
|
471
|
-
};
|
472
643
|
|
473
|
-
|
644
|
+
return raw === true ? result : result.map(RightJS.$);
|
645
|
+
}
|
646
|
+
};
|
474
647
|
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
})(RightJS);
|
648
|
+
// hooking up the rightjs wrappers with the new methods
|
649
|
+
RightJS.$ext(RightJS.Element.prototype, dom_extension);
|
650
|
+
RightJS.$ext(RightJS.Document.prototype, dom_extension);
|
479
651
|
}
|
652
|
+
})(RightJS);
|