nitro 0.23.0 → 0.24.0
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/CHANGELOG +350 -0
- data/INSTALL +2 -2
- data/ProjectInfo +61 -0
- data/README +5 -4
- data/Rakefile +5 -4
- data/bin/nitrogen +3 -1
- data/doc/AUTHORS +27 -3
- data/doc/RELEASES +193 -0
- data/doc/lhttpd.txt +4 -0
- data/lib/nitro.rb +1 -1
- data/lib/nitro/adapter/cgi.rb +6 -321
- data/lib/nitro/adapter/fastcgi.rb +2 -14
- data/lib/nitro/adapter/scgi.rb +237 -71
- data/lib/nitro/adapter/webrick.rb +25 -7
- data/lib/nitro/caching.rb +1 -0
- data/lib/nitro/cgi.rb +296 -0
- data/lib/nitro/{cookie.rb → cgi/cookie.rb} +0 -0
- data/lib/nitro/cgi/http.rb +62 -0
- data/lib/nitro/{request.rb → cgi/request.rb} +4 -1
- data/lib/nitro/{response.rb → cgi/response.rb} +0 -0
- data/lib/nitro/cgi/stream.rb +43 -0
- data/lib/nitro/cgi/utils.rb +38 -0
- data/lib/nitro/compiler.rb +23 -11
- data/lib/nitro/compiler/css.rb +8 -0
- data/lib/nitro/compiler/morphing.rb +66 -0
- data/lib/nitro/context.rb +21 -30
- data/lib/nitro/controller.rb +23 -100
- data/lib/nitro/dispatcher.rb +18 -8
- data/lib/nitro/element.rb +6 -2
- data/lib/nitro/flash.rb +2 -2
- data/lib/nitro/mixin/buffer.rb +2 -2
- data/lib/nitro/mixin/form.rb +204 -93
- data/lib/nitro/mixin/javascript.rb +170 -11
- data/lib/nitro/mixin/markup.rb +1 -0
- data/lib/nitro/mixin/pager.rb +7 -4
- data/lib/nitro/mixin/rss.rb +2 -0
- data/lib/nitro/mixin/table.rb +23 -6
- data/lib/nitro/mixin/xhtml.rb +2 -2
- data/lib/nitro/render.rb +19 -5
- data/lib/nitro/scaffold.rb +12 -6
- data/lib/nitro/server.rb +4 -6
- data/lib/nitro/server/runner.rb +2 -2
- data/lib/nitro/session.rb +8 -1
- data/lib/nitro/session/file.rb +40 -0
- data/lib/part/admin.rb +2 -0
- data/lib/part/admin/controller.rb +7 -3
- data/lib/part/admin/skin.rb +8 -1
- data/lib/part/admin/template/index.xhtml +39 -1
- data/proto/public/error.xhtml +5 -3
- data/proto/public/js/behaviour.js +254 -254
- data/proto/public/js/controls.js +427 -165
- data/proto/public/js/dragdrop.js +255 -276
- data/proto/public/js/effects.js +476 -277
- data/proto/public/js/prototype.js +561 -127
- data/proto/public/js/scaffold.js +74 -0
- data/proto/public/js/scriptaculous.js +44 -0
- data/proto/public/js/util.js +548 -0
- data/proto/public/scaffold/list.xhtml +4 -1
- data/proto/scgi.rb +333 -0
- data/script/scgi_ctl +221 -0
- data/script/scgi_service +120 -0
- data/test/nitro/adapter/raw_post1.bin +0 -0
- data/test/nitro/{tc_cookie.rb → cgi/tc_cookie.rb} +1 -1
- data/test/nitro/{tc_request.rb → cgi/tc_request.rb} +1 -1
- data/test/nitro/mixin/tc_xhtml.rb +1 -1
- data/test/nitro/{adapter/tc_cgi.rb → tc_cgi.rb} +12 -12
- data/test/nitro/tc_controller.rb +9 -5
- metadata +159 -169
- data/benchmark/bench.rb +0 -5
- data/benchmark/simple-webrick-n-200.txt +0 -44
- data/benchmark/static-webrick-n-200.txt +0 -43
- data/benchmark/tiny-lhttpd-n-200-c-5.txt +0 -43
- data/benchmark/tiny-webrick-n-200-c-5.txt +0 -44
- data/benchmark/tiny-webrick-n-200.txt +0 -44
- data/benchmark/tiny2-webrick-n-200.txt +0 -44
- data/examples/README +0 -7
@@ -0,0 +1,74 @@
|
|
1
|
+
|
2
|
+
Behaviour.register({
|
3
|
+
'.naction_remove_hash': function(el) {
|
4
|
+
el.onclick = function(){
|
5
|
+
//remove a hash list item
|
6
|
+
parentEl = el
|
7
|
+
while(parentEl.tagName != 'LI'){
|
8
|
+
parentEl = parentEl.parentNode
|
9
|
+
}
|
10
|
+
Element.remove(parentEl);
|
11
|
+
return false;
|
12
|
+
}
|
13
|
+
},
|
14
|
+
'.naction_add_hash': function(el) {
|
15
|
+
el.onclick = function() {
|
16
|
+
//add a hash list item
|
17
|
+
ulEl = $(el.id+'_list');
|
18
|
+
newkey = $(el.id+'_key').value;
|
19
|
+
if(newkey.length > 0){
|
20
|
+
new Ajax.Request('../hash_tag_item/'+el.id+'/'+newkey+'/'+$(el.id+'_value').value, {
|
21
|
+
asynchronous:true,
|
22
|
+
onComplete: function(t){
|
23
|
+
ulEl.innerHTML += t.responseText;
|
24
|
+
Behaviour.apply();
|
25
|
+
}
|
26
|
+
});
|
27
|
+
}
|
28
|
+
return false;
|
29
|
+
}
|
30
|
+
},
|
31
|
+
'.naction_remove_rel': function(el) {
|
32
|
+
el.onclick = function() {
|
33
|
+
//remove rel from list and add option to pulldown
|
34
|
+
parentEl = el
|
35
|
+
while(parentEl.tagName != 'LI'){
|
36
|
+
parentEl = parentEl.parentNode
|
37
|
+
}
|
38
|
+
rel_oid = parentEl.getElementsByTagName('input')[0].value;
|
39
|
+
rel_name = parentEl.getElementsByTagName('input')[0].name.substr(0, parentEl.getElementsByTagName('input')[0].name.length-2);
|
40
|
+
rel_display = parentEl.getElementsByTagName('span')[0].innerHTML;
|
41
|
+
newOpt = document.createElement('option');
|
42
|
+
newOpt.value = rel_oid;
|
43
|
+
newOpt.appendChild(document.createTextNode(rel_display));
|
44
|
+
$(rel_name+'_selector').appendChild(newOpt);
|
45
|
+
Element.remove(parentEl);
|
46
|
+
return false;
|
47
|
+
}
|
48
|
+
},
|
49
|
+
'.naction_add_rel': function(el) {
|
50
|
+
el.onclick = function() {
|
51
|
+
//add a relation list item and remove item from options
|
52
|
+
ulEl = $(el.id+'_list');
|
53
|
+
selectorEl = $(el.id+'_selector');
|
54
|
+
// TODO: moz allows a select box with 0 options in it? ... disabled must be set with js
|
55
|
+
selectedElement = selectorEl.options[selectorEl.selectedIndex]
|
56
|
+
sURL = '../relation_item/'+el.id+'/'+selectedElement.innerHTML+'/'+selectedElement.value
|
57
|
+
new Ajax.Request(sURL, {
|
58
|
+
asynchronous:true,
|
59
|
+
onComplete: function(t){
|
60
|
+
ulEl.innerHTML += t.responseText;
|
61
|
+
Behaviour.apply();
|
62
|
+
},
|
63
|
+
onFailure: function(t){
|
64
|
+
// TODO: put the rel back in the option list
|
65
|
+
// chrisfarms: UNTESTED... selectedEl might not be availible?
|
66
|
+
// prob wont work in ffox. since moz doesnt like innerHTML used like this with options
|
67
|
+
selectorEl.innerHTML += '<option value="'+selectedElement.value+'">'+selectedElement.innerHTML+'</option>'
|
68
|
+
}
|
69
|
+
});
|
70
|
+
Element.remove(selectedElement);
|
71
|
+
return false;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
});
|
@@ -0,0 +1,44 @@
|
|
1
|
+
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
2
|
+
//
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
// a copy of this software and associated documentation files (the
|
5
|
+
// "Software"), to deal in the Software without restriction, including
|
6
|
+
// without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
// distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
// permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
// the following conditions:
|
10
|
+
//
|
11
|
+
// The above copyright notice and this permission notice shall be
|
12
|
+
// included in all copies or substantial portions of the Software.
|
13
|
+
//
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
var Scriptaculous = {
|
23
|
+
Version: '1.5_rc3',
|
24
|
+
require: function(libraryName) {
|
25
|
+
// inserting via DOM fails in Safari 2.0, so brute force approach
|
26
|
+
document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
|
27
|
+
},
|
28
|
+
load: function() {
|
29
|
+
var scriptTags = document.getElementsByTagName("script");
|
30
|
+
for(var i=0;i<scriptTags.length;i++) {
|
31
|
+
if(scriptTags[i].src && scriptTags[i].src.match(/scriptaculous\.js(\?.*)?$/)) {
|
32
|
+
var path = scriptTags[i].src.replace(/scriptaculous\.js(\?.*)?$/,'');
|
33
|
+
this.require(path + 'util.js');
|
34
|
+
this.require(path + 'effects.js');
|
35
|
+
this.require(path + 'dragdrop.js');
|
36
|
+
this.require(path + 'controls.js');
|
37
|
+
this.require(path + 'slider.js');
|
38
|
+
break;
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
Scriptaculous.load();
|
@@ -0,0 +1,548 @@
|
|
1
|
+
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
2
|
+
//
|
3
|
+
// See scriptaculous.js for full license.
|
4
|
+
|
5
|
+
|
6
|
+
Object.debug = function(obj) {
|
7
|
+
var info = [];
|
8
|
+
|
9
|
+
if(typeof obj in ["string","number"]) {
|
10
|
+
return obj;
|
11
|
+
} else {
|
12
|
+
for(property in obj)
|
13
|
+
if(typeof obj[property]!="function")
|
14
|
+
info.push(property + ' => ' +
|
15
|
+
(typeof obj[property] == "string" ?
|
16
|
+
'"' + obj[property] + '"' :
|
17
|
+
obj[property]));
|
18
|
+
}
|
19
|
+
|
20
|
+
return ("'" + obj + "' #" + typeof obj +
|
21
|
+
": {" + info.join(", ") + "}");
|
22
|
+
}
|
23
|
+
|
24
|
+
|
25
|
+
String.prototype.toArray = function() {
|
26
|
+
var results = [];
|
27
|
+
for (var i = 0; i < this.length; i++)
|
28
|
+
results.push(this.charAt(i));
|
29
|
+
return results;
|
30
|
+
}
|
31
|
+
|
32
|
+
/*--------------------------------------------------------------------------*/
|
33
|
+
|
34
|
+
var Builder = {
|
35
|
+
NODEMAP: {
|
36
|
+
AREA: 'map',
|
37
|
+
CAPTION: 'table',
|
38
|
+
COL: 'table',
|
39
|
+
COLGROUP: 'table',
|
40
|
+
LEGEND: 'fieldset',
|
41
|
+
OPTGROUP: 'select',
|
42
|
+
OPTION: 'select',
|
43
|
+
PARAM: 'object',
|
44
|
+
TBODY: 'table',
|
45
|
+
TD: 'table',
|
46
|
+
TFOOT: 'table',
|
47
|
+
TH: 'table',
|
48
|
+
THEAD: 'table',
|
49
|
+
TR: 'table'
|
50
|
+
},
|
51
|
+
// note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
|
52
|
+
// due to a Firefox bug
|
53
|
+
node: function(elementName) {
|
54
|
+
elementName = elementName.toUpperCase();
|
55
|
+
|
56
|
+
// try innerHTML approach
|
57
|
+
var parentTag = this.NODEMAP[elementName] || 'div';
|
58
|
+
var parentElement = document.createElement(parentTag);
|
59
|
+
parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
|
60
|
+
var element = parentElement.firstChild || null;
|
61
|
+
|
62
|
+
// see if browser added wrapping tags
|
63
|
+
if(element && (element.tagName != elementName))
|
64
|
+
element = element.getElementsByTagName(elementName)[0];
|
65
|
+
|
66
|
+
// fallback to createElement approach
|
67
|
+
if(!element) element = document.createElement(elementName);
|
68
|
+
|
69
|
+
// abort if nothing could be created
|
70
|
+
if(!element) return;
|
71
|
+
|
72
|
+
// attributes (or text)
|
73
|
+
if(arguments[1])
|
74
|
+
if(this._isStringOrNumber(arguments[1]) ||
|
75
|
+
(arguments[1] instanceof Array)) {
|
76
|
+
this._children(element, arguments[1]);
|
77
|
+
} else {
|
78
|
+
var attrs = this._attributes(arguments[1]);
|
79
|
+
if(attrs.length) {
|
80
|
+
parentElement.innerHTML = "<" +elementName + " " +
|
81
|
+
attrs + "></" + elementName + ">";
|
82
|
+
element = parentElement.firstChild || null;
|
83
|
+
// workaround firefox 1.0.X bug
|
84
|
+
if(!element) {
|
85
|
+
element = document.createElement(elementName);
|
86
|
+
for(attr in arguments[1])
|
87
|
+
element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
|
88
|
+
}
|
89
|
+
if(element.tagName != elementName)
|
90
|
+
element = parentElement.getElementsByTagName(elementName)[0];
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
// text, or array of children
|
95
|
+
if(arguments[2])
|
96
|
+
this._children(element, arguments[2]);
|
97
|
+
|
98
|
+
return element;
|
99
|
+
},
|
100
|
+
_text: function(text) {
|
101
|
+
return document.createTextNode(text);
|
102
|
+
},
|
103
|
+
_attributes: function(attributes) {
|
104
|
+
var attrs = [];
|
105
|
+
for(attribute in attributes)
|
106
|
+
attrs.push((attribute=='className' ? 'class' : attribute) +
|
107
|
+
'="' + attributes[attribute].toString().escapeHTML() + '"');
|
108
|
+
return attrs.join(" ");
|
109
|
+
},
|
110
|
+
_children: function(element, children) {
|
111
|
+
if(typeof children=='object') { // array can hold nodes and text
|
112
|
+
children.flatten().each( function(e) {
|
113
|
+
if(typeof e=='object')
|
114
|
+
element.appendChild(e)
|
115
|
+
else
|
116
|
+
if(Builder._isStringOrNumber(e))
|
117
|
+
element.appendChild(Builder._text(e));
|
118
|
+
});
|
119
|
+
} else
|
120
|
+
if(Builder._isStringOrNumber(children))
|
121
|
+
element.appendChild(Builder._text(children));
|
122
|
+
},
|
123
|
+
_isStringOrNumber: function(param) {
|
124
|
+
return(typeof param=='string' || typeof param=='number');
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
/* ------------- element ext -------------- */
|
129
|
+
|
130
|
+
// adapted from http://dhtmlkitchen.com/learn/js/setstyle/index4.jsp
|
131
|
+
// note: Safari return null on elements with display:none; see http://bugzilla.opendarwin.org/show_bug.cgi?id=4125
|
132
|
+
// instead of "auto" values returns null so it's easier to use with || constructs
|
133
|
+
|
134
|
+
String.prototype.camelize = function() {
|
135
|
+
var oStringList = this.split('-');
|
136
|
+
if(oStringList.length == 1)
|
137
|
+
return oStringList[0];
|
138
|
+
var ret = this.indexOf("-") == 0 ?
|
139
|
+
oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) : oStringList[0];
|
140
|
+
for(var i = 1, len = oStringList.length; i < len; i++){
|
141
|
+
var s = oStringList[i];
|
142
|
+
ret += s.charAt(0).toUpperCase() + s.substring(1)
|
143
|
+
}
|
144
|
+
return ret;
|
145
|
+
}
|
146
|
+
|
147
|
+
Element.getStyle = function(element, style) {
|
148
|
+
element = $(element);
|
149
|
+
var value = element.style[style.camelize()];
|
150
|
+
if(!value)
|
151
|
+
if(document.defaultView && document.defaultView.getComputedStyle) {
|
152
|
+
var css = document.defaultView.getComputedStyle(element, null);
|
153
|
+
value = (css!=null) ? css.getPropertyValue(style) : null;
|
154
|
+
} else if(element.currentStyle) {
|
155
|
+
value = element.currentStyle[style.camelize()];
|
156
|
+
}
|
157
|
+
|
158
|
+
// If top, left, bottom, or right values have been queried, return "auto" for consistency resaons
|
159
|
+
// if position is "static", as Opera (and others?) returns the pixel values relative to root element
|
160
|
+
// (or positioning context?)
|
161
|
+
if (window.opera && (style == "left" || style == "top" || style == "right" || style == "bottom"))
|
162
|
+
if (Element.getStyle(element, "position") == "static") value = "auto";
|
163
|
+
|
164
|
+
if(value=='auto') value = null;
|
165
|
+
return value;
|
166
|
+
}
|
167
|
+
|
168
|
+
// converts rgb() and #xxx to #xxxxxx format,
|
169
|
+
// returns self (or first argument) if not convertable
|
170
|
+
String.prototype.parseColor = function() {
|
171
|
+
color = "#";
|
172
|
+
if(this.slice(0,4) == "rgb(") {
|
173
|
+
var cols = this.slice(4,this.length-1).split(',');
|
174
|
+
var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
|
175
|
+
} else {
|
176
|
+
if(this.slice(0,1) == '#') {
|
177
|
+
if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
|
178
|
+
if(this.length==7) color = this.toLowerCase();
|
179
|
+
}
|
180
|
+
}
|
181
|
+
return(color.length==7 ? color : (arguments[0] || this));
|
182
|
+
}
|
183
|
+
|
184
|
+
Element.makePositioned = function(element) {
|
185
|
+
element = $(element);
|
186
|
+
var pos = Element.getStyle(element, 'position');
|
187
|
+
if(pos =='static' || !pos) {
|
188
|
+
element._madePositioned = true;
|
189
|
+
element.style.position = "relative";
|
190
|
+
// Opera returns the offset relative to the positioning context, when an element is position relative
|
191
|
+
// but top and left have not been defined
|
192
|
+
if (window.opera){
|
193
|
+
element.style.top = 0;
|
194
|
+
element.style.left = 0;
|
195
|
+
}
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
Element.undoPositioned = function(element) {
|
200
|
+
element = $(element);
|
201
|
+
if(typeof element._madePositioned != "undefined"){
|
202
|
+
element._madePositioned = undefined;
|
203
|
+
element.style.position = "";
|
204
|
+
element.style.top = "";
|
205
|
+
element.style.left = "";
|
206
|
+
element.style.bottom = "";
|
207
|
+
element.style.right = "";
|
208
|
+
}
|
209
|
+
}
|
210
|
+
|
211
|
+
Element.makeClipping = function(element) {
|
212
|
+
element = $(element);
|
213
|
+
if (typeof element._overflow != 'undefined') return;
|
214
|
+
element._overflow = element.style.overflow;
|
215
|
+
if((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') element.style.overflow = 'hidden';
|
216
|
+
}
|
217
|
+
|
218
|
+
Element.undoClipping = function(element) {
|
219
|
+
element = $(element);
|
220
|
+
if (typeof element._overflow == 'undefined') return;
|
221
|
+
element.style.overflow = element._overflow;
|
222
|
+
element._overflow = undefined;
|
223
|
+
}
|
224
|
+
|
225
|
+
Element.collectTextNodesIgnoreClass = function(element, ignoreclass) {
|
226
|
+
var children = $(element).childNodes;
|
227
|
+
var text = "";
|
228
|
+
var classtest = new RegExp("^([^ ]+ )*" + ignoreclass+ "( [^ ]+)*$","i");
|
229
|
+
|
230
|
+
for (var i = 0; i < children.length; i++) {
|
231
|
+
if(children[i].nodeType==3) {
|
232
|
+
text+=children[i].nodeValue;
|
233
|
+
} else {
|
234
|
+
if((!children[i].className.match(classtest)) && children[i].hasChildNodes())
|
235
|
+
text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass);
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
return text;
|
240
|
+
}
|
241
|
+
|
242
|
+
Element.setContentZoom = function(element, percent) {
|
243
|
+
element = $(element);
|
244
|
+
element.style.fontSize = (percent/100) + "em";
|
245
|
+
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
|
246
|
+
}
|
247
|
+
|
248
|
+
Element.getOpacity = function(element){
|
249
|
+
var opacity;
|
250
|
+
if (opacity = Element.getStyle(element, "opacity"))
|
251
|
+
return parseFloat(opacity);
|
252
|
+
if (opacity = (Element.getStyle(element, "filter") || '').match(/alpha\(opacity=(.*)\)/))
|
253
|
+
if(opacity[1]) return parseFloat(opacity[1]) / 100;
|
254
|
+
return 1.0;
|
255
|
+
}
|
256
|
+
|
257
|
+
Element.setOpacity = function(element, value){
|
258
|
+
element= $(element);
|
259
|
+
var els = element.style;
|
260
|
+
if (value == 1){
|
261
|
+
els.opacity = '0.999999';
|
262
|
+
if(/MSIE/.test(navigator.userAgent))
|
263
|
+
els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'');
|
264
|
+
} else {
|
265
|
+
if(value < 0.00001) value = 0;
|
266
|
+
els.opacity = value;
|
267
|
+
if(/MSIE/.test(navigator.userAgent))
|
268
|
+
els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
|
269
|
+
"alpha(opacity="+value*100+")";
|
270
|
+
}
|
271
|
+
}
|
272
|
+
|
273
|
+
Element.getInlineOpacity = function(element){
|
274
|
+
element= $(element);
|
275
|
+
var op;
|
276
|
+
op = element.style.opacity;
|
277
|
+
if (typeof op != "undefined" && op != "") return op;
|
278
|
+
return "";
|
279
|
+
}
|
280
|
+
|
281
|
+
Element.setInlineOpacity = function(element, value){
|
282
|
+
element= $(element);
|
283
|
+
var els = element.style;
|
284
|
+
els.opacity = value;
|
285
|
+
}
|
286
|
+
|
287
|
+
Element.getDimensions = function(element){
|
288
|
+
element = $(element);
|
289
|
+
// All *Width and *Height properties give 0 on elements with display "none",
|
290
|
+
// so enable the element temporarily
|
291
|
+
if (Element.getStyle(element,'display') == "none"){
|
292
|
+
var els = element.style;
|
293
|
+
var originalVisibility = els.visibility;
|
294
|
+
var originalPosition = els.position;
|
295
|
+
els.visibility = "hidden";
|
296
|
+
els.position = "absolute";
|
297
|
+
els.display = "";
|
298
|
+
var originalWidth = element.clientWidth;
|
299
|
+
var originalHeight = element.clientHeight;
|
300
|
+
els.display = "none";
|
301
|
+
els.position = originalPosition;
|
302
|
+
els.visibility = originalVisibility;
|
303
|
+
return {width: originalWidth, height: originalHeight};
|
304
|
+
}
|
305
|
+
|
306
|
+
return {width: element.offsetWidth, height: element.offsetHeight};
|
307
|
+
}
|
308
|
+
|
309
|
+
/*--------------------------------------------------------------------------*/
|
310
|
+
|
311
|
+
Position.positionedOffset = function(element) {
|
312
|
+
var valueT = 0, valueL = 0;
|
313
|
+
do {
|
314
|
+
valueT += element.offsetTop || 0;
|
315
|
+
valueL += element.offsetLeft || 0;
|
316
|
+
element = element.offsetParent;
|
317
|
+
if (element) {
|
318
|
+
p = Element.getStyle(element,'position');
|
319
|
+
if(p == 'relative' || p == 'absolute') break;
|
320
|
+
}
|
321
|
+
} while (element);
|
322
|
+
return [valueL, valueT];
|
323
|
+
}
|
324
|
+
|
325
|
+
// Safari returns margins on body which is incorrect if the child is absolutely positioned.
|
326
|
+
// for performance reasons, we create a specialized version of Position.cumulativeOffset for
|
327
|
+
// KHTML/WebKit only
|
328
|
+
|
329
|
+
if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
|
330
|
+
Position.cumulativeOffset = function(element) {
|
331
|
+
var valueT = 0, valueL = 0;
|
332
|
+
do {
|
333
|
+
valueT += element.offsetTop || 0;
|
334
|
+
valueL += element.offsetLeft || 0;
|
335
|
+
|
336
|
+
if (element.offsetParent==document.body)
|
337
|
+
if (Element.getStyle(element,'position')=='absolute') break;
|
338
|
+
|
339
|
+
element = element.offsetParent;
|
340
|
+
} while (element);
|
341
|
+
return [valueL, valueT];
|
342
|
+
}
|
343
|
+
}
|
344
|
+
|
345
|
+
Position.page = function(forElement) {
|
346
|
+
var valueT = 0, valueL = 0;
|
347
|
+
|
348
|
+
var element = forElement;
|
349
|
+
do {
|
350
|
+
valueT += element.offsetTop || 0;
|
351
|
+
valueL += element.offsetLeft || 0;
|
352
|
+
|
353
|
+
// Safari fix
|
354
|
+
if (element.offsetParent==document.body)
|
355
|
+
if (Element.getStyle(element,'position')=='absolute') break;
|
356
|
+
|
357
|
+
} while (element = element.offsetParent);
|
358
|
+
|
359
|
+
element = forElement;
|
360
|
+
do {
|
361
|
+
valueT -= element.scrollTop || 0;
|
362
|
+
valueL -= element.scrollLeft || 0;
|
363
|
+
} while (element = element.parentNode);
|
364
|
+
|
365
|
+
return [valueL, valueT];
|
366
|
+
}
|
367
|
+
|
368
|
+
// elements with display:none don't return an offsetParent,
|
369
|
+
// fall back to manual calculation
|
370
|
+
Position.offsetParent = function(element) {
|
371
|
+
if(element.offsetParent) return element.offsetParent;
|
372
|
+
if(element == document.body) return element;
|
373
|
+
|
374
|
+
while ((element = element.parentNode) && element != document.body)
|
375
|
+
if (Element.getStyle(element,'position')!='static')
|
376
|
+
return element;
|
377
|
+
|
378
|
+
return document.body;
|
379
|
+
}
|
380
|
+
|
381
|
+
Position.clone = function(source, target) {
|
382
|
+
var options = Object.extend({
|
383
|
+
setLeft: true,
|
384
|
+
setTop: true,
|
385
|
+
setWidth: true,
|
386
|
+
setHeight: true,
|
387
|
+
offsetTop: 0,
|
388
|
+
offsetLeft: 0
|
389
|
+
}, arguments[2] || {})
|
390
|
+
|
391
|
+
// find page position of source
|
392
|
+
source = $(source);
|
393
|
+
var p = Position.page(source);
|
394
|
+
|
395
|
+
// find coordinate system to use
|
396
|
+
target = $(target);
|
397
|
+
var delta = [0, 0];
|
398
|
+
var parent = null;
|
399
|
+
// delta [0,0] will do fine with position: fixed elements,
|
400
|
+
// position:absolute needs offsetParent deltas
|
401
|
+
if (Element.getStyle(target,'position') == 'absolute') {
|
402
|
+
parent = Position.offsetParent(target);
|
403
|
+
delta = Position.page(parent);
|
404
|
+
}
|
405
|
+
|
406
|
+
// correct by body offsets (fixes Safari)
|
407
|
+
if (parent==document.body) {
|
408
|
+
delta[0] -= document.body.offsetLeft;
|
409
|
+
delta[1] -= document.body.offsetTop;
|
410
|
+
}
|
411
|
+
|
412
|
+
// set position
|
413
|
+
if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + "px";
|
414
|
+
if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + "px";
|
415
|
+
if(options.setWidth) target.style.width = source.offsetWidth + "px";
|
416
|
+
if(options.setHeight) target.style.height = source.offsetHeight + "px";
|
417
|
+
}
|
418
|
+
|
419
|
+
Position.absolutize = function(element) {
|
420
|
+
element = $(element);
|
421
|
+
if(element.style.position=='absolute') return;
|
422
|
+
Position.prepare();
|
423
|
+
|
424
|
+
var offsets = Position.positionedOffset(element);
|
425
|
+
var top = offsets[1];
|
426
|
+
var left = offsets[0];
|
427
|
+
var width = element.clientWidth;
|
428
|
+
var height = element.clientHeight;
|
429
|
+
|
430
|
+
element._originalLeft = left - parseFloat(element.style.left || 0);
|
431
|
+
element._originalTop = top - parseFloat(element.style.top || 0);
|
432
|
+
element._originalWidth = element.style.width;
|
433
|
+
element._originalHeight = element.style.height;
|
434
|
+
|
435
|
+
element.style.position = 'absolute';
|
436
|
+
element.style.top = top + 'px';;
|
437
|
+
element.style.left = left + 'px';;
|
438
|
+
element.style.width = width + 'px';;
|
439
|
+
element.style.height = height + 'px';;
|
440
|
+
}
|
441
|
+
|
442
|
+
Position.relativize = function(element) {
|
443
|
+
element = $(element);
|
444
|
+
if(element.style.position=='relative') return;
|
445
|
+
Position.prepare();
|
446
|
+
|
447
|
+
element.style.position = 'relative';
|
448
|
+
var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
|
449
|
+
var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
|
450
|
+
|
451
|
+
element.style.top = top + 'px';
|
452
|
+
element.style.left = left + 'px';
|
453
|
+
element.style.height = element._originalHeight;
|
454
|
+
element.style.width = element._originalWidth;
|
455
|
+
}
|
456
|
+
|
457
|
+
/*--------------------------------------------------------------------------*/
|
458
|
+
|
459
|
+
Element.Class = {
|
460
|
+
// Element.toggleClass(element, className) toggles the class being on/off
|
461
|
+
// Element.toggleClass(element, className1, className2) toggles between both classes,
|
462
|
+
// defaulting to className1 if neither exist
|
463
|
+
toggle: function(element, className) {
|
464
|
+
if(Element.Class.has(element, className)) {
|
465
|
+
Element.Class.remove(element, className);
|
466
|
+
if(arguments.length == 3) Element.Class.add(element, arguments[2]);
|
467
|
+
} else {
|
468
|
+
Element.Class.add(element, className);
|
469
|
+
if(arguments.length == 3) Element.Class.remove(element, arguments[2]);
|
470
|
+
}
|
471
|
+
},
|
472
|
+
|
473
|
+
// gets space-delimited classnames of an element as an array
|
474
|
+
get: function(element) {
|
475
|
+
return $(element).className.split(' ');
|
476
|
+
},
|
477
|
+
|
478
|
+
// functions adapted from original functions by Gavin Kistner
|
479
|
+
remove: function(element) {
|
480
|
+
element = $(element);
|
481
|
+
var removeClasses = arguments;
|
482
|
+
$R(1,arguments.length-1).each( function(index) {
|
483
|
+
element.className =
|
484
|
+
element.className.split(' ').reject(
|
485
|
+
function(klass) { return (klass == removeClasses[index]) } ).join(' ');
|
486
|
+
});
|
487
|
+
},
|
488
|
+
|
489
|
+
add: function(element) {
|
490
|
+
element = $(element);
|
491
|
+
for(var i = 1; i < arguments.length; i++) {
|
492
|
+
Element.Class.remove(element, arguments[i]);
|
493
|
+
element.className += (element.className.length > 0 ? ' ' : '') + arguments[i];
|
494
|
+
}
|
495
|
+
},
|
496
|
+
|
497
|
+
// returns true if all given classes exist in said element
|
498
|
+
has: function(element) {
|
499
|
+
element = $(element);
|
500
|
+
if(!element || !element.className) return false;
|
501
|
+
var regEx;
|
502
|
+
for(var i = 1; i < arguments.length; i++) {
|
503
|
+
if((typeof arguments[i] == 'object') &&
|
504
|
+
(arguments[i].constructor == Array)) {
|
505
|
+
for(var j = 0; j < arguments[i].length; j++) {
|
506
|
+
regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
|
507
|
+
if(!regEx.test(element.className)) return false;
|
508
|
+
}
|
509
|
+
} else {
|
510
|
+
regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
|
511
|
+
if(!regEx.test(element.className)) return false;
|
512
|
+
}
|
513
|
+
}
|
514
|
+
return true;
|
515
|
+
},
|
516
|
+
|
517
|
+
// expects arrays of strings and/or strings as optional paramters
|
518
|
+
// Element.Class.has_any(element, ['classA','classB','classC'], 'classD')
|
519
|
+
has_any: function(element) {
|
520
|
+
element = $(element);
|
521
|
+
if(!element || !element.className) return false;
|
522
|
+
var regEx;
|
523
|
+
for(var i = 1; i < arguments.length; i++) {
|
524
|
+
if((typeof arguments[i] == 'object') &&
|
525
|
+
(arguments[i].constructor == Array)) {
|
526
|
+
for(var j = 0; j < arguments[i].length; j++) {
|
527
|
+
regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
|
528
|
+
if(regEx.test(element.className)) return true;
|
529
|
+
}
|
530
|
+
} else {
|
531
|
+
regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
|
532
|
+
if(regEx.test(element.className)) return true;
|
533
|
+
}
|
534
|
+
}
|
535
|
+
return false;
|
536
|
+
},
|
537
|
+
|
538
|
+
childrenWith: function(element, className) {
|
539
|
+
var children = $(element).getElementsByTagName('*');
|
540
|
+
var elements = new Array();
|
541
|
+
|
542
|
+
for (var i = 0; i < children.length; i++)
|
543
|
+
if (Element.Class.has(children[i], className))
|
544
|
+
elements.push(children[i]);
|
545
|
+
|
546
|
+
return elements;
|
547
|
+
}
|
548
|
+
}
|