Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge [5497] from trunk.

git-svn-id: http://svn-commit.rubyonrails.org/rails/branches/1-2-pre-release@5500 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 69ada0e26eb5f0f73380293dbf488db31dc09f23 1 parent 9eaad14
@sstephenson sstephenson authored
View
2  actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Update to Prototype 1.5.0_rc2. [Sam Stephenson]
+
* Remove JavaScriptLiteral in favor of ActiveSupport::JSON::Variable. [Sam Stephenson]
* assert_response supports symbolic status codes. #6569 [Kevin Clark]
View
418 actionpack/lib/action_view/helpers/javascripts/prototype.js
@@ -1,5 +1,5 @@
-/* Prototype JavaScript framework, version 1.5.0_rc1
- * (c) 2005 Sam Stephenson <sam@conio.net>
+/* Prototype JavaScript framework, version 1.5.0_rc2
+ * (c) 2005, 2006 Sam Stephenson <sam@conio.net>
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://prototype.conio.net/
@@ -7,7 +7,7 @@
/*--------------------------------------------------------------------------*/
var Prototype = {
- Version: '1.5.0_rc1',
+ Version: '1.5.0_rc2',
BrowserFeatures: {
XPath: !!document.evaluate
},
@@ -37,8 +37,8 @@ Object.extend = function(destination, source) {
Object.extend(Object, {
inspect: function(object) {
try {
- if (object == undefined) return 'undefined';
- if (object == null) return 'null';
+ if (object === undefined) return 'undefined';
+ if (object === null) return 'null';
return object.inspect ? object.inspect() : object.toString();
} catch (e) {
if (e instanceof RangeError) return '...';
@@ -100,7 +100,7 @@ var Try = {
these: function() {
var returnValue;
- for (var i = 0; i < arguments.length; i++) {
+ for (var i = 0, length = arguments.length; i < length; i++) {
var lambda = arguments[i];
try {
returnValue = lambda();
@@ -221,13 +221,23 @@ Object.extend(String.prototype, {
return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
},
- toQueryParams: function() {
- var pairs = this.match(/^\??(.*)$/)[1].split('&');
- return pairs.inject({}, function(params, pairString) {
- var pair = pairString.split('=');
- var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
- params[decodeURIComponent(pair[0])] = value;
- return params;
+ toQueryParams: function(separator) {
+ var match = this.strip().match(/([^?#]*)(#.*)?$/);
+ if (!match) return {};
+
+ return match[1].split(separator || '&').inject({}, function(hash, pair) {
+ if ((pair = pair.split('='))[0]) {
+ var name = decodeURIComponent(pair[0]);
+ var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+
+ if (hash[name] !== undefined) {
+ if (hash[name].constructor != Array)
+ hash[name] = [hash[name]];
+ if (value) hash[name].push(value);
+ }
+ else hash[name] = value;
+ }
+ return hash;
});
},
@@ -243,7 +253,7 @@ Object.extend(String.prototype, {
? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
: oStringList[0];
- for (var i = 1, len = oStringList.length; i < len; i++) {
+ for (var i = 1, length = oStringList.length; i < length; i++) {
var s = oStringList[i];
camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
}
@@ -338,7 +348,7 @@ var Enumerable = {
return results;
},
- detect: function (iterator) {
+ detect: function(iterator) {
var result;
this.each(function(value, index) {
if (iterator(value, index)) {
@@ -490,7 +500,7 @@ var $A = Array.from = function(iterable) {
return iterable.toArray();
} else {
var results = [];
- for (var i = 0; i < iterable.length; i++)
+ for (var i = 0, length = iterable.length; i < length; i++)
results.push(iterable[i]);
return results;
}
@@ -503,7 +513,7 @@ if (!Array.prototype._reverse)
Object.extend(Array.prototype, {
_each: function(iterator) {
- for (var i = 0; i < this.length; i++)
+ for (var i = 0, length = this.length; i < length; i++)
iterator(this[i]);
},
@@ -541,7 +551,7 @@ Object.extend(Array.prototype, {
},
indexOf: function(object) {
- for (var i = 0; i < this.length; i++)
+ for (var i = 0, length = this.length; i < length; i++)
if (this[i] == object) return i;
return -1;
},
@@ -568,6 +578,8 @@ Object.extend(Array.prototype, {
return '[' + this.map(Object.inspect).join(', ') + ']';
}
});
+
+Array.prototype.toArray = Array.prototype.clone;
var Hash = {
_each: function(iterator) {
for (var key in this) {
@@ -590,7 +602,7 @@ var Hash = {
},
merge: function(hash) {
- return $H(hash).inject($H(this), function(mergedHash, pair) {
+ return $H(hash).inject(this, function(mergedHash, pair) {
mergedHash[pair.key] = pair.value;
return mergedHash;
});
@@ -598,6 +610,22 @@ var Hash = {
toQueryString: function() {
return this.map(function(pair) {
+ if (!pair.key) return null;
+
+ if (pair.value && pair.value.constructor == Array) {
+ pair.value = pair.value.compact();
+
+ if (pair.value.length < 2) {
+ pair.value = pair.value.reduce();
+ } else {
+ var key = encodeURIComponent(pair.key);
+ return pair.value.map(function(value) {
+ return key + '=' + encodeURIComponent(value);
+ }).join('&');
+ }
+ }
+
+ if (pair.value == undefined) pair[1] = '';
return pair.map(encodeURIComponent).join('=');
}).join('&');
},
@@ -664,18 +692,18 @@ Ajax.Responders = {
this.responders._each(iterator);
},
- register: function(responderToAdd) {
- if (!this.include(responderToAdd))
- this.responders.push(responderToAdd);
+ register: function(responder) {
+ if (!this.include(responder))
+ this.responders.push(responder);
},
- unregister: function(responderToRemove) {
- this.responders = this.responders.without(responderToRemove);
+ unregister: function(responder) {
+ this.responders = this.responders.without(responder);
},
dispatch: function(callback, request, transport, json) {
this.each(function(responder) {
- if (responder[callback] && typeof responder[callback] == 'function') {
+ if (typeof responder[callback] == 'function') {
try {
responder[callback].apply(responder, [request, transport, json]);
} catch (e) {}
@@ -690,7 +718,6 @@ Ajax.Responders.register({
onCreate: function() {
Ajax.activeRequestCount++;
},
-
onComplete: function() {
Ajax.activeRequestCount--;
}
@@ -703,19 +730,14 @@ Ajax.Base.prototype = {
method: 'post',
asynchronous: true,
contentType: 'application/x-www-form-urlencoded',
+ encoding: 'UTF-8',
parameters: ''
}
Object.extend(this.options, options || {});
- },
- responseIsSuccess: function() {
- return this.transport.status == undefined
- || this.transport.status == 0
- || (this.transport.status >= 200 && this.transport.status < 300);
- },
-
- responseIsFailure: function() {
- return !this.responseIsSuccess();
+ this.options.method = this.options.method.toLowerCase();
+ this.options.parameters = $H(typeof this.options.parameters == 'string' ?
+ this.options.parameters.toQueryParams() : this.options.parameters);
}
}
@@ -731,24 +753,28 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
},
request: function(url) {
- var parameters = this.options.parameters || '';
- if (parameters.length > 0) parameters += '&_=';
+ var params = this.options.parameters;
+ if (params.any()) params['_'] = '';
- /* Simulate other verbs over post */
- if (this.options.method != 'get' && this.options.method != 'post') {
- parameters += (parameters.length > 0 ? '&' : '') + '_method=' + this.options.method;
+ if (!['get', 'post'].include(this.options.method)) {
+ // simulate other verbs over post
+ params['_method'] = this.options.method;
this.options.method = 'post';
}
- try {
- this.url = url;
- if (this.options.method == 'get' && parameters.length > 0)
- this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
+ this.url = url;
+
+ // when GET, append parameters to URL
+ if (this.options.method == 'get' && params.any())
+ this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') +
+ params.toQueryString();
+ try {
Ajax.Responders.dispatch('onCreate', this, this.transport);
- this.transport.open(this.options.method, this.url,
- this.options.asynchronous);
+ this.transport.open(this.options.method.toUpperCase(), this.url,
+ this.options.asynchronous, this.options.username,
+ this.options.password);
if (this.options.asynchronous)
setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
@@ -756,95 +782,116 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
this.transport.onreadystatechange = this.onStateChange.bind(this);
this.setRequestHeaders();
- var body = this.options.postBody ? this.options.postBody : parameters;
- this.transport.send(this.options.method == 'post' ? body : null);
+ var body = this.options.method == 'post' ?
+ (this.options.postBody || params.toQueryString()) : null;
+
+ this.transport.send(body);
/* Force Firefox to handle ready state 4 for synchronous requests */
if (!this.options.asynchronous && this.transport.overrideMimeType)
this.onStateChange();
-
- } catch (e) {
+ }
+ catch (e) {
this.dispatchException(e);
}
},
+ onStateChange: function() {
+ var readyState = this.transport.readyState;
+ if (readyState > 1)
+ this.respondToReadyState(this.transport.readyState);
+ },
+
setRequestHeaders: function() {
- var requestHeaders =
- ['X-Requested-With', 'XMLHttpRequest',
- 'X-Prototype-Version', Prototype.Version,
- 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*'];
+ var headers = {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'X-Prototype-Version': Prototype.Version,
+ 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+ };
if (this.options.method == 'post') {
- requestHeaders.push('Content-type', this.options.contentType);
+ headers['Content-type'] = this.options.contentType +
+ (this.options.encoding ? '; charset=' + this.options.encoding : '');
- /* Force "Connection: close" for Mozilla browsers to work around
- * a bug where XMLHttpReqeuest sends an incorrect Content-length
- * header. See Mozilla Bugzilla #246651.
+ /* Force "Connection: close" for older Mozilla browsers to work
+ * around a bug where XMLHttpRequest sends an incorrect
+ * Content-length header. See Mozilla Bugzilla #246651.
*/
- if (this.transport.overrideMimeType)
- requestHeaders.push('Connection', 'close');
+ if (this.transport.overrideMimeType &&
+ (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+ headers['Connection'] = 'close';
}
- if (this.options.requestHeaders)
- requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
-
- for (var i = 0; i < requestHeaders.length; i += 2)
- this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
- },
-
- onStateChange: function() {
- var readyState = this.transport.readyState;
- if (readyState != 1)
- this.respondToReadyState(this.transport.readyState);
- },
+ // user-defined headers
+ if (typeof this.options.requestHeaders == 'object') {
+ var extras = this.options.requestHeaders;
- header: function(name) {
- try {
- return this.transport.getResponseHeader(name);
- } catch (e) {}
- },
+ if (typeof extras.push == 'function')
+ for (var i = 0, length = extras.length; i < length; i += 2)
+ headers[extras[i]] = extras[i+1];
+ else
+ $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+ }
- evalJSON: function() {
- try {
- return eval('(' + this.header('X-JSON') + ')');
- } catch (e) {}
+ for (var name in headers)
+ this.transport.setRequestHeader(name, headers[name]);
},
- evalResponse: function() {
- try {
- return eval(this.transport.responseText);
- } catch (e) {
- this.dispatchException(e);
- }
+ success: function() {
+ return !this.transport.status
+ || (this.transport.status >= 200 && this.transport.status < 300);
},
respondToReadyState: function(readyState) {
- var event = Ajax.Request.Events[readyState];
+ var state = Ajax.Request.Events[readyState];
var transport = this.transport, json = this.evalJSON();
- if (event == 'Complete') {
+ if (state == 'Complete') {
try {
(this.options['on' + this.transport.status]
- || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
+ || this.options['on' + (this.success() ? 'Success' : 'Failure')]
|| Prototype.emptyFunction)(transport, json);
} catch (e) {
this.dispatchException(e);
}
-
- if ((this.header('Content-type') || '').match(/^text\/javascript/i))
- this.evalResponse();
}
try {
- (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + event, this, transport, json);
+ (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + state, this, transport, json);
} catch (e) {
this.dispatchException(e);
}
- /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
- if (event == 'Complete')
+ if (state == 'Complete') {
+ if ((this.getHeader('Content-type') || '').strip().
+ match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+ this.evalResponse();
+
+ // avoid memory leak in MSIE: clean up
this.transport.onreadystatechange = Prototype.emptyFunction;
+ }
+ },
+
+ getHeader: function(name) {
+ try {
+ return this.transport.getResponseHeader(name);
+ } catch (e) { return null }
+ },
+
+ evalJSON: function() {
+ try {
+ var json = this.getHeader('X-JSON');
+ return json ? eval('(' + json + ')') : null;
+ } catch (e) { return null }
+ },
+
+ evalResponse: function() {
+ try {
+ return eval(this.transport.responseText);
+ } catch (e) {
+ this.dispatchException(e);
+ }
},
dispatchException: function(exception) {
@@ -857,41 +904,37 @@ Ajax.Updater = Class.create();
Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
initialize: function(container, url, options) {
- this.containers = {
- success: container.success ? $(container.success) : $(container),
- failure: container.failure ? $(container.failure) :
- (container.success ? null : $(container))
+ this.container = {
+ success: (container.success || container),
+ failure: (container.failure || (container.success ? null : container))
}
this.transport = Ajax.getTransport();
this.setOptions(options);
var onComplete = this.options.onComplete || Prototype.emptyFunction;
- this.options.onComplete = (function(transport, object) {
+ this.options.onComplete = (function(transport, param) {
this.updateContent();
- onComplete(transport, object);
+ onComplete(transport, param);
}).bind(this);
this.request(url);
},
updateContent: function() {
- var receiver = this.responseIsSuccess() ?
- this.containers.success : this.containers.failure;
+ var receiver = this.container[this.success() ? 'success' : 'failure'];
var response = this.transport.responseText;
- if (!this.options.evalScripts)
- response = response.stripScripts();
+ if (!this.options.evalScripts) response = response.stripScripts();
- if (receiver) {
- if (this.options.insertion) {
+ if (receiver = $(receiver)) {
+ if (this.options.insertion)
new this.options.insertion(receiver, response);
- } else {
- Element.update(receiver, response);
- }
+ else
+ receiver.update(response);
}
- if (this.responseIsSuccess()) {
+ if (this.success()) {
if (this.onComplete)
setTimeout(this.onComplete.bind(this), 10);
}
@@ -940,15 +983,15 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
-function $() {
- var results = [], element;
- for (var i = 0; i < arguments.length; i++) {
- element = arguments[i];
- if (typeof element == 'string')
- element = document.getElementById(element);
- results.push(Element.extend(element));
+function $(element) {
+ if (arguments.length > 1) {
+ for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+ elements.push($(arguments[i]));
+ return elements;
}
- return results.reduce();
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+ return Element.extend(element);
}
if (Prototype.BrowserFeatures.XPath) {
@@ -956,7 +999,7 @@ if (Prototype.BrowserFeatures.XPath) {
var results = [];
var query = document.evaluate(expression, $(parentElement) || document,
null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
- for (var i = 0, len = query.snapshotLength; i < len; i++)
+ for (var i = 0, length = query.snapshotLength; i < length; i++)
results.push(query.snapshotItem(i));
return results;
}
@@ -969,11 +1012,9 @@ document.getElementsByClassName = function(className, parentElement) {
} else {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
var elements = [], child;
- for (var i = 0, len = children.length; i < len; i++) {
+ for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
- if (child.className.length == 0) continue;
- if (child.className == className ||
- child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+ if (Element.hasClassName(child, className))
elements.push(Element.extend(child));
}
return elements;
@@ -997,9 +1038,11 @@ Element.extend = function(element) {
if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
Object.extend(methods, Form.Element.Methods);
+ Object.extend(methods, Element.Methods.Simulated);
+
for (var property in methods) {
var value = methods[property];
- if (typeof value == 'function')
+ if (typeof value == 'function' && !(property in element))
element[property] = cache.findOrStore(value);
}
}
@@ -1093,6 +1136,13 @@ Element.Methods = {
return $A(element.getElementsByTagName('*'));
},
+ immediateDescendants: function(element) {
+ if (!(element = $(element).firstChild)) return [];
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ if (element) return [element].concat($(element).nextSiblings());
+ return [];
+ },
+
previousSiblings: function(element) {
return $(element).recursivelyCollect('previousSibling');
},
@@ -1139,6 +1189,10 @@ Element.Methods = {
return document.getElementsByClassName(className, element);
},
+ readAttribute: function(element, name) {
+ return $(element).getAttribute(name);
+ },
+
getHeight: function(element) {
element = $(element);
return element.offsetHeight;
@@ -1150,7 +1204,12 @@ Element.Methods = {
hasClassName: function(element, className) {
if (!(element = $(element))) return;
- return Element.classNames(element).include(className);
+ var elementClassName = element.className;
+ if (elementClassName.length == 0) return false;
+ if (elementClassName == className ||
+ elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+ return true;
+ return false;
},
addClassName: function(element, className) {
@@ -1300,13 +1359,19 @@ Element.Methods = {
}
}
+Element.Methods.Simulated = {
+ hasAttribute: function(element, attribute) {
+ return $(element).getAttributeNode(attribute).specified;
+ }
+}
+
// IE is missing .innerHTML support for TABLE-related elements
if(document.all){
Element.Methods.update = function(element, html) {
element = $(element);
html = typeof html == 'undefined' ? '' : html.toString();
var tagName = element.tagName.toUpperCase();
- if (['THEAD','TBODY','TR','TD'].indexOf(tagName) > -1) {
+ if (['THEAD','TBODY','TR','TD'].include(tagName)) {
var div = document.createElement('div');
switch (tagName) {
case 'THEAD':
@@ -1352,16 +1417,19 @@ if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
Element.addMethods = function(methods) {
Object.extend(Element.Methods, methods || {});
- function copy(methods, destination) {
+ function copy(methods, destination, onlyIfAbsent) {
+ onlyIfAbsent = onlyIfAbsent || false;
var cache = Element.extend.cache;
for (var property in methods) {
var value = methods[property];
- destination[property] = cache.findOrStore(value);
+ if (!onlyIfAbsent || !(property in destination))
+ destination[property] = cache.findOrStore(value);
}
}
if (typeof HTMLElement != 'undefined') {
copy(Element.Methods, HTMLElement.prototype);
+ copy(Element.Methods.Simulated, HTMLElement.prototype, true);
copy(Form.Methods, HTMLFormElement.prototype);
[HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
copy(Form.Element.Methods, klass.prototype);
@@ -1388,8 +1456,8 @@ Abstract.Insertion.prototype = {
try {
this.element.insertAdjacentHTML(this.adjacency, this.content);
} catch (e) {
- var tagName = this.element.tagName.toLowerCase();
- if (tagName == 'tbody' || tagName == 'tr') {
+ var tagName = this.element.tagName.toUpperCase();
+ if (['TBODY', 'TR'].include(tagName)) {
this.insertContent(this.contentFromAnonymousTable());
} else {
throw e;
@@ -1488,18 +1556,16 @@ Element.ClassNames.prototype = {
add: function(classNameToAdd) {
if (this.include(classNameToAdd)) return;
- this.set(this.toArray().concat(classNameToAdd).join(' '));
+ this.set($A(this).concat(classNameToAdd).join(' '));
},
remove: function(classNameToRemove) {
if (!this.include(classNameToRemove)) return;
- this.set(this.select(function(className) {
- return className != classNameToRemove;
- }).join(' '));
+ this.set($A(this).without(classNameToRemove).join(' '));
},
toString: function() {
- return this.toArray().join(' ');
+ return $A(this).join(' ');
}
}
@@ -1552,7 +1618,7 @@ Selector.prototype = {
if (clause = params.tagName)
conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
if ((clause = params.classNames).length > 0)
- for (var i = 0; i < clause.length; i++)
+ for (var i = 0, length = clause.length; i < length; i++)
conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')');
if (clause = params.attributes) {
clause.each(function(attribute) {
@@ -1594,7 +1660,7 @@ Selector.prototype = {
scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
var results = [];
- for (var i = 0; i < scope.length; i++)
+ for (var i = 0, length = scope.length; i < length; i++)
if (this.match(element = scope[i]))
results.push(Element.extend(element));
@@ -1636,32 +1702,30 @@ var Form = {
reset: function(form) {
$(form).reset();
return form;
+ },
+
+ serializeElements: function(elements) {
+ return elements.inject([], function(queryComponents, element) {
+ var queryComponent = Form.Element.serialize(element);
+ if (queryComponent) queryComponents.push(queryComponent);
+ return queryComponents;
+ }).join('&');
}
};
Form.Methods = {
serialize: function(form) {
- return this.serializeElements(Form.getElements($(form)));
- },
-
- serializeElements: function(elements) {
- var queryComponents = new Array();
-
- for (var i = 0; i < elements.length; i++) {
- var queryComponent = Form.Element.serialize(elements[i]);
- if (queryComponent)
- queryComponents.push(queryComponent);
- }
-
- return queryComponents.join('&');
+ return Form.serializeElements($(form).getElements());
},
getElements: function(form) {
- return $A($(form).getElementsByTagName('*')).inject([], function(elements, child) {
- if (Form.Element.Serializers[child.tagName.toLowerCase()])
- elements.push(Element.extend(child));
- return elements;
- });
+ return $A($(form).getElementsByTagName('*')).inject([],
+ function(elements, child) {
+ if (Form.Element.Serializers[child.tagName.toLowerCase()])
+ elements.push(Element.extend(child));
+ return elements;
+ }
+ );
},
getInputs: function(form, typeName, name) {
@@ -1672,12 +1736,12 @@ Form.Methods = {
return inputs;
var matchingInputs = new Array();
- for (var i = 0; i < inputs.length; i++) {
+ for (var i = 0, length = inputs.length; i < length; i++) {
var input = inputs[i];
if ((typeName && input.type != typeName) ||
(name && input.name != name))
continue;
- matchingInputs.push(input);
+ matchingInputs.push(Element.extend(input));
}
return matchingInputs;
@@ -1685,27 +1749,23 @@ Form.Methods = {
disable: function(form) {
form = $(form);
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
+ form.getElements().each(function(element) {
element.blur();
element.disabled = 'true';
- }
+ });
return form;
},
enable: function(form) {
form = $(form);
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
+ form.getElements().each(function(element) {
element.disabled = '';
- }
+ });
return form;
},
findFirstElement: function(form) {
- return Form.getElements(form).find(function(element) {
+ return $(form).getElements().find(function(element) {
return element.type != 'hidden' && !element.disabled &&
['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
});
@@ -1713,7 +1773,7 @@ Form.Methods = {
focusFirstElement: function(form) {
form = $(form);
- Field.activate(Form.findFirstElement(form));
+ form.findFirstElement().activate();
return form;
}
}
@@ -1828,18 +1888,20 @@ Form.Element.Serializers = {
selectOne: function(element) {
var value = '', opt, index = element.selectedIndex;
if (index >= 0) {
- opt = element.options[index];
- value = opt.value || opt.text;
+ opt = Element.extend(element.options[index]);
+ // Uses the new potential extension if hasAttribute isn't native.
+ value = opt.hasAttribute('value') ? opt.value : opt.text;
}
return [element.name, value];
},
selectMany: function(element) {
var value = [];
- for (var i = 0; i < element.length; i++) {
- var opt = element.options[i];
+ for (var i = 0, length = element.length; i < length; i++) {
+ var opt = Element.extend(element.options[i]);
if (opt.selected)
- value.push(opt.value || opt.text);
+ // Uses the new potential extension if hasAttribute isn't native.
+ value.push(opt.hasAttribute('value') ? opt.value : opt.text);
}
return [element.name, value];
}
@@ -1913,9 +1975,7 @@ Abstract.EventObserver.prototype = {
},
registerFormCallbacks: function() {
- var elements = Form.getElements(this.element);
- for (var i = 0; i < elements.length; i++)
- this.registerCallback(elements[i]);
+ Form.getElements(this.element).each(this.registerCallback.bind(this));
},
registerCallback: function(element) {
@@ -2019,7 +2079,7 @@ Object.extend(Event, {
unloadCache: function() {
if (!Event.observers) return;
- for (var i = 0; i < Event.observers.length; i++) {
+ for (var i = 0, length = Event.observers.length; i < length; i++) {
Event.stopObserving.apply(this, Event.observers[i]);
Event.observers[i][0] = null;
}
View
2  railties/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Update to Prototype 1.5.0_rc2. [Sam Stephenson]
+
* Add grep-based fallback to reaper, to work in pidless setups [Jamis Buck]
* Alter prior change to use require_dependency instead of require_or_load. Causes ApplicationController to be reloaded again. Closes #6587. [Nicholas Seckar]
View
418 railties/html/javascripts/prototype.js
@@ -1,5 +1,5 @@
-/* Prototype JavaScript framework, version 1.5.0_rc1
- * (c) 2005 Sam Stephenson <sam@conio.net>
+/* Prototype JavaScript framework, version 1.5.0_rc2
+ * (c) 2005, 2006 Sam Stephenson <sam@conio.net>
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://prototype.conio.net/
@@ -7,7 +7,7 @@
/*--------------------------------------------------------------------------*/
var Prototype = {
- Version: '1.5.0_rc1',
+ Version: '1.5.0_rc2',
BrowserFeatures: {
XPath: !!document.evaluate
},
@@ -37,8 +37,8 @@ Object.extend = function(destination, source) {
Object.extend(Object, {
inspect: function(object) {
try {
- if (object == undefined) return 'undefined';
- if (object == null) return 'null';
+ if (object === undefined) return 'undefined';
+ if (object === null) return 'null';
return object.inspect ? object.inspect() : object.toString();
} catch (e) {
if (e instanceof RangeError) return '...';
@@ -100,7 +100,7 @@ var Try = {
these: function() {
var returnValue;
- for (var i = 0; i < arguments.length; i++) {
+ for (var i = 0, length = arguments.length; i < length; i++) {
var lambda = arguments[i];
try {
returnValue = lambda();
@@ -221,13 +221,23 @@ Object.extend(String.prototype, {
return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
},
- toQueryParams: function() {
- var pairs = this.match(/^\??(.*)$/)[1].split('&');
- return pairs.inject({}, function(params, pairString) {
- var pair = pairString.split('=');
- var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
- params[decodeURIComponent(pair[0])] = value;
- return params;
+ toQueryParams: function(separator) {
+ var match = this.strip().match(/([^?#]*)(#.*)?$/);
+ if (!match) return {};
+
+ return match[1].split(separator || '&').inject({}, function(hash, pair) {
+ if ((pair = pair.split('='))[0]) {
+ var name = decodeURIComponent(pair[0]);
+ var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+
+ if (hash[name] !== undefined) {
+ if (hash[name].constructor != Array)
+ hash[name] = [hash[name]];
+ if (value) hash[name].push(value);
+ }
+ else hash[name] = value;
+ }
+ return hash;
});
},
@@ -243,7 +253,7 @@ Object.extend(String.prototype, {
? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
: oStringList[0];
- for (var i = 1, len = oStringList.length; i < len; i++) {
+ for (var i = 1, length = oStringList.length; i < length; i++) {
var s = oStringList[i];
camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
}
@@ -338,7 +348,7 @@ var Enumerable = {
return results;
},
- detect: function (iterator) {
+ detect: function(iterator) {
var result;
this.each(function(value, index) {
if (iterator(value, index)) {
@@ -490,7 +500,7 @@ var $A = Array.from = function(iterable) {
return iterable.toArray();
} else {
var results = [];
- for (var i = 0; i < iterable.length; i++)
+ for (var i = 0, length = iterable.length; i < length; i++)
results.push(iterable[i]);
return results;
}
@@ -503,7 +513,7 @@ if (!Array.prototype._reverse)
Object.extend(Array.prototype, {
_each: function(iterator) {
- for (var i = 0; i < this.length; i++)
+ for (var i = 0, length = this.length; i < length; i++)
iterator(this[i]);
},
@@ -541,7 +551,7 @@ Object.extend(Array.prototype, {
},
indexOf: function(object) {
- for (var i = 0; i < this.length; i++)
+ for (var i = 0, length = this.length; i < length; i++)
if (this[i] == object) return i;
return -1;
},
@@ -568,6 +578,8 @@ Object.extend(Array.prototype, {
return '[' + this.map(Object.inspect).join(', ') + ']';
}
});
+
+Array.prototype.toArray = Array.prototype.clone;
var Hash = {
_each: function(iterator) {
for (var key in this) {
@@ -590,7 +602,7 @@ var Hash = {
},
merge: function(hash) {
- return $H(hash).inject($H(this), function(mergedHash, pair) {
+ return $H(hash).inject(this, function(mergedHash, pair) {
mergedHash[pair.key] = pair.value;
return mergedHash;
});
@@ -598,6 +610,22 @@ var Hash = {
toQueryString: function() {
return this.map(function(pair) {
+ if (!pair.key) return null;
+
+ if (pair.value && pair.value.constructor == Array) {
+ pair.value = pair.value.compact();
+
+ if (pair.value.length < 2) {
+ pair.value = pair.value.reduce();
+ } else {
+ var key = encodeURIComponent(pair.key);
+ return pair.value.map(function(value) {
+ return key + '=' + encodeURIComponent(value);
+ }).join('&');
+ }
+ }
+
+ if (pair.value == undefined) pair[1] = '';
return pair.map(encodeURIComponent).join('=');
}).join('&');
},
@@ -664,18 +692,18 @@ Ajax.Responders = {
this.responders._each(iterator);
},
- register: function(responderToAdd) {
- if (!this.include(responderToAdd))
- this.responders.push(responderToAdd);
+ register: function(responder) {
+ if (!this.include(responder))
+ this.responders.push(responder);
},
- unregister: function(responderToRemove) {
- this.responders = this.responders.without(responderToRemove);
+ unregister: function(responder) {
+ this.responders = this.responders.without(responder);
},
dispatch: function(callback, request, transport, json) {
this.each(function(responder) {
- if (responder[callback] && typeof responder[callback] == 'function') {
+ if (typeof responder[callback] == 'function') {
try {
responder[callback].apply(responder, [request, transport, json]);
} catch (e) {}
@@ -690,7 +718,6 @@ Ajax.Responders.register({
onCreate: function() {
Ajax.activeRequestCount++;
},
-
onComplete: function() {
Ajax.activeRequestCount--;
}
@@ -703,19 +730,14 @@ Ajax.Base.prototype = {
method: 'post',
asynchronous: true,
contentType: 'application/x-www-form-urlencoded',
+ encoding: 'UTF-8',
parameters: ''
}
Object.extend(this.options, options || {});
- },
- responseIsSuccess: function() {
- return this.transport.status == undefined
- || this.transport.status == 0
- || (this.transport.status >= 200 && this.transport.status < 300);
- },
-
- responseIsFailure: function() {
- return !this.responseIsSuccess();
+ this.options.method = this.options.method.toLowerCase();
+ this.options.parameters = $H(typeof this.options.parameters == 'string' ?
+ this.options.parameters.toQueryParams() : this.options.parameters);
}
}
@@ -731,24 +753,28 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
},
request: function(url) {
- var parameters = this.options.parameters || '';
- if (parameters.length > 0) parameters += '&_=';
+ var params = this.options.parameters;
+ if (params.any()) params['_'] = '';
- /* Simulate other verbs over post */
- if (this.options.method != 'get' && this.options.method != 'post') {
- parameters += (parameters.length > 0 ? '&' : '') + '_method=' + this.options.method;
+ if (!['get', 'post'].include(this.options.method)) {
+ // simulate other verbs over post
+ params['_method'] = this.options.method;
this.options.method = 'post';
}
- try {
- this.url = url;
- if (this.options.method == 'get' && parameters.length > 0)
- this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
+ this.url = url;
+
+ // when GET, append parameters to URL
+ if (this.options.method == 'get' && params.any())
+ this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') +
+ params.toQueryString();
+ try {
Ajax.Responders.dispatch('onCreate', this, this.transport);
- this.transport.open(this.options.method, this.url,
- this.options.asynchronous);
+ this.transport.open(this.options.method.toUpperCase(), this.url,
+ this.options.asynchronous, this.options.username,
+ this.options.password);
if (this.options.asynchronous)
setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
@@ -756,95 +782,116 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
this.transport.onreadystatechange = this.onStateChange.bind(this);
this.setRequestHeaders();
- var body = this.options.postBody ? this.options.postBody : parameters;
- this.transport.send(this.options.method == 'post' ? body : null);
+ var body = this.options.method == 'post' ?
+ (this.options.postBody || params.toQueryString()) : null;
+
+ this.transport.send(body);
/* Force Firefox to handle ready state 4 for synchronous requests */
if (!this.options.asynchronous && this.transport.overrideMimeType)
this.onStateChange();
-
- } catch (e) {
+ }
+ catch (e) {
this.dispatchException(e);
}
},
+ onStateChange: function() {
+ var readyState = this.transport.readyState;
+ if (readyState > 1)
+ this.respondToReadyState(this.transport.readyState);
+ },
+
setRequestHeaders: function() {
- var requestHeaders =
- ['X-Requested-With', 'XMLHttpRequest',
- 'X-Prototype-Version', Prototype.Version,
- 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*'];
+ var headers = {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'X-Prototype-Version': Prototype.Version,
+ 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+ };
if (this.options.method == 'post') {
- requestHeaders.push('Content-type', this.options.contentType);
+ headers['Content-type'] = this.options.contentType +
+ (this.options.encoding ? '; charset=' + this.options.encoding : '');
- /* Force "Connection: close" for Mozilla browsers to work around
- * a bug where XMLHttpReqeuest sends an incorrect Content-length
- * header. See Mozilla Bugzilla #246651.
+ /* Force "Connection: close" for older Mozilla browsers to work
+ * around a bug where XMLHttpRequest sends an incorrect
+ * Content-length header. See Mozilla Bugzilla #246651.
*/
- if (this.transport.overrideMimeType)
- requestHeaders.push('Connection', 'close');
+ if (this.transport.overrideMimeType &&
+ (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+ headers['Connection'] = 'close';
}
- if (this.options.requestHeaders)
- requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
-
- for (var i = 0; i < requestHeaders.length; i += 2)
- this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
- },
-
- onStateChange: function() {
- var readyState = this.transport.readyState;
- if (readyState != 1)
- this.respondToReadyState(this.transport.readyState);
- },
+ // user-defined headers
+ if (typeof this.options.requestHeaders == 'object') {
+ var extras = this.options.requestHeaders;
- header: function(name) {
- try {
- return this.transport.getResponseHeader(name);
- } catch (e) {}
- },
+ if (typeof extras.push == 'function')
+ for (var i = 0, length = extras.length; i < length; i += 2)
+ headers[extras[i]] = extras[i+1];
+ else
+ $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+ }
- evalJSON: function() {
- try {
- return eval('(' + this.header('X-JSON') + ')');
- } catch (e) {}
+ for (var name in headers)
+ this.transport.setRequestHeader(name, headers[name]);
},
- evalResponse: function() {
- try {
- return eval(this.transport.responseText);
- } catch (e) {
- this.dispatchException(e);
- }
+ success: function() {
+ return !this.transport.status
+ || (this.transport.status >= 200 && this.transport.status < 300);
},
respondToReadyState: function(readyState) {
- var event = Ajax.Request.Events[readyState];
+ var state = Ajax.Request.Events[readyState];
var transport = this.transport, json = this.evalJSON();
- if (event == 'Complete') {
+ if (state == 'Complete') {
try {
(this.options['on' + this.transport.status]
- || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
+ || this.options['on' + (this.success() ? 'Success' : 'Failure')]
|| Prototype.emptyFunction)(transport, json);
} catch (e) {
this.dispatchException(e);
}
-
- if ((this.header('Content-type') || '').match(/^text\/javascript/i))
- this.evalResponse();
}
try {
- (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + event, this, transport, json);
+ (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + state, this, transport, json);
} catch (e) {
this.dispatchException(e);
}
- /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
- if (event == 'Complete')
+ if (state == 'Complete') {
+ if ((this.getHeader('Content-type') || '').strip().
+ match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+ this.evalResponse();
+
+ // avoid memory leak in MSIE: clean up
this.transport.onreadystatechange = Prototype.emptyFunction;
+ }
+ },
+
+ getHeader: function(name) {
+ try {
+ return this.transport.getResponseHeader(name);
+ } catch (e) { return null }
+ },
+
+ evalJSON: function() {
+ try {
+ var json = this.getHeader('X-JSON');
+ return json ? eval('(' + json + ')') : null;
+ } catch (e) { return null }
+ },
+
+ evalResponse: function() {
+ try {
+ return eval(this.transport.responseText);
+ } catch (e) {
+ this.dispatchException(e);
+ }
},
dispatchException: function(exception) {
@@ -857,41 +904,37 @@ Ajax.Updater = Class.create();
Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
initialize: function(container, url, options) {
- this.containers = {
- success: container.success ? $(container.success) : $(container),
- failure: container.failure ? $(container.failure) :
- (container.success ? null : $(container))
+ this.container = {
+ success: (container.success || container),
+ failure: (container.failure || (container.success ? null : container))
}
this.transport = Ajax.getTransport();
this.setOptions(options);
var onComplete = this.options.onComplete || Prototype.emptyFunction;
- this.options.onComplete = (function(transport, object) {
+ this.options.onComplete = (function(transport, param) {
this.updateContent();
- onComplete(transport, object);
+ onComplete(transport, param);
}).bind(this);
this.request(url);
},
updateContent: function() {
- var receiver = this.responseIsSuccess() ?
- this.containers.success : this.containers.failure;
+ var receiver = this.container[this.success() ? 'success' : 'failure'];
var response = this.transport.responseText;
- if (!this.options.evalScripts)
- response = response.stripScripts();
+ if (!this.options.evalScripts) response = response.stripScripts();
- if (receiver) {
- if (this.options.insertion) {
+ if (receiver = $(receiver)) {
+ if (this.options.insertion)
new this.options.insertion(receiver, response);
- } else {
- Element.update(receiver, response);
- }
+ else
+ receiver.update(response);
}
- if (this.responseIsSuccess()) {
+ if (this.success()) {
if (this.onComplete)
setTimeout(this.onComplete.bind(this), 10);
}
@@ -940,15 +983,15 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
-function $() {
- var results = [], element;
- for (var i = 0; i < arguments.length; i++) {
- element = arguments[i];
- if (typeof element == 'string')
- element = document.getElementById(element);
- results.push(Element.extend(element));
+function $(element) {
+ if (arguments.length > 1) {
+ for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+ elements.push($(arguments[i]));
+ return elements;
}
- return results.reduce();
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+ return Element.extend(element);
}
if (Prototype.BrowserFeatures.XPath) {
@@ -956,7 +999,7 @@ if (Prototype.BrowserFeatures.XPath) {
var results = [];
var query = document.evaluate(expression, $(parentElement) || document,
null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
- for (var i = 0, len = query.snapshotLength; i < len; i++)
+ for (var i = 0, length = query.snapshotLength; i < length; i++)
results.push(query.snapshotItem(i));
return results;
}
@@ -969,11 +1012,9 @@ document.getElementsByClassName = function(className, parentElement) {
} else {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
var elements = [], child;
- for (var i = 0, len = children.length; i < len; i++) {
+ for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
- if (child.className.length == 0) continue;
- if (child.className == className ||
- child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+ if (Element.hasClassName(child, className))
elements.push(Element.extend(child));
}
return elements;
@@ -997,9 +1038,11 @@ Element.extend = function(element) {
if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
Object.extend(methods, Form.Element.Methods);
+ Object.extend(methods, Element.Methods.Simulated);
+
for (var property in methods) {
var value = methods[property];
- if (typeof value == 'function')
+ if (typeof value == 'function' && !(property in element))
element[property] = cache.findOrStore(value);
}
}
@@ -1093,6 +1136,13 @@ Element.Methods = {
return $A(element.getElementsByTagName('*'));
},
+ immediateDescendants: function(element) {
+ if (!(element = $(element).firstChild)) return [];
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ if (element) return [element].concat($(element).nextSiblings());
+ return [];
+ },
+
previousSiblings: function(element) {
return $(element).recursivelyCollect('previousSibling');
},
@@ -1139,6 +1189,10 @@ Element.Methods = {
return document.getElementsByClassName(className, element);
},
+ readAttribute: function(element, name) {
+ return $(element).getAttribute(name);
+ },
+
getHeight: function(element) {
element = $(element);
return element.offsetHeight;
@@ -1150,7 +1204,12 @@ Element.Methods = {
hasClassName: function(element, className) {
if (!(element = $(element))) return;
- return Element.classNames(element).include(className);
+ var elementClassName = element.className;
+ if (elementClassName.length == 0) return false;
+ if (elementClassName == className ||
+ elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+ return true;
+ return false;
},
addClassName: function(element, className) {
@@ -1300,13 +1359,19 @@ Element.Methods = {
}
}
+Element.Methods.Simulated = {
+ hasAttribute: function(element, attribute) {
+ return $(element).getAttributeNode(attribute).specified;
+ }
+}
+
// IE is missing .innerHTML support for TABLE-related elements
if(document.all){
Element.Methods.update = function(element, html) {
element = $(element);
html = typeof html == 'undefined' ? '' : html.toString();
var tagName = element.tagName.toUpperCase();
- if (['THEAD','TBODY','TR','TD'].indexOf(tagName) > -1) {
+ if (['THEAD','TBODY','TR','TD'].include(tagName)) {
var div = document.createElement('div');
switch (tagName) {
case 'THEAD':
@@ -1352,16 +1417,19 @@ if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
Element.addMethods = function(methods) {
Object.extend(Element.Methods, methods || {});
- function copy(methods, destination) {
+ function copy(methods, destination, onlyIfAbsent) {
+ onlyIfAbsent = onlyIfAbsent || false;
var cache = Element.extend.cache;
for (var property in methods) {
var value = methods[property];
- destination[property] = cache.findOrStore(value);
+ if (!onlyIfAbsent || !(property in destination))
+ destination[property] = cache.findOrStore(value);
}
}
if (typeof HTMLElement != 'undefined') {
copy(Element.Methods, HTMLElement.prototype);
+ copy(Element.Methods.Simulated, HTMLElement.prototype, true);
copy(Form.Methods, HTMLFormElement.prototype);
[HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
copy(Form.Element.Methods, klass.prototype);
@@ -1388,8 +1456,8 @@ Abstract.Insertion.prototype = {
try {
this.element.insertAdjacentHTML(this.adjacency, this.content);
} catch (e) {
- var tagName = this.element.tagName.toLowerCase();
- if (tagName == 'tbody' || tagName == 'tr') {
+ var tagName = this.element.tagName.toUpperCase();
+ if (['TBODY', 'TR'].include(tagName)) {
this.insertContent(this.contentFromAnonymousTable());
} else {
throw e;
@@ -1488,18 +1556,16 @@ Element.ClassNames.prototype = {
add: function(classNameToAdd) {
if (this.include(classNameToAdd)) return;
- this.set(this.toArray().concat(classNameToAdd).join(' '));
+ this.set($A(this).concat(classNameToAdd).join(' '));
},
remove: function(classNameToRemove) {
if (!this.include(classNameToRemove)) return;
- this.set(this.select(function(className) {
- return className != classNameToRemove;
- }).join(' '));
+ this.set($A(this).without(classNameToRemove).join(' '));
},
toString: function() {
- return this.toArray().join(' ');
+ return $A(this).join(' ');
}
}
@@ -1552,7 +1618,7 @@ Selector.prototype = {
if (clause = params.tagName)
conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
if ((clause = params.classNames).length > 0)
- for (var i = 0; i < clause.length; i++)
+ for (var i = 0, length = clause.length; i < length; i++)
conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')');
if (clause = params.attributes) {
clause.each(function(attribute) {
@@ -1594,7 +1660,7 @@ Selector.prototype = {
scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
var results = [];
- for (var i = 0; i < scope.length; i++)
+ for (var i = 0, length = scope.length; i < length; i++)
if (this.match(element = scope[i]))
results.push(Element.extend(element));
@@ -1636,32 +1702,30 @@ var Form = {
reset: function(form) {
$(form).reset();
return form;
+ },
+
+ serializeElements: function(elements) {
+ return elements.inject([], function(queryComponents, element) {
+ var queryComponent = Form.Element.serialize(element);
+ if (queryComponent) queryComponents.push(queryComponent);
+ return queryComponents;
+ }).join('&');
}
};
Form.Methods = {
serialize: function(form) {
- return this.serializeElements(Form.getElements($(form)));
- },
-
- serializeElements: function(elements) {
- var queryComponents = new Array();
-
- for (var i = 0; i < elements.length; i++) {
- var queryComponent = Form.Element.serialize(elements[i]);
- if (queryComponent)
- queryComponents.push(queryComponent);
- }
-
- return queryComponents.join('&');
+ return Form.serializeElements($(form).getElements());
},
getElements: function(form) {
- return $A($(form).getElementsByTagName('*')).inject([], function(elements, child) {
- if (Form.Element.Serializers[child.tagName.toLowerCase()])
- elements.push(Element.extend(child));
- return elements;
- });
+ return $A($(form).getElementsByTagName('*')).inject([],
+ function(elements, child) {
+ if (Form.Element.Serializers[child.tagName.toLowerCase()])
+ elements.push(Element.extend(child));
+ return elements;
+ }
+ );
},
getInputs: function(form, typeName, name) {
@@ -1672,12 +1736,12 @@ Form.Methods = {
return inputs;
var matchingInputs = new Array();
- for (var i = 0; i < inputs.length; i++) {
+ for (var i = 0, length = inputs.length; i < length; i++) {
var input = inputs[i];
if ((typeName && input.type != typeName) ||
(name && input.name != name))
continue;
- matchingInputs.push(input);
+ matchingInputs.push(Element.extend(input));
}
return matchingInputs;
@@ -1685,27 +1749,23 @@ Form.Methods = {
disable: function(form) {
form = $(form);
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
+ form.getElements().each(function(element) {
element.blur();
element.disabled = 'true';
- }
+ });
return form;
},
enable: function(form) {
form = $(form);
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
+ form.getElements().each(function(element) {
element.disabled = '';
- }
+ });
return form;
},
findFirstElement: function(form) {
- return Form.getElements(form).find(function(element) {
+ return $(form).getElements().find(function(element) {
return element.type != 'hidden' && !element.disabled &&
['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
});
@@ -1713,7 +1773,7 @@ Form.Methods = {
focusFirstElement: function(form) {
form = $(form);
- Field.activate(Form.findFirstElement(form));
+ form.findFirstElement().activate();
return form;
}
}
@@ -1828,18 +1888,20 @@ Form.Element.Serializers = {
selectOne: function(element) {
var value = '', opt, index = element.selectedIndex;
if (index >= 0) {
- opt = element.options[index];
- value = opt.value || opt.text;
+ opt = Element.extend(element.options[index]);
+ // Uses the new potential extension if hasAttribute isn't native.
+ value = opt.hasAttribute('value') ? opt.value : opt.text;
}
return [element.name, value];
},
selectMany: function(element) {
var value = [];
- for (var i = 0; i < element.length; i++) {
- var opt = element.options[i];
+ for (var i = 0, length = element.length; i < length; i++) {
+ var opt = Element.extend(element.options[i]);
if (opt.selected)
- value.push(opt.value || opt.text);
+ // Uses the new potential extension if hasAttribute isn't native.
+ value.push(opt.hasAttribute('value') ? opt.value : opt.text);
}
return [element.name, value];
}
@@ -1913,9 +1975,7 @@ Abstract.EventObserver.prototype = {
},
registerFormCallbacks: function() {
- var elements = Form.getElements(this.element);
- for (var i = 0; i < elements.length; i++)
- this.registerCallback(elements[i]);
+ Form.getElements(this.element).each(this.registerCallback.bind(this));
},
registerCallback: function(element) {
@@ -2019,7 +2079,7 @@ Object.extend(Event, {
unloadCache: function() {
if (!Event.observers) return;
- for (var i = 0; i < Event.observers.length; i++) {
+ for (var i = 0, length = Event.observers.length; i < length; i++) {
Event.stopObserving.apply(this, Event.observers[i]);
Event.observers[i][0] = null;
}
Please sign in to comment.
Something went wrong with that request. Please try again.