prototype: Add Function#curry, Function#delay, Function#defer, and Function#wrap. Closes #8134.

This commit is contained in:
Sam Stephenson 2007-04-29 05:37:07 +00:00
parent e9e1a67475
commit 562e61fc8c
6 changed files with 100 additions and 23 deletions

View File

@ -1,5 +1,7 @@
*SVN*
* Add Function#curry, Function#delay, Function#defer, and Function#wrap. Closes #8134. [Andrew Dupont, Tobie Langel, sam]
*1.5.1* (it is a mystery)
*1.5.1_rc4* (April 27, 2007)

View File

@ -107,8 +107,7 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
this.transport.open(this.method.toUpperCase(), this.url,
this.options.asynchronous);
if (this.options.asynchronous)
setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
this.transport.onreadystatechange = this.onStateChange.bind(this);
this.setRequestHeaders();
@ -267,8 +266,7 @@ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
}
if (this.success()) {
if (this.onComplete)
setTimeout(this.onComplete.bind(this), 10);
if (this.onComplete) this.onComplete.bind(this).defer();
}
}
});
@ -307,8 +305,7 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
this.lastText = request.responseText;
}
this.timer = setTimeout(this.onTimerEvent.bind(this),
this.decay * this.frequency * 1000);
this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
},
onTimerEvent: function() {

View File

@ -1,4 +1,4 @@
var $A = Array.from = function(iterable) {
function $A(iterable) {
if (!iterable) return [];
if (iterable.toArray) {
return iterable.toArray();
@ -11,7 +11,7 @@ var $A = Array.from = function(iterable) {
}
if (Prototype.Browser.WebKit) {
$A = Array.from = function(iterable) {
function $A(iterable) {
if (!iterable) return [];
if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
iterable.toArray) {
@ -25,6 +25,8 @@ if (Prototype.Browser.WebKit) {
}
}
Array.from = $A;
Object.extend(Array.prototype, Enumerable);
if (!Array.prototype._reverse)

View File

@ -66,19 +66,44 @@ Object.extend(Object, {
}
});
Function.prototype.bind = function() {
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
}
Object.extend(Function.prototype, {
bind: function() {
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
},
bindAsEventListener: function() {
var __method = this, args = $A(arguments), object = args.shift();
return function(event) {
return __method.apply(object, [(event || window.event)].concat(args).concat($A(arguments)));
}
},
curry: function() {
var __method = this, args = $A(arguments);
return function() {
return __method.apply(this, args.concat($A(arguments)));
}
},
Function.prototype.bindAsEventListener = function(object) {
var __method = this, args = $A(arguments), object = args.shift();
return function(event) {
return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
delay: function() {
var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
return window.setTimeout(function() {
return __method.apply(__method, args);
}, timeout);
},
wrap: function(wrapper) {
var __method = this;
return function() {
return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
}
}
}
});
Function.prototype.defer = Function.prototype.delay.curry(0.01);
Object.extend(Number.prototype, {
toColorPart: function() {

View File

@ -105,7 +105,7 @@ Element.Methods = {
update: function(element, html) {
html = typeof html == 'undefined' ? '' : html.toString();
$(element).innerHTML = html.stripScripts();
setTimeout(function() {html.evalScripts()}, 10);
html.evalScripts.bind(html).defer();
return element;
},
@ -120,7 +120,7 @@ Element.Methods = {
element.parentNode.replaceChild(
range.createContextualFragment(html.stripScripts()), element);
}
setTimeout(function() {html.evalScripts()}, 10);
html.evalScripts.bind(html).defer();
return element;
},
@ -504,7 +504,7 @@ else if (Prototype.Browser.IE) {
} else {
element.innerHTML = html.stripScripts();
}
setTimeout(function() { html.evalScripts() }, 10);
html.evalScripts.bind(html).defer();
return element;
}
}
@ -698,7 +698,7 @@ Abstract.Insertion.prototype = {
this.insertContent([this.range.createContextualFragment(this.content)]);
}
setTimeout(function() {content.evalScripts()}, 10);
content.evalScripts.bind(content).defer();
},
contentFromAnonymousTable: function() {

View File

@ -85,6 +85,57 @@
assertEqual('withBindArgsAndArgs,arg1,arg2,arg3,arg4', globalBindTest);
}},
testFunctionCurry: function() { with(this) {
var split = function(delimiter, string) { return string.split(delimiter); };
var splitOnColons = split.curry(":");
assertEnumEqual(split(":", "0:1:2:3:4:5"), splitOnColons("0:1:2:3:4:5"));
}},
testFunctionDelay: function() { with(this) {
window.delayed = undefined;
var delayedFunction = function() { window.delayed = true; };
var delayedFunctionWithArgs = function() { window.delayedWithArgs = $A(arguments).join(' '); };
delayedFunction.delay(0.8);
delayedFunctionWithArgs.delay(0.8, 'hello', 'world');
assertUndefined(window.delayed);
wait(1000, function() {
assert(window.delayed);
assertEqual('hello world', window.delayedWithArgs);
});
}},
testFunctionWrap: function() { with(this) {
function sayHello(){
return 'hello world';
};
assertEqual('HELLO WORLD', sayHello.wrap(function(proceed) {
return proceed().toUpperCase();
})());
var temp = String.prototype.capitalize;
String.prototype.capitalize = String.prototype.capitalize.wrap(function(proceed, eachWord) {
if(eachWord && this.include(' ')) return this.split(' ').map(function(str){
return str.capitalize();
}).join(' ');
return proceed();
});
assertEqual('Hello world', 'hello world'.capitalize());
assertEqual('Hello World', 'hello world'.capitalize(true));
assertEqual('Hello', 'hello'.capitalize());
String.prototype.capitalize = temp;
}},
testFunctionDefer: function() { with(this) {
window.deferred = undefined;
var deferredFunction = function() { window.deferred = true; };
deferredFunction.defer();
assertUndefined(window.deferred);
wait(50, function() {
assert(window.deferred);
});
}},
testObjectInspect: function() { with(this) {
assertEqual('undefined', Object.inspect());
assertEqual('undefined', Object.inspect(undefined));