nitro 0.24.0 → 0.25.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 +279 -0
- data/ProjectInfo +7 -7
- data/doc/AUTHORS +4 -2
- data/doc/RELEASES +96 -1
- data/lib/nitro.rb +5 -2
- data/lib/nitro/adapter/cgi.rb +1 -1
- data/lib/nitro/adapter/webrick.rb +7 -5
- data/lib/nitro/caching/output.rb +3 -2
- data/lib/nitro/cgi/utils.rb +8 -4
- data/lib/nitro/compiler.rb +9 -5
- data/lib/nitro/compiler/include.rb +42 -0
- data/lib/nitro/compiler/markup.rb +1 -1
- data/lib/nitro/compiler/morphing.rb +120 -50
- data/lib/nitro/compiler/squeeze.rb +2 -2
- data/lib/nitro/context.rb +9 -0
- data/lib/nitro/controller.rb +8 -4
- data/lib/nitro/dispatcher.rb +5 -5
- data/lib/nitro/dispatcher/nice.rb +16 -5
- data/lib/nitro/element.rb +30 -8
- data/lib/nitro/helper.rb +56 -0
- data/lib/nitro/{mixin → helper}/benchmark.rb +1 -1
- data/lib/nitro/{mixin → helper}/buffer.rb +1 -2
- data/lib/nitro/{mixin → helper}/debug.rb +1 -1
- data/lib/nitro/{mixin/helper.rb → helper/default.rb} +4 -4
- data/lib/nitro/{mixin → helper}/form.rb +3 -3
- data/lib/nitro/{mixin → helper}/javascript.rb +17 -1
- data/lib/nitro/{mixin → helper}/pager.rb +1 -1
- data/lib/nitro/{mixin → helper}/rss.rb +3 -3
- data/lib/nitro/{mixin → helper}/table.rb +1 -1
- data/lib/nitro/{mixin → helper}/xhtml.rb +2 -2
- data/lib/nitro/{mixin → helper}/xml.rb +1 -1
- data/lib/nitro/render.rb +16 -8
- data/lib/nitro/scaffold.rb +6 -6
- data/lib/nitro/server/runner.rb +12 -0
- data/lib/nitro/session/drbserver.rb +16 -1
- data/proto/public/js/builder.js +97 -0
- data/proto/public/js/controls.js +18 -5
- data/proto/public/js/dragdrop.js +8 -5
- data/proto/public/js/effects.js +185 -4
- data/proto/public/js/prototype.js +432 -178
- data/proto/public/js/scriptaculous.js +6 -2
- data/proto/public/js/slider.js +226 -0
- data/proto/public/js/unittest.js +363 -0
- data/proto/public/media/nitro.png +0 -0
- data/{script → proto/script}/scgi_ctl +0 -0
- data/{script → proto/script}/scgi_service +16 -8
- data/proto/src/skin.rb +24 -0
- data/{lib → src}/part/admin.rb +0 -0
- data/src/part/admin/controller.rb +47 -0
- data/{lib → src}/part/admin/skin.rb +0 -0
- data/src/part/admin/template/denied.xhtml +1 -0
- data/{lib → src}/part/admin/template/index.xhtml +0 -0
- data/test/nitro/{mixin → helper}/tc_pager.rb +2 -2
- data/test/nitro/{mixin → helper}/tc_rss.rb +3 -3
- data/test/nitro/{mixin → helper}/tc_table.rb +3 -3
- data/test/nitro/{mixin → helper}/tc_xhtml.rb +3 -3
- data/test/nitro/tc_caching.rb +4 -1
- data/test/nitro/tc_controller.rb +2 -2
- data/test/nitro/tc_element.rb +30 -0
- data/test/nitro/tc_helper.rb +36 -0
- data/test/nitro/tc_render.rb +1 -1
- metadata +70 -38
- data/lib/nitro/mixin/markup.rb +0 -122
- data/lib/part/admin/controller.rb +0 -28
- data/proto/README +0 -11
- data/proto/doc/README +0 -1
- data/proto/scgi.rb +0 -333
data/lib/nitro/scaffold.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'mega/orm_support'
|
|
2
2
|
|
|
3
3
|
require 'nitro/compiler'
|
|
4
|
-
require 'nitro/
|
|
4
|
+
require 'nitro/helper/form'
|
|
5
5
|
|
|
6
6
|
module Nitro
|
|
7
7
|
|
|
@@ -15,8 +15,8 @@ module Scaffolding
|
|
|
15
15
|
|
|
16
16
|
def self.append_features(base) # :nodoc:
|
|
17
17
|
super
|
|
18
|
-
base.
|
|
19
|
-
base.extend
|
|
18
|
+
base.helper :form
|
|
19
|
+
base.extend ClassMethods
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def self.class_to_name(klass)
|
|
@@ -59,13 +59,13 @@ module Scaffolding
|
|
|
59
59
|
|
|
60
60
|
# Add methods to the scaffolded class.
|
|
61
61
|
|
|
62
|
-
unless klass.
|
|
62
|
+
unless klass.instance_methods.include? 'to_href'
|
|
63
63
|
klass.send(:define_method, :to_href) do
|
|
64
64
|
"#{name}/#{@oid}"
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
unless klass.
|
|
68
|
+
unless klass.instance_methods.include? 'to_edit_link'
|
|
69
69
|
klass.send(:define_method, :to_edit_link) do |base|
|
|
70
70
|
%{<a href="#{base}/#{name}/#{@oid}">#{self}</a> (<a href="#{base}/edit#{suffix}/#{@oid}">edit</a>, <a href="#{base}/delete#{suffix}/#{@oid}">del</a>)}
|
|
71
71
|
end
|
|
@@ -137,7 +137,7 @@ module Scaffolding
|
|
|
137
137
|
oid = oid.to_s # in case oid is a StringIO (multipart).
|
|
138
138
|
obj = request.fill(#{klass}[oid], :assign_relations => true, :force_boolean => true)
|
|
139
139
|
else
|
|
140
|
-
obj = request.fill(#{klass}.
|
|
140
|
+
obj = request.fill(#{klass}.create, :assign_relations => true)
|
|
141
141
|
end
|
|
142
142
|
unless obj.valid?
|
|
143
143
|
session[:ERRORS] = obj.errors
|
data/lib/nitro/server/runner.rb
CHANGED
|
@@ -17,6 +17,9 @@ module Nitro
|
|
|
17
17
|
#
|
|
18
18
|
# You can implement your own, custom version of the Runner
|
|
19
19
|
# to run your custom web applications.
|
|
20
|
+
#--
|
|
21
|
+
# FIXME: Rename/Reimplement this class.
|
|
22
|
+
#++
|
|
20
23
|
|
|
21
24
|
class Runner
|
|
22
25
|
|
|
@@ -194,6 +197,15 @@ class Runner
|
|
|
194
197
|
when :live
|
|
195
198
|
setup_live
|
|
196
199
|
end
|
|
200
|
+
|
|
201
|
+
# Special setup for distributed sessions.
|
|
202
|
+
=begin
|
|
203
|
+
if defined?(Session) and defined?(DRbObject)
|
|
204
|
+
if Session.store.is_a?(DRbObject)
|
|
205
|
+
system('ruby ' + File.join(Nitro::LibPath, 'session', 'drbserver.rb') + ' --address #{Session.drb_address} --port #{Session.drb_port} --daemon')
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
=end
|
|
197
209
|
end
|
|
198
210
|
|
|
199
211
|
# Setup in debug mode.
|
|
@@ -8,10 +8,14 @@ require 'nitro/session'
|
|
|
8
8
|
|
|
9
9
|
# A distributes session store implemented as
|
|
10
10
|
# a simple DRb server.
|
|
11
|
+
#--
|
|
12
|
+
# TODO: add daemonize support.
|
|
13
|
+
#++
|
|
11
14
|
|
|
12
15
|
address = '127.0.0.1'
|
|
13
16
|
port = 9069
|
|
14
17
|
debug = false
|
|
18
|
+
daemon = false
|
|
15
19
|
|
|
16
20
|
parser = OptionParser.new do |opts|
|
|
17
21
|
|
|
@@ -30,7 +34,11 @@ parser = OptionParser.new do |opts|
|
|
|
30
34
|
opts.on('-D', '--debug', 'Run in debug mode.') do |p|
|
|
31
35
|
debug = true
|
|
32
36
|
end
|
|
33
|
-
|
|
37
|
+
|
|
38
|
+
opts.on('-d', '--daemon', 'Run as daemon.') do |p|
|
|
39
|
+
daemon = true
|
|
40
|
+
end
|
|
41
|
+
|
|
34
42
|
opts.on_tail('-h', '--help', 'Show this message.') do
|
|
35
43
|
puts opts
|
|
36
44
|
exit
|
|
@@ -63,6 +71,13 @@ if debug
|
|
|
63
71
|
|
|
64
72
|
end
|
|
65
73
|
|
|
74
|
+
puts "Drb session server listening at druby://#{address}:#{port}."
|
|
75
|
+
|
|
76
|
+
if daemon
|
|
77
|
+
require 'daemons/daemonize'
|
|
78
|
+
Daemonize.daemonize()
|
|
79
|
+
end
|
|
80
|
+
|
|
66
81
|
DRb.start_service("druby://#{address}:#{port}", sessions)
|
|
67
82
|
DRb.thread.join
|
|
68
83
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
|
2
|
+
//
|
|
3
|
+
// See scriptaculous.js for full license.
|
|
4
|
+
|
|
5
|
+
var Builder = {
|
|
6
|
+
NODEMAP: {
|
|
7
|
+
AREA: 'map',
|
|
8
|
+
CAPTION: 'table',
|
|
9
|
+
COL: 'table',
|
|
10
|
+
COLGROUP: 'table',
|
|
11
|
+
LEGEND: 'fieldset',
|
|
12
|
+
OPTGROUP: 'select',
|
|
13
|
+
OPTION: 'select',
|
|
14
|
+
PARAM: 'object',
|
|
15
|
+
TBODY: 'table',
|
|
16
|
+
TD: 'table',
|
|
17
|
+
TFOOT: 'table',
|
|
18
|
+
TH: 'table',
|
|
19
|
+
THEAD: 'table',
|
|
20
|
+
TR: 'table'
|
|
21
|
+
},
|
|
22
|
+
// note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
|
|
23
|
+
// due to a Firefox bug
|
|
24
|
+
node: function(elementName) {
|
|
25
|
+
elementName = elementName.toUpperCase();
|
|
26
|
+
|
|
27
|
+
// try innerHTML approach
|
|
28
|
+
var parentTag = this.NODEMAP[elementName] || 'div';
|
|
29
|
+
var parentElement = document.createElement(parentTag);
|
|
30
|
+
parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
|
|
31
|
+
var element = parentElement.firstChild || null;
|
|
32
|
+
|
|
33
|
+
// see if browser added wrapping tags
|
|
34
|
+
if(element && (element.tagName != elementName))
|
|
35
|
+
element = element.getElementsByTagName(elementName)[0];
|
|
36
|
+
|
|
37
|
+
// fallback to createElement approach
|
|
38
|
+
if(!element) element = document.createElement(elementName);
|
|
39
|
+
|
|
40
|
+
// abort if nothing could be created
|
|
41
|
+
if(!element) return;
|
|
42
|
+
|
|
43
|
+
// attributes (or text)
|
|
44
|
+
if(arguments[1])
|
|
45
|
+
if(this._isStringOrNumber(arguments[1]) ||
|
|
46
|
+
(arguments[1] instanceof Array)) {
|
|
47
|
+
this._children(element, arguments[1]);
|
|
48
|
+
} else {
|
|
49
|
+
var attrs = this._attributes(arguments[1]);
|
|
50
|
+
if(attrs.length) {
|
|
51
|
+
parentElement.innerHTML = "<" +elementName + " " +
|
|
52
|
+
attrs + "></" + elementName + ">";
|
|
53
|
+
element = parentElement.firstChild || null;
|
|
54
|
+
// workaround firefox 1.0.X bug
|
|
55
|
+
if(!element) {
|
|
56
|
+
element = document.createElement(elementName);
|
|
57
|
+
for(attr in arguments[1])
|
|
58
|
+
element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
|
|
59
|
+
}
|
|
60
|
+
if(element.tagName != elementName)
|
|
61
|
+
element = parentElement.getElementsByTagName(elementName)[0];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// text, or array of children
|
|
66
|
+
if(arguments[2])
|
|
67
|
+
this._children(element, arguments[2]);
|
|
68
|
+
|
|
69
|
+
return element;
|
|
70
|
+
},
|
|
71
|
+
_text: function(text) {
|
|
72
|
+
return document.createTextNode(text);
|
|
73
|
+
},
|
|
74
|
+
_attributes: function(attributes) {
|
|
75
|
+
var attrs = [];
|
|
76
|
+
for(attribute in attributes)
|
|
77
|
+
attrs.push((attribute=='className' ? 'class' : attribute) +
|
|
78
|
+
'="' + attributes[attribute].toString().escapeHTML() + '"');
|
|
79
|
+
return attrs.join(" ");
|
|
80
|
+
},
|
|
81
|
+
_children: function(element, children) {
|
|
82
|
+
if(typeof children=='object') { // array can hold nodes and text
|
|
83
|
+
children.flatten().each( function(e) {
|
|
84
|
+
if(typeof e=='object')
|
|
85
|
+
element.appendChild(e)
|
|
86
|
+
else
|
|
87
|
+
if(Builder._isStringOrNumber(e))
|
|
88
|
+
element.appendChild(Builder._text(e));
|
|
89
|
+
});
|
|
90
|
+
} else
|
|
91
|
+
if(Builder._isStringOrNumber(children))
|
|
92
|
+
element.appendChild(Builder._text(children));
|
|
93
|
+
},
|
|
94
|
+
_isStringOrNumber: function(param) {
|
|
95
|
+
return(typeof param=='string' || typeof param=='number');
|
|
96
|
+
}
|
|
97
|
+
}
|
data/proto/public/js/controls.js
CHANGED
|
@@ -184,7 +184,10 @@ Autocompleter.Base.prototype = {
|
|
|
184
184
|
this.show();
|
|
185
185
|
this.active = true;
|
|
186
186
|
}
|
|
187
|
-
} else
|
|
187
|
+
} else {
|
|
188
|
+
this.active = false;
|
|
189
|
+
this.hide();
|
|
190
|
+
}
|
|
188
191
|
},
|
|
189
192
|
|
|
190
193
|
markPrevious: function() {
|
|
@@ -425,6 +428,15 @@ Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
|
|
|
425
428
|
//
|
|
426
429
|
// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
|
|
427
430
|
|
|
431
|
+
// Use this if you notice weird scrolling problems on some browsers,
|
|
432
|
+
// the DOM might be a bit confused when this gets called so do this
|
|
433
|
+
// waits 1 ms (with setTimeout) until it does the activation
|
|
434
|
+
Field.scrollFreeActivate = function(field) {
|
|
435
|
+
setTimeout(function() {
|
|
436
|
+
Field.activate(field);
|
|
437
|
+
}, 1);
|
|
438
|
+
}
|
|
439
|
+
|
|
428
440
|
Ajax.InPlaceEditor = Class.create();
|
|
429
441
|
Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
|
|
430
442
|
Ajax.InPlaceEditor.prototype = {
|
|
@@ -490,7 +502,7 @@ Ajax.InPlaceEditor.prototype = {
|
|
|
490
502
|
Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
|
|
491
503
|
}
|
|
492
504
|
},
|
|
493
|
-
enterEditMode: function() {
|
|
505
|
+
enterEditMode: function(evt) {
|
|
494
506
|
if (this.saving) return;
|
|
495
507
|
if (this.editing) return;
|
|
496
508
|
this.editing = true;
|
|
@@ -501,11 +513,12 @@ Ajax.InPlaceEditor.prototype = {
|
|
|
501
513
|
Element.hide(this.element);
|
|
502
514
|
this.createForm();
|
|
503
515
|
this.element.parentNode.insertBefore(this.form, this.element);
|
|
504
|
-
Field.
|
|
516
|
+
Field.scrollFreeActivate(this.editField);
|
|
505
517
|
// stop the event to avoid a page refresh in Safari
|
|
506
|
-
if (
|
|
507
|
-
Event.stop(
|
|
518
|
+
if (evt) {
|
|
519
|
+
Event.stop(evt);
|
|
508
520
|
}
|
|
521
|
+
return false;
|
|
509
522
|
},
|
|
510
523
|
createForm: function() {
|
|
511
524
|
this.form = document.createElement("form");
|
data/proto/public/js/dragdrop.js
CHANGED
|
@@ -233,8 +233,8 @@ Draggable.prototype = {
|
|
|
233
233
|
this.originalTop = this.currentTop();
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
|
|
237
|
-
|
|
236
|
+
if(this.options.zindex)
|
|
237
|
+
this.element.style.zIndex = this.originalZ;
|
|
238
238
|
|
|
239
239
|
if(this.options.endeffect)
|
|
240
240
|
this.options.endeffect(this.element);
|
|
@@ -280,7 +280,7 @@ Draggable.prototype = {
|
|
|
280
280
|
style.position = "relative";
|
|
281
281
|
|
|
282
282
|
if(this.options.zindex) {
|
|
283
|
-
this.
|
|
283
|
+
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
|
|
284
284
|
style.zIndex = this.options.zindex;
|
|
285
285
|
}
|
|
286
286
|
|
|
@@ -355,8 +355,8 @@ var Sortable = {
|
|
|
355
355
|
hoverclass: null,
|
|
356
356
|
ghosting: false,
|
|
357
357
|
format: null,
|
|
358
|
-
onChange:
|
|
359
|
-
onUpdate:
|
|
358
|
+
onChange: Prototype.emptyFunction,
|
|
359
|
+
onUpdate: Prototype.emptyFunction
|
|
360
360
|
}, arguments[1] || {});
|
|
361
361
|
|
|
362
362
|
// clear any old sortable with same element
|
|
@@ -472,7 +472,10 @@ var Sortable = {
|
|
|
472
472
|
|
|
473
473
|
onEmptyHover: function(element, dropon) {
|
|
474
474
|
if(element.parentNode!=dropon) {
|
|
475
|
+
var oldParentNode = element.parentNode;
|
|
475
476
|
dropon.appendChild(element);
|
|
477
|
+
Sortable.options(oldParentNode).onChange(element);
|
|
478
|
+
Sortable.options(dropon).onChange(element);
|
|
476
479
|
}
|
|
477
480
|
},
|
|
478
481
|
|
data/proto/public/js/effects.js
CHANGED
|
@@ -4,7 +4,182 @@
|
|
|
4
4
|
// Mark Pilgrim (http://diveintomark.org/)
|
|
5
5
|
// Martin Bialasinki
|
|
6
6
|
//
|
|
7
|
-
// See scriptaculous.js for full license.
|
|
7
|
+
// See scriptaculous.js for full license.
|
|
8
|
+
|
|
9
|
+
/* ------------- element ext -------------- */
|
|
10
|
+
|
|
11
|
+
// converts rgb() and #xxx to #xxxxxx format,
|
|
12
|
+
// returns self (or first argument) if not convertable
|
|
13
|
+
String.prototype.parseColor = function() {
|
|
14
|
+
color = "#";
|
|
15
|
+
if(this.slice(0,4) == "rgb(") {
|
|
16
|
+
var cols = this.slice(4,this.length-1).split(',');
|
|
17
|
+
var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
|
|
18
|
+
} else {
|
|
19
|
+
if(this.slice(0,1) == '#') {
|
|
20
|
+
if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
|
|
21
|
+
if(this.length==7) color = this.toLowerCase();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return(color.length==7 ? color : (arguments[0] || this));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Element.collectTextNodesIgnoreClass = function(element, ignoreclass) {
|
|
28
|
+
var children = $(element).childNodes;
|
|
29
|
+
var text = "";
|
|
30
|
+
var classtest = new RegExp("^([^ ]+ )*" + ignoreclass+ "( [^ ]+)*$","i");
|
|
31
|
+
|
|
32
|
+
for (var i = 0; i < children.length; i++) {
|
|
33
|
+
if(children[i].nodeType==3) {
|
|
34
|
+
text+=children[i].nodeValue;
|
|
35
|
+
} else {
|
|
36
|
+
if((!children[i].className.match(classtest)) && children[i].hasChildNodes())
|
|
37
|
+
text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return text;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
Element.setContentZoom = function(element, percent) {
|
|
45
|
+
element = $(element);
|
|
46
|
+
element.style.fontSize = (percent/100) + "em";
|
|
47
|
+
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
Element.getOpacity = function(element){
|
|
51
|
+
var opacity;
|
|
52
|
+
if (opacity = Element.getStyle(element, "opacity"))
|
|
53
|
+
return parseFloat(opacity);
|
|
54
|
+
if (opacity = (Element.getStyle(element, "filter") || '').match(/alpha\(opacity=(.*)\)/))
|
|
55
|
+
if(opacity[1]) return parseFloat(opacity[1]) / 100;
|
|
56
|
+
return 1.0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
Element.setOpacity = function(element, value){
|
|
60
|
+
element= $(element);
|
|
61
|
+
var els = element.style;
|
|
62
|
+
if (value == 1){
|
|
63
|
+
els.opacity = '0.999999';
|
|
64
|
+
if(/MSIE/.test(navigator.userAgent))
|
|
65
|
+
els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'');
|
|
66
|
+
} else {
|
|
67
|
+
if(value < 0.00001) value = 0;
|
|
68
|
+
els.opacity = value;
|
|
69
|
+
if(/MSIE/.test(navigator.userAgent))
|
|
70
|
+
els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
|
|
71
|
+
"alpha(opacity="+value*100+")";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
Element.getInlineOpacity = function(element){
|
|
76
|
+
element= $(element);
|
|
77
|
+
var op;
|
|
78
|
+
op = element.style.opacity;
|
|
79
|
+
if (typeof op != "undefined" && op != "") return op;
|
|
80
|
+
return "";
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
Element.setInlineOpacity = function(element, value){
|
|
84
|
+
element= $(element);
|
|
85
|
+
var els = element.style;
|
|
86
|
+
els.opacity = value;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/*--------------------------------------------------------------------------*/
|
|
90
|
+
|
|
91
|
+
Element.Class = {
|
|
92
|
+
// Element.toggleClass(element, className) toggles the class being on/off
|
|
93
|
+
// Element.toggleClass(element, className1, className2) toggles between both classes,
|
|
94
|
+
// defaulting to className1 if neither exist
|
|
95
|
+
toggle: function(element, className) {
|
|
96
|
+
if(Element.Class.has(element, className)) {
|
|
97
|
+
Element.Class.remove(element, className);
|
|
98
|
+
if(arguments.length == 3) Element.Class.add(element, arguments[2]);
|
|
99
|
+
} else {
|
|
100
|
+
Element.Class.add(element, className);
|
|
101
|
+
if(arguments.length == 3) Element.Class.remove(element, arguments[2]);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
// gets space-delimited classnames of an element as an array
|
|
106
|
+
get: function(element) {
|
|
107
|
+
return $(element).className.split(' ');
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
// functions adapted from original functions by Gavin Kistner
|
|
111
|
+
remove: function(element) {
|
|
112
|
+
element = $(element);
|
|
113
|
+
var removeClasses = arguments;
|
|
114
|
+
$R(1,arguments.length-1).each( function(index) {
|
|
115
|
+
element.className =
|
|
116
|
+
element.className.split(' ').reject(
|
|
117
|
+
function(klass) { return (klass == removeClasses[index]) } ).join(' ');
|
|
118
|
+
});
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
add: function(element) {
|
|
122
|
+
element = $(element);
|
|
123
|
+
for(var i = 1; i < arguments.length; i++) {
|
|
124
|
+
Element.Class.remove(element, arguments[i]);
|
|
125
|
+
element.className += (element.className.length > 0 ? ' ' : '') + arguments[i];
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
// returns true if all given classes exist in said element
|
|
130
|
+
has: function(element) {
|
|
131
|
+
element = $(element);
|
|
132
|
+
if(!element || !element.className) return false;
|
|
133
|
+
var regEx;
|
|
134
|
+
for(var i = 1; i < arguments.length; i++) {
|
|
135
|
+
if((typeof arguments[i] == 'object') &&
|
|
136
|
+
(arguments[i].constructor == Array)) {
|
|
137
|
+
for(var j = 0; j < arguments[i].length; j++) {
|
|
138
|
+
regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
|
|
139
|
+
if(!regEx.test(element.className)) return false;
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
|
|
143
|
+
if(!regEx.test(element.className)) return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return true;
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
// expects arrays of strings and/or strings as optional paramters
|
|
150
|
+
// Element.Class.has_any(element, ['classA','classB','classC'], 'classD')
|
|
151
|
+
has_any: function(element) {
|
|
152
|
+
element = $(element);
|
|
153
|
+
if(!element || !element.className) return false;
|
|
154
|
+
var regEx;
|
|
155
|
+
for(var i = 1; i < arguments.length; i++) {
|
|
156
|
+
if((typeof arguments[i] == 'object') &&
|
|
157
|
+
(arguments[i].constructor == Array)) {
|
|
158
|
+
for(var j = 0; j < arguments[i].length; j++) {
|
|
159
|
+
regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
|
|
160
|
+
if(regEx.test(element.className)) return true;
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
|
|
164
|
+
if(regEx.test(element.className)) return true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
childrenWith: function(element, className) {
|
|
171
|
+
var children = $(element).getElementsByTagName('*');
|
|
172
|
+
var elements = new Array();
|
|
173
|
+
|
|
174
|
+
for (var i = 0; i < children.length; i++)
|
|
175
|
+
if (Element.Class.has(children[i], className))
|
|
176
|
+
elements.push(children[i]);
|
|
177
|
+
|
|
178
|
+
return elements;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/*--------------------------------------------------------------------------*/
|
|
8
183
|
|
|
9
184
|
var Effect = {
|
|
10
185
|
tagifyText: function(element) {
|
|
@@ -81,6 +256,9 @@ Effect.Transitions.full = function(pos) {
|
|
|
81
256
|
|
|
82
257
|
Effect.Queue = {
|
|
83
258
|
effects: [],
|
|
259
|
+
_each: function(iterator) {
|
|
260
|
+
this.effects._each(iterator);
|
|
261
|
+
},
|
|
84
262
|
interval: null,
|
|
85
263
|
add: function(effect) {
|
|
86
264
|
var timestamp = new Date().getTime();
|
|
@@ -117,6 +295,7 @@ Effect.Queue = {
|
|
|
117
295
|
this.effects.invoke('loop', timePos);
|
|
118
296
|
}
|
|
119
297
|
}
|
|
298
|
+
Object.extend(Effect.Queue, Enumerable);
|
|
120
299
|
|
|
121
300
|
Effect.Base = function() {};
|
|
122
301
|
Effect.Base.prototype = {
|
|
@@ -342,6 +521,8 @@ Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype),
|
|
|
342
521
|
this.start(options);
|
|
343
522
|
},
|
|
344
523
|
setup: function() {
|
|
524
|
+
// Prevent executing on elements not in the layout flow
|
|
525
|
+
if(this.element.style.display=='none') { this.cancel(); return; }
|
|
345
526
|
// Disable background image during the effect
|
|
346
527
|
this.oldBgImage = this.element.style.backgroundImage;
|
|
347
528
|
this.element.style.backgroundImage = "none";
|
|
@@ -572,7 +753,7 @@ Effect.SlideDown = function(element) {
|
|
|
572
753
|
},
|
|
573
754
|
afterUpdateInternal: function(effect) {
|
|
574
755
|
effect.element.firstChild.style.bottom =
|
|
575
|
-
(effect.
|
|
756
|
+
(effect.dims[0] - effect.element.clientHeight) + 'px'; },
|
|
576
757
|
afterFinishInternal: function(effect) {
|
|
577
758
|
Element.undoClipping(effect.element);
|
|
578
759
|
Element.undoPositioned(effect.element.firstChild);
|
|
@@ -599,7 +780,7 @@ Effect.SlideUp = function(element) {
|
|
|
599
780
|
},
|
|
600
781
|
afterUpdateInternal: function(effect) {
|
|
601
782
|
effect.element.firstChild.style.bottom =
|
|
602
|
-
(effect.
|
|
783
|
+
(effect.dims[0] - effect.element.clientHeight) + 'px'; },
|
|
603
784
|
afterFinishInternal: function(effect) {
|
|
604
785
|
Element.hide(effect.element);
|
|
605
786
|
Element.undoClipping(effect.element);
|
|
@@ -697,7 +878,7 @@ Effect.Grow = function(element) {
|
|
|
697
878
|
els.top = oldTop;
|
|
698
879
|
els.left = oldLeft;
|
|
699
880
|
els.height = oldHeight;
|
|
700
|
-
els.width = originalWidth;
|
|
881
|
+
els.width = originalWidth + 'px';
|
|
701
882
|
Element.setInlineOpacity(el, oldOpacity);
|
|
702
883
|
}
|
|
703
884
|
}, options)
|