prototype: Refactor Element.extend and eliminate Element.extend.cache.
This commit is contained in:
parent
f457c98673
commit
67a4d00588
@ -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)
|
||||
|
@ -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)));
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
83
src/dom.js
83
src/dom.js
@ -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 };
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user