prototype: Refactor Element.extend and eliminate Element.extend.cache.

This commit is contained in:
Sam Stephenson 2007-05-12 04:32:30 +00:00
parent f457c98673
commit 67a4d00588
5 changed files with 65 additions and 41 deletions

View File

@ -1,5 +1,7 @@
*SVN*
* Refactor Element.extend and eliminate Element.extend.cache. [sam]
* Add Function#curry, Function#delay, Function#defer, and Function#wrap. Closes #8134. [Andrew Dupont, Tobie Langel, sam]
*1.5.1* (May 1, 2007)

View File

@ -100,6 +100,14 @@ Object.extend(Function.prototype, {
return function() {
return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
}
},
methodize: function() {
if (this._methodized) return this._methodized;
var __method = this;
return this._methodized = function() {
return __method.apply(null, [this].concat($A(arguments)));
};
}
});

View File

@ -39,42 +39,6 @@ if (Prototype.BrowserFeatures.XPath) {
if (!window.Element) var Element = {};
Element.extend = function(element) {
var F = Prototype.BrowserFeatures;
if (!element || !element.tagName || element.nodeType == 3 ||
element._extended || F.SpecificElementExtensions || element == window)
return element;
var methods = {}, tagName = element.tagName, cache = Element.extend.cache,
T = Element.Methods.ByTag;
// extend methods for all tags (Safari doesn't need this)
if (!F.ElementExtensions) {
Object.extend(methods, Element.Methods),
Object.extend(methods, Element.Methods.Simulated);
}
// extend methods for specific tags
if (T[tagName]) Object.extend(methods, T[tagName]);
for (var property in methods) {
var value = methods[property];
if (typeof value == 'function' && !(property in element))
element[property] = cache.findOrStore(value);
}
element._extended = Prototype.emptyFunction;
return element;
};
Element.extend.cache = {
findOrStore: function(value) {
return this[value] = this[value] || function() {
return value.apply(null, [this].concat($A(arguments)));
}
}
};
Element.Methods = {
visible: function(element) {
return $(element).style.display != 'none';
@ -572,8 +536,47 @@ Element.Methods.ByTag = {};
Object.extend(Element, Element.Methods);
Element.extend = (function() {
if (Prototype.BrowserFeatures.SpecificElementExtensions)
return Prototype.K;
var Methods = {}, ByTag = Element.Methods.ByTag;
var extend = Object.extend(function(element) {
if (!element || element._extendedByPrototype ||
element.nodeType != 1 || element == window) return element;
var methods = Object.clone(Methods),
tagName = element.tagName, property, value;
// extend methods for specific tags
if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
for (property in methods) {
value = methods[property];
if (typeof value == 'function' && !(property in element))
element[property] = value.methodize();
}
element._extendedByPrototype = Prototype.emptyFunction;
return element;
}, {
refresh: function() {
// extend methods for all tags (Safari doesn't need this)
if (!Prototype.BrowserFeatures.ElementExtensions) {
Object.extend(Methods, Element.Methods);
Object.extend(Methods, Element.Methods.Simulated);
}
}
});
extend.refresh();
return extend;
})();
if (!Prototype.BrowserFeatures.ElementExtensions &&
document.createElement('div').__proto__) {
document.createElement('div').__proto__) {
window.HTMLElement = {};
window.HTMLElement.prototype = document.createElement('div').__proto__;
Prototype.BrowserFeatures.ElementExtensions = true;
@ -618,11 +621,11 @@ Element.addMethods = function(methods) {
function copy(methods, destination, onlyIfAbsent) {
onlyIfAbsent = onlyIfAbsent || false;
var cache = Element.extend.cache;
for (var property in methods) {
var value = methods[property];
if (typeof value != 'function') continue;
if (!onlyIfAbsent || !(property in destination))
destination[property] = cache.findOrStore(value);
destination[property] = value.methodize();
}
}
@ -666,6 +669,8 @@ Element.addMethods = function(methods) {
Object.extend(Element, Element.Methods);
delete Element.ByTag;
if (Element.extend.refresh) Element.extend.refresh();
};
var Toggle = { display: Element.toggle };

View File

@ -135,6 +135,15 @@
assert(window.deferred);
});
}},
testFunctionMethodize: function() { with(this) {
var Foo = { bar: function(baz) { return baz } };
var baz = { quux: Foo.bar.methodize() };
assertEqual(Foo.bar.methodize(), baz.quux);
assertEqual(baz, Foo.bar(baz));
assertEqual(baz, baz.quux());
}},
testObjectInspect: function() { with(this) {
assertEqual('undefined', Object.inspect());

View File

@ -345,8 +345,8 @@
Element.addMethods('INPUT', { anInputMethod: function(input) { return 'input' } });
Element.addMethods('SELECT', { aSelectMethod: function(select) { return 'select' } });
document.getElementById('tf_text')._extended = false;
document.getElementById('tf_selectOne')._extended = false;
document.getElementById('tf_text')._extendedByPrototype = false;
document.getElementById('tf_selectOne')._extendedByPrototype = false;
assert($('tf_text').anInputMethod);
assert(!$('tf_text').aSelectMethod);