actionpack 1.11.0 → 1.11.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +45 -0
- data/lib/action_controller/assertions.rb +1 -1
- data/lib/action_controller/base.rb +24 -12
- data/lib/action_controller/caching.rb +1 -0
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +1 -0
- data/lib/action_controller/cgi_process.rb +44 -27
- data/lib/action_controller/components.rb +2 -2
- data/lib/action_controller/flash.rb +16 -7
- data/lib/action_controller/helpers.rb +12 -1
- data/lib/action_controller/layout.rb +3 -1
- data/lib/action_controller/macros/in_place_editing.rb +1 -1
- data/lib/action_controller/request.rb +20 -16
- data/lib/action_controller/session/active_record_store.rb +57 -51
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +0 -2
- data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -1
- data/lib/action_controller/vendor/html-scanner/html/node.rb.rej +17 -0
- data/lib/action_pack/version.rb +2 -2
- data/lib/action_view/base.rb +4 -5
- data/lib/action_view/helpers/asset_tag_helper.rb +2 -2
- data/lib/action_view/helpers/form_options_helper.rb +1 -1
- data/lib/action_view/helpers/form_tag_helper.rb +1 -1
- data/lib/action_view/helpers/java_script_macros_helper.rb +11 -9
- data/lib/action_view/helpers/javascripts/controls.js +30 -1
- data/lib/action_view/helpers/javascripts/dragdrop.js +37 -17
- data/lib/action_view/helpers/javascripts/effects.js +3 -91
- data/lib/action_view/helpers/javascripts/prototype.js +109 -67
- data/lib/action_view/helpers/text_helper.rb +30 -9
- data/rakefile +2 -2
- data/test/controller/active_record_assertions_test.rb +1 -0
- data/test/controller/active_record_store_test.rb +12 -6
- data/test/controller/flash_test.rb +1 -1
- data/test/controller/helper_test.rb +21 -5
- data/test/controller/new_render_test.rb +31 -0
- data/test/controller/request_test.rb +5 -0
- data/test/fixtures/helpers/fun/pdf_helper.rb +3 -0
- data/test/fixtures/test/render_file_with_ivar.rhtml +1 -0
- data/test/fixtures/test/render_file_with_locals.rhtml +1 -0
- data/test/template/form_options_helper_test.rb +16 -6
- data/test/template/text_helper_test.rb +7 -0
- metadata +7 -3
@@ -86,97 +86,9 @@ Element.setInlineOpacity = function(element, value){
|
|
86
86
|
els.opacity = value;
|
87
87
|
}
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
Element.
|
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
|
-
}
|
89
|
+
Element.childrenWithClassName = function(element, className) {
|
90
|
+
return $A($(element).getElementsByTagName('*')).select(
|
91
|
+
function(c) { return Element.hasClassName(c, className) });
|
180
92
|
}
|
181
93
|
|
182
94
|
/*--------------------------------------------------------------------------*/
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Prototype JavaScript framework, version 1.4.
|
1
|
+
/* Prototype JavaScript framework, version 1.4.0_rc4
|
2
2
|
* (c) 2005 Sam Stephenson <sam@conio.net>
|
3
3
|
*
|
4
4
|
* THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
|
@@ -11,7 +11,8 @@
|
|
11
11
|
/*--------------------------------------------------------------------------*/
|
12
12
|
|
13
13
|
var Prototype = {
|
14
|
-
Version: '1.4.
|
14
|
+
Version: '1.4.0_rc4',
|
15
|
+
ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
|
15
16
|
|
16
17
|
emptyFunction: function() {},
|
17
18
|
K: function(x) {return x}
|
@@ -143,6 +144,22 @@ Object.extend(String.prototype, {
|
|
143
144
|
return this.replace(/<\/?[^>]+>/gi, '');
|
144
145
|
},
|
145
146
|
|
147
|
+
stripScripts: function() {
|
148
|
+
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
|
149
|
+
},
|
150
|
+
|
151
|
+
extractScripts: function() {
|
152
|
+
var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
|
153
|
+
var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
|
154
|
+
return (this.match(matchAll) || []).map(function(scriptTag) {
|
155
|
+
return (scriptTag.match(matchOne) || ['', ''])[1];
|
156
|
+
});
|
157
|
+
},
|
158
|
+
|
159
|
+
evalScripts: function() {
|
160
|
+
return this.extractScripts().map(eval);
|
161
|
+
},
|
162
|
+
|
146
163
|
escapeHTML: function() {
|
147
164
|
var div = document.createElement('div');
|
148
165
|
var text = document.createTextNode(this);
|
@@ -214,8 +231,8 @@ var Enumerable = {
|
|
214
231
|
all: function(iterator) {
|
215
232
|
var result = true;
|
216
233
|
this.each(function(value, index) {
|
217
|
-
|
218
|
-
|
234
|
+
result = result && !!(iterator || Prototype.K)(value, index);
|
235
|
+
if (!result) throw $break;
|
219
236
|
});
|
220
237
|
return result;
|
221
238
|
},
|
@@ -223,7 +240,7 @@ var Enumerable = {
|
|
223
240
|
any: function(iterator) {
|
224
241
|
var result = true;
|
225
242
|
this.each(function(value, index) {
|
226
|
-
if (result
|
243
|
+
if (result = !!(iterator || Prototype.K)(value, index))
|
227
244
|
throw $break;
|
228
245
|
});
|
229
246
|
return result;
|
@@ -388,12 +405,19 @@ var $A = Array.from = function(iterable) {
|
|
388
405
|
|
389
406
|
Object.extend(Array.prototype, Enumerable);
|
390
407
|
|
408
|
+
Array.prototype._reverse = Array.prototype.reverse;
|
409
|
+
|
391
410
|
Object.extend(Array.prototype, {
|
392
411
|
_each: function(iterator) {
|
393
412
|
for (var i = 0; i < this.length; i++)
|
394
413
|
iterator(this[i]);
|
395
414
|
},
|
396
415
|
|
416
|
+
clear: function() {
|
417
|
+
this.length = 0;
|
418
|
+
return this;
|
419
|
+
},
|
420
|
+
|
397
421
|
first: function() {
|
398
422
|
return this[0];
|
399
423
|
},
|
@@ -425,14 +449,11 @@ Object.extend(Array.prototype, {
|
|
425
449
|
indexOf: function(object) {
|
426
450
|
for (var i = 0; i < this.length; i++)
|
427
451
|
if (this[i] == object) return i;
|
428
|
-
return
|
452
|
+
return -1;
|
429
453
|
},
|
430
454
|
|
431
|
-
reverse: function() {
|
432
|
-
|
433
|
-
for (var i = this.length; i > 0; i--)
|
434
|
-
result.push(this[i-1]);
|
435
|
-
return result;
|
455
|
+
reverse: function(inline) {
|
456
|
+
return (inline !== false ? this : this.toArray())._reverse();
|
436
457
|
},
|
437
458
|
|
438
459
|
inspect: function() {
|
@@ -486,9 +507,9 @@ function $H(object) {
|
|
486
507
|
Object.extend(hash, Hash);
|
487
508
|
return hash;
|
488
509
|
}
|
489
|
-
|
490
|
-
Object.extend(
|
491
|
-
Object.extend(
|
510
|
+
ObjectRange = Class.create();
|
511
|
+
Object.extend(ObjectRange.prototype, Enumerable);
|
512
|
+
Object.extend(ObjectRange.prototype, {
|
492
513
|
initialize: function(start, end, exclusive) {
|
493
514
|
this.start = start;
|
494
515
|
this.end = end;
|
@@ -513,7 +534,7 @@ Object.extend(Range.prototype, {
|
|
513
534
|
});
|
514
535
|
|
515
536
|
var $R = function(start, end, exclusive) {
|
516
|
-
return new
|
537
|
+
return new ObjectRange(start, end, exclusive);
|
517
538
|
}
|
518
539
|
|
519
540
|
var Ajax = {
|
@@ -549,8 +570,7 @@ Ajax.Responders = {
|
|
549
570
|
if (responder[callback] && typeof responder[callback] == 'function') {
|
550
571
|
try {
|
551
572
|
responder[callback].apply(responder, [request, transport, json]);
|
552
|
-
} catch (e) {
|
553
|
-
}
|
573
|
+
} catch (e) {}
|
554
574
|
}
|
555
575
|
});
|
556
576
|
}
|
@@ -626,8 +646,7 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
|
|
626
646
|
this.transport.send(this.options.method == 'post' ? body : null);
|
627
647
|
|
628
648
|
} catch (e) {
|
629
|
-
|
630
|
-
Ajax.Responders.dispatch('onException', this, e);
|
649
|
+
this.dispatchException(e);
|
631
650
|
}
|
632
651
|
},
|
633
652
|
|
@@ -661,12 +680,23 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
|
|
661
680
|
this.respondToReadyState(this.transport.readyState);
|
662
681
|
},
|
663
682
|
|
683
|
+
header: function(name) {
|
684
|
+
try {
|
685
|
+
return this.transport.getResponseHeader(name);
|
686
|
+
} catch (e) {}
|
687
|
+
},
|
688
|
+
|
664
689
|
evalJSON: function() {
|
665
690
|
try {
|
666
|
-
|
667
|
-
|
668
|
-
|
691
|
+
return eval(this.header('X-JSON'));
|
692
|
+
} catch (e) {}
|
693
|
+
},
|
694
|
+
|
695
|
+
evalResponse: function() {
|
696
|
+
try {
|
697
|
+
return eval(this.transport.responseText);
|
669
698
|
} catch (e) {
|
699
|
+
this.dispatchException(e);
|
670
700
|
}
|
671
701
|
},
|
672
702
|
|
@@ -674,22 +704,38 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
|
|
674
704
|
var event = Ajax.Request.Events[readyState];
|
675
705
|
var transport = this.transport, json = this.evalJSON();
|
676
706
|
|
677
|
-
if (event == 'Complete')
|
678
|
-
|
679
|
-
|
680
|
-
|
707
|
+
if (event == 'Complete') {
|
708
|
+
try {
|
709
|
+
(this.options['on' + this.transport.status]
|
710
|
+
|| this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
|
711
|
+
|| Prototype.emptyFunction)(transport, json);
|
712
|
+
} catch (e) {
|
713
|
+
this.dispatchException(e);
|
714
|
+
}
|
681
715
|
|
682
|
-
|
683
|
-
|
716
|
+
if ((this.header('Content-type') || '').match(/^text\/javascript/i))
|
717
|
+
this.evalResponse();
|
718
|
+
}
|
719
|
+
|
720
|
+
try {
|
721
|
+
(this.options['on' + event] || Prototype.emptyFunction)(transport, json);
|
722
|
+
Ajax.Responders.dispatch('on' + event, this, transport, json);
|
723
|
+
} catch (e) {
|
724
|
+
this.dispatchException(e);
|
725
|
+
}
|
684
726
|
|
685
727
|
/* Avoid memory leak in MSIE: clean up the oncomplete event handler */
|
686
728
|
if (event == 'Complete')
|
687
729
|
this.transport.onreadystatechange = Prototype.emptyFunction;
|
730
|
+
},
|
731
|
+
|
732
|
+
dispatchException: function(exception) {
|
733
|
+
(this.options.onException || Prototype.emptyFunction)(this, exception);
|
734
|
+
Ajax.Responders.dispatch('onException', this, exception);
|
688
735
|
}
|
689
736
|
});
|
690
737
|
|
691
738
|
Ajax.Updater = Class.create();
|
692
|
-
Ajax.Updater.ScriptFragment = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)';
|
693
739
|
|
694
740
|
Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
|
695
741
|
initialize: function(container, url, options) {
|
@@ -714,16 +760,16 @@ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
|
|
714
760
|
updateContent: function() {
|
715
761
|
var receiver = this.responseIsSuccess() ?
|
716
762
|
this.containers.success : this.containers.failure;
|
763
|
+
var response = this.transport.responseText;
|
717
764
|
|
718
|
-
|
719
|
-
|
720
|
-
var scripts = this.transport.responseText.match(match);
|
765
|
+
if (!this.options.evalScripts)
|
766
|
+
response = response.stripScripts();
|
721
767
|
|
722
768
|
if (receiver) {
|
723
769
|
if (this.options.insertion) {
|
724
770
|
new this.options.insertion(receiver, response);
|
725
771
|
} else {
|
726
|
-
receiver
|
772
|
+
Element.update(receiver, response);
|
727
773
|
}
|
728
774
|
}
|
729
775
|
|
@@ -731,14 +777,6 @@ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
|
|
731
777
|
if (this.onComplete)
|
732
778
|
setTimeout(this.onComplete.bind(this), 10);
|
733
779
|
}
|
734
|
-
|
735
|
-
if (this.options.evalScripts && scripts) {
|
736
|
-
match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
|
737
|
-
setTimeout((function() {
|
738
|
-
for (var i = 0; i < scripts.length; i++)
|
739
|
-
eval(scripts[i].match(match)[1]);
|
740
|
-
}).bind(this), 10);
|
741
|
-
}
|
742
780
|
}
|
743
781
|
});
|
744
782
|
|
@@ -830,6 +868,11 @@ Object.extend(Element, {
|
|
830
868
|
element.parentNode.removeChild(element);
|
831
869
|
},
|
832
870
|
|
871
|
+
update: function(element, html) {
|
872
|
+
$(element).innerHTML = html.stripScripts();
|
873
|
+
setTimeout(function() {html.evalScripts()}, 10);
|
874
|
+
},
|
875
|
+
|
833
876
|
getHeight: function(element) {
|
834
877
|
element = $(element);
|
835
878
|
return element.offsetHeight;
|
@@ -893,6 +936,12 @@ Object.extend(Element, {
|
|
893
936
|
return value == 'auto' ? null : value;
|
894
937
|
},
|
895
938
|
|
939
|
+
setStyle: function(element, style) {
|
940
|
+
element = $(element);
|
941
|
+
for (name in style)
|
942
|
+
element.style[name.camelize()] = style[name];
|
943
|
+
},
|
944
|
+
|
896
945
|
getDimensions: function(element) {
|
897
946
|
element = $(element);
|
898
947
|
if (Element.getStyle(element, 'display') != 'none')
|
@@ -969,7 +1018,7 @@ Abstract.Insertion = function(adjacency) {
|
|
969
1018
|
Abstract.Insertion.prototype = {
|
970
1019
|
initialize: function(element, content) {
|
971
1020
|
this.element = $(element);
|
972
|
-
this.content = content;
|
1021
|
+
this.content = content.stripScripts();
|
973
1022
|
|
974
1023
|
if (this.adjacency && this.element.insertAdjacentHTML) {
|
975
1024
|
try {
|
@@ -986,6 +1035,8 @@ Abstract.Insertion.prototype = {
|
|
986
1035
|
if (this.initializeRange) this.initializeRange();
|
987
1036
|
this.insertContent([this.range.createContextualFragment(this.content)]);
|
988
1037
|
}
|
1038
|
+
|
1039
|
+
setTimeout(function() {content.evalScripts()}, 10);
|
989
1040
|
},
|
990
1041
|
|
991
1042
|
contentFromAnonymousTable: function() {
|
@@ -1018,7 +1069,7 @@ Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
|
|
1018
1069
|
},
|
1019
1070
|
|
1020
1071
|
insertContent: function(fragments) {
|
1021
|
-
fragments.reverse().each((function(fragment) {
|
1072
|
+
fragments.reverse(false).each((function(fragment) {
|
1022
1073
|
this.element.insertBefore(fragment, this.element.firstChild);
|
1023
1074
|
}).bind(this));
|
1024
1075
|
}
|
@@ -1079,7 +1130,7 @@ Element.ClassNames.prototype = {
|
|
1079
1130
|
if (!this.include(classNameToRemove)) return;
|
1080
1131
|
this.set(this.select(function(className) {
|
1081
1132
|
return className != classNameToRemove;
|
1082
|
-
}));
|
1133
|
+
}).join(' '));
|
1083
1134
|
},
|
1084
1135
|
|
1085
1136
|
toString: function() {
|
@@ -1109,8 +1160,10 @@ var Field = {
|
|
1109
1160
|
},
|
1110
1161
|
|
1111
1162
|
activate: function(element) {
|
1112
|
-
$(element)
|
1113
|
-
|
1163
|
+
element = $(element);
|
1164
|
+
element.focus();
|
1165
|
+
if (element.select)
|
1166
|
+
element.select();
|
1114
1167
|
}
|
1115
1168
|
}
|
1116
1169
|
|
@@ -1178,16 +1231,15 @@ var Form = {
|
|
1178
1231
|
}
|
1179
1232
|
},
|
1180
1233
|
|
1234
|
+
findFirstElement: function(form) {
|
1235
|
+
return Form.getElements(form).find(function(element) {
|
1236
|
+
return element.type != 'hidden' && !element.disabled &&
|
1237
|
+
['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
|
1238
|
+
});
|
1239
|
+
},
|
1240
|
+
|
1181
1241
|
focusFirstElement: function(form) {
|
1182
|
-
|
1183
|
-
var elements = Form.getElements(form);
|
1184
|
-
for (var i = 0; i < elements.length; i++) {
|
1185
|
-
var element = elements[i];
|
1186
|
-
if (element.type != 'hidden' && !element.disabled) {
|
1187
|
-
Field.activate(element);
|
1188
|
-
break;
|
1189
|
-
}
|
1190
|
-
}
|
1242
|
+
Field.activate(Form.findFirstElement(form));
|
1191
1243
|
},
|
1192
1244
|
|
1193
1245
|
reset: function(form) {
|
@@ -1349,24 +1401,14 @@ Abstract.EventObserver.prototype = {
|
|
1349
1401
|
switch (element.type.toLowerCase()) {
|
1350
1402
|
case 'checkbox':
|
1351
1403
|
case 'radio':
|
1352
|
-
element
|
1353
|
-
element.prev_onclick = element.onclick || Prototype.emptyFunction;
|
1354
|
-
element.onclick = function() {
|
1355
|
-
this.prev_onclick();
|
1356
|
-
this.target.onElementEvent();
|
1357
|
-
}
|
1404
|
+
Event.observe(element, 'click', this.onElementEvent.bind(this));
|
1358
1405
|
break;
|
1359
1406
|
case 'password':
|
1360
1407
|
case 'text':
|
1361
1408
|
case 'textarea':
|
1362
1409
|
case 'select-one':
|
1363
1410
|
case 'select-multiple':
|
1364
|
-
element
|
1365
|
-
element.prev_onchange = element.onchange || Prototype.emptyFunction;
|
1366
|
-
element.onchange = function() {
|
1367
|
-
this.prev_onchange();
|
1368
|
-
this.target.onElementEvent();
|
1369
|
-
}
|
1411
|
+
Event.observe(element, 'change', this.onElementEvent.bind(this));
|
1370
1412
|
break;
|
1371
1413
|
}
|
1372
1414
|
}
|