prototype: Add Object.isString, Object.isNumber, and Object.isUndefined, and clean up the source to make use of Object.isXXX where possible.

This commit is contained in:
Sam Stephenson 2007-08-08 23:19:45 +00:00
parent ae2ab03294
commit df71a6b54f
13 changed files with 100 additions and 52 deletions

View File

@ -1,5 +1,7 @@
*SVN*
* Add Object.isString, Object.isNumber, and Object.isUndefined, and clean up the source to make use of Object.isXXX where possible. [sam]
* Add the document.viewport object for querying dimensions and scroll offsets of the browser viewport. [Andrew Dupont, Thomas Fuchs, sam]
Example:
document.viewport.getDimensions() // { width: 1149, height: 923 }

View File

@ -28,10 +28,10 @@ Ajax.Responders = {
dispatch: function(callback, request, transport, json) {
this.each(function(responder) {
if (typeof responder[callback] == 'function') {
if (Object.isFunction(responder[callback])) {
try {
responder[callback].apply(responder, [request, transport, json]);
} catch (e) {}
} catch (e) { }
}
});
}
@ -48,7 +48,7 @@ Ajax.Responders.register({
}
});
Ajax.Base = function() {};
Ajax.Base = function() { };
Ajax.Base.prototype = {
setOptions: function(options) {
this.options = {
@ -60,10 +60,10 @@ Ajax.Base.prototype = {
evalJSON: true,
evalJS: true
};
Object.extend(this.options, options || {});
Object.extend(this.options, options || { });
this.options.method = this.options.method.toLowerCase();
if (typeof this.options.parameters == 'string')
if (Object.isString(this.options.parameters))
this.options.parameters = this.options.parameters.toQueryParams();
}
};
@ -158,7 +158,7 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
if (typeof this.options.requestHeaders == 'object') {
var extras = this.options.requestHeaders;
if (typeof extras.push == 'function')
if (Object.isFunction(extras.push))
for (var i = 0, length = extras.length; i < length; i += 2)
headers[extras[i]] = extras[i+1];
else
@ -332,8 +332,8 @@ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
if (receiver = $(receiver)) {
if (options.insertion) {
if (typeof options.insertion == 'string') {
var insertion = {}; insertion[options.insertion] = responseText;
if (Object.isString(options.insertion)) {
var insertion = { }; insertion[options.insertion] = responseText;
receiver.insert(insertion);
}
else options.insertion(receiver, responseText);
@ -356,7 +356,7 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
this.frequency = (this.options.frequency || 2);
this.decay = (this.options.decay || 1);
this.updater = {};
this.updater = { };
this.container = container;
this.url = url;

View File

@ -12,8 +12,8 @@ function $A(iterable) {
if (Prototype.Browser.WebKit) {
function $A(iterable) {
if (!iterable) return [];
if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
iterable.toArray) {
if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
iterable.toArray) {
return iterable.toArray();
} else {
var results = [];
@ -114,7 +114,7 @@ Object.extend(Array.prototype, {
});
// use native browser JS 1.6 implementation if available
if (typeof Array.prototype.forEach == 'function')
if (Object.isFunction(Array.prototype.forEach))
Array.prototype._each = Array.prototype.forEach;
if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {

View File

@ -1,7 +1,7 @@
/* Based on Alex Arnell's inheritance implementation. */
var Class = {
create: function(parent, methods) {
if (arguments.length == 1 && typeof parent !== 'function')
if (arguments.length == 1 && !Object.isFunction(parent))
methods = parent, parent = null;
var method = function() {
@ -137,6 +137,18 @@ Object.extend(Object, {
isFunction: function(object) {
return typeof object == "function";
},
isString: function(object) {
return typeof object == "string";
},
isNumber: function(object) {
return typeof object == "number";
},
isUndefined: function(object) {
return typeof object == "undefined";
}
});
@ -212,7 +224,7 @@ var Try = {
try {
returnValue = lambda();
break;
} catch (e) {}
} catch (e) { }
}
return returnValue;

View File

@ -106,7 +106,7 @@ var Position = {
page: Element.Methods.viewportOffset,
clone: function(source, target, options) {
options = options || {};
options = options || { };
return Element.clonePosition(target, source, options);
}
};

View File

@ -4,7 +4,7 @@ function $(element) {
elements.push($(arguments[i]));
return elements;
}
if (typeof element == 'string')
if (Object.isString(element))
element = document.getElementById(element);
return Element.extend(element);
}
@ -113,7 +113,7 @@ Element.Methods = {
insert: function(element, insertions) {
element = $(element);
if (typeof insertions == 'string' || typeof insertions == 'number' ||
if (Object.isString(insertions) || Object.isNumber(insertions) ||
Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
insertions = {bottom:insertions};
@ -146,7 +146,7 @@ Element.Methods = {
element = $(element);
if (Object.isElement(wrapper))
$(wrapper).writeAttribute(attributes || { });
else if (typeof wrapper == 'string') wrapper = new Element(wrapper, attributes);
else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
else wrapper = new Element('div', wrapper);
if (element.parentNode)
element.parentNode.replaceChild(wrapper, element);
@ -209,7 +209,7 @@ Element.Methods = {
},
match: function(element, selector) {
if (typeof selector == 'string')
if (Object.isString(selector))
selector = new Selector(selector);
return selector.match($(element));
},
@ -383,7 +383,7 @@ Element.Methods = {
setStyle: function(element, styles) {
element = $(element);
var elementStyle = element.style, match;
if (typeof styles === 'string') {
if (Object.isString(styles)) {
element.style.cssText += ';' + styles;
return styles.include('opacity') ?
element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
@ -680,9 +680,9 @@ if (!document.createRange || Prototype.Browser.Opera) {
Element.Methods.insert = function(element, insertions) {
element = $(element);
if (typeof insertions == 'string' || typeof insertions == 'number' ||
if (Object.isString(insertions) || Object.isNumber(insertions) ||
Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
insertions = {bottom:insertions};
insertions = { bottom: insertions };
var t = Element._insertionTranslations, content, position, pos, tagName;
@ -1056,7 +1056,7 @@ Element.extend = (function() {
for (property in methods) {
value = methods[property];
if (typeof value == 'function' && !(property in element))
if (Object.isFunction(value) && !(property in element))
element[property] = value.methodize();
}
@ -1118,7 +1118,7 @@ Element.addMethods = function(methods) {
onlyIfAbsent = onlyIfAbsent || false;
for (var property in methods) {
var value = methods[property];
if (typeof value != 'function') continue;
if (!Object.isFunction(value)) continue;
if (!onlyIfAbsent || !(property in destination))
destination[property] = value.methodize();
}
@ -1157,7 +1157,7 @@ Element.addMethods = function(methods) {
if (F.SpecificElementExtensions) {
for (var tag in Element.Methods.ByTag) {
var klass = findDOMClass(tag);
if (typeof klass == "undefined") continue;
if (Object.isUndefined(klass)) continue;
copy(T[tag], klass.prototype);
}
}
@ -1171,8 +1171,8 @@ Element.addMethods = function(methods) {
document.viewport = {
getDimensions: function() {
var dimensions = {};
$w('width height').each( function(d) {
var dimensions = { };
$w('width height').each(function(d) {
var D = d.capitalize();
dimensions[d] = self['inner' + D] ||
(document.documentElement['client' + D] || document.body['client' + D]);

View File

@ -1,4 +1,4 @@
var $break = {};
var $break = { };
var Enumerable = {
each: function(iterator, context) {
@ -77,7 +77,7 @@ var Enumerable = {
iterator = iterator ? iterator.bind(context) : Prototype.K;
var results = [];
if (typeof filter == "string")
if (Object.isString(filter))
filter = new RegExp(filter);
this.each(function(value, index) {
@ -88,7 +88,7 @@ var Enumerable = {
},
include: function(object) {
if (typeof this.indexOf == 'function')
if (Object.isFunction(this.indexOf))
return this.indexOf(object) != -1;
var found = false;
@ -190,7 +190,7 @@ var Enumerable = {
zip: function() {
var iterator = Prototype.K, args = $A(arguments);
if (typeof args.last() == 'function')
if (Object.isFunction(args.last()))
iterator = args.pop();
var collections = [this].concat(args).map($A);

View File

@ -220,7 +220,7 @@ Object.extend(Event, (function() {
}
event.eventName = eventName;
event.memo = memo || {};
event.memo = memo || { };
if (document.createEvent) {
element.dispatchEvent(event);

View File

@ -9,7 +9,7 @@ var Form = {
else if (options.hash === undefined) options.hash = true;
var key, value, submitted = false, submit = options.submit;
var data = elements.inject({}, function(result, element) {
var data = elements.inject({ }, function(result, element) {
if (!element.disabled && element.name) {
key = element.name; value = $(element).getValue();
if (value != null && (element.type != 'submit' || (!submitted &&
@ -92,14 +92,14 @@ Form.Methods = {
},
request: function(form, options) {
form = $(form), options = Object.clone(options || {});
form = $(form), options = Object.clone(options || { });
var params = options.parameters, action = form.readAttribute('action') || '';
if (action.blank()) action = window.location.href;
options.parameters = form.serialize(true);
if (params) {
if (typeof params == 'string') params = params.toQueryParams();
if (Object.isString(params)) params = params.toQueryParams();
Object.extend(options.parameters, params);
}
@ -130,7 +130,7 @@ Form.Element.Methods = {
if (!element.disabled && element.name) {
var value = element.getValue();
if (value != undefined) {
var pair = {};
var pair = { };
pair[element.name] = value;
return Hash.toQueryString(pair);
}
@ -167,7 +167,7 @@ Form.Element.Methods = {
if (element.select && (element.tagName.toLowerCase() != 'input' ||
!['button', 'reset', 'submit'].include(element.type)))
element.select();
} catch (e) {}
} catch (e) { }
return element;
},
@ -257,7 +257,7 @@ Form.Element.Serializers = {
/*--------------------------------------------------------------------------*/
Abstract.TimedObserver = function() {};
Abstract.TimedObserver = function() { };
Abstract.TimedObserver.prototype = {
initialize: function(element, frequency, callback) {
this.frequency = frequency;
@ -274,7 +274,7 @@ Abstract.TimedObserver.prototype = {
onTimerEvent: function() {
var value = this.getValue();
var changed = ('string' == typeof this.lastValue && 'string' == typeof value
var changed = (Object.isString(this.lastValue) && Object.isString(value)
? this.lastValue != value : String(this.lastValue) != String(value));
if (changed) {
this.callback(this.element, value);
@ -299,7 +299,7 @@ Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
/*--------------------------------------------------------------------------*/
Abstract.EventObserver = function() {};
Abstract.EventObserver = function() { };
Abstract.EventObserver.prototype = {
initialize: function(element, callback) {
this.element = $(element);

View File

@ -1,6 +1,6 @@
var Hash = function(object) {
if (object instanceof Hash) this.merge(object);
else Object.extend(this, object || {});
else Object.extend(this, object || { });
};
Object.extend(Hash, {

View File

@ -19,8 +19,10 @@ Selector.prototype = {
c = Selector.criteria, le, p, m;
if (Selector._cache[e]) {
this.matcher = Selector._cache[e]; return;
this.matcher = Selector._cache[e];
return;
}
this.matcher = ["this.matcher = function(root) {",
"var r = root, h = Selector.handlers, c = false, n;"];
@ -29,7 +31,7 @@ Selector.prototype = {
for (var i in ps) {
p = ps[i];
if (m = e.match(p)) {
this.matcher.push(typeof c[i] == 'function' ? c[i](m) :
this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
new Template(c[i]).evaluate(m));
e = e.replace(m[0], '');
break;
@ -55,7 +57,7 @@ Selector.prototype = {
le = e;
for (var i in ps) {
if (m = e.match(ps[i])) {
this.matcher.push(typeof x[i] == 'function' ? x[i](m) :
this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
new Template(x[i]).evaluate(m));
e = e.replace(m[0], '');
break;
@ -119,7 +121,7 @@ Selector.prototype = {
};
Object.extend(Selector, {
_cache: {},
_cache: { },
xpath: {
descendant: "//*",
@ -141,7 +143,7 @@ Object.extend(Selector, {
pseudo: function(m) {
var h = Selector.xpath.pseudos[m[1]];
if (!h) return '';
if (typeof h === 'function') return h(m);
if (Object.isFunction(h)) return h(m);
return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
},
operators: {
@ -170,7 +172,7 @@ Object.extend(Selector, {
le = e;
for (var i in p) {
if (m = e.match(p[i])) {
v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m);
v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
exclusion.push("(" + v.substring(1, v.length - 1) + ")");
e = e.replace(m[0], '');
break;
@ -604,7 +606,7 @@ Object.extend(Selector, {
},
findElement: function(elements, expression, index) {
if (typeof expression == 'number') {
if (Object.isNumber(expression)) {
index = expression; expression = false;
}
return Selector.matchElements(elements, expression || '*')[index || 0];

View File

@ -91,9 +91,9 @@ Object.extend(String.prototype, {
toQueryParams: function(separator) {
var match = this.strip().match(/([^?#]*)(#.*)?$/);
if (!match) return {};
if (!match) return { };
return match[1].split(separator || '&').inject({}, function(hash, pair) {
return match[1].split(separator || '&').inject({ }, function(hash, pair) {
if ((pair = pair.split('='))[0]) {
var key = decodeURIComponent(pair.shift());
var value = pair.length > 1 ? pair.join('=') : pair[0];
@ -216,7 +216,7 @@ if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.proto
});
String.prototype.gsub.prepareReplacement = function(replacement) {
if (typeof replacement == 'function') return replacement;
if (Object.isFunction(replacement)) return replacement;
var template = new Template(replacement);
return function(match) { return template.evaluate(match) };
};
@ -239,7 +239,7 @@ Template.prototype = {
},
evaluate: function(object) {
if (typeof object.toTemplateReplacements == 'function')
if (Object.isFunction(object.toTemplateReplacements))
object = object.toTemplateReplacements();
return this.template.gsub(this.pattern, function(match) {

View File

@ -241,6 +241,38 @@
assert(!Object.isFunction(undefined));
}},
testObjectIsString: function() { with(this) {
assert(!Object.isString(function() { }));
assert(Object.isString("a string"));
assert(!Object.isString(0));
assert(!Object.isString([]));
assert(!Object.isString({}));
assert(!Object.isString(false));
assert(!Object.isString(undefined));
}},
testObjectIsNumber: function() { with(this) {
assert(Object.isNumber(0));
assert(Object.isNumber(1.0));
assert(!Object.isNumber(function() { }));
assert(!Object.isNumber("a string"));
assert(!Object.isNumber([]));
assert(!Object.isNumber({}));
assert(!Object.isNumber(false));
assert(!Object.isNumber(undefined));
}},
testObjectIsUndefined: function() { with(this) {
assert(Object.isUndefined(undefined));
assert(!Object.isUndefined(null));
assert(!Object.isUndefined(false));
assert(!Object.isUndefined(0));
assert(!Object.isUndefined(""));
assert(!Object.isUndefined(function() { }));
assert(!Object.isUndefined([]));
assert(!Object.isUndefined({}));
}},
// sanity check
testDoesntExtendObjectPrototype: function() {with(this) {
// for-in is supported with objects