Merge branch 'master' of git@github.com:sstephenson/prototype
This commit is contained in:
commit
4dedcd3b62
@ -8,7 +8,7 @@
|
||||
*
|
||||
* Actual requests are made by creating instances of [[Ajax.Request]].
|
||||
*
|
||||
* <h4>Request headers</h4>
|
||||
* <h5>Request headers</h5>
|
||||
*
|
||||
* The following headers are sent with all Ajax requests (and can be
|
||||
* overridden with the `requestHeaders` option described below):
|
||||
@ -21,7 +21,7 @@
|
||||
* * `Content-type` is automatically determined based on the `contentType`
|
||||
* and `encoding` options.
|
||||
*
|
||||
* <h4>Ajax options</h4>
|
||||
* <h5>Ajax options</h5>
|
||||
*
|
||||
* All Ajax classes share a common set of _options_ and _callbacks_.
|
||||
* Callbacks are called at various points in the life-cycle of a request, and
|
||||
@ -64,7 +64,7 @@
|
||||
* `true` otherwise): Sanitizes the contents of
|
||||
* [[Ajax.Response#responseText]] before evaluating it.
|
||||
*
|
||||
* <h4>Common callbacks</h4>
|
||||
* <h5>Common callbacks</h5>
|
||||
*
|
||||
* When used on individual instances, all callbacks (except `onException`) are
|
||||
* invoked with two parameters: the `XMLHttpRequest` object and the result of
|
||||
|
@ -16,7 +16,7 @@
|
||||
* keeping track of the response text so it can (optionally) react to
|
||||
* receiving the exact same response consecutively.
|
||||
*
|
||||
* <h4>Additional options</h4>
|
||||
* <h5>Additional options</h5>
|
||||
*
|
||||
* `Ajax.PeriodicalUpdater` features all the common options and callbacks
|
||||
* described in the [[Ajax section]] — _plus_ those added by `Ajax.Updater`.
|
||||
@ -34,7 +34,7 @@
|
||||
* is the same; when the result is different once again, `frequency` will
|
||||
* revert to its original value.
|
||||
*
|
||||
* <h4>Disabling and re-enabling a <code>PeriodicalUpdater</code></h4>
|
||||
* <h5>Disabling and re-enabling a <code>PeriodicalUpdater</code></h5>
|
||||
*
|
||||
* You can hit the brakes on a running `PeriodicalUpdater` by calling
|
||||
* [[Ajax.PeriodicalUpdater#stop]]. If you wish to re-enable it later, call
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* `Ajax.Request` is a general-purpose class for making HTTP requests.
|
||||
*
|
||||
* <h4>Automatic JavaScript response evaluation</h4>
|
||||
* <h5>Automatic JavaScript response evaluation</h5>
|
||||
*
|
||||
* If an Ajax request follows the _same-origin policy_ **and** its response
|
||||
* has a JavaScript-related `Content-type`, the content of the `responseText`
|
||||
@ -28,7 +28,7 @@
|
||||
*
|
||||
* The MIME-type string is examined in a case-insensitive manner.
|
||||
*
|
||||
* <h4>Methods you may find useful</h4>
|
||||
* <h5>Methods you may find useful</h5>
|
||||
*
|
||||
* Instances of the `Request` object provide several methods that can come in
|
||||
* handy in your callback functions, especially once the request is complete.
|
||||
|
@ -34,7 +34,7 @@
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* <h4>Responder callbacks</h4>
|
||||
* <h5>Responder callbacks</h5>
|
||||
*
|
||||
* The callbacks for responders are similar to the callbacks described in
|
||||
* the [[Ajax section]], but take a different signature. They're invoked with
|
||||
|
@ -7,7 +7,7 @@
|
||||
* `Ajax.Updater` is a subclass of [[Ajax.Request]] built for a common
|
||||
* use-case.
|
||||
*
|
||||
* <h4>Example</h4>
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* new Ajax.Updater('items', '/items', {
|
||||
* parameters: { text: $F('text') }
|
||||
@ -17,13 +17,13 @@
|
||||
* parameters); it will then replace the contents of the element with the ID
|
||||
* of `items` with whatever response it receives.
|
||||
*
|
||||
* <h4>Callbacks</h4>
|
||||
* <h5>Callbacks</h5>
|
||||
*
|
||||
* `Ajax.Updater` supports all the callbacks listed in the [[Ajax section]].
|
||||
* Note that the `onComplete` callback will be invoked **after** the element
|
||||
* is updated.
|
||||
*
|
||||
* <h4>Additional options</h4>
|
||||
* <h5>Additional options</h5>
|
||||
*
|
||||
* `Ajax.Updater` has some options of its own apart from the common options
|
||||
* described in the [[Ajax section]]:
|
||||
@ -37,7 +37,7 @@
|
||||
* `top`, `bottom`, `before`, or `after` — and _inserts_ the contents of the
|
||||
* response in the manner described by [[Element#insert]].
|
||||
*
|
||||
* <h4>More About `evalScripts`</h4>
|
||||
* <h5>More About `evalScripts`</h5>
|
||||
*
|
||||
* If you use `evalScripts: true`, any _inline_ `<script>` block will be evaluated.
|
||||
* This **does not** mean it will be evaluated in the global scope; it won't, and that
|
||||
@ -45,7 +45,7 @@
|
||||
* that only inline `<script>` blocks are supported; external scripts are ignored.
|
||||
* See [[String#evalScripts]] for the details.
|
||||
*
|
||||
* <h4>Single container, or success/failure split?</h4>
|
||||
* <h5>Single container, or success/failure split?</h5>
|
||||
*
|
||||
* The examples above all assume you're going to update the same container
|
||||
* whether your request succeeds or fails. Instead, you may want to update
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* The namespace for Prototype's event system.
|
||||
*
|
||||
* <h4>Events: a fine mess</h4>
|
||||
* <h5>Events: a fine mess</h5>
|
||||
*
|
||||
* Event management is one of the really sore spots of cross-browser
|
||||
* scripting.
|
||||
@ -17,7 +17,7 @@
|
||||
* Safari). Also, MSIE has a tendency to leak memory when it comes to
|
||||
* discarding event handlers.
|
||||
*
|
||||
* <h4>Prototype to the rescue</h4>
|
||||
* <h5>Prototype to the rescue</h5>
|
||||
*
|
||||
* Of course, Prototype smooths it over so well you'll forget these
|
||||
* troubles even exist. Enter the `Event` namespace. It is replete with
|
||||
|
@ -490,7 +490,7 @@ Form.Element.Serializers = {
|
||||
* [[Form.Observer]], which serializes a form and triggers when the result has changed; and
|
||||
* [[Form.Element.Observer]], which triggers when the value of a given form field changes.
|
||||
*
|
||||
* <h4>Creating Your Own TimedObserver Implementations</h4>
|
||||
* <h5>Creating Your Own TimedObserver Implementations</h5>
|
||||
*
|
||||
* It's easy to create your own `TimedObserver` implementations: Simply subclass `TimedObserver`
|
||||
* and provide the `getValue()` method. For example, this is the complete source code for
|
||||
|
@ -52,7 +52,7 @@ Array.from = $A;
|
||||
* their `[]` indexing operator. They become very powerful objects that
|
||||
* greatly simplify the code for 99% of the common use cases involving them.
|
||||
*
|
||||
* <h4>Why you should stop using for...in to iterate</h4>
|
||||
* <h5>Why you should stop using for...in to iterate</h5>
|
||||
*
|
||||
* Many JavaScript authors have been misled into using the `for...in` JavaScript
|
||||
* construct to loop over array elements. This kind of code just won't work
|
||||
@ -77,7 +77,7 @@ Array.from = $A;
|
||||
* those coming from the [[Enumerable]] module, and those Prototype puts in the
|
||||
* Array namespace (listed further below).
|
||||
*
|
||||
* <h4>What you should use instead</h4>
|
||||
* <h5>What you should use instead</h5>
|
||||
*
|
||||
* You can revert to vanilla loops:
|
||||
*
|
||||
@ -99,7 +99,7 @@ Array.from = $A;
|
||||
* module. So manual loops should be fairly rare.
|
||||
*
|
||||
*
|
||||
* <h4>A note on performance</h4>
|
||||
* <h5>A note on performance</h5>
|
||||
*
|
||||
* Should you have a very large array, using iterators with lexical closures
|
||||
* (anonymous functions that you pass to the iterators and that get invoked at
|
||||
@ -134,7 +134,7 @@ Array.from = $A;
|
||||
*
|
||||
* Clears the array (makes it empty) and returns the array reference.
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var guys = ['Sam', 'Justin', 'Andrew', 'Dan'];
|
||||
* guys.clear();
|
||||
@ -170,7 +170,7 @@ Array.from = $A;
|
||||
*
|
||||
* Returns a **copy** of the array without any `null` or `undefined` values.
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var orig = [undefined, 'A', undefined, 'B', null, 'C'];
|
||||
* var copy = orig.compact();
|
||||
@ -193,7 +193,7 @@ Array.from = $A;
|
||||
* useful when handling the results of a recursive collection algorithm,
|
||||
* for instance.
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var a = ['frank', ['bob', 'lisa'], ['jill', ['tom', 'sally']]];
|
||||
* var b = a.flatten();
|
||||
@ -216,7 +216,7 @@ Array.from = $A;
|
||||
* Produces a new version of the array that does not contain any of the
|
||||
* specified values, leaving the original array unchanged.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* [3, 5, 6].without(3)
|
||||
* // -> [5, 6]
|
||||
@ -238,7 +238,7 @@ Array.from = $A;
|
||||
*
|
||||
* Reverses the array's contents, optionally cloning it first.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* // Making a copy
|
||||
* var nums = [3, 5, 6, 1, 20];
|
||||
@ -266,7 +266,7 @@ Array.from = $A;
|
||||
* On large arrays when `sorted` is `false`, this method has a potentially
|
||||
* large performance cost.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* [1, 3, 2, 1].uniq();
|
||||
* // -> [1, 2, 3]
|
||||
@ -325,7 +325,7 @@ Array.from = $A;
|
||||
*
|
||||
* Returns the debug-oriented string representation of an array.
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* ['Apples', {good: 'yes', bad: 'no'}, 3, 34].inspect()
|
||||
* // -> "['Apples', [object Object], 3, 34]"
|
||||
@ -339,7 +339,7 @@ Array.from = $A;
|
||||
*
|
||||
* Returns a JSON string representation of the array.
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* ['a', {b: null}].toJSON();
|
||||
* //-> '["a", {"b": null}]'
|
||||
@ -363,7 +363,7 @@ Array.from = $A;
|
||||
* or `-1` if `item` doesn't exist in the array. `Array#indexOf` compares
|
||||
* items using *strict equality* (`===`).
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* [3, 5, 6, 1, 20].indexOf(1)
|
||||
* // -> 3
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Produces a string representation of the date in ISO 8601 format.
|
||||
* The time zone is always UTC, as denoted by the suffix "Z".
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var d = new Date(1969, 11, 31, 19);
|
||||
* d.getTimezoneOffset();
|
||||
|
@ -12,7 +12,7 @@
|
||||
* are [[Array]] and [[Hash]], but you'll find it in less obvious spots as
|
||||
* well, such as in [[ObjectRange]] and various DOM- or Ajax-related objects.
|
||||
*
|
||||
* <h4>The <code>context</code> parameter</h4>
|
||||
* <h5>The <code>context</code> parameter</h5>
|
||||
*
|
||||
* Every method of `Enumerable` that takes an iterator also takes the "context
|
||||
* object" as the next (optional) parameter. The context object is what the
|
||||
@ -31,7 +31,7 @@
|
||||
* If there is no `context` argument, the iterator function will execute in
|
||||
* the scope from which the `Enumerable` method itself was called.
|
||||
*
|
||||
* <h4>Mixing <code>Enumerable</code> into your own objects</h4>
|
||||
* <h5>Mixing <code>Enumerable</code> into your own objects</h5>
|
||||
*
|
||||
* So, let's say you've created your very own collection-like object (say,
|
||||
* some sort of Set, or perhaps something that dynamically fetches data
|
||||
@ -93,12 +93,12 @@ var Enumerable = (function() {
|
||||
*
|
||||
* Calls `iterator` for each item in the collection.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* ['one', 'two', 'three'].each(alert);
|
||||
* // Alerts "one", then alerts "two", then alerts "three"
|
||||
*
|
||||
* ### Built-In Variants
|
||||
* <h5>Built-In Variants</h5>
|
||||
*
|
||||
* Most of the common use cases for `each` are already available pre-coded
|
||||
* as other methods on `Enumerable`. Whether you want to find the first
|
||||
@ -131,7 +131,7 @@ var Enumerable = (function() {
|
||||
* fewer than `number` items; it won't "pad" the last group with empty
|
||||
* values. For that behavior, use [[Enumerable#inGroupsOf]].
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var students = [
|
||||
* { name: 'Sunny', age: 20 },
|
||||
@ -168,7 +168,7 @@ var Enumerable = (function() {
|
||||
* is boolean-equivalent to `false`, such as `undefined`, `0`, or indeed
|
||||
* `false`);
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* [].all();
|
||||
* // -> true (empty arrays have no elements that could be falsy)
|
||||
@ -203,7 +203,7 @@ var Enumerable = (function() {
|
||||
* Determines whether at least one element is truthy (boolean-equivalent to
|
||||
* `true`), either directly or through computation by the provided iterator.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* [].any();
|
||||
* // -> false (empty arrays have no elements that could be truthy)
|
||||
@ -235,7 +235,7 @@ var Enumerable = (function() {
|
||||
* `iterator` is provided, the elements are simply copied to the
|
||||
* returned array.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* ['Hitch', "Hiker's", 'Guide', 'to', 'the', 'Galaxy'].collect(function(s) {
|
||||
* return s.charAt(0).toUpperCase();
|
||||
@ -266,7 +266,7 @@ var Enumerable = (function() {
|
||||
* Returns the first element for which the iterator returns a truthy value.
|
||||
* Aliased by the [[Enumerable#find]] method.
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* [1, 7, -2, -4, 5].detect(function(n) { return n < 0; });
|
||||
* // -> -2
|
||||
@ -291,7 +291,7 @@ var Enumerable = (function() {
|
||||
* Returns all the elements for which the iterator returned a truthy value.
|
||||
* For the opposite operation, see [[Enumerable#reject]].
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* [1, 'two', 3, 'four', 5].findAll(Object.isString);
|
||||
* // -> ['two', 'four']
|
||||
@ -326,7 +326,7 @@ var Enumerable = (function() {
|
||||
* or a falsy value not to. Note that the `RegExp` `match` function will
|
||||
* convert elements to Strings to perform matching.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* // Get all strings containing a repeated letter
|
||||
* ['hello', 'world', 'this', 'is', 'cool'].grep(/(.)\1/);
|
||||
@ -358,7 +358,7 @@ var Enumerable = (function() {
|
||||
* based on the `==` comparison operator (equality with implicit type
|
||||
* conversion).
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* $R(1, 15).include(10);
|
||||
* // -> true
|
||||
@ -392,7 +392,7 @@ var Enumerable = (function() {
|
||||
* Like [[Enumerable#eachSlice]], but pads out the last chunk with the
|
||||
* specified value if necessary and doesn't support the `iterator` function.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* var students = [
|
||||
* { name: 'Sunny', age: 20 },
|
||||
@ -434,7 +434,7 @@ var Enumerable = (function() {
|
||||
* argument, the element as its second argument, and the element's index as
|
||||
* its third. It returns the new value for the accumulator.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* $R(1,10).inject(0, function(acc, n) { return acc + n; });
|
||||
* // -> 55 (sum of 1 to 10)
|
||||
@ -462,7 +462,7 @@ var Enumerable = (function() {
|
||||
* Invokes the same method, with the same arguments, for all items in a
|
||||
* collection. Returns an array of the results of the method calls.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* ['hello', 'world'].invoke('toUpperCase');
|
||||
* // -> ['HELLO', 'WORLD']
|
||||
@ -499,7 +499,7 @@ var Enumerable = (function() {
|
||||
* evaluated, and its index in the enumeration; it should return the value
|
||||
* `max` should consider (and potentially return).
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* ['c', 'b', 'a'].max();
|
||||
* // -> 'c'
|
||||
@ -539,7 +539,7 @@ var Enumerable = (function() {
|
||||
* evaluated, and its index in the enumeration; it should return the value
|
||||
* `min` should consider (and potentially return).
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* ['c', 'b', 'a'].min();
|
||||
* // -> 'a'
|
||||
@ -578,7 +578,7 @@ var Enumerable = (function() {
|
||||
* then using [[Enumerable#reject]] because the enumeration is only processed
|
||||
* once.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* ['hello', null, 42, false, true, , 17].partition();
|
||||
* // -> [['hello', 42, true, 17], [null, false, undefined]]
|
||||
@ -606,7 +606,7 @@ var Enumerable = (function() {
|
||||
* and [[Enumerable#each]]: fetching the same property for all of the
|
||||
* elements. Returns an array of the property values.
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* ['hello', 'world', 'this', 'is', 'nice'].pluck('length');
|
||||
* // -> [5, 5, 4, 2, 4]
|
||||
@ -628,7 +628,7 @@ var Enumerable = (function() {
|
||||
* Returns all the elements for which the iterator returns a falsy value.
|
||||
* For the opposite operation, see [[Enumerable#findAll]].
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* [1, "two", 3, "four", 5].reject(Object.isString);
|
||||
* // -> [1, 3, 5]
|
||||
@ -657,7 +657,7 @@ var Enumerable = (function() {
|
||||
* `sortBy` does not guarantee a *stable* sort; adjacent equivalent elements
|
||||
* may be swapped.
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* ['hello', 'world', 'this', 'is', 'nice'].sortBy(function(s) {
|
||||
* return s.length;
|
||||
@ -681,7 +681,7 @@ var Enumerable = (function() {
|
||||
*
|
||||
* Returns an Array containing the elements of the enumeration.
|
||||
*
|
||||
* ### Example
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* $R(1, 5).toArray();
|
||||
* // -> [1, 2, 3, 4, 5]
|
||||
@ -708,7 +708,7 @@ var Enumerable = (function() {
|
||||
* If supplied, `iterator` is called with each tuple as its only argument
|
||||
* and should return the value to use in place of that tuple.
|
||||
*
|
||||
* ### Examples
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* var firstNames = ['Jane', 'Nitin', 'Guy'];
|
||||
* var lastNames = ['Doe', 'Patel', 'Forcier'];
|
||||
|
@ -23,6 +23,17 @@ Object.extend(Function.prototype, (function() {
|
||||
* Reads the argument names as stated in the function definition and returns
|
||||
* the values as an array of strings (or an empty array if the function is
|
||||
* defined without parameters).
|
||||
*
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* function fn(foo, bar) {
|
||||
* return foo + bar;
|
||||
* }
|
||||
* fn.argumentNames();
|
||||
* //-> ['foo', 'bar']
|
||||
*
|
||||
* Prototype.emptyFunction.argumentNames();
|
||||
* //-> []
|
||||
**/
|
||||
function argumentNames() {
|
||||
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
|
||||
@ -31,12 +42,68 @@ Object.extend(Function.prototype, (function() {
|
||||
return names.length == 1 && !names[0] ? [] : names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function#bind(object[, args...]) -> Function
|
||||
* - object (Object): The object to bind to.
|
||||
/** related to: Function#bindAsEventListener
|
||||
* Function#bind(context[, args...]) -> Function
|
||||
* - context (Object): The object to bind to.
|
||||
* - args (?): Optional additional arguments to curry for the function.
|
||||
*
|
||||
* Wraps the function in another, locking its execution scope to an object
|
||||
* specified by `object`.
|
||||
* Binds this function to the given `context` by wrapping it in another
|
||||
* function and returning the wrapper. Whenever the resulting "bound"
|
||||
* function is called, it will call the original ensuring that `this` is set
|
||||
* to `context`. Also optionally curries arguments for the function.
|
||||
*
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* A typical use of `Function#bind` is to ensure that a callback (event
|
||||
* handler, etc.) that is an object method gets called with the correct
|
||||
* object as its context (`this` value):
|
||||
*
|
||||
* var AlertOnClick = Class.create({
|
||||
* initialize: function(msg) {
|
||||
* this.msg = msg;
|
||||
* },
|
||||
* handleClick: function(event) {
|
||||
* event.stop();
|
||||
* alert(this.msg);
|
||||
* }
|
||||
* });
|
||||
* var myalert = new AlertOnClick("Clicked!");
|
||||
* $('foo').observe('click', myalert.handleClick); // <= WRONG
|
||||
* // -> If 'foo' is clicked, the alert will be blank; "this" is wrong
|
||||
* $('bar').observe('click', myalert.handleClick.bind(myalert)); // <= RIGHT
|
||||
* // -> If 'bar' is clicked, the alert will be "Clicked!"
|
||||
*
|
||||
* `bind` can also *curry* (burn in) arguments for the function if you
|
||||
* provide them after the `context` argument:
|
||||
*
|
||||
* var Averager = Class.create({
|
||||
* initialize: function() {
|
||||
* this.count = 0;
|
||||
* this.total = 0;
|
||||
* },
|
||||
* add: function(addend) {
|
||||
* ++this.count;
|
||||
* this.total += addend;
|
||||
* },
|
||||
* getAverage: function() {
|
||||
* return this.count == 0 ? NaN : this.total / this.count;
|
||||
* }
|
||||
* });
|
||||
* var a = new Averager();
|
||||
* var b = new Averager();
|
||||
* var aAdd5 = a.add.bind(a, 5); // Bind to a, curry 5
|
||||
* var aAdd10 = a.add.bind(a, 10); // Bind to a, curry 10
|
||||
* var bAdd20 = b.add.bind(b, 20); // Bind to b, curry 20
|
||||
* aAdd5();
|
||||
* aAdd10();
|
||||
* bAdd20();
|
||||
* bAdd20();
|
||||
* alert(a.getAverage());
|
||||
* // -> Alerts "7.5" (average of [5, 10])
|
||||
* alert(b.getAverage());
|
||||
* // -> Alerts "20" (average of [20, 20])
|
||||
*
|
||||
* (To curry without binding, see [[Function#curry]].)
|
||||
**/
|
||||
function bind(context) {
|
||||
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
|
||||
@ -48,12 +115,59 @@ Object.extend(Function.prototype, (function() {
|
||||
}
|
||||
|
||||
/** related to: Function#bind
|
||||
* Function#bindAsEventListener(object[, args...]) -> Function
|
||||
* - object (Object): The object to bind to.
|
||||
* Function#bindAsEventListener(context[, args...]) -> Function
|
||||
* - context (Object): The object to bind to.
|
||||
* - args (?): Optional arguments to curry after the event argument.
|
||||
*
|
||||
* An event-specific variant of [[Function#bind]] which ensures the function
|
||||
* will recieve the current event object as the first argument when
|
||||
* executing.
|
||||
*
|
||||
* It is not necessary to use `bindAsEventListener` for all bound event
|
||||
* handlers; [[Function#bind]] works well for the vast majority of cases.
|
||||
* `bindAsEventListener` is only needed when:
|
||||
*
|
||||
* - Using old-style DOM0 handlers rather than handlers hooked up via
|
||||
* [[Event.observe]], because `bindAsEventListener` gets the event object
|
||||
* from the right place (even on MSIE). (If you're using `Event.observe`,
|
||||
* that's already handled.)
|
||||
* - You want to bind an event handler and curry additional arguments but
|
||||
* have those arguments appear after, rather than before, the event object.
|
||||
* This mostly happens if the number of arguments will vary, and so you
|
||||
* want to know the event object is the first argument.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var ContentUpdater = Class.create({
|
||||
* initialize: function(initialData) {
|
||||
* this.data = Object.extend({}, initialData);
|
||||
* },
|
||||
* // On an event, update the content in the elements whose
|
||||
* // IDs are passed as arguments from our data
|
||||
* updateTheseHandler: function(event) {
|
||||
* var argIndex, id, element;
|
||||
* event.stop();
|
||||
* for (argIndex = 1; argIndex < arguments.length; ++argIndex) {
|
||||
* id = arguments[argIndex];
|
||||
* element = $(id);
|
||||
* if (element) {
|
||||
* element.update(String(this.data[id]).escapeHTML());
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
* var cu = new ContentUpdater({
|
||||
* dispName: 'Joe Bloggs',
|
||||
* dispTitle: 'Manager <provisional>',
|
||||
* dispAge: 47
|
||||
* });
|
||||
* // Using bindAsEventListener because of the variable arg lists:
|
||||
* $('btnUpdateName').observe('click',
|
||||
* cu.updateTheseHandler.bindAsEventListener(cu, 'dispName')
|
||||
* );
|
||||
* $('btnUpdateAll').observe('click',
|
||||
* cu.updateTheseHandler.bindAsEventListener(cu, 'dispName', 'dispTitle', 'dispAge')
|
||||
* );
|
||||
**/
|
||||
function bindAsEventListener(context) {
|
||||
var __method = this, args = slice.call(arguments, 1);
|
||||
@ -65,12 +179,27 @@ Object.extend(Function.prototype, (function() {
|
||||
|
||||
/**
|
||||
* Function#curry(args...) -> Function
|
||||
* Partially applies the function, returning a function with one or more
|
||||
* arguments already "filled in."
|
||||
* - args (?): The arguments to curry.
|
||||
*
|
||||
* Function#curry works just like [[Function#bind]] without the initial
|
||||
* scope argument. Use the latter if you need to partially apply a function
|
||||
* _and_ modify its execution scope at the same time.
|
||||
* *Curries* (burns in) arguments to a function, returning a new function
|
||||
* that when called with call the original passing in the curried arguments
|
||||
* (along with any new ones):
|
||||
*
|
||||
* function showArguments() {
|
||||
* alert($A(arguments).join(', '));
|
||||
* }
|
||||
* showArguments(1, 2,, 3);
|
||||
* // -> alerts "1, 2, 3"
|
||||
*
|
||||
* var f = showArguments.curry(1, 2, 3);
|
||||
* f('a', 'b');
|
||||
* // -> alerts "1, 2, 3, a, b"
|
||||
*
|
||||
* `Function#curry` works just like [[Function#bind]] without the initial
|
||||
* context argument. Use `bind` if you need to curry arguments _and_ set
|
||||
* context at the same time.
|
||||
*
|
||||
* The name "curry" comes from [mathematics](http://en.wikipedia.org/wiki/Currying).
|
||||
**/
|
||||
function curry() {
|
||||
if (!arguments.length) return this;
|
||||
@ -82,21 +211,32 @@ Object.extend(Function.prototype, (function() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Function#delay(seconds[, args...]) -> Number
|
||||
* - seconds (Number): How long to wait before calling the function.
|
||||
* Function#delay(timeout[, args...]) -> Number
|
||||
* - timeout (Number): The time, in seconds, to wait before calling the
|
||||
* function.
|
||||
* - args (?): Optional arguments to pass to the function when calling it.
|
||||
*
|
||||
* Schedules the function to run after the specified amount of time, passing
|
||||
* any arguments given.
|
||||
*
|
||||
* Behaves much like `window.setTimeout`. Returns an integer ID that can be
|
||||
* used to clear the timeout with `window.clearTimeout` before it runs.
|
||||
* Behaves much like `window.setTimeout`, but the timeout is in seconds
|
||||
* rather than milliseconds. Returns an integer ID that can be used to
|
||||
* clear the timeout with `window.clearTimeout` before it runs.
|
||||
*
|
||||
* To schedule a function to run as soon as the interpreter is idle, use
|
||||
* [[Function#defer]].
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* function showMsg(msg) {
|
||||
* alert(msg);
|
||||
* }
|
||||
* showMsg.delay(0.1, "Hi there!");
|
||||
* // -> Waits a 10th of a second, then alerts "Hi there!"
|
||||
**/
|
||||
function delay(timeout) {
|
||||
var __method = this, args = slice.call(arguments, 1);
|
||||
timeout = timeout * 1000
|
||||
timeout = timeout * 1000;
|
||||
return window.setTimeout(function() {
|
||||
return __method.apply(__method, args);
|
||||
}, timeout);
|
||||
@ -104,6 +244,8 @@ Object.extend(Function.prototype, (function() {
|
||||
|
||||
/**
|
||||
* Function#defer(args...) -> Number
|
||||
* - args (?): Optional arguments to pass into the function.
|
||||
*
|
||||
* Schedules the function to run as soon as the interpreter is idle.
|
||||
*
|
||||
* A "deferred" function will not run immediately; rather, it will run as soon
|
||||
@ -112,6 +254,18 @@ Object.extend(Function.prototype, (function() {
|
||||
* Behaves much like `window.setTimeout` with a delay set to `0`. Returns an
|
||||
* ID that can be used to clear the timeout with `window.clearTimeout` before
|
||||
* it runs.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* function showMsg(msg) {
|
||||
* alert(msg);
|
||||
* }
|
||||
*
|
||||
* showMsg("One");
|
||||
* showMsg.defer("Two");
|
||||
* showMsg("Three");
|
||||
* // Alerts "One", then "Three", then (after a brief pause) "Two"
|
||||
* // Note that "Three" happens before "Two"
|
||||
**/
|
||||
function defer() {
|
||||
var args = update([0.01], arguments);
|
||||
@ -119,8 +273,8 @@ Object.extend(Function.prototype, (function() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Function#wrap(wrapperFunction) -> Function
|
||||
* - wrapperFunction (Function): The function to act as a wrapper.
|
||||
* Function#wrap(wrapper) -> Function
|
||||
* - wrapper (Function): The function to use as a wrapper.
|
||||
*
|
||||
* Returns a function "wrapped" around the original function.
|
||||
*
|
||||
@ -128,6 +282,35 @@ Object.extend(Function.prototype, (function() {
|
||||
* a single method, letting you easily build on existing functions by
|
||||
* specifying before and after behavior, transforming the return value, or
|
||||
* even preventing the original function from being called.
|
||||
*
|
||||
* The wraper function is called with this signature:
|
||||
*
|
||||
* function wrapper(callOriginal[, args...])
|
||||
*
|
||||
* ...where `callOriginal` is a function that can be used to call the
|
||||
* original (wrapped) function (or not, as appropriate). (`callOriginal` is
|
||||
* not a direct reference to the original function, there's a layer of
|
||||
* indirection in-between that sets up the proper context \[`this` value\] for
|
||||
* it.)
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* // Wrap String#capitalize so it accepts an additional argument
|
||||
* String.prototype.capitalize = String.prototype.capitalize.wrap(
|
||||
* function(callOriginal, eachWord) {
|
||||
* if (eachWord && this.include(" ")) {
|
||||
* // capitalize each word in the string
|
||||
* return this.split(" ").invoke("capitalize").join(" ");
|
||||
* } else {
|
||||
* // proceed using the original function
|
||||
* return callOriginal();
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* "hello world".capitalize();
|
||||
* // -> "Hello world" (only the 'H' is capitalized)
|
||||
* "hello world".capitalize(true);
|
||||
* // -> "Hello World" (both 'H' and 'W' are capitalized)
|
||||
**/
|
||||
function wrap(wrapper) {
|
||||
var __method = this;
|
||||
@ -139,10 +322,51 @@ Object.extend(Function.prototype, (function() {
|
||||
|
||||
/**
|
||||
* Function#methodize() -> Function
|
||||
* Wraps the function inside another function that, at call time, pushes
|
||||
* `this` to the original function as the first argument.
|
||||
*
|
||||
* Used to define both a generic method and an instance method.
|
||||
* Wraps the function inside another function that, when called, pushes
|
||||
* `this` to the original function as the first argument (with any further
|
||||
* arguments following it).
|
||||
*
|
||||
* The `methodize` method transforms the original function that has an
|
||||
* explicit first argument to a function that passes `this` (the current
|
||||
* context) as an implicit first argument at call time. It is useful when we
|
||||
* want to transform a function that takes an object to a method of that
|
||||
* object or its prototype, shortening its signature by one argument.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* // A function that sets a name on a target object
|
||||
* function setName(target, name) {
|
||||
* target.name = name;
|
||||
* }
|
||||
*
|
||||
* // Use it
|
||||
* obj = {};
|
||||
* setName(obj, 'Fred');
|
||||
* obj.name;
|
||||
* // -> "Fred"
|
||||
*
|
||||
* // Make it a method of the object
|
||||
* obj.setName = setName.methodize();
|
||||
*
|
||||
* // Use the method instead
|
||||
* obj.setName('Barney');
|
||||
* obj.name;
|
||||
* // -> "Barney"
|
||||
*
|
||||
* The example above is quite simplistic. It's more useful to copy methodized
|
||||
* functions to object prototypes so that new methods are immediately shared
|
||||
* among instances. In the Prototype library, `methodize` is used in various
|
||||
* places such as the DOM module, so that (for instance) you can hide an
|
||||
* element either by calling the static version of `Element.hide` and passing in
|
||||
* an element reference or ID, like so:
|
||||
*
|
||||
* Element.hide('myElement');
|
||||
*
|
||||
* ...or if you already have an element reference, just calling the
|
||||
* methodized form instead:
|
||||
*
|
||||
* myElement.hide();
|
||||
**/
|
||||
function methodize() {
|
||||
if (this._methodized) return this._methodized;
|
||||
|
203
src/lang/hash.js
203
src/lang/hash.js
@ -1,11 +1,9 @@
|
||||
/** section: Language, related to: Hash
|
||||
* $H([object]) -> Hash
|
||||
*
|
||||
* Creates a `Hash`.
|
||||
*
|
||||
* `$H` is a convenience wrapper around the Hash constructor, with a safeguard
|
||||
* that lets you pass an existing Hash object and get it back untouched
|
||||
* (instead of uselessly cloning it).
|
||||
* Creates a `Hash`. This is purely a convenience wrapper around the Hash
|
||||
* constructor, it does not do anything other than pass any argument it's
|
||||
* given into the Hash constructor and return the result.
|
||||
**/
|
||||
function $H(object) {
|
||||
return new Hash(object);
|
||||
@ -24,13 +22,12 @@ function $H(object) {
|
||||
* methods that let you enumerate keys and values, iterate over key/value
|
||||
* pairs, merge two hashes together, and much more.
|
||||
*
|
||||
* <h4>Creating a hash</h4>
|
||||
* <h5>Creating a hash</h5>
|
||||
*
|
||||
* There are two ways to construct a Hash instance: the first is regular
|
||||
* JavaScript object instantiation with the `new` keyword, and the second is
|
||||
* using the [[$H]] function. There is one difference between them: if a `Hash`
|
||||
* is passed to `$H`, it will be returned as-is, wherease the same hash passed
|
||||
* to `new Hash` will be _cloned_ instead.
|
||||
* You can create a Hash either via `new Hash()` or the convenience alias
|
||||
* `$H()`; there is **no** difference between them. In either case, you may
|
||||
* optionally pass in an object to seed the `Hash`. If you pass in a `Hash`,
|
||||
* it will be cloned.
|
||||
*
|
||||
**/
|
||||
var Hash = Class.create(Enumerable, (function() {
|
||||
@ -44,6 +41,45 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
|
||||
}
|
||||
|
||||
// Docs for #each even though technically it's implemented by Enumerable
|
||||
/**
|
||||
* Hash#each(iterator[, context]) -> Hash
|
||||
* - iterator (Function): A function that expects each item in the `Hash`
|
||||
* as the first argument and a numerical index as the second.
|
||||
* - context (Object): The scope in which to call `iterator`. Determines what
|
||||
* `this` means inside `iterator`.
|
||||
*
|
||||
* Iterates over the name/value pairs in the hash.
|
||||
*
|
||||
* This is actually just the [[Enumerable#each #each]] method from the
|
||||
* mixed-in [[Enumerable]] module. It is documented here to describe the
|
||||
* structure of the elements passed to the iterator and the order of
|
||||
* iteration.
|
||||
*
|
||||
* The iterator's first argument (the "item") is an object with two
|
||||
* properties:
|
||||
*
|
||||
* - `key`: the key name as a `String`
|
||||
* - `value`: the corresponding value (which may be `undefined`)
|
||||
*
|
||||
* The order of iteration is implementation-dependent, as it relies on
|
||||
* the order of the native `for..in` loop. Although most modern
|
||||
* implementations exhibit *ordered* behavior, this is not standardized and
|
||||
* may not always be the case, and so cannot be relied upon.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var h = $H({version: 1.6, author: 'The Core Team'});
|
||||
*
|
||||
* h.each(function(pair) {
|
||||
* alert(pair.key + ' = "' + pair.value + '"');
|
||||
* });
|
||||
* // Alerts 'version = "1.6"' and 'author = "The Core Team"'
|
||||
* // -or-
|
||||
* // Alerts 'author = "The Core Team"' and 'version = "1.6"'
|
||||
**/
|
||||
|
||||
// Our _internal_ each
|
||||
function _each(iterator) {
|
||||
for (var key in this._object) {
|
||||
var value = this._object[key], pair = [key, value];
|
||||
@ -55,8 +91,22 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
|
||||
/**
|
||||
* Hash#set(key, value) -> value
|
||||
* - key (String): The key to use for this value.
|
||||
* - value (?): The value to use for this key.
|
||||
*
|
||||
* Sets the hash's `key` property to `value` and returns `value`.
|
||||
* Stores `value` in the hash using the key `key` and returns `value`.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var h = $H();
|
||||
* h.keys();
|
||||
* // -> [] (initially empty)
|
||||
* h.set('a', 'apple');
|
||||
* // -> "apple"
|
||||
* h.keys();
|
||||
* // -> ["a"] (has the new entry)
|
||||
* h.get('a');
|
||||
* // -> "apple"
|
||||
**/
|
||||
function set(key, value) {
|
||||
return this._object[key] = value;
|
||||
@ -65,7 +115,13 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
/**
|
||||
* Hash#get(key) -> value
|
||||
*
|
||||
* Returns the value of the hash's `key` property.
|
||||
* Returns the stored value for the given `key`.
|
||||
*
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* var h = new Hash({a: 'apple', b: 'banana', c: 'coconut'});
|
||||
* h.get('a');
|
||||
* // -> 'apple'
|
||||
**/
|
||||
function get(key) {
|
||||
// simulating poorly supported hasOwnProperty
|
||||
@ -76,7 +132,18 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
/**
|
||||
* Hash#unset(key) -> value
|
||||
*
|
||||
* Deletes the hash's `key` property and returns its value.
|
||||
* Deletes the stored pair for the given `key` from the hash and returns its
|
||||
* value.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var h = new Hash({a: 'apple', b: 'banana', c: 'coconut'});
|
||||
* h.keys();
|
||||
* // -> ["a", "b", "c"]
|
||||
* h.unset('a');
|
||||
* // -> 'apple'
|
||||
* h.keys();
|
||||
* // -> ["b", "c"] ("a" is no longer in the hash)
|
||||
**/
|
||||
function unset(key) {
|
||||
var value = this._object[key];
|
||||
@ -87,7 +154,15 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
/**
|
||||
* Hash#toObject() -> Object
|
||||
*
|
||||
* Returns a cloned, vanilla object.
|
||||
* Returns a cloned, vanilla object whose properties (and property values)
|
||||
* match the keys (and values) from the hash.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var h = new Hash({ a: 'apple', b: 'banana', c: 'coconut' });
|
||||
* var obj = h.toObject();
|
||||
* obj.a;
|
||||
* // -> "apple"
|
||||
**/
|
||||
function toObject() {
|
||||
return Object.clone(this._object);
|
||||
@ -96,7 +171,15 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
/**
|
||||
* Hash#keys() -> [String...]
|
||||
*
|
||||
* Provides an Array of keys (that is, property names) for the hash.
|
||||
* Provides an Array containing the keys for items stored in the hash.
|
||||
*
|
||||
* The order of the keys is not guaranteed.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var h = $H({one: "uno", two: "due", three: "tre"});
|
||||
* h.keys();
|
||||
* // -> ["one", "three", "two"] (these may be in any order)
|
||||
**/
|
||||
function keys() {
|
||||
return this.pluck('key');
|
||||
@ -105,7 +188,15 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
/**
|
||||
* Hash#values() -> Array
|
||||
*
|
||||
* Collect the values of a hash and returns them in an array.
|
||||
* Collects the values of the hash and returns them in an array.
|
||||
*
|
||||
* The order of the values is not guaranteed.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var h = $H({one: "uno", two: "due", three: "tre"});
|
||||
* h.values();
|
||||
* // -> ["uno", "tre", "due"] (these may be in any order)
|
||||
**/
|
||||
function values() {
|
||||
return this.pluck('value');
|
||||
@ -126,10 +217,22 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
|
||||
/**
|
||||
* Hash#merge(object) -> Hash
|
||||
* - object (Object | Hash): The object to merge with this hash to produce
|
||||
* the resulting hash.
|
||||
*
|
||||
* Returns a new `Hash` instance with `object`'s key/value pairs merged in;
|
||||
* this hash remains unchanged.
|
||||
*
|
||||
* Returns a new hash with `object`'s key/value pairs merged in.
|
||||
* To modify the original hash in place, use [[Hash#update]].
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var h = $H({one: "uno", two: "due"});
|
||||
* var h2 = h.merge({three: "tre"});
|
||||
* h.keys();
|
||||
* // -> ["one", "two"] (unchanged)
|
||||
* h2.keys();
|
||||
* // -> ["one", "two", "three"] (has merged contents)
|
||||
**/
|
||||
function merge(object) {
|
||||
return this.clone().update(object);
|
||||
@ -137,10 +240,22 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
|
||||
/**
|
||||
* Hash#update(object) -> Hash
|
||||
* - object (Object | Hash): The object to merge with this hash to produce
|
||||
* the resulting hash.
|
||||
*
|
||||
* Updates hash with the key/value pairs of `object`.
|
||||
* The original hash will be modified. To return a new hash instead, use
|
||||
* Updates a hash *in place* with the key/value pairs of `object`, returns
|
||||
* the hash.
|
||||
*
|
||||
* `update` modifies the hash. To get a new hash instead, use
|
||||
* [[Hash#merge]].
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var h = $H({one: "uno", two: "due"});
|
||||
* h.update({three: "tre"});
|
||||
* // -> h (a reference to the original hash)
|
||||
* h.keys();
|
||||
* // -> ["one", "two", "three"] (has merged contents)
|
||||
**/
|
||||
function update(object) {
|
||||
return new Hash(object).inject(this, function(result, pair) {
|
||||
@ -158,7 +273,41 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
/** related to: String#toQueryParams
|
||||
* Hash#toQueryString() -> String
|
||||
*
|
||||
* Turns a hash into its URL-encoded query string representation.
|
||||
* Returns a URL-encoded string containing the hash's contents as query
|
||||
* parameters according to the following rules:
|
||||
*
|
||||
* - An undefined value results a parameter with no value portion at all
|
||||
* (simply the key name, no equal sign).
|
||||
* - A null value results a parameter with a blank value (the key followed
|
||||
* by an equal sign and nothing else).
|
||||
* - A boolean value results a parameter with the value "true" or "false".
|
||||
* - An Array value results in a parameter for each array element, in
|
||||
* array order, each using the same key.
|
||||
* - All keys and values are URI-encoded using JavaScript's native
|
||||
* `encodeURIComponent` function.
|
||||
*
|
||||
* The order of pairs in the string is not guaranteed, other than the order
|
||||
* of array values described above.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* $H({action: 'ship',
|
||||
* order_id: 123,
|
||||
* fees: ['f1', 'f2']
|
||||
* }).toQueryString();
|
||||
* // -> "action=ship&order_id=123&fees=f1&fees=f2"
|
||||
*
|
||||
* $H({comment: '',
|
||||
* 'key with spaces': true,
|
||||
* related_order: undefined,
|
||||
* contents: null,
|
||||
* 'label': 'a demo'
|
||||
* }).toQueryString();
|
||||
* // -> "comment=&key%20with%20spaces=true&related_order&contents=&label=a%20demo"
|
||||
*
|
||||
* // an empty hash is an empty query string:
|
||||
* $H().toQueryString();
|
||||
* // -> ""
|
||||
**/
|
||||
function toQueryString() {
|
||||
return this.inject([], function(results, pair) {
|
||||
@ -175,7 +324,7 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
/** related to: Object.inspect
|
||||
* Hash#inspect() -> String
|
||||
*
|
||||
* Returns the debug-oriented string representation of the hash.
|
||||
* Returns the debug-oriented string representation of the Hash.
|
||||
**/
|
||||
function inspect() {
|
||||
return '#<Hash:{' + this.map(function(pair) {
|
||||
@ -186,7 +335,13 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
/** related to: Object.toJSON
|
||||
* Hash#toJSON() -> String
|
||||
*
|
||||
* Returns a JSON string.
|
||||
* Returns a JSON string containing the keys and values in this hash.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* var h = $H({'a': 'apple', 'b': 23, 'c': false});
|
||||
* h.toJSON();
|
||||
* // -> {"a": "apple", "b": 23, "c": false}
|
||||
**/
|
||||
function toJSON() {
|
||||
return Object.toJSON(this.toObject());
|
||||
@ -195,7 +350,7 @@ var Hash = Class.create(Enumerable, (function() {
|
||||
/**
|
||||
* Hash#clone() -> Hash
|
||||
*
|
||||
* Returns a clone of hash.
|
||||
* Returns a clone of this Hash.
|
||||
**/
|
||||
function clone() {
|
||||
return new Hash(this);
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Prototype extends native JavaScript numbers in order to provide:
|
||||
*
|
||||
* * [[ObjectRange]] compatibility, through [[Number#succ]].
|
||||
* * Ruby-like numerical loops with [[Number#times]].
|
||||
* * Numerical loops with [[Number#times]].
|
||||
* * Simple utility methods such as [[Number#toColorPart]] and
|
||||
* [[Number#toPaddedString]].
|
||||
* * Instance-method aliases of many functions in the `Math` namespace.
|
||||
@ -17,8 +17,13 @@ Object.extend(Number.prototype, (function() {
|
||||
* Number#toColorPart() -> String
|
||||
*
|
||||
* Produces a 2-digit hexadecimal representation of the number
|
||||
* (which is therefore assumed to be in the [0..255] range).
|
||||
* (which is therefore assumed to be in the \[0..255\] range, inclusive).
|
||||
* Useful for composing CSS color strings.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* 10.toColorPart()
|
||||
* // -> "0a"
|
||||
**/
|
||||
function toColorPart() {
|
||||
return this.toPaddedString(2, 16);
|
||||
@ -35,11 +40,31 @@ Object.extend(Number.prototype, (function() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Number#times(iterator) -> Number
|
||||
* Number#times(iterator[,context]) -> Number
|
||||
* - iterator (Function): An iterator function to call.
|
||||
* - context (Object): An optional context (`this` value) to use when
|
||||
* calling `iterator`.
|
||||
*
|
||||
* Calls `iterator` the specified number of times.
|
||||
* The function takes an integer as the first parameter; it will start at 0
|
||||
* and be incremented after each invocation.
|
||||
* Calls `iterator` the specified number of times, passing in a number as
|
||||
* the first parameter. The number will be 0 on first call, 1 on second
|
||||
* call, etc. `times` returns the number instance it was called on.
|
||||
*
|
||||
* <h5>Example</h5>
|
||||
*
|
||||
* (3).times(alert);
|
||||
* // -> Alerts "0", then "1", then "2"; returns 3
|
||||
*
|
||||
* var obj = {count: 0, total: 0};
|
||||
* function add(addend) {
|
||||
* ++this.count;
|
||||
* this.total += addend;
|
||||
* }
|
||||
* (4).times(add, obj);
|
||||
* // -> 4
|
||||
* obj.count;
|
||||
* // -> 4
|
||||
* obj.total;
|
||||
* // -> 6 (e.g., 0 + 1 + 2 + 3)
|
||||
**/
|
||||
function times(iterator, context) {
|
||||
$R(0, this, true).each(iterator, context);
|
||||
@ -48,10 +73,30 @@ Object.extend(Number.prototype, (function() {
|
||||
|
||||
/**
|
||||
* Number#toPaddedString(length[, radix]) -> String
|
||||
* - length (Number): The minimum length for the resulting string.
|
||||
* - radix (Number): An optional radix for the string representation,
|
||||
* defaults to 10 (decimal).
|
||||
*
|
||||
* Converts the number into a string padded with 0s so that the string's length
|
||||
* is at least equal to `length`.
|
||||
* Takes an optional `radix` argument which specifies the base to use for conversion.
|
||||
* Returns a string representation of the number padded with leading 0s so
|
||||
* that the string's length is at least equal to `length`. Takes an optional
|
||||
* `radix` argument which specifies the base to use for conversion.
|
||||
*
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* (13).toPaddedString(4);
|
||||
* // -> "0013"
|
||||
*
|
||||
* (13).toPaddedString(2);
|
||||
* // -> "13"
|
||||
*
|
||||
* (13).toPaddedString(1);
|
||||
* // -> "13"
|
||||
*
|
||||
* (13).toPaddedString(4, 16)
|
||||
* // -> "000d"
|
||||
*
|
||||
* (13).toPaddedString(4, 2);
|
||||
* // -> "1101"
|
||||
**/
|
||||
function toPaddedString(length, radix) {
|
||||
var string = this.toString(radix || 10);
|
||||
@ -70,7 +115,8 @@ Object.extend(Number.prototype, (function() {
|
||||
/**
|
||||
* Number#abs() -> Number
|
||||
*
|
||||
* Returns the absolute value of the number.
|
||||
* Returns the absolute value of the number. Convenience method that simply
|
||||
* calls `Math.abs` on this instance and returns the result.
|
||||
**/
|
||||
function abs() {
|
||||
return Math.abs(this);
|
||||
@ -79,7 +125,8 @@ Object.extend(Number.prototype, (function() {
|
||||
/**
|
||||
* Number#round() -> Number
|
||||
*
|
||||
* Rounds the number to the nearest integer.
|
||||
* Rounds the number to the nearest integer. Convenience method that simply
|
||||
* calls `Math.round` on this instance and returns the result.
|
||||
**/
|
||||
function round() {
|
||||
return Math.round(this);
|
||||
@ -89,6 +136,8 @@ Object.extend(Number.prototype, (function() {
|
||||
* Number#ceil() -> Number
|
||||
*
|
||||
* Returns the smallest integer greater than or equal to the number.
|
||||
* Convenience method that simply calls `Math.ceil` on this instance and
|
||||
* returns the result.
|
||||
**/
|
||||
function ceil() {
|
||||
return Math.ceil(this);
|
||||
@ -98,6 +147,8 @@ Object.extend(Number.prototype, (function() {
|
||||
* Number#floor() -> Number
|
||||
*
|
||||
* Returns the largest integer less than or equal to the number.
|
||||
* Convenience method that simply calls `Math.floor` on this instance and
|
||||
* returns the result.
|
||||
**/
|
||||
function floor() {
|
||||
return Math.floor(this);
|
||||
|
@ -167,12 +167,32 @@
|
||||
* Object.clone(object) -> Object
|
||||
* - object (Object): The object to clone.
|
||||
*
|
||||
* Duplicates the passed object.
|
||||
*
|
||||
* Copies all the original's key/value pairs onto an empty object.
|
||||
* Creates and returns a shallow duplicate of the passed object by copying
|
||||
* all of the original's key/value pairs onto an empty object.
|
||||
*
|
||||
* Do note that this is a _shallow_ copy, not a _deep_ copy. Nested objects
|
||||
* will retain their references.
|
||||
*
|
||||
* <h5>Examples</h5>
|
||||
*
|
||||
* var original = {name: 'primaryColors', values: ['red', 'green', 'blue']};
|
||||
* var copy = Object.clone(original);
|
||||
* original.name;
|
||||
* // -> "primaryColors"
|
||||
* original.values[0];
|
||||
* // -> "red"
|
||||
* copy.name;
|
||||
* // -> "primaryColors"
|
||||
* copy.name = "secondaryColors";
|
||||
* original.name;
|
||||
* // -> "primaryColors"
|
||||
* copy.name;
|
||||
* // -> "secondaryColors"
|
||||
* copy.values[0] = 'magenta';
|
||||
* copy.values[1] = 'cyan';
|
||||
* copy.values[2] = 'yellow';
|
||||
* original.values[0];
|
||||
* // -> "magenta" (it was a shallow copy, so they shared the array)
|
||||
**/
|
||||
function clone(object) {
|
||||
return extend({ }, object);
|
||||
|
@ -14,7 +14,7 @@
|
||||
* expression. The `Template` class provides a much nicer and clearer way of
|
||||
* achieving this formatting.
|
||||
*
|
||||
* <h4>Straightforward templates</h4>
|
||||
* <h5>Straightforward templates</h5>
|
||||
*
|
||||
* The `Template` class uses a basic formatting syntax, similar to what is
|
||||
* used in Ruby. The templates are created from strings that have embedded
|
||||
@ -36,7 +36,7 @@
|
||||
* myTemplate.evaluate(show);
|
||||
* // -> "The TV show The Simpsons was created by Matt Groening."
|
||||
*
|
||||
* <h4>Templates are meant to be reused</h4>
|
||||
* <h5>Templates are meant to be reused</h5>
|
||||
*
|
||||
* As the example illustrates, `Template` objects are not tied to specific
|
||||
* data. The data is bound to the template only during the evaluation of the
|
||||
@ -60,7 +60,7 @@
|
||||
* // -> Multiply by 0.9478 to convert from kilojoules to BTUs.
|
||||
* // -> Multiply by 1024 to convert from megabytes to gigabytes.
|
||||
*
|
||||
* <h4>Escape sequence</h4>
|
||||
* <h5>Escape sequence</h5>
|
||||
*
|
||||
* There's always the chance that one day you'll need to have a literal in your
|
||||
* template that looks like a symbol, but is not supposed to be replaced. For
|
||||
@ -75,7 +75,7 @@
|
||||
* t.evaluate(data);
|
||||
* // -> in Ruby we also use the #{variable} syntax for templates.
|
||||
*
|
||||
* <h4>Custom syntaxes</h4>
|
||||
* <h5>Custom syntaxes</h5>
|
||||
*
|
||||
* The default syntax of the template strings will probably be enough for most
|
||||
* scenarios. In the rare occasion where the default Ruby-like syntax is
|
||||
|
Loading…
Reference in New Issue
Block a user