Descriptions of all the classes/namespaces in the "Language" section.
This commit is contained in:
parent
2895be3587
commit
8c2af9bd66
|
@ -1,4 +1,4 @@
|
|||
/** section: Language, alias of: Array.from
|
||||
/** section: Language, alias of: Array.from, related to: Array
|
||||
* $A(iterable) -> Array
|
||||
*
|
||||
* Accepts an array-like collection (anything with numeric indices) and returns
|
||||
|
@ -29,7 +29,7 @@ if (Prototype.Browser.WebKit) {
|
|||
};
|
||||
}
|
||||
|
||||
/** section: Language
|
||||
/** section: Language, related to: Array
|
||||
* $w(string) -> Array
|
||||
* - string (String): A string with zero or more spaces.
|
||||
*
|
||||
|
@ -43,11 +43,94 @@ function $w(string) {
|
|||
return string ? string.split(/\s+/) : [];
|
||||
}
|
||||
|
||||
/** alias of: $A
|
||||
* Array.from(iterable) -> Array
|
||||
**/
|
||||
Array.from = $A;
|
||||
|
||||
/** section: Language
|
||||
* class Array
|
||||
*
|
||||
* Prototype extends all native JavaScript arrays with quite a few powerful
|
||||
* methods.
|
||||
*
|
||||
* This is done in two ways:
|
||||
*
|
||||
* * It mixes in the [[Enumerable]] module, which brings a ton of methods in
|
||||
* already.
|
||||
* * It adds quite a few extra methods, which are documented in this section.
|
||||
*
|
||||
* With Prototype, arrays become much, much more than the trivial objects we
|
||||
* used to manipulate, limiting ourselves to using their `length` property and
|
||||
* 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>
|
||||
*
|
||||
* 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
|
||||
* with Prototype.
|
||||
*
|
||||
* The ECMA 262 standard, which defines ECMAScript 3rd edition, supposedly
|
||||
* implemented by all major browsers including MSIE, defines ten methods
|
||||
* on Array (§15.4.4), including nice methods like `concat`, `join`, `pop`, and
|
||||
* `push`.
|
||||
*
|
||||
* This same standard explicitely defines that the `for…in` construct (§12.6.4)
|
||||
* exists to enumerate the properties of the object appearing on the right side
|
||||
* of the `in` keyword. Only properties specifically marked as _non-enumerable_
|
||||
* are ignored by such a loop. By default, the `prototype` and `length`
|
||||
* properties are so marked, which prevents you from enumerating over array
|
||||
* methods when using for…in. This comfort led developers to use `for…in` as a
|
||||
* shortcut for indexing loops, when it is not its actual purpose.
|
||||
*
|
||||
* However, Prototype has no way to mark the methods it adds to
|
||||
* `Array.prototype` as non-enumerable. Therefore, using `for…in` on arrays
|
||||
* when using Prototype will enumerate all extended methods as well, such as
|
||||
* those coming from the [[Enumerable]] module, and those Prototype puts in the
|
||||
* Array namespace (listed further below).
|
||||
*
|
||||
* <h4>What you should use instead</h4>
|
||||
*
|
||||
* You can revert to vanilla loops:
|
||||
*
|
||||
* for (var index = 0; index < myArray.length; ++index) {
|
||||
* var item = myArray[index];
|
||||
* // Your code working on item here...
|
||||
* }
|
||||
*
|
||||
* Or you can use iterators, such as [[Array#each]]:
|
||||
*
|
||||
* myArray.each(function(item) {
|
||||
* // Your code working on item here...
|
||||
* });
|
||||
*
|
||||
*
|
||||
* The inability to use `for...in` on arrays is not much of a burden: as you’ll
|
||||
* see, most of what you used to loop over arrays for can be concisely done
|
||||
* using the new methods provided by Array or the mixed-in [[Enumerable]]
|
||||
* module. So manual loops should be fairly rare.
|
||||
*
|
||||
*
|
||||
* <h4>A note on performance</h4>
|
||||
*
|
||||
* 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
|
||||
* every loop iteration) in methods like [[Array#each]] — _or_ relying on
|
||||
* repetitive array construction (such as uniq), may yield unsatisfactory
|
||||
* performance. In such cases, you’re better off writing manual indexing loops,
|
||||
* but take care then to cache the length property and use the prefix `++`
|
||||
* operator:
|
||||
*
|
||||
* // Custom loop with cached length property: maximum full-loop
|
||||
* // performance on very large arrays!
|
||||
* for (var index = 0, len = myArray.length; index < len; ++index) {
|
||||
* var item = myArray[index];
|
||||
* // Your code working on item here...
|
||||
* }
|
||||
*
|
||||
**/
|
||||
|
||||
(function() {
|
||||
var arrayProto = Array.prototype,
|
||||
slice = arrayProto.slice,
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
/** section: Language
|
||||
* class Date
|
||||
*
|
||||
* Extensions to the built-in `Date` object.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Date#toJSON -> String
|
||||
* Date#toJSON() -> String
|
||||
*
|
||||
* Produces a string representation of the date in ISO 8601 format.
|
||||
*
|
||||
**/
|
||||
Date.prototype.toJSON = function() {
|
||||
return '"' + this.getUTCFullYear() + '-' +
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
/** section: Language
|
||||
/** section: Language, related to: Hash
|
||||
* $H([object]) -> Hash
|
||||
*
|
||||
* Creates a Hash (which is synonymous to “map” or “associative array” for our purposes).
|
||||
* 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`.
|
||||
*
|
||||
* `$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).
|
||||
**/
|
||||
function $H(object) {
|
||||
return new Hash(object);
|
||||
|
@ -11,6 +13,24 @@ function $H(object) {
|
|||
|
||||
/** section: Language
|
||||
* class Hash
|
||||
*
|
||||
* A set of key/value pairs.
|
||||
*
|
||||
* `Hash` can be thought of as an associative array, binding unique keys to
|
||||
* values (which are not necessarily unique), though it can not guarantee
|
||||
* consistent order its elements when iterating. Because of the nature of
|
||||
* JavaScript, every object is in fact a hash; but `Hash` adds a number of
|
||||
* 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>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**/
|
||||
var Hash = Class.create(Enumerable, (function() {
|
||||
/**
|
||||
|
@ -35,7 +55,7 @@ var Hash = Class.create(Enumerable, (function() {
|
|||
/**
|
||||
* Hash#set(key, value) -> value
|
||||
*
|
||||
* Sets the hash’s `key` property to value and returns value.
|
||||
* Sets the hash’s `key` property to `value` and returns `value`.
|
||||
**/
|
||||
function set(key, value) {
|
||||
return this._object[key] = value;
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
/** section: Language
|
||||
* class Number
|
||||
*
|
||||
* Extensions to the built-in `Number` object.
|
||||
*
|
||||
* Prototype extends native JavaScript numbers in order to provide:
|
||||
*
|
||||
* * [[ObjectRange]] compatibility, through [[Number#succ]].
|
||||
* * Ruby-like 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.
|
||||
*
|
||||
**/
|
||||
Object.extend(Number.prototype, (function() {
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
/** section: Language
|
||||
* class Object
|
||||
*
|
||||
* Extensions to the built-in `Object` object.
|
||||
*
|
||||
* Because it is dangerous and invasive to augment `Object.prototype` (i.e.,
|
||||
* add instance methods to objects), all these methods are static methods that
|
||||
* take an `Object` as their first parameter.
|
||||
*
|
||||
**/
|
||||
(function() {
|
||||
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
/** section: Language
|
||||
* class PeriodicalExecuter
|
||||
*
|
||||
* A class that oversees the calling of a particular function periodically.
|
||||
*
|
||||
* `PeriodicalExecuter` shields you from multiple parallel executions of the
|
||||
* `callback` function, should it take longer than the given interval to
|
||||
* execute.
|
||||
*
|
||||
* This is especially useful if you use one to interact with the user at
|
||||
* given intervals (e.g. use a prompt or confirm call): this will avoid
|
||||
* multiple message boxes all waiting to be actioned.
|
||||
**/
|
||||
var PeriodicalExecuter = Class.create({
|
||||
/**
|
||||
|
@ -8,18 +18,7 @@ var PeriodicalExecuter = Class.create({
|
|||
* - frequency (Number): the amount of time, in sections, to wait in between
|
||||
* callbacks.
|
||||
*
|
||||
* Creates an object that oversees the calling of a particular function via
|
||||
* `window.setInterval`.
|
||||
*
|
||||
* The only notable advantage provided by `PeriodicalExecuter` is that it
|
||||
* shields you against multiple parallel executions of the `callback`
|
||||
* function, should it take longer than the given interval to execute (it
|
||||
* maintains an internal “running” flag, which is shielded against
|
||||
* exceptions in the callback function).
|
||||
*
|
||||
* This is especially useful if you use one to interact with the user at
|
||||
* given intervals (e.g. use a prompt or confirm call): this will avoid
|
||||
* multiple message boxes all waiting to be actioned.
|
||||
* Creates an `PeriodicalExecuter`.
|
||||
**/
|
||||
initialize: function(callback, frequency) {
|
||||
this.callback = callback;
|
||||
|
|
|
@ -1,5 +1,21 @@
|
|||
/** section: Language
|
||||
* class ObjectRange
|
||||
*
|
||||
* Ranges represent an interval of values. The value type just needs to be
|
||||
* "compatible" — that is, to implement a `succ` method letting us step from
|
||||
* one value to the next (its successor).
|
||||
*
|
||||
* Prototype provides such a method for [[Number]] and [[String]], but you
|
||||
* are (of course) welcome to implement useful semantics in your own objects,
|
||||
* in order to enable ranges based on them.
|
||||
*
|
||||
* `ObjectRange` mixes in [[Enumerable]], which makes ranges very versatile.
|
||||
* It takes care, however, to override the default code for `include`, to
|
||||
* achieve better efficiency.
|
||||
*
|
||||
* While `ObjectRange` does provide a constructor, the preferred way to obtain
|
||||
* a range is to use the [[$R]] utility function, which is strictly equivalent
|
||||
* (only way more concise to use).
|
||||
**/
|
||||
|
||||
/** section: Language
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/** section: Language
|
||||
* class RegExp
|
||||
*
|
||||
* Extensions to the built-in `RegExp` object.
|
||||
**/
|
||||
|
||||
/** alias of: RegExp#test
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
/** section: Language
|
||||
* class String
|
||||
*
|
||||
* Extensions to the built-in `String` class.
|
||||
*
|
||||
* Prototype enhances the `String` object with a series of useful methods for
|
||||
* ranging from the trivial to the complex. Tired of stripping trailing
|
||||
* whitespace? Try [[String#strip]]. Want to replace `replace`? Have a look at
|
||||
* [[String#sub]] and [[String#gsub]]. Need to parse a query string? We have
|
||||
* [[String#toQueryParams]].
|
||||
**/
|
||||
Object.extend(String, {
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,107 @@
|
|||
/** section: Language
|
||||
* class Template
|
||||
*
|
||||
* A class for sophisticated string interpolation.
|
||||
*
|
||||
* Any time you have a group of similar objects and you need to produce
|
||||
* formatted output for these objects, maybe inside a loop, you typically
|
||||
* resort to concatenating string literals with the object's fields. There's
|
||||
* nothing wrong with this approach, except that it is hard to visualize the
|
||||
* output immediately just by glancing at the concatenation expression. The
|
||||
* `Template` class provides a much nicer and clearer way of achieving this
|
||||
* formatting.
|
||||
*
|
||||
* <h4>Straightforward templates</h4>
|
||||
*
|
||||
* The Template class uses a basic formatting syntax, similar to what is used
|
||||
* in Ruby. The templates are created from strings that have embedded symbols
|
||||
* in the form (e.g., `#{fieldName}`) that will be replaced by actual values
|
||||
* when the template is applied (evaluated) to an object.
|
||||
*
|
||||
*
|
||||
* // the template (our formatting expression)
|
||||
* var myTemplate = new Template(
|
||||
* 'The TV show #{title} was created by #{author}.');
|
||||
*
|
||||
* // our data to be formatted by the template
|
||||
* var show = {
|
||||
* title: 'The Simpsons',
|
||||
* author: 'Matt Groening',
|
||||
* network: 'FOX'
|
||||
* };
|
||||
*
|
||||
* // let's format our data
|
||||
* myTemplate.evaluate(show);
|
||||
* // -> "The TV show The Simpsons was created by Matt Groening."
|
||||
*
|
||||
* <h4>Templates are meant to be reused</h4>
|
||||
*
|
||||
* 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
|
||||
* template, without affecting the template itself. The next example shows the
|
||||
* same template being used with a handful of distinct objects.
|
||||
*
|
||||
*
|
||||
* // creating a few similar objects
|
||||
* var conversion1 = { from: 'meters', to: 'feet', factor: 3.28 };
|
||||
* var conversion2 = { from: 'kilojoules', to: 'BTUs', factor: 0.9478 };
|
||||
* var conversion3 = { from: 'megabytes', to: 'gigabytes', factor: 1024 };
|
||||
*
|
||||
* // the template
|
||||
* var templ = new Template(
|
||||
* 'Multiply by #{factor} to convert from #{from} to #{to}.');
|
||||
*
|
||||
* // let's format each object
|
||||
* [conversion1, conversion2, conversion3].each( function(conv){
|
||||
* templ.evaluate(conv);
|
||||
* });
|
||||
* // -> Multiply by 3.28 to convert from meters to feet.
|
||||
* // -> Multiply by 0.9478 to convert from kilojoules to BTUs.
|
||||
* // -> Multiply by 1024 to convert from megabytes to gigabytes.
|
||||
*
|
||||
* <h4>Escape sequence</h4>
|
||||
*
|
||||
* 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
|
||||
* these situations there's an escape character: the backslash (`\`).
|
||||
*
|
||||
* // NOTE: you're seeing two backslashes here because the backslash
|
||||
* // is also an escape character in JavaScript strings, so a literal
|
||||
* // backslash is represented by two backslashes.
|
||||
* var t = new Template(
|
||||
* 'in #{lang} we also use the \\#{variable} syntax for templates.');
|
||||
* var data = { lang:'Ruby', variable: '(not used)' };
|
||||
* t.evaluate(data);
|
||||
* // -> in Ruby we also use the #{variable} syntax for templates.
|
||||
*
|
||||
*
|
||||
*
|
||||
* <h4>Custom syntaxes</h4>
|
||||
*
|
||||
* 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
|
||||
* inadequate, there's a provision for customization. `Template`'s
|
||||
* constructor accepts an optional second argument that is a regular expression
|
||||
* object to match the replaceable symbols in the template string. Let's put
|
||||
* together a template that uses a syntax similar to the ubiquitous `<%= %>`
|
||||
* constructs:
|
||||
*
|
||||
* // matches symbols like '<%= field %>'
|
||||
* var syntax = /(^|.|\r|\n)(\<%=\s*(\w+)\s*%\>)/;
|
||||
*
|
||||
* var t = new Template(
|
||||
* '<div>Name: <b><%= name %></b>, Age: <b><%=age%></b></div>', syntax);
|
||||
* t.evaluate( {name: 'John Smith', age: 26} );
|
||||
* // -> <div>Name: <b>John Smith</b>, Age: <b>26</b></div>
|
||||
*
|
||||
* There are important constraints to any custom syntax. Any syntax must
|
||||
* provide at least three groupings in the regular expression. The first
|
||||
* grouping is to capture what comes before the symbol, to detect the backslash
|
||||
* escape character (no, you cannot use a different character). The second
|
||||
* grouping captures the entire symbol and will be completely replaced upon
|
||||
* evaluation. Lastly, the third required grouping captures the name of the
|
||||
* field inside the symbol.
|
||||
*
|
||||
**/
|
||||
var Template = Class.create({
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue