minifiedjs-rails 0.0.1.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE.txt +22 -0
- data/README.md +44 -0
- data/lib/minifiedjs/rails.rb +8 -0
- data/lib/minifiedjs/rails/version.rb +5 -0
- data/vendor/assets/javascripts/minified_web.js +3086 -0
- data/vendor/assets/javascripts/minified_web.min.js +1 -0
- data/vendor/assets/javascripts/minified_web_noie.js +2900 -0
- data/vendor/assets/javascripts/minified_web_noie.min.js +1 -0
- metadata +104 -0
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 TM Lee
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# minifiedjs-rails
|
|
2
|
+
|
|
3
|
+
MinifiedJS (http://minifiedjs.com/), A Truly Lightweight JavaScript Library for Rails via Assets Pipeline
|
|
4
|
+
The Javascript library that replaces jQuery or MooTools with a <4kB Library.
|
|
5
|
+
|
|
6
|
+
## Installation with Rails 3.1+
|
|
7
|
+
|
|
8
|
+
Add this to your `Gemfile` as part of the `assets` group:
|
|
9
|
+
|
|
10
|
+
group :assets do
|
|
11
|
+
gem 'minifiedjs-rails'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
And then execute:
|
|
15
|
+
|
|
16
|
+
$ bundle
|
|
17
|
+
|
|
18
|
+
Require `minified_web` in your JavaScript manifest, for example in `application.js` if you are using Rails 3.1+:
|
|
19
|
+
|
|
20
|
+
//= require minified_web
|
|
21
|
+
|
|
22
|
+
Your other options include a minified version and also with IE6-8 support removed (more information at http://minifiedjs.com/download/). You should only pick one of the following to be included in your app.
|
|
23
|
+
|
|
24
|
+
//= require minified_web
|
|
25
|
+
//= require minified_web.min
|
|
26
|
+
//= require minified_web_noie
|
|
27
|
+
//= require minified_web_noie.min
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
Quick start guide can be found at http://minifiedjs.com/docs/quickstart.html
|
|
32
|
+
|
|
33
|
+
For more documentations, visit http://minifiedjs.com/docs/
|
|
34
|
+
|
|
35
|
+
For the complete API, check out http://minifiedjs.com/api/
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## Contributing
|
|
39
|
+
|
|
40
|
+
1. Fork it
|
|
41
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
42
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
43
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
44
|
+
5. Create new Pull Request
|
|
@@ -0,0 +1,3086 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Minified-web.js - Complete library for JavaScript interaction in less than 4kb
|
|
3
|
+
*
|
|
4
|
+
* Public Domain. Use, modify and distribute it any way you like. No attribution required.
|
|
5
|
+
*
|
|
6
|
+
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
|
7
|
+
*
|
|
8
|
+
* Contains code based on https://github.com/douglascrockford/JSON-js (also Public Domain).
|
|
9
|
+
*
|
|
10
|
+
* https://github.com/timjansen/minified.js
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* When you read this code, please keep in mind that it is optimized to produce small and gzip'able code
|
|
15
|
+
* after being minimized with Closure (http://closure-compiler.appspot.com). Run-time performance and readability
|
|
16
|
+
* should be acceptable, but are not a primary concern.
|
|
17
|
+
*
|
|
18
|
+
*
|
|
19
|
+
* Various comment annotations control the builder in parser-src.js / builder-src.js. This file should always work without the builder,
|
|
20
|
+
* but only the builder allows you to remove functions.
|
|
21
|
+
*
|
|
22
|
+
* Here's a short summary of that the non-documenting tags mean.
|
|
23
|
+
*
|
|
24
|
+
* Multi-Line Comments:
|
|
25
|
+
* - @id marks the beginning of an optional block. It ends with the next @id block, or the next @stop comment.
|
|
26
|
+
* - @requires defines the ids that the current block depends on. They will always be available.
|
|
27
|
+
* - @configurable the block can be selected in the GUI. If the value is 'default', it is a enabled by default. If it is 'optional', it is not.
|
|
28
|
+
* - @dependency if set, the block is only used as a dependency and won't show up in builder or documentation
|
|
29
|
+
* - @name a name for builder and reference docs
|
|
30
|
+
* - @doc if 'no', the section will not be displayed in reference docs, only in builder
|
|
31
|
+
* - @module the module(s), comma-separated. Can be WEB, UTIL or APP
|
|
32
|
+
*
|
|
33
|
+
* Single-Line Comments
|
|
34
|
+
* - @cond id defines that the code following after the id will be included if the block id is enabled
|
|
35
|
+
* - @cond !id include the following line only if the block id is disabled
|
|
36
|
+
* - @condblock id will include all following lines if id is enabled until the next @condend. @condblocks can be nested.
|
|
37
|
+
* - @condend ends a @condblock
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
// ==ClosureCompiler==
|
|
41
|
+
// @output_file_name minified.js
|
|
42
|
+
// @compilation_level ADVANCED_OPTIMIZATIONS
|
|
43
|
+
// ==/ClosureCompiler==
|
|
44
|
+
|
|
45
|
+
/*$
|
|
46
|
+
* @id require
|
|
47
|
+
* @name require()
|
|
48
|
+
* @syntax require(name)
|
|
49
|
+
* @group OPTIONS
|
|
50
|
+
* @module WEB, UTIL, APP
|
|
51
|
+
* Returns a reference to a module. If you do not use an AMD loader to load Minified, just call <var>require()</var> with the
|
|
52
|
+
* argument 'minified' to get a reference to Minified.
|
|
53
|
+
* If you do use an AMD loader, Minified will not define this function and you can use the AMD loader to obtain the
|
|
54
|
+
* reference to Minified.
|
|
55
|
+
* Minified's version of <var>require</var> is very simple and will only support Minified, but <strong>no other libraries</strong>. You can not
|
|
56
|
+
* use it to load other modules, and it will be incompatible with all non-AMD libraries that also define a function
|
|
57
|
+
* of the same name. If you need to work with several libraries, you need a real AMD loader.
|
|
58
|
+
*
|
|
59
|
+
* @param name the name of the module to request. In Minified's implementation, only 'minified' is supported.
|
|
60
|
+
* @return the reference to Minified if 'minified' had been used as name. <var>undefined</var> otherwise.
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
/*$
|
|
64
|
+
* @id amdsupport
|
|
65
|
+
* @name AMD support
|
|
66
|
+
* @configurable default
|
|
67
|
+
* @group OPTIONS
|
|
68
|
+
* @doc no
|
|
69
|
+
* @module WEB, UTIL
|
|
70
|
+
* If enabled, Minified will work correctly with AMD frameworks. If not, it will just provide a global
|
|
71
|
+
* function ##require(), which can be used only to load 'minified'.
|
|
72
|
+
*/
|
|
73
|
+
if (/^u/.test(typeof define)) { // no AMD support available ? define a minimal version
|
|
74
|
+
var def = {};
|
|
75
|
+
this['define'] = function(name, f) {def[name] = f();};
|
|
76
|
+
this['require'] = function(name) { return def[name]; };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
define('minified', function() {
|
|
81
|
+
/*$
|
|
82
|
+
* @stop
|
|
83
|
+
*/
|
|
84
|
+
// @cond !amdsupport (function() {
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
//// GLOBAL VARIABLES ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @const
|
|
91
|
+
*/
|
|
92
|
+
var _window = this;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @const
|
|
96
|
+
*/
|
|
97
|
+
var _document = document;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @const
|
|
101
|
+
* @type {!string}
|
|
102
|
+
*/
|
|
103
|
+
var BACKSLASHB = '\\b';
|
|
104
|
+
/** @const */
|
|
105
|
+
var undef;
|
|
106
|
+
|
|
107
|
+
var PUSH = [].push;
|
|
108
|
+
|
|
109
|
+
/*$
|
|
110
|
+
* @id ready_vars
|
|
111
|
+
* @dependency
|
|
112
|
+
*/
|
|
113
|
+
/** @type {!Array.<function()>} */
|
|
114
|
+
var DOMREADY_HANDLER = [];
|
|
115
|
+
|
|
116
|
+
/*$
|
|
117
|
+
* @id animation_vars
|
|
118
|
+
* @dependency
|
|
119
|
+
*/
|
|
120
|
+
/** @type {!Array.<{c:!function(), t:!number, s:!function()}>} */
|
|
121
|
+
var ANIMATION_HANDLERS = []; // global list of {c: <callback function>, t: <timestamp>, s:<stop function>} currently active
|
|
122
|
+
|
|
123
|
+
/** @type {!function()} */
|
|
124
|
+
var REQUEST_ANIMATION_FRAME = _window['requestAnimationFrame'] || function(callback) {
|
|
125
|
+
delay(callback, 33); // 30 fps as fallback
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
/*$
|
|
130
|
+
* @id ie8compatibility
|
|
131
|
+
* @group OPTIONS
|
|
132
|
+
* @configurable default
|
|
133
|
+
* @doc no
|
|
134
|
+
* @name Backward-Compatibility for IE8 and similar browsers
|
|
135
|
+
* The only difference for Minified between IE8 and IE9 is the lack of support for the CSS opacity attribute in IE8,
|
|
136
|
+
* and the existence of cssText (which is used instead of the style attribute).
|
|
137
|
+
*/
|
|
138
|
+
/**
|
|
139
|
+
* @const
|
|
140
|
+
* @type {boolean}
|
|
141
|
+
*/
|
|
142
|
+
// @condblock ready_vars
|
|
143
|
+
var IS_PRE_IE9 = !!_document.all && !DOMREADY_HANDLER.map;
|
|
144
|
+
// @condend
|
|
145
|
+
// @cond !ready_vars var IS_PRE_IE9 = !!_document.all && ![].map;
|
|
146
|
+
/*$
|
|
147
|
+
* @id ie7compatibility
|
|
148
|
+
* @requires ie8compatibility
|
|
149
|
+
* @group OPTIONS
|
|
150
|
+
* @configurable default
|
|
151
|
+
* @doc no
|
|
152
|
+
* @name Backward-Compatibility for IE7 and similar browsers
|
|
153
|
+
* The difference between IE7 and IE8 compatibility that IE7 provides neither native selector support (querySelectorAll) nor native JSON.
|
|
154
|
+
* Disabling IE6 and IE7 will not only make Minified smaller, but give you full CSS selectors and complete JSON support.
|
|
155
|
+
*/
|
|
156
|
+
// @condblock ucode
|
|
157
|
+
/**
|
|
158
|
+
* @const
|
|
159
|
+
* @type {Object.<string, string>}
|
|
160
|
+
*/
|
|
161
|
+
var STRING_SUBSTITUTIONS = { // table of character substitutions
|
|
162
|
+
'\t': '\\t',
|
|
163
|
+
'\r': '\\r',
|
|
164
|
+
'\n': '\\n',
|
|
165
|
+
'"' : '\\"',
|
|
166
|
+
'\\': '\\\\'
|
|
167
|
+
};
|
|
168
|
+
// @condend
|
|
169
|
+
|
|
170
|
+
/*$
|
|
171
|
+
* @id ie6compatibility
|
|
172
|
+
* @requires ie7compatibility
|
|
173
|
+
* @group OPTIONS
|
|
174
|
+
* @configurable default
|
|
175
|
+
* @doc no
|
|
176
|
+
* @name Backward-Compatibility for IE6 and similar browsers
|
|
177
|
+
* The only difference for Minified between IE6 and IE7 is the lack of a native XmlHttpRequest in IE6 which makes the library a tiny
|
|
178
|
+
* little bit larger.
|
|
179
|
+
*/
|
|
180
|
+
|
|
181
|
+
/*$
|
|
182
|
+
* @id fadeslide
|
|
183
|
+
* @requires animate set
|
|
184
|
+
* @group ANIMATION
|
|
185
|
+
* @configurable default
|
|
186
|
+
* @doc no
|
|
187
|
+
* @name Support for $$fade and $$slide
|
|
188
|
+
*/
|
|
189
|
+
/*$
|
|
190
|
+
* @stop
|
|
191
|
+
*/
|
|
192
|
+
|
|
193
|
+
//// GLOBAL FUNCTIONS ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
194
|
+
|
|
195
|
+
/** @param s {?} */
|
|
196
|
+
function toString(s) { // wrapper for Closure optimization
|
|
197
|
+
return s!=null ? ''+s : '';
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* @param s {?}
|
|
201
|
+
* @param o {string}
|
|
202
|
+
*/
|
|
203
|
+
function isType(s,o) {
|
|
204
|
+
return typeof s == o;
|
|
205
|
+
}
|
|
206
|
+
/** @param s {?} */
|
|
207
|
+
function isString(s) {
|
|
208
|
+
return isType(s, 'string');
|
|
209
|
+
}
|
|
210
|
+
function isFunction(f) {
|
|
211
|
+
return isType(f, 'function') && !f['item']; // item check as work-around webkit bug 14547
|
|
212
|
+
}
|
|
213
|
+
function isObject(f) {
|
|
214
|
+
return isType(f, 'object');
|
|
215
|
+
}
|
|
216
|
+
function isNode(n) {
|
|
217
|
+
return n && n['nodeType'];
|
|
218
|
+
}
|
|
219
|
+
function isList(v) {
|
|
220
|
+
return v && v.length != null && !isString(v) && !isNode(v) && !isFunction(v);
|
|
221
|
+
}
|
|
222
|
+
function eachObj(obj, cb) {
|
|
223
|
+
for (var n in obj)
|
|
224
|
+
if (obj.hasOwnProperty(n))
|
|
225
|
+
cb(n, obj[n]);
|
|
226
|
+
return obj;
|
|
227
|
+
}
|
|
228
|
+
function each(list, cb) {
|
|
229
|
+
for (var i = 0; list && i < list.length; i++)
|
|
230
|
+
cb(list[i], i);
|
|
231
|
+
return list;
|
|
232
|
+
}
|
|
233
|
+
function filter(list, filterFunc) {
|
|
234
|
+
var r = [];
|
|
235
|
+
each(list, function(node,index) {
|
|
236
|
+
if (filterFunc(node,index))
|
|
237
|
+
r.push(node);
|
|
238
|
+
});
|
|
239
|
+
return r;
|
|
240
|
+
}
|
|
241
|
+
function collect(obj, collectFunc) {
|
|
242
|
+
var result = [];
|
|
243
|
+
each(obj, function (a, b) {
|
|
244
|
+
if (isList(a = collectFunc(a, b))) // caution: extreme variable re-using of 'a'
|
|
245
|
+
each(a, function(rr) { result.push(rr); });
|
|
246
|
+
else if (a != null)
|
|
247
|
+
result.push(a);
|
|
248
|
+
});
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
function collectObj(obj, collectFunc) { // warning: 1:1 copy of collect(), with one diff... good for gzip..
|
|
252
|
+
var result = [];
|
|
253
|
+
eachObj(obj, function (a, b) {
|
|
254
|
+
if (isList(a = collectFunc(a, b))) // caution: extreme variable re-using of 'a'
|
|
255
|
+
each(a, function(rr) { result.push(rr); });
|
|
256
|
+
else if (a != null)
|
|
257
|
+
result.push(a);
|
|
258
|
+
});
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
function replace(s, regexp, sub) {
|
|
262
|
+
return toString(s).replace(regexp, sub||'');
|
|
263
|
+
}
|
|
264
|
+
function delay(f, delayMs) {
|
|
265
|
+
_window.setTimeout(f, delayMs||0);
|
|
266
|
+
}
|
|
267
|
+
function extractNumber(v) {
|
|
268
|
+
return parseFloat(replace(v, /^[^\d-]+/));
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function getNaturalHeight(elementList) {
|
|
272
|
+
var q = {'$position': 'absolute', '$visibility': 'hidden', '$display': 'block', '$height': null};
|
|
273
|
+
var oldStyles = elementList['get'](q);
|
|
274
|
+
elementList['set'](q);
|
|
275
|
+
var h = elementList['get']('$height', true);
|
|
276
|
+
elementList['set'](oldStyles);
|
|
277
|
+
return h;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function now() {
|
|
281
|
+
return new Date().getTime();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function callArg(f) {f();}
|
|
285
|
+
|
|
286
|
+
// for ready()
|
|
287
|
+
function triggerDomReady() {
|
|
288
|
+
each(DOMREADY_HANDLER, callArg);
|
|
289
|
+
DOMREADY_HANDLER = null;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function ready(handler) {
|
|
293
|
+
// @cond debug if (typeof handler != 'function') error("First argument must be a function");
|
|
294
|
+
if (DOMREADY_HANDLER)
|
|
295
|
+
DOMREADY_HANDLER.push(handler);
|
|
296
|
+
else
|
|
297
|
+
delay(handler);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function $$(selector) {
|
|
301
|
+
return dollarRaw(selector)[0];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function EE(elementName, attributes, children, onCreate) {
|
|
305
|
+
// @cond debug if (!elementName) error("EE() requires the element name.");
|
|
306
|
+
// @cond debug if (/:/.test(elementName)) error("The element name can not create a colon (':').");
|
|
307
|
+
|
|
308
|
+
return function() {
|
|
309
|
+
var list = $(_document.createElement(elementName));
|
|
310
|
+
(isList(attributes) || !isObject(attributes)) ? list['add'](attributes) : list['set'](attributes)['add'](children);
|
|
311
|
+
if (onCreate)
|
|
312
|
+
onCreate(list);
|
|
313
|
+
return list;
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function promise() {
|
|
318
|
+
var state; // undefined/null = pending, true = fulfilled, false = rejected
|
|
319
|
+
var values = []; // an array of values as arguments for the then() handlers
|
|
320
|
+
var deferred = []; // functions to call when set() is invoked
|
|
321
|
+
|
|
322
|
+
var set = function (newState, newValues) {
|
|
323
|
+
if (state == null) {
|
|
324
|
+
state = newState;
|
|
325
|
+
values = newValues;
|
|
326
|
+
delay(function() {
|
|
327
|
+
each(deferred, callArg);
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
/*$
|
|
332
|
+
* @id then
|
|
333
|
+
* @group REQUEST
|
|
334
|
+
* @name promise.then()
|
|
335
|
+
* @syntax promise.then()
|
|
336
|
+
* @syntax promise.then(onSuccess)
|
|
337
|
+
* @syntax promise.then(onSuccess, onError)
|
|
338
|
+
*
|
|
339
|
+
* @module WEB, UTIL
|
|
340
|
+
* Registers two callbacks that will be invoked when the ##promise#Promise##'s asynchronous operation finished
|
|
341
|
+
* successfully (<var>onSuccess</var>) or an error occurred (<var>onError</var>). The callbacks will be called after
|
|
342
|
+
* <var>then()</var> returned, from the browser's event loop.
|
|
343
|
+
* Minified implements the Promises/A+ specification, allowing interoperability with other Promises frameworks.
|
|
344
|
+
* You can chain <var>then()</var> invocations, as <var>then()</var> returns another Promise object that you can attach to.
|
|
345
|
+
*
|
|
346
|
+
* @example Simple handler for an HTTP request. Handles only success and ignores errors.
|
|
347
|
+
* <pre>
|
|
348
|
+
* $.request('get', '/weather.html')
|
|
349
|
+
* .then(function(txt) {
|
|
350
|
+
* alert('Got response!');
|
|
351
|
+
* });
|
|
352
|
+
* </pre>
|
|
353
|
+
*
|
|
354
|
+
* @example Including an error handler.
|
|
355
|
+
* <pre>
|
|
356
|
+
* $.request('get', '/weather.html')
|
|
357
|
+
* .then(function(txt) {
|
|
358
|
+
* alert('Got response!');
|
|
359
|
+
* }, function(err) {
|
|
360
|
+
* alert('Error!');
|
|
361
|
+
* }));
|
|
362
|
+
* </pre>
|
|
363
|
+
*
|
|
364
|
+
* @example Chained handler.
|
|
365
|
+
* <pre>
|
|
366
|
+
* $.request('get', '/weather.do')
|
|
367
|
+
* .then(function(txt) {
|
|
368
|
+
* showWeather(txt);
|
|
369
|
+
* }
|
|
370
|
+
* .then(function() {
|
|
371
|
+
* return $.request('get', '/traffic.do');
|
|
372
|
+
* }
|
|
373
|
+
* .then(function(txt) {
|
|
374
|
+
* showTraffic(txt);
|
|
375
|
+
* }
|
|
376
|
+
* .then(function() {
|
|
377
|
+
* alert('All result displayed');
|
|
378
|
+
* }, function() {
|
|
379
|
+
* alert('An error occurred');
|
|
380
|
+
* });
|
|
381
|
+
* </pre>
|
|
382
|
+
*
|
|
383
|
+
* @param onSuccess optional a callback function to be called when the operation has been completed successfully. The exact arguments it receives depend on the operation.
|
|
384
|
+
* If the function returns a ##promise#Promise##, that Promise will be evaluated to determine the state of the promise returned by <var>then()</var>. If it returns any other value, the
|
|
385
|
+
* returned Promise will also succeed. If the function throws an error, the returned Promise will be in error state.
|
|
386
|
+
* Pass <var>null</var> or <var>undefined</var> if you do not need the success handler.
|
|
387
|
+
* @param onError optional a callback function to be called when the operation failed. The exact arguments it receives depend on the operation. If the function returns a ##promise#Promise##, that promise will
|
|
388
|
+
* be evaluated to determine the state of the Promise returned by <var>then()</var>. If it returns anything else, the returned Promise will
|
|
389
|
+
* have success status. If the function throws an error, the returned Promise will be in the error state.
|
|
390
|
+
* You can pass <var>null</var> or <var>undefined</var> if you do not need the error handler.
|
|
391
|
+
* @return a new ##promise#Promise## object. If you specified a callback for success or error, the new Promises's state will be determined by that callback if it is called.
|
|
392
|
+
* If no callback has been provided and the original Promise changes to that state, the new Promise will change to that state as well.
|
|
393
|
+
*/
|
|
394
|
+
var then = set['then'] = function(onFulfilled, onRejected) {
|
|
395
|
+
var newPromise = promise();
|
|
396
|
+
var callCallbacks = function() {
|
|
397
|
+
try {
|
|
398
|
+
var f = (state ? onFulfilled : onRejected);
|
|
399
|
+
if (isFunction(f)) {
|
|
400
|
+
var r = f.apply(null, values);
|
|
401
|
+
if (r && isFunction(r['then']))
|
|
402
|
+
r['then'](function(value){newPromise(true,[value]);}, function(value){newPromise(false,[value]);});
|
|
403
|
+
else
|
|
404
|
+
newPromise(true, [r]);
|
|
405
|
+
}
|
|
406
|
+
else
|
|
407
|
+
newPromise(state, values);
|
|
408
|
+
}
|
|
409
|
+
catch (e) {
|
|
410
|
+
newPromise(false, [e]);
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
if (state != null)
|
|
414
|
+
delay(callCallbacks);
|
|
415
|
+
else
|
|
416
|
+
deferred.push(callCallbacks);
|
|
417
|
+
return newPromise;
|
|
418
|
+
};
|
|
419
|
+
/*$
|
|
420
|
+
* @id always
|
|
421
|
+
* @group REQUEST
|
|
422
|
+
* @name promise.always()
|
|
423
|
+
* @syntax promise.always(callback)
|
|
424
|
+
* @module WEB, UTIL
|
|
425
|
+
* Registers a callback that will always be called when the ##promise#Promise##'s operation ended, no matter whether the operation succeeded or not.
|
|
426
|
+
* This is a convenience function that will call ##then() with the same function for both arguments. It shares all of its semantics.
|
|
427
|
+
*
|
|
428
|
+
* @example Simple handler for a HTTP request.
|
|
429
|
+
* <pre>
|
|
430
|
+
* $.request('get', '/weather.html')
|
|
431
|
+
* .always(function() {
|
|
432
|
+
* alert('Got response or error!');
|
|
433
|
+
* });
|
|
434
|
+
* </pre>
|
|
435
|
+
*
|
|
436
|
+
* @param callback a function to be called when the operation has been finished, no matter what its result was. The exact arguments depend on the operation and may
|
|
437
|
+
* vary depending on whether it succeeded or not. If the function returns a ##promise#Promise##, that Promise will
|
|
438
|
+
* be evaluated to determine the state of the returned Promise. If provided and it returns regularly, the returned promise will
|
|
439
|
+
* have success status. If it throws an error, the returned Promise will be in the error state.
|
|
440
|
+
* @return a new ##promise#Promise## object. Its state is determined by the callback.
|
|
441
|
+
*/
|
|
442
|
+
set['always'] = function(func) { return then(func, func); };
|
|
443
|
+
|
|
444
|
+
/*$
|
|
445
|
+
* @id error
|
|
446
|
+
* @group REQUEST
|
|
447
|
+
* @name promise.error()
|
|
448
|
+
* @syntax promise.error(callback)
|
|
449
|
+
* @module WEB, UTIL
|
|
450
|
+
* Registers a callback that will be called when the operation failed.
|
|
451
|
+
* This is a convenience function that will invoke ##then() with the only the second argument set. It shares all of its semantics.
|
|
452
|
+
*
|
|
453
|
+
* @example Simple handler for a HTTP request.
|
|
454
|
+
* <pre>
|
|
455
|
+
* $.request('get', '/weather.html')
|
|
456
|
+
* .error(function() {
|
|
457
|
+
* alert('Got error!');
|
|
458
|
+
* });
|
|
459
|
+
* </pre>
|
|
460
|
+
*
|
|
461
|
+
* @param callback a function to be called when the operation has failed. The exact arguments depend on the operation. If the function returns a ##promise#Promise##, that Promise will
|
|
462
|
+
* be evaluated to determine the state of the returned Promise. If it returns regularly, the returned Promise will
|
|
463
|
+
* have success status. If it throws an error, the returned Promise will be in error state.
|
|
464
|
+
* @return a new ##promise#Promise## object. Its state is determined by the callback.
|
|
465
|
+
*/
|
|
466
|
+
set['error'] = function(func) { return then(0, func); };
|
|
467
|
+
return set;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/*$
|
|
471
|
+
* @id ucode
|
|
472
|
+
* @dependency
|
|
473
|
+
*/
|
|
474
|
+
// @condblock ie7compatibility
|
|
475
|
+
function ucode(a) {
|
|
476
|
+
return STRING_SUBSTITUTIONS[a] || ('\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4));
|
|
477
|
+
}
|
|
478
|
+
// @condend
|
|
479
|
+
|
|
480
|
+
/*$
|
|
481
|
+
* @stop
|
|
482
|
+
*/
|
|
483
|
+
|
|
484
|
+
function $(selector, context, childOnly) {
|
|
485
|
+
// @condblock ready
|
|
486
|
+
// isList(selector) is no joke, older Webkit versions return a function for childNodes...
|
|
487
|
+
return isFunction(selector) ? ready(selector) : new M(dollarRaw(selector, context, childOnly));
|
|
488
|
+
// @condend
|
|
489
|
+
// @cond !ready return new M(dollarRaw(selector, context));
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/*$
|
|
493
|
+
* @id debug
|
|
494
|
+
* @group OPTIONS
|
|
495
|
+
* (TBD) @configurable optional
|
|
496
|
+
* @doc no
|
|
497
|
+
* @name Debugging Support
|
|
498
|
+
*/
|
|
499
|
+
function error(msg) {
|
|
500
|
+
if (_window.console) console.log(msg);
|
|
501
|
+
throw Exception("Minified debug error: " + msg);
|
|
502
|
+
}
|
|
503
|
+
// @cond debug MINI['debug'] = true;
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
/*$
|
|
507
|
+
* @id dollarraw
|
|
508
|
+
* @requires
|
|
509
|
+
* @dependency yes
|
|
510
|
+
*/
|
|
511
|
+
function dollarRaw(selector, context, childOnly) {
|
|
512
|
+
|
|
513
|
+
function filterElements(list) { // converts into array, makes sure context is respected
|
|
514
|
+
var retList = (function flatten(a) { // flatten list, keep non-lists, remove nulls
|
|
515
|
+
return isList(a) ? collect(a, flatten) : a;
|
|
516
|
+
})(list);
|
|
517
|
+
if (parent)
|
|
518
|
+
return filter(retList, function(node) {
|
|
519
|
+
var a = node;
|
|
520
|
+
while (a = a.parentNode) {
|
|
521
|
+
if (a === parent)
|
|
522
|
+
return true;
|
|
523
|
+
if (childOnly)
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
// fall through to return undef
|
|
527
|
+
});
|
|
528
|
+
else
|
|
529
|
+
return retList;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
var parent, steps, dotPos, subSelectors;
|
|
533
|
+
var elements, regexpFilter, useGEbC, className, elementName, reg;
|
|
534
|
+
|
|
535
|
+
if (context && (context = dollarRaw(context)).length != 1) // if not exactly one node, iterate through all and concat
|
|
536
|
+
return collect(context, function(ci) { return dollarRaw(selector, ci, childOnly);});
|
|
537
|
+
parent = context && context[0]; // note that context may have changed in the previous two lines!! you can't move this line
|
|
538
|
+
|
|
539
|
+
if (!isString(selector))
|
|
540
|
+
return filterElements(isList(selector) ? selector : [selector]);
|
|
541
|
+
|
|
542
|
+
// @condblock ie7compatibility
|
|
543
|
+
if ((subSelectors = selector.split(/\s*,\s*/)).length>1)
|
|
544
|
+
return collect(subSelectors, function(ssi) { return dollarRaw(ssi, parent, childOnly);});
|
|
545
|
+
|
|
546
|
+
if (steps = (/(\S+)\s+(.+)$/.exec(selector)))
|
|
547
|
+
return dollarRaw(steps[2], dollarRaw(steps[1], parent), childOnly);
|
|
548
|
+
|
|
549
|
+
if (selector != (subSelectors = replace(selector, /^#/)))
|
|
550
|
+
return filterElements([_document.getElementById(subSelectors)]);
|
|
551
|
+
|
|
552
|
+
// @cond debug if (/\s/.test(selector)) error("Selector has invalid format, please check for whitespace.");
|
|
553
|
+
// @cond debug if (/[ :\[\]]/.test(selector)) error("Only simple selectors with ids, classes and element names are allowed.");
|
|
554
|
+
|
|
555
|
+
parent = parent || _document;
|
|
556
|
+
|
|
557
|
+
elementName = (dotPos = /([^.]*)\.?([^.]*)/.exec(selector))[1];
|
|
558
|
+
className = dotPos[2];
|
|
559
|
+
elements = (useGEbC = parent.getElementsByClassName && className) ? parent.getElementsByClassName(className) : parent.getElementsByTagName(elementName || '*');
|
|
560
|
+
|
|
561
|
+
if (regexpFilter = useGEbC ? elementName : className) {
|
|
562
|
+
reg = new RegExp(BACKSLASHB + regexpFilter + BACKSLASHB, 'i');
|
|
563
|
+
elements = filter(elements, function(l) {return reg.test(l[useGEbC ? 'nodeName' : 'className']);});
|
|
564
|
+
}
|
|
565
|
+
// @condend
|
|
566
|
+
|
|
567
|
+
// @cond !ie7compatibility elements = (parent || _document).querySelectorAll(selector);
|
|
568
|
+
return parent ? filterElements(elements) : elements;
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
/*$
|
|
573
|
+
* @id length
|
|
574
|
+
* @group SELECTORS
|
|
575
|
+
* @requires dollar
|
|
576
|
+
* @name .length
|
|
577
|
+
* @syntax length
|
|
578
|
+
* @module WEB, UTIL
|
|
579
|
+
*
|
|
580
|
+
* Contains the number of elements in the list.
|
|
581
|
+
*
|
|
582
|
+
* @example
|
|
583
|
+
* <pre>
|
|
584
|
+
* var list = $('input');
|
|
585
|
+
* var myValues = {};
|
|
586
|
+
* for (var i = 0; i < list.length; i++)
|
|
587
|
+
* myValues[list[i].name] = list[i].value;
|
|
588
|
+
* </pre>
|
|
589
|
+
*/
|
|
590
|
+
// empty, always defined below
|
|
591
|
+
|
|
592
|
+
/*$
|
|
593
|
+
* @id listctor
|
|
594
|
+
*/
|
|
595
|
+
/** @constructor */
|
|
596
|
+
function M(array) {
|
|
597
|
+
var len = this['length'] = array.length;
|
|
598
|
+
for (var i = 0; i < len; i++)
|
|
599
|
+
this[i] = array[i];
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
//// LIST FUNCTIONS ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
603
|
+
|
|
604
|
+
eachObj({
|
|
605
|
+
/*$
|
|
606
|
+
* @id each
|
|
607
|
+
* @group SELECTORS
|
|
608
|
+
* @requires dollar
|
|
609
|
+
* @configurable default
|
|
610
|
+
* @name .each()
|
|
611
|
+
* @syntax each(callback)
|
|
612
|
+
* @module WEB, UTIL
|
|
613
|
+
* Invokes the given function once for each item in the list. The function will be called with the item as first parameter and
|
|
614
|
+
* the zero-based index as second.
|
|
615
|
+
*
|
|
616
|
+
* @example This goes through all h2 elements of the class 'section' and changes their content:
|
|
617
|
+
* <pre>
|
|
618
|
+
* $('h2.section').each(function(item, index) {
|
|
619
|
+
* item.innerHTML = 'Section ' + index + ': ' + item.innerHTML;
|
|
620
|
+
* });
|
|
621
|
+
* </pre>
|
|
622
|
+
*
|
|
623
|
+
* @param callback The callback <code>function(item, index)</code> to invoke for each list element.
|
|
624
|
+
* <dl><dt>item</dt><dd>The current list element.</dd><dt>index</dt><dd>The second the zero-based index of the current element.</dd></dl>
|
|
625
|
+
* The callback's return value will be ignored.
|
|
626
|
+
* @return the list
|
|
627
|
+
*/
|
|
628
|
+
'each': function (callback) {
|
|
629
|
+
return each(this, callback);
|
|
630
|
+
},
|
|
631
|
+
|
|
632
|
+
/*$
|
|
633
|
+
* @id filter
|
|
634
|
+
* @group SELECTORS
|
|
635
|
+
* @requires dollar
|
|
636
|
+
* @configurable default
|
|
637
|
+
* @name .filter()
|
|
638
|
+
* @syntax filter(filterFunc)
|
|
639
|
+
* @module WEB, UTIL
|
|
640
|
+
* Creates a new ##list#Minified list## that contains only those items approved by the given callback function. The function is
|
|
641
|
+
* called once for each item.
|
|
642
|
+
* If the callback function returns true, the item is shallow-copied in the new list, otherwise it will be removed.
|
|
643
|
+
*
|
|
644
|
+
* @example Creates a list of all unchecked checkboxes.
|
|
645
|
+
* <pre>
|
|
646
|
+
* var list = $('input').filter(function(item) {
|
|
647
|
+
* return item.getAttribute('type') == 'checkbox' && item.checked;
|
|
648
|
+
* });
|
|
649
|
+
* </pre>
|
|
650
|
+
*
|
|
651
|
+
* @param filterFunc The filter callback <code>function(item, index)</code> that decides which elements to include:
|
|
652
|
+
* <dl><dt>item</dt><dd>The current list element.</dd><dt>index</dt><dd>The second the zero-based index of the current element.</dd>
|
|
653
|
+
* <dt class="returnValue">(callback return value)</dt><dd><var>true</var> to include the item in the new list, <var>false</var> to omit it.</dd></dl>
|
|
654
|
+
* @return the new, filtered ##list#list##
|
|
655
|
+
*/
|
|
656
|
+
'filter': function(filterFunc) {
|
|
657
|
+
return new M(filter(this, filterFunc));
|
|
658
|
+
},
|
|
659
|
+
|
|
660
|
+
/*$
|
|
661
|
+
* @id collect
|
|
662
|
+
* @group SELECTORS
|
|
663
|
+
* @requires dollar
|
|
664
|
+
* @configurable default
|
|
665
|
+
* @name .collect()
|
|
666
|
+
* @syntax collect(collectFunc)
|
|
667
|
+
* @module WEB, UTIL
|
|
668
|
+
* Creates a new ##list#Minified list## from the current list using the given callback function.
|
|
669
|
+
* The callback is invoked once for each element of the current list. The callback results will be added to the result list.
|
|
670
|
+
* The callback can return
|
|
671
|
+
* <ul>
|
|
672
|
+
* <li>an array or another list-like object. Its content will be appended to the resulting list.</li>
|
|
673
|
+
* <li>a regular object which will be appended to the list</li>
|
|
674
|
+
* <li><var>null</var> (or <var>undefined</var>), which means that no object will be added to the list.
|
|
675
|
+
* If you need to add <var>null</var> or <var>undefined</var> to the result list, put it into a single-element array.</li>
|
|
676
|
+
* </ul>
|
|
677
|
+
*
|
|
678
|
+
*
|
|
679
|
+
* @example Goes through input elements. If they are text inputs, their value will be added to the list:
|
|
680
|
+
* <pre>
|
|
681
|
+
* var texts = $('input').collect(function(input) {
|
|
682
|
+
* if (input.getAttribute('type') != null || input.getAttribute('type') == 'text')
|
|
683
|
+
* return input.value;
|
|
684
|
+
* else
|
|
685
|
+
* return null; // ignore
|
|
686
|
+
* });
|
|
687
|
+
* </pre>
|
|
688
|
+
*
|
|
689
|
+
* @example Creates a list of all children of the selected list.
|
|
690
|
+
* <pre>
|
|
691
|
+
* var childList = $('.mySections').collect(function(node) {
|
|
692
|
+
* return node.childNodes; // adds a while list of nodes
|
|
693
|
+
* });
|
|
694
|
+
* </pre>
|
|
695
|
+
*
|
|
696
|
+
* @example Goes through selected input elements. For each hit, the innerHTML is added twice, once in lower case and once in upper case:
|
|
697
|
+
* <pre>
|
|
698
|
+
* var elements = $('input.myTexts').collect(function(item) {
|
|
699
|
+
* return [item.innerHTML.toLowerCase(), item.innerHTML.toUpperCase()];
|
|
700
|
+
* });
|
|
701
|
+
* </pre>
|
|
702
|
+
*
|
|
703
|
+
* @param collectFunc The callback <code>function(item, index)</code> to invoke for each item:
|
|
704
|
+
* <dl><dt>item</dt><dd>The current list element.</dd><dt>index</dt><dd>The second the zero-based index of the current element.</dd>
|
|
705
|
+
* <dt class="returnValue">(callback return value)</dt><dd>If the callback returns a list, its elements will be added to
|
|
706
|
+
* the result list. Other objects will also be added. Nulls and <var>undefined</var> will be ignored and be not added to
|
|
707
|
+
* the new result list. </dd></dl>
|
|
708
|
+
* @return the new ##list#list##
|
|
709
|
+
*/
|
|
710
|
+
'collect': function(collectFunc) {
|
|
711
|
+
return new M(collect(this, collectFunc));
|
|
712
|
+
},
|
|
713
|
+
|
|
714
|
+
/*$
|
|
715
|
+
* @id sub
|
|
716
|
+
* @group SELECTORS
|
|
717
|
+
* @requires filter
|
|
718
|
+
* @configurable default
|
|
719
|
+
* @name .sub()
|
|
720
|
+
* @syntax sub(startIndex)
|
|
721
|
+
* @syntax sub(startIndex, endIndex)
|
|
722
|
+
* @module WEB, UTIL
|
|
723
|
+
* Returns a new ##list#Minified list## containing only the elements in the specified range. If there are no elements in the range,
|
|
724
|
+
* an empty list is returned.
|
|
725
|
+
* Negative indices are supported and will be added to the list's length, thus allowing you to specify ranges at the list's end.
|
|
726
|
+
*
|
|
727
|
+
* @example Adds some text the 3rd to 5th list elements:
|
|
728
|
+
* <pre>
|
|
729
|
+
* $('#myList li').sub(3, 6).add('Hello');
|
|
730
|
+
* </pre>
|
|
731
|
+
*
|
|
732
|
+
* @example Clears all elements but the first:
|
|
733
|
+
* <pre>
|
|
734
|
+
* $('#myList li').sub(1).fill();
|
|
735
|
+
* </pre>
|
|
736
|
+
*
|
|
737
|
+
* @example Changes the class of the last list element:
|
|
738
|
+
* <pre>
|
|
739
|
+
* $('#myList li').sub(-1).set('+lastItem');
|
|
740
|
+
* </pre>
|
|
741
|
+
*
|
|
742
|
+
* @param startIndex the 0-based position of the sub-list start. If negative, the list's length is added and the position is relative
|
|
743
|
+
* to the list's end.
|
|
744
|
+
* @param endIndex optional the 0-based position of the sub-list end. If negative, the list's length is added and the position is relative
|
|
745
|
+
* to the list's end. If omitted or null, all elements following the <var>startIndex</var> are included in the result.
|
|
746
|
+
* @return a new ##list#list## containing only the items in the index range.
|
|
747
|
+
*/
|
|
748
|
+
'sub': function(startIndex, endIndex) {
|
|
749
|
+
var self = this;
|
|
750
|
+
var s = (startIndex < 0 ? self['length']+startIndex : startIndex);
|
|
751
|
+
var e = endIndex >= 0 ? endIndex : self['length'] + (endIndex || 0);
|
|
752
|
+
return new M(filter(self, function(o, index) {
|
|
753
|
+
return index >= s && index < e;
|
|
754
|
+
}));
|
|
755
|
+
},
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
/*$
|
|
759
|
+
* @id find
|
|
760
|
+
* @group SELECTORS
|
|
761
|
+
* @requires
|
|
762
|
+
* @configurable default
|
|
763
|
+
* @name .find()
|
|
764
|
+
* @syntax find(findFunc)
|
|
765
|
+
* @syntax find(element)
|
|
766
|
+
* @module WEB, UTIL
|
|
767
|
+
* Finds a specific value in the list. There are two ways of calling <var>find()</var>:
|
|
768
|
+
* <ol>
|
|
769
|
+
* <li>With an element as argument. Then <var>find()</var> will search for the first occurrence of that element in the list
|
|
770
|
+
* and return the index. If it is not found, <var>find()</var> returns <var>undefined</var>.</li>
|
|
771
|
+
* <li>With a callback function. <var>find()</var> will then call the given function for each list element until the function
|
|
772
|
+
* returns a value that is not <var>null</var> or <var>undefined</var>. This value will be returned.</li>
|
|
773
|
+
* </ol>
|
|
774
|
+
*
|
|
775
|
+
* @example Determines the position of the element with the id '#wanted' among all li elements:
|
|
776
|
+
* <pre>
|
|
777
|
+
* var elementIndex = $('li').find($$('#wanted'));
|
|
778
|
+
* </pre>
|
|
779
|
+
*
|
|
780
|
+
* @example Goes through the elements to find the first div that has the class 'myClass', and returns this element:
|
|
781
|
+
* <pre>
|
|
782
|
+
* var myClassElement = $('div').find(function(e) { if ($(e).hasClass('myClass')) return e; });
|
|
783
|
+
* </pre>
|
|
784
|
+
*
|
|
785
|
+
* @param findFunc The callback <code>function(item, index)</code> that will be invoked for every list item until it returns a non-null value:
|
|
786
|
+
* <dl><dt>item</dt><dd>The current list element.</dd><dt>index</dt><dd>The second the zero-based index of the current element.</dd>
|
|
787
|
+
* <dt class="returnValue">(callback return value)</dt><dd>If the callback returns something other than <var>null</var> or
|
|
788
|
+
* <var>undefined</var>, <var>find()</var> will return it directly. Otherwise it will continue. </dd></dl>
|
|
789
|
+
* @param element the element to search for
|
|
790
|
+
* @return if called with an element, either the element's index in the list or <var>undefined</var> if not found. If called with a callback function,
|
|
791
|
+
* it returns either the value returned by the callback or <var>undefined</var>.
|
|
792
|
+
*/
|
|
793
|
+
'find': function(findFunc) {
|
|
794
|
+
var self = this, r;
|
|
795
|
+
var f = isFunction(findFunc) ? findFunc : function(obj, index) { if (findFunc === obj) return index; };
|
|
796
|
+
for (var i = 0; i < self.length; i++)
|
|
797
|
+
if ((r = f(self[i], i)) != null)
|
|
798
|
+
return r;
|
|
799
|
+
},
|
|
800
|
+
|
|
801
|
+
/*$
|
|
802
|
+
* @id hasclass
|
|
803
|
+
* @group SELECTORS
|
|
804
|
+
* @requires find
|
|
805
|
+
* @configurable default
|
|
806
|
+
* @name .hasClass()
|
|
807
|
+
* @syntax hasClass(className)
|
|
808
|
+
* @module WEB
|
|
809
|
+
* Checks whether at least one HTML element in the list has the given CSS class name.
|
|
810
|
+
* If yes, the first element that matches is returned. Otherwise the function returns <var>undefined</var>. List elements that do not
|
|
811
|
+
* have a <var>className</var> property will be ignored.
|
|
812
|
+
*
|
|
813
|
+
* @example Checks whether the element 'myElement' has the class 'myClass'. If yes, it sets the text color to red.
|
|
814
|
+
* <pre>
|
|
815
|
+
* if($('#myElement').hasClass('myClass'))
|
|
816
|
+
* $('#myElement').set('$color', 'red');
|
|
817
|
+
* </pre>
|
|
818
|
+
*
|
|
819
|
+
* @param className the class to to find
|
|
820
|
+
* @return the first element that has the given class, or <var>undefined</var> if not found
|
|
821
|
+
*/
|
|
822
|
+
'hasClass': function(className) {
|
|
823
|
+
var regexp = new RegExp(BACKSLASHB + className + BACKSLASHB);
|
|
824
|
+
return this['find'](function(e) { return regexp.test(e.className) ? e : null; });
|
|
825
|
+
},
|
|
826
|
+
|
|
827
|
+
/*$
|
|
828
|
+
* @id remove
|
|
829
|
+
* @group SELECTORS
|
|
830
|
+
* @requires dollar
|
|
831
|
+
* @configurable default
|
|
832
|
+
* @name .remove()
|
|
833
|
+
* @syntax remove()
|
|
834
|
+
* @module WEB
|
|
835
|
+
* Removes all nodes of the list from the DOM tree.
|
|
836
|
+
*
|
|
837
|
+
* @example Removes the element with the id 'myContainer', including all children, from the DOM tree.
|
|
838
|
+
* <pre>
|
|
839
|
+
* $('#myContainer').remove();
|
|
840
|
+
* </pre>
|
|
841
|
+
*/
|
|
842
|
+
'remove': function() {
|
|
843
|
+
each(this, function(obj) {obj.parentNode.removeChild(obj);});
|
|
844
|
+
},
|
|
845
|
+
|
|
846
|
+
/*$
|
|
847
|
+
* @id text
|
|
848
|
+
* @group SELECTORS
|
|
849
|
+
* @requires dollar
|
|
850
|
+
* @configurable default
|
|
851
|
+
* @name .text()
|
|
852
|
+
* @syntax text()
|
|
853
|
+
* @module WEB
|
|
854
|
+
* Returns the concatenated text content of all nodes in the list.
|
|
855
|
+
* This is done by going recursively through all elements and their children. The values of text and CDATA nodes
|
|
856
|
+
* will be appended to the resulting string.
|
|
857
|
+
*
|
|
858
|
+
* Please note that, unlike jQuery's <var>text()</var>, Minified's will not set text content. Use ##fill() to do this.
|
|
859
|
+
*
|
|
860
|
+
* @example Returns the text of the element with the id 'myContainer'.
|
|
861
|
+
* <pre>
|
|
862
|
+
* var content = $('#myContainer').text();
|
|
863
|
+
* </pre>
|
|
864
|
+
*/
|
|
865
|
+
'text': function () {
|
|
866
|
+
function extractString(e) {
|
|
867
|
+
var nodeType = isNode(e);
|
|
868
|
+
if (nodeType == 1)
|
|
869
|
+
return collect(e['childNodes'], extractString);
|
|
870
|
+
else if (nodeType < 5) // 2 is impossible (attribute), so only 3 (text) and 4 (cdata)..
|
|
871
|
+
return e['data'];
|
|
872
|
+
else
|
|
873
|
+
return null;
|
|
874
|
+
}
|
|
875
|
+
return collect(this, extractString)['join']('');
|
|
876
|
+
},
|
|
877
|
+
|
|
878
|
+
/*$
|
|
879
|
+
* @id get
|
|
880
|
+
* @group SELECTORS
|
|
881
|
+
* @requires dollar
|
|
882
|
+
* @configurable default
|
|
883
|
+
* @name .get()
|
|
884
|
+
* @syntax get(name)
|
|
885
|
+
* @syntax get(name, toNumber)
|
|
886
|
+
* @syntax get(list)
|
|
887
|
+
* @syntax get(list, toNumber)
|
|
888
|
+
* @syntax get(map)
|
|
889
|
+
* @syntax get(map, toNumber)
|
|
890
|
+
* @module WEB
|
|
891
|
+
* Retrieves properties, attributes and styles from the list's first element. The syntax to request those values is mostly identical with ##set(). You can either
|
|
892
|
+
* get a single value if you specify only one name, or get a name->value map when you specify several names using an array or a map.
|
|
893
|
+
*
|
|
894
|
+
* @example Retrieves the id, title attribute and the background color of the element '#myElement':
|
|
895
|
+
* <pre>
|
|
896
|
+
* var id = $('#myElement).get('id');
|
|
897
|
+
* var title = $('#myElement).get('@title');
|
|
898
|
+
* var bgColor = $('#myElement).get('$backgroundColor');
|
|
899
|
+
* </pre>
|
|
900
|
+
*
|
|
901
|
+
* @example Retrieves the id, title attribute and the background color of the element '#myElement' as a map:
|
|
902
|
+
* <pre>
|
|
903
|
+
* var m = $('#myElement).get(['id', '@title', '$backgroundColor']);
|
|
904
|
+
* var id = m.id;
|
|
905
|
+
* var title = m['@title'];
|
|
906
|
+
* var bgColor = m.$backgroundColor;
|
|
907
|
+
* </pre>
|
|
908
|
+
*
|
|
909
|
+
* @example Uses ##get() and ##set() to reposition an element:
|
|
910
|
+
* <pre>
|
|
911
|
+
* var coords = $('#myElement').get({$top: 0, $left: 0}, true);
|
|
912
|
+
* coords.$top = coords.$top + 10 + 'px';
|
|
913
|
+
* coords.$left = coords.$left + 20 + 'px';
|
|
914
|
+
* $('#myElement').set(coords);
|
|
915
|
+
* </pre>
|
|
916
|
+
* Please note that the values of $top and $left in the <var>get()</var> invocation do not matter and will be ignored!
|
|
917
|
+
*
|
|
918
|
+
* @param name the name of the property, attribute or style. To retrieve a JavaScript property, just use its name without prefix. To get an attribute value,
|
|
919
|
+
* prefix the name with a '@'. A '$' prefix will retrieve a CSS style. The syntax for the CSS styles is camel-case (e.g. "backgroundColor", not "background-color").
|
|
920
|
+
* Shorthand properties like "border" or "margin" are not supported. You must use the full name, e.g. "marginTop". Minified will try to determine the effective style
|
|
921
|
+
* and thus will return the value set in style sheets if not overwritten using a regular style.
|
|
922
|
+
* Using just '$' as name will retrieve the 'className' property of the object, a space-separated list of all CSS classes.
|
|
923
|
+
* The special name '$$' will set the element's style attribute in a browser independent way.
|
|
924
|
+
* '$$fade' returns a value between 0 and 1 that specifies the element's
|
|
925
|
+
* opacity. '$$slide' returns the height of the element in pixels, with a 'px' suffix. Both '$$fade' and '$$slide' will also check the CSS styles 'visibility' and 'display'
|
|
926
|
+
* to determine whether the object is visible at all. If not, they will return 0.
|
|
927
|
+
* @param list in order to retrieve more than one value, you can specify several names in an array or list. <var>get()</var> will then return a name->value map of results.
|
|
928
|
+
* @param map if you specify an object that is neither list nor string, <var>get()</var> will use it as a map of property names. Each property name will be requested. The values of the properties in
|
|
929
|
+
* the map will be ignored. <var>get()</var> will then return a name->value map of results.
|
|
930
|
+
* @param toNumber if 'true', <var>get()</var> converts all returned values into numbers. If they are strings,
|
|
931
|
+
* <var>get()</var> removes any non-numeric characters before the conversion. This is useful when you request
|
|
932
|
+
* a CSS property such as '$marginTop' that returns a value with a unit suffix, like "21px". <var>get()</var> will convert it
|
|
933
|
+
* into a number and return 21. If the returned value is not parsable as a number, <var>NaN</var> will be returned.
|
|
934
|
+
* @return if <var>get()</var> was called with a single name, it returns the corresponding value.
|
|
935
|
+
* If a list or map was given, <var>get()</var> returns a new map with the names as keys and the values as values.
|
|
936
|
+
* Always returns <var>undefined</var> if the list is empty.
|
|
937
|
+
*/
|
|
938
|
+
'get': function(spec, toNumber) {
|
|
939
|
+
var self = this, element = self[0];
|
|
940
|
+
|
|
941
|
+
if (element) {
|
|
942
|
+
if (isString(spec)) {
|
|
943
|
+
var name = replace(spec, /^[$@]/);
|
|
944
|
+
var s;
|
|
945
|
+
if (spec == '$')
|
|
946
|
+
s = element.className;
|
|
947
|
+
else if (spec == '$$') {
|
|
948
|
+
// @condblock ie8compatibility
|
|
949
|
+
if (IS_PRE_IE9)
|
|
950
|
+
s = element['style']['cssText'];
|
|
951
|
+
else
|
|
952
|
+
// @condend
|
|
953
|
+
s = element.getAttribute('style');
|
|
954
|
+
}
|
|
955
|
+
// @condblock fadeslide
|
|
956
|
+
else if (/\$\$/.test(spec) && (element['style']['visibility'] == 'hidden' || element['style']['display'] == 'none')) {
|
|
957
|
+
s = 0;
|
|
958
|
+
}
|
|
959
|
+
else if (spec == '$$fade') {
|
|
960
|
+
s = isNaN(s =
|
|
961
|
+
// @condblock ie8compatibility
|
|
962
|
+
IS_PRE_IE9 ? extractNumber(element['style']['filter'])/100 :
|
|
963
|
+
// @condend
|
|
964
|
+
extractNumber(element['style']['opacity'])
|
|
965
|
+
) ? 1 : s;
|
|
966
|
+
}
|
|
967
|
+
else if (spec == '$$slide') {
|
|
968
|
+
s = self['get']('$height');
|
|
969
|
+
}
|
|
970
|
+
// @condend fadeslide
|
|
971
|
+
else if (/^\$/.test(spec)) {
|
|
972
|
+
// @condblock ie8compatibility
|
|
973
|
+
if (!_window.getComputedStyle)
|
|
974
|
+
s = (element.currentStyle||element['style'])[name];
|
|
975
|
+
else
|
|
976
|
+
// @condend
|
|
977
|
+
s = _window.getComputedStyle(element, null).getPropertyValue(replace(name, /[A-Z]/g, function (match) { return '-' + match.toLowerCase(); }));
|
|
978
|
+
}
|
|
979
|
+
else if (/^@/.test(spec))
|
|
980
|
+
s = element.getAttribute(name);
|
|
981
|
+
else
|
|
982
|
+
s = element[name];
|
|
983
|
+
return toNumber ? extractNumber(s) : s;
|
|
984
|
+
}
|
|
985
|
+
else {
|
|
986
|
+
var r = {};
|
|
987
|
+
(isList(spec) ? each : eachObj)(spec, function(name) {
|
|
988
|
+
r[name] = self['get'](name, toNumber);
|
|
989
|
+
});
|
|
990
|
+
return r;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
},
|
|
994
|
+
|
|
995
|
+
/*$
|
|
996
|
+
* @id set
|
|
997
|
+
* @group SELECTORS
|
|
998
|
+
* @requires dollar get
|
|
999
|
+
* @configurable default
|
|
1000
|
+
* @name .set()
|
|
1001
|
+
* @syntax set(name, value)
|
|
1002
|
+
* @syntax set(properties)
|
|
1003
|
+
* @syntax set(cssClasses)
|
|
1004
|
+
* @module WEB
|
|
1005
|
+
*
|
|
1006
|
+
* Modifies the list's elements by setting their properties, attributes, CSS styles and/or CSS classes. You can either supply a
|
|
1007
|
+
* single name and value to set only one property, or you can provide an object that contains name/value pairs to describe more than one property.
|
|
1008
|
+
* More complex operations can be accomplished by supplying a function as value. It will then be called for each element that will
|
|
1009
|
+
* be set.
|
|
1010
|
+
*
|
|
1011
|
+
* The name given to <var>set()</var> defines what kind of data you are setting. The following name schemes are supported:
|
|
1012
|
+
*
|
|
1013
|
+
* <table>
|
|
1014
|
+
* <tr><th>Name Schema</th><th>Example</th><th>Sets what?</th><th>Description</th></tr>
|
|
1015
|
+
* <tr><td>name</td><td>innerHTML</td><td>Property</td><td>A name without prefix of '$' or '@' sets a property of the object.</td></tr>
|
|
1016
|
+
* <tr><td>@name</td><td>@href</td><td>Attribute</td><td>Sets the HTML attribute using setAttribute(). In order to stay compatible with Internet Explorer 7 and earlier,
|
|
1017
|
+
* you should not set the attributes '@class' and '@style'. Instead use '$' and '$$' as shown below.</td></tr>
|
|
1018
|
+
* <tr><td>$name</td><td>$fontSize</td><td>CSS Property</td><td>Sets a style using the element's <var>style</var> object.</td></tr>
|
|
1019
|
+
* <tr><td>$</td><td>$</td><td>CSS Classes</td><td>A simple <var>$</var> modifies the element's CSS classes using the object's <var>className</var> property. The value is a
|
|
1020
|
+
* space-separated list of class names. If prefixed with '-' the class is removed, a '+' prefix adds the class and a class name without prefix toggles the class.
|
|
1021
|
+
* The name '$' can also be omitted if <var>set</var> is called with class names as only argument.</td></tr>
|
|
1022
|
+
* <tr><td>$$</td><td>$$</td><td>Style</td><td>Sets the element's style attribute in a browser-independent way.</td></tr>
|
|
1023
|
+
* <tr><td>$$fade</td><td>$$fade</td><td>Fade Effect</td><td>The name '$$fade' sets the opacity of the element in a browser-independent way. The value must be a number
|
|
1024
|
+
* between 0 and 1. '$$fade' will also automatically control the element's 'visibility' and 'display' styles. If the value is 0,
|
|
1025
|
+
* the element's visibility will automatically be set to 'hidden'. If the value is larger, the visibility will be set to
|
|
1026
|
+
* 'visible' and the display style to 'block'. '$$fade' only works with block elements.</td></tr>
|
|
1027
|
+
* <tr><td>$$slide</td><td>$$slide</td><td>Slide Effect</td><td>The name '$$slide' allows a vertical slide-out or slide-in effect. The value must be a number
|
|
1028
|
+
* between 0 and 1. '$$slide' will also automatically control the element's 'visibility' and 'display' styles. If the value is 0,
|
|
1029
|
+
* the element's visibility will automatically be set to 'hidden'. If the value is larger, the visibility will be set to
|
|
1030
|
+
* 'visible' and the display style to 'block'. '$$slide' only works with block elements.</td></tr>
|
|
1031
|
+
* </table>
|
|
1032
|
+
*
|
|
1033
|
+
* @example Unchecking checkboxes:
|
|
1034
|
+
* <pre>
|
|
1035
|
+
* $('input.checkbox').set('checked', false);
|
|
1036
|
+
* </pre>
|
|
1037
|
+
*
|
|
1038
|
+
* @example Changing the <var>innerHTML</var property of an element:
|
|
1039
|
+
* <pre>
|
|
1040
|
+
* $('#toc').set('innerHTML', 'Content');
|
|
1041
|
+
* </pre>
|
|
1042
|
+
*
|
|
1043
|
+
* @example Changing attributes:
|
|
1044
|
+
* <pre>
|
|
1045
|
+
* $('a.someLinks').set('@href', 'http://www.example.com/');
|
|
1046
|
+
* </pre>
|
|
1047
|
+
*
|
|
1048
|
+
* @example Removing attributes:
|
|
1049
|
+
* <pre>
|
|
1050
|
+
* $('a.someLinks').set('@title', null);
|
|
1051
|
+
* </pre>
|
|
1052
|
+
*
|
|
1053
|
+
* @example Changing styles:
|
|
1054
|
+
* <pre>
|
|
1055
|
+
* $('.bigText').set('$font-size', 'x-large');
|
|
1056
|
+
* </pre>
|
|
1057
|
+
*
|
|
1058
|
+
* @example Adding and removing CSS classes:
|
|
1059
|
+
* <pre>
|
|
1060
|
+
* $('.myElem').set('$', '+myClass -otherClass');
|
|
1061
|
+
* </pre>
|
|
1062
|
+
*
|
|
1063
|
+
* @example Toggling a CSS class:
|
|
1064
|
+
* <pre>
|
|
1065
|
+
* $('.myElem').set('$', 'on');
|
|
1066
|
+
* </pre>
|
|
1067
|
+
*
|
|
1068
|
+
* @example Shortcut for CSS manipulation:
|
|
1069
|
+
* <pre>
|
|
1070
|
+
* $('.myElem').set('+myClass -otherClass on');
|
|
1071
|
+
* </pre>
|
|
1072
|
+
*
|
|
1073
|
+
* @example Making an element transparent:
|
|
1074
|
+
* <pre>
|
|
1075
|
+
* $('.seeThrough').set('$$fade', 0.5);
|
|
1076
|
+
* </pre>
|
|
1077
|
+
*
|
|
1078
|
+
* @example Making an element visible. Note that $$fade will set the element's display style to 'block' and visibility style to 'visible'.
|
|
1079
|
+
* <pre>
|
|
1080
|
+
* $('.myElem').set('$$fade', 1);
|
|
1081
|
+
* </pre>
|
|
1082
|
+
*
|
|
1083
|
+
* @example Using a map to change several properties:
|
|
1084
|
+
* <pre>
|
|
1085
|
+
* $('input.checkbox').set({checked: false,
|
|
1086
|
+
* 'parentNode.@title': 'Check this'});
|
|
1087
|
+
* </pre>
|
|
1088
|
+
*
|
|
1089
|
+
* @example Changing CSS with a map:
|
|
1090
|
+
* <pre>
|
|
1091
|
+
* $('.importantText').set({$fontSize: 'x-large',
|
|
1092
|
+
* $color: 'black',
|
|
1093
|
+
* $backgroundColor: 'red',
|
|
1094
|
+
* $: '+selected -default'});
|
|
1095
|
+
* </pre>
|
|
1096
|
+
*
|
|
1097
|
+
* @example You can specify a function as value to modify a value instead of just setting it:
|
|
1098
|
+
* <pre>
|
|
1099
|
+
* $('h2').set('innerHTML', function(oldValue, index) {
|
|
1100
|
+
* return 'Chapter ' + index + ': ' + oldValue.toUpperCase();
|
|
1101
|
+
* });
|
|
1102
|
+
* </pre>
|
|
1103
|
+
*
|
|
1104
|
+
* @param name the name of a single property or attribute to modify. If prefixed with '@', it is treated as a DOM element's attribute.
|
|
1105
|
+
* A dollar ('$') prefix is a shortcut for CSS styles. A simple dollar ('$') as name modifies CSS classes.
|
|
1106
|
+
* The special name '$$' allows you to set the <var>style</var> attribute in a browser independent way.
|
|
1107
|
+
* The special name '$$fade' and '$$slide' create fade and slide effects, and both expect a value between 0 and 1.
|
|
1108
|
+
*
|
|
1109
|
+
*
|
|
1110
|
+
* @param value the value to set. If value is null and name specified an attribute, the attribute will be removed.
|
|
1111
|
+
* If a dollar ('$') has been passed as name, the value can contain space-separated CSS class names. If prefixed with a '+' the class will be added,
|
|
1112
|
+
* with a '-' prefix the class will be removed. Without prefix, the class will be toggled.
|
|
1113
|
+
* If <var>value</var> is a function, the <code>function(oldValue, index, obj)</code> will be invoked for each list element
|
|
1114
|
+
* to evaluate the new value:
|
|
1115
|
+
* <dl><dt>oldValue</dt><dd>The old value of the property to be changed, as returned by ##get().
|
|
1116
|
+
* For the CSS style names, this is the computed style of the property </dd>
|
|
1117
|
+
* <dt>index</dt><dd>The list index of the object owning the property</dd>
|
|
1118
|
+
* <dt>obj</dt><dd>The list element owning the property.<dd>
|
|
1119
|
+
* <dt class="returnValue">(callback return value)</dt><dd>The value to be set.</dd></dl>
|
|
1120
|
+
* Functions are not supported by '$'.
|
|
1121
|
+
* @param properties a Object as map containing names as keys and the values to set as map values. See above for the name syntax.
|
|
1122
|
+
* @param cssClasses if <var>set()</var> is invoked with a string as single argument, the name "$" (CSS classes) is used and the argument is the
|
|
1123
|
+
* value. See above for CSS syntax.
|
|
1124
|
+
* Instead of a string, you can also specify a <code>function(oldValue, index, obj)</code> to modify the existing classes.
|
|
1125
|
+
* @return the list
|
|
1126
|
+
*/
|
|
1127
|
+
'set': function (name, value) {
|
|
1128
|
+
function setAttr(obj, n, v) {
|
|
1129
|
+
if (v != null)
|
|
1130
|
+
obj.setAttribute(n, v);
|
|
1131
|
+
else
|
|
1132
|
+
obj.removeAttribute(n);
|
|
1133
|
+
}
|
|
1134
|
+
var self = this, v;
|
|
1135
|
+
// @cond debug if (name == null) error("First argument must be set!");
|
|
1136
|
+
if (value !== undef) {
|
|
1137
|
+
// @cond debug if (!/string/i.test(typeof name)) error('If second argument is given, the first one must be a string specifying the property name");
|
|
1138
|
+
|
|
1139
|
+
// @condblock fadeslide
|
|
1140
|
+
if (name == '$$fade' || name == '$$slide') {
|
|
1141
|
+
self.set({'$visibility': (v = extractNumber(value)) > 0 ? 'visible' : 'hidden', '$display': 'block'})
|
|
1142
|
+
.set((name == '$$fade') ? (
|
|
1143
|
+
// @condblock ie8compatibility
|
|
1144
|
+
IS_PRE_IE9 ? {'$filter': 'alpha(opacity = '+(100*v)+')', '$zoom': 1} :
|
|
1145
|
+
// @condend ie8compatibility
|
|
1146
|
+
{'$opacity': v})
|
|
1147
|
+
:
|
|
1148
|
+
{'$height': /px$/.test(value) ? value : function(oldValue, idx, element) { return v * (v && getNaturalHeight($(element))) + 'px';},
|
|
1149
|
+
'$overflow': 'hidden'}
|
|
1150
|
+
);
|
|
1151
|
+
}
|
|
1152
|
+
else
|
|
1153
|
+
// @condend fadeslide
|
|
1154
|
+
each(self, function(obj, c) {
|
|
1155
|
+
var nameClean = replace(name, /^[@$]/);
|
|
1156
|
+
var className = obj['className'] || '';
|
|
1157
|
+
var newObj = /^\$/.test(name) ? obj.style : obj;
|
|
1158
|
+
var newValue = isFunction(value) ? value($(obj).get(name), c, obj) : value;
|
|
1159
|
+
if (name == '$') {
|
|
1160
|
+
if (newValue != null) {
|
|
1161
|
+
each(newValue.split(/\s+/), function(clzz) {
|
|
1162
|
+
var cName = replace(clzz, /^[+-]/);
|
|
1163
|
+
var oldClassName = className;
|
|
1164
|
+
className = replace(className, new RegExp(BACKSLASHB + cName + BACKSLASHB));
|
|
1165
|
+
if (/^\+/.test(clzz) || (cName==clzz && oldClassName == className)) // for + and toggle-add
|
|
1166
|
+
className += ' ' + cName;
|
|
1167
|
+
});
|
|
1168
|
+
obj['className'] = replace(className, /^\s+|\s+(?=\s|$)/g);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
else if (name == '$$') {
|
|
1172
|
+
// @condblock ie8compatibility
|
|
1173
|
+
if (IS_PRE_IE9)
|
|
1174
|
+
newObj['cssText'] = newValue;
|
|
1175
|
+
else
|
|
1176
|
+
// @condend
|
|
1177
|
+
setAttr(obj, 'style', newValue);
|
|
1178
|
+
}
|
|
1179
|
+
else if (!/^@/.test(name))
|
|
1180
|
+
newObj[nameClean] = newValue;
|
|
1181
|
+
else
|
|
1182
|
+
setAttr(newObj, nameClean, newValue);
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
else if (isString(name) || isFunction(name))
|
|
1186
|
+
self.set('$', name);
|
|
1187
|
+
else
|
|
1188
|
+
eachObj(name, function(n,v) { self.set(n, v); });
|
|
1189
|
+
return self;
|
|
1190
|
+
},
|
|
1191
|
+
|
|
1192
|
+
|
|
1193
|
+
/*$
|
|
1194
|
+
* @id add
|
|
1195
|
+
* @group ELEMENT
|
|
1196
|
+
* @requires dollar
|
|
1197
|
+
* @configurable default
|
|
1198
|
+
* @name .add()
|
|
1199
|
+
* @syntax add(text)
|
|
1200
|
+
* @syntax add(factoryFunction)
|
|
1201
|
+
* @syntax add(list)
|
|
1202
|
+
* @syntax add(node)
|
|
1203
|
+
* @module WEB
|
|
1204
|
+
* Adds the given node(s) as content to the list's HTML elements. If a string has been given, it will be added as text node.
|
|
1205
|
+
* If you pass a function, it will be invoked for each list element to create the node to add. This is called a factory function. It can return all
|
|
1206
|
+
* values allowed by <var>add()</var>, including another function to be called.
|
|
1207
|
+
* If you pass a list or a function returning a list, all its elements will be added using the rules above.
|
|
1208
|
+
*
|
|
1209
|
+
* It is also possible to pass a DOM node, but it will be added <strong>only to the first element of the list</strong>, because DOM
|
|
1210
|
+
* does not allow adding it more than once. You should use a factory function to add DOM elements to more than one list element. ##EE()
|
|
1211
|
+
* and ##clone() are two simple ways to create factory functions.
|
|
1212
|
+
*
|
|
1213
|
+
* @example Using the following HTML:
|
|
1214
|
+
* <pre>
|
|
1215
|
+
* <div id="comments">Here is some text.<br/></div>
|
|
1216
|
+
* </pre>
|
|
1217
|
+
* The next line appends a text node to the given 'comment' div:
|
|
1218
|
+
* <pre>
|
|
1219
|
+
* $('#comments').add('Some additional text.');
|
|
1220
|
+
* </pre>
|
|
1221
|
+
* This results in:
|
|
1222
|
+
* <pre>
|
|
1223
|
+
* <div id="comments">Here is some text.<br/><Some additional text./div>
|
|
1224
|
+
* </pre>
|
|
1225
|
+
*
|
|
1226
|
+
* @example Using the following HTML:
|
|
1227
|
+
* <pre>
|
|
1228
|
+
* <ul id="myList">
|
|
1229
|
+
* <li>First list entry</li>
|
|
1230
|
+
* <li>Second list entry</li>
|
|
1231
|
+
* </ul>
|
|
1232
|
+
* </pre>
|
|
1233
|
+
* The following Javascript adds an element to the list:
|
|
1234
|
+
* <pre>
|
|
1235
|
+
* $('#myList').add(EE('li', 'My extra point');
|
|
1236
|
+
* </pre>
|
|
1237
|
+
* This results in
|
|
1238
|
+
* <pre>
|
|
1239
|
+
* <ul id="myList">
|
|
1240
|
+
* <li>First list entry</li>
|
|
1241
|
+
* <li>Second list entry</li>
|
|
1242
|
+
* <li>My extra point</li>
|
|
1243
|
+
* </ul>
|
|
1244
|
+
* </pre>
|
|
1245
|
+
*
|
|
1246
|
+
* @example Use a list to add several elements at once:
|
|
1247
|
+
* <pre>
|
|
1248
|
+
* $('#comments').add([
|
|
1249
|
+
* EE('br'),
|
|
1250
|
+
* 'Some text',
|
|
1251
|
+
* EE('span', {'className': 'highlight'}, 'Some highlighted text')
|
|
1252
|
+
* ]);
|
|
1253
|
+
* </pre>
|
|
1254
|
+
*
|
|
1255
|
+
* @example You can implement functions to create elements depending on the context:
|
|
1256
|
+
* <pre>
|
|
1257
|
+
* $('.chapter').add(function(parent, index) { return EE('h2', 'Chapter number ' + index); });
|
|
1258
|
+
* </pre>
|
|
1259
|
+
*
|
|
1260
|
+
* @param text a string or number to add as text node
|
|
1261
|
+
* @param factoryFunction a <code>function(listItem, listIndex)</code> that will be invoked for each list element to create the nodes:
|
|
1262
|
+
* <dl><dt>listItem</dt><dd>The list element that will receive the new children.</dd>
|
|
1263
|
+
* <dt>listIndex</dt><dd>The index of the list element that will receive the new children.</dd>
|
|
1264
|
+
* <dt class="returnValue">(callback return value)<dt><dd>The node(s) to be added to the list element.
|
|
1265
|
+
* Can be either a string for a text node, an HTML element or a list containing strings, lists, functions and/or DOM nodes.
|
|
1266
|
+
* If a function is returned or in the list, it will be invoked recursively with the same arguments.</dd></dl>
|
|
1267
|
+
* @param list a list containing text, functions, nodes or more lists. Please note that if you have DOM nodes in this list
|
|
1268
|
+
* and attempt to add them to more than one element, the result is undefined. You should always use factories
|
|
1269
|
+
* if you add DOM nodes to more than one element.
|
|
1270
|
+
* @param node a DOM node to add <strong>only to the first element</strong> of the list.
|
|
1271
|
+
* @return the current list
|
|
1272
|
+
*/
|
|
1273
|
+
'add': function (children, addFunction) {
|
|
1274
|
+
return each(this, function(e, index) {
|
|
1275
|
+
var lastAdded;
|
|
1276
|
+
(function appendChildren(c) {
|
|
1277
|
+
if (isList(c))
|
|
1278
|
+
each(c, appendChildren);
|
|
1279
|
+
else if (isFunction(c))
|
|
1280
|
+
appendChildren(c(e, index));
|
|
1281
|
+
else if (c != null) { // must check null, as 0 is a valid parameter
|
|
1282
|
+
var n = isNode(c) ? c : _document.createTextNode(c);
|
|
1283
|
+
if (lastAdded)
|
|
1284
|
+
lastAdded.parentNode.insertBefore(n, lastAdded.nextSibling);
|
|
1285
|
+
else if (addFunction)
|
|
1286
|
+
addFunction(n, e, e.parentNode);
|
|
1287
|
+
else
|
|
1288
|
+
e.appendChild(n);
|
|
1289
|
+
lastAdded = n;
|
|
1290
|
+
}
|
|
1291
|
+
})(isNode(children) && index ? null : children);
|
|
1292
|
+
});
|
|
1293
|
+
},
|
|
1294
|
+
|
|
1295
|
+
|
|
1296
|
+
/*$
|
|
1297
|
+
* @id fill
|
|
1298
|
+
* @group ELEMENT
|
|
1299
|
+
* @requires dollar add remove
|
|
1300
|
+
* @configurable default
|
|
1301
|
+
* @name .fill()
|
|
1302
|
+
* @syntax fill()
|
|
1303
|
+
* @syntax fill(text)
|
|
1304
|
+
* @syntax fill(factoryFunction)
|
|
1305
|
+
* @syntax fill(list)
|
|
1306
|
+
* @syntax fill(node)
|
|
1307
|
+
* @module WEB
|
|
1308
|
+
* Sets the content of the list's HTML elements, replacing old content. If a string has been given, it will be added as text node.
|
|
1309
|
+
* If you pass a function, it will be invoked for each list member to create a node. The function prototype is <code>function(parent, index)</code>.
|
|
1310
|
+
* It can return all values allowed by <var>fill()</var>, including another function to be called.
|
|
1311
|
+
* If you pass a list or a function returns a list, all its elements will be added using the rules above.
|
|
1312
|
+
*
|
|
1313
|
+
* It is also possible to pass a DOM node, but it will be set <strong>only in the first element of the list</strong>, because DOM
|
|
1314
|
+
* does not allow adding it more than once.
|
|
1315
|
+
*
|
|
1316
|
+
* Call <var>fill()</var> without arguments to remove all children from a node.
|
|
1317
|
+
*
|
|
1318
|
+
* @example Using the following HTML:
|
|
1319
|
+
* <pre>
|
|
1320
|
+
* <div id="status">Done</div>
|
|
1321
|
+
* </pre>
|
|
1322
|
+
* <var>fill()</var> with a simple string replaces the element's content with the text:
|
|
1323
|
+
* <pre>
|
|
1324
|
+
* $('#status').fill('Please Wait..');
|
|
1325
|
+
* </pre>
|
|
1326
|
+
* Results in:
|
|
1327
|
+
* <pre>
|
|
1328
|
+
* <div id="status">Please Wait..</div>
|
|
1329
|
+
* </pre>
|
|
1330
|
+
*
|
|
1331
|
+
* @example Pass an Element Factory to replace the old content with that:
|
|
1332
|
+
* <pre>
|
|
1333
|
+
* $('#status').fill(EE('span', {'className': 'bold'}, 'Please Wait...'));
|
|
1334
|
+
* </pre>
|
|
1335
|
+
* With the previous example's HTML, this would create this:
|
|
1336
|
+
* <pre>
|
|
1337
|
+
* <div id="status"><span class='bold'>Please Wait..</span></div>
|
|
1338
|
+
* </pre>
|
|
1339
|
+
*
|
|
1340
|
+
* @example You can also pass a list of elements and texts:
|
|
1341
|
+
* <pre>
|
|
1342
|
+
* $('#status').fill(['Here', EE('br'), 'are', EE('br'), 'four', EE('br'), 'lines.]);
|
|
1343
|
+
* </pre>
|
|
1344
|
+
*
|
|
1345
|
+
* @example Or a complete structure built using EE:
|
|
1346
|
+
* <pre>
|
|
1347
|
+
* $('#myListContainer').fill([
|
|
1348
|
+
* EE('h2', 'My List'),
|
|
1349
|
+
* EE('ol', [EE('li', 'First Item'), EE('li', 'Second Item'), EE('li', 'Third Item')])
|
|
1350
|
+
* ]);
|
|
1351
|
+
* </pre>
|
|
1352
|
+
*
|
|
1353
|
+
* @example You can write a factory function that re-creates the list for every instance:
|
|
1354
|
+
* <pre>
|
|
1355
|
+
* $('.listContainers').fill(function(e, index) { return [
|
|
1356
|
+
* EE('h2', 'List Number '+index),
|
|
1357
|
+
* EE('ol', [EE('li', 'First Item'),
|
|
1358
|
+
* EE('li', 'Second Item'),
|
|
1359
|
+
* EE('li', 'Third Item')
|
|
1360
|
+
* ])]});
|
|
1361
|
+
* </pre>
|
|
1362
|
+
*
|
|
1363
|
+
* @example <var>fill()</var> without arguments deletes the content of the list elements:
|
|
1364
|
+
* <pre>
|
|
1365
|
+
* $('.listContainers').fill();
|
|
1366
|
+
* </pre>
|
|
1367
|
+
*
|
|
1368
|
+
* @param text a string to set as text node of the list elements
|
|
1369
|
+
* @param factoryFunction a <code>function(listItem, listIndex)</code> that will be invoked for each list element to create the nodes:
|
|
1370
|
+
* <dl><dt>listItem</dt><dd>The list element that will receive the new children.</dd>
|
|
1371
|
+
* <dt>listIndex</dt><dd>The index of the list element that will receive the new children.</dd>
|
|
1372
|
+
* <dt class="returnValue">(callback return value)<dt><dd>The node(s) to be added to the list element.
|
|
1373
|
+
* Can be either a string for a text node, an HTML element or a list containing strings, lists, functions and/or DOM nodes.
|
|
1374
|
+
* If a function is returned or in the list, it will be invoked recursively with the same arguments.</dd></dl>
|
|
1375
|
+
|
|
1376
|
+
* @param list a list containing text, functions, nodes or more list. Please note that if you have DOM nodes in this list
|
|
1377
|
+
* and attempt to add them to more than one element, the result is <var>undefined</var>. You should always use factories if your
|
|
1378
|
+
* Minified list contains more than one item.
|
|
1379
|
+
* @param node a DOM node to set <strong>only in the first element</strong> of the list.
|
|
1380
|
+
|
|
1381
|
+
* @return the current list
|
|
1382
|
+
*/
|
|
1383
|
+
'fill': function (children) {
|
|
1384
|
+
return each(this, function(e) { $(e.childNodes)['remove'](); }).add(children);
|
|
1385
|
+
},
|
|
1386
|
+
|
|
1387
|
+
/*$
|
|
1388
|
+
* @id addbefore
|
|
1389
|
+
* @group ELEMENT
|
|
1390
|
+
* @requires dollar add
|
|
1391
|
+
* @configurable default
|
|
1392
|
+
* @name .addBefore()
|
|
1393
|
+
* @syntax addBefore(text)
|
|
1394
|
+
* @syntax addBefore(factoryFunction)
|
|
1395
|
+
* @syntax addBefore(list)
|
|
1396
|
+
* @syntax addBefore(node)
|
|
1397
|
+
* @module WEB
|
|
1398
|
+
* Inserts the given text or element(s) as sibling in front of each HTML element in the list.
|
|
1399
|
+
* If a string has been given, it will be added as text node.
|
|
1400
|
+
* If you pass a function, it will be invoked for each list element to create the new node, with the arguments <code>function(parent, index)</code>.
|
|
1401
|
+
* It can return all values allowed by <var>addBefore()</var>, including another function to be called.
|
|
1402
|
+
* If you pass a list or a function returns a list, all its elements will be added using the rules above.
|
|
1403
|
+
*
|
|
1404
|
+
* It is also possible to pass a DOM node, but it will be added <strong>only to the first element of the list</strong>, because DOM
|
|
1405
|
+
* does not allow adding it more than once.
|
|
1406
|
+
*
|
|
1407
|
+
* @example Using the following HTML:
|
|
1408
|
+
* <pre>
|
|
1409
|
+
* <div>
|
|
1410
|
+
* <div id="mainText">Here is some text</div>
|
|
1411
|
+
* </div>
|
|
1412
|
+
* </pre>
|
|
1413
|
+
* addBefore() adds text in front of the selected list items.
|
|
1414
|
+
* <pre>
|
|
1415
|
+
* $('#mainText').addBefore('COMMENT');
|
|
1416
|
+
* </pre>
|
|
1417
|
+
* This results in:
|
|
1418
|
+
* <pre>
|
|
1419
|
+
* <div>
|
|
1420
|
+
* COMMENT
|
|
1421
|
+
* <div id="mainText">Here is some text</div>
|
|
1422
|
+
* </div>
|
|
1423
|
+
* </pre>
|
|
1424
|
+
*
|
|
1425
|
+
* @example You can also pass an Element Factory:
|
|
1426
|
+
* <pre>
|
|
1427
|
+
* $('#mainText').addBefore(EE('span', {'className': 'important'}, 'WARNING'));
|
|
1428
|
+
* </pre>
|
|
1429
|
+
* With the previous example's HTML, this would create this HTML:
|
|
1430
|
+
* <pre>
|
|
1431
|
+
* <div>
|
|
1432
|
+
* <span class="important">WARNING</span>
|
|
1433
|
+
* <div id="mainText">Here is some text</div>
|
|
1434
|
+
* </div>
|
|
1435
|
+
* </pre>
|
|
1436
|
+
*
|
|
1437
|
+
* @example Lists of elements and nodes are possible as well.
|
|
1438
|
+
* <pre>
|
|
1439
|
+
* $('#status').addBefore([EE('hr'), 'WARNING']);
|
|
1440
|
+
* </pre>
|
|
1441
|
+
*
|
|
1442
|
+
* @param text a string to add as text node of the list elements
|
|
1443
|
+
* @param factoryFunction a <code>function(listItem, listIndex)</code> that will be invoked for each list element to create the nodes:
|
|
1444
|
+
* <dl><dt>listItem</dt><dd>The list element that will receive the new children.</dd>
|
|
1445
|
+
* <dt>listIndex</dt><dd>The index of the list element that will receive the new children.</dd>
|
|
1446
|
+
* <dt class="returnValue">(callback return value)<dt><dd>The node(s) to be added to the list element.
|
|
1447
|
+
* Can be either a string for a text node, an HTML element or a list containing strings, lists, functions and/or DOM nodes.
|
|
1448
|
+
* If a function is returned or in the list, it will be invoked recursively with the same arguments.</dd></dl>
|
|
1449
|
+
* @param list a list containing text, functions, nodes or more list. Please note that if you have DOM nodes in this list
|
|
1450
|
+
* and attempt to add them to more than one element, the result is <var>undefined</var>. You should always use factories if your
|
|
1451
|
+
* Minified list contains more than one item.
|
|
1452
|
+
* @param node a DOM node to add <strong>only to the first element</strong> of the list.
|
|
1453
|
+
* @return the current list
|
|
1454
|
+
*/
|
|
1455
|
+
'addBefore': function (children) {
|
|
1456
|
+
return this.add(children, function(newNode, refNode, parent) { parent.insertBefore(newNode, refNode); });
|
|
1457
|
+
},
|
|
1458
|
+
|
|
1459
|
+
/*$
|
|
1460
|
+
* @id addafter
|
|
1461
|
+
* @group ELEMENT
|
|
1462
|
+
* @requires dollar add
|
|
1463
|
+
* @configurable default
|
|
1464
|
+
* @name .addAfter()
|
|
1465
|
+
* @syntax addAfter(text)
|
|
1466
|
+
* @syntax addAfter(factoryFunction)
|
|
1467
|
+
* @syntax addAfter(list)
|
|
1468
|
+
* @syntax addAfter(node)
|
|
1469
|
+
* @module WEB
|
|
1470
|
+
* Inserts the given text or element(s) as sibling after each HTML element in the list.
|
|
1471
|
+
* If a string has been given, it will be added as text node.
|
|
1472
|
+
* If you pass a function, it will be invoked for each list element to create the node(s) to add. It can return all values
|
|
1473
|
+
* allowed by <var>addAfter()</var>, including another function to be called.
|
|
1474
|
+
* If you pass a list or a function returns a list, all its elements will be added using the rules above.
|
|
1475
|
+
*
|
|
1476
|
+
* It is also possible to pass a DOM node, but it will be added <strong>only to the first element of the list</strong>, because DOM
|
|
1477
|
+
* does not allow adding it more than once.
|
|
1478
|
+
*
|
|
1479
|
+
* @example Using the following HTML:
|
|
1480
|
+
* <pre>
|
|
1481
|
+
* <div>
|
|
1482
|
+
* <div id="mainText">Here is some text</div>
|
|
1483
|
+
* </div>
|
|
1484
|
+
* </pre>
|
|
1485
|
+
* Use addAfter() with a simple string to add a text node.
|
|
1486
|
+
* <pre>
|
|
1487
|
+
* $('#mainText').addAfter('Disclaimer: bla bla bla');
|
|
1488
|
+
* </pre>
|
|
1489
|
+
* This results in the following HTML:
|
|
1490
|
+
* <pre>
|
|
1491
|
+
* <div>
|
|
1492
|
+
* <div id="mainText">Here is some text</div>
|
|
1493
|
+
* Disclaimer: bla bla bla
|
|
1494
|
+
* </div>
|
|
1495
|
+
* </pre>
|
|
1496
|
+
*
|
|
1497
|
+
* @example You can also pass an Element Factory:
|
|
1498
|
+
* <pre>
|
|
1499
|
+
* $('#mainText').addAfter(EE('span', {'className': 'disclaimer'}, 'Disclaimer: bla bla bla'));
|
|
1500
|
+
* </pre>
|
|
1501
|
+
* With the previous example's HTML, this would create this:
|
|
1502
|
+
* <pre>
|
|
1503
|
+
* <div>
|
|
1504
|
+
* <div id="mainText">Disclaimer: bla bla bla</div>
|
|
1505
|
+
* <span class="disclaimer">WARNING</span>
|
|
1506
|
+
* </div>
|
|
1507
|
+
* </pre>
|
|
1508
|
+
*
|
|
1509
|
+
* @param text a string to add as text node of the list elements
|
|
1510
|
+
* @param factoryFunction a <code>function(listItem, listIndex)</code> that will be invoked for each list element to create the nodes:
|
|
1511
|
+
* <dl><dt>listItem</dt><dd>The list element that will receive the new children.</dd>
|
|
1512
|
+
* <dt>listIndex</dt><dd>The index of the list element that will receive the new children.</dd>
|
|
1513
|
+
* <dt class="returnValue">(callback return value)<dt><dd>The node(s) to be added to the list element.
|
|
1514
|
+
* Can be either a string for a text node, an HTML element or a list containing strings, lists, functions and/or DOM nodes.
|
|
1515
|
+
* If a function is returned or in the list, it will be invoked recursively with the same arguments.</dd></dl>
|
|
1516
|
+
* @param list a list containing text, functions, nodes or more list. Please note that if you have DOM nodes in this list
|
|
1517
|
+
* and attempt to add them to more than one element, the result is <var>undefined</var>. You should always use factories if your
|
|
1518
|
+
* Minified list contains more than one item.
|
|
1519
|
+
* @param node a DOM node to add <strong>only to the first element</strong> of the list.
|
|
1520
|
+
* @return the current list
|
|
1521
|
+
*/
|
|
1522
|
+
'addAfter': function (children) {
|
|
1523
|
+
return this.add(children, function(newNode, refNode, parent) { parent.insertBefore(newNode, refNode.nextSibling); });
|
|
1524
|
+
},
|
|
1525
|
+
|
|
1526
|
+
/*$
|
|
1527
|
+
* @id addfront
|
|
1528
|
+
* @group ELEMENT
|
|
1529
|
+
* @requires dollar add
|
|
1530
|
+
* @configurable default
|
|
1531
|
+
* @name .addFront()
|
|
1532
|
+
* @syntax addFront(text)
|
|
1533
|
+
* @syntax addFront(factoryFunction)
|
|
1534
|
+
* @syntax addFront(list)
|
|
1535
|
+
* @syntax addFront(node)
|
|
1536
|
+
* @module WEB
|
|
1537
|
+
* Adds the given node(s) as children to the list's HTML elements. Unlike ##add(), the new nodes will be the first children and not the last.
|
|
1538
|
+
* If a string has been given, it will be added as text node.
|
|
1539
|
+
* If you pass a function, it will be invoked for each list element to create node(s) with the arguments <code>function(parent, index)</code>.
|
|
1540
|
+
* It can return all values allowed by <var>addFront()</var>, including another function to be called.
|
|
1541
|
+
* If you pass a list or a function returns a list, all its elements will be added using the rules above.
|
|
1542
|
+
*
|
|
1543
|
+
* It is also possible to pass a DOM node, but it will be added <strong>only to the first element of the list</strong>, because DOM
|
|
1544
|
+
* does not allow adding it more than once.
|
|
1545
|
+
*
|
|
1546
|
+
* @example Using the following HTML:
|
|
1547
|
+
* <pre>
|
|
1548
|
+
* <div id="comments">Here is some text.<br/></div>
|
|
1549
|
+
* </pre>
|
|
1550
|
+
* Add a text to the given 'comment' div:
|
|
1551
|
+
* <pre>
|
|
1552
|
+
* $('#comments').addFront('Some additional text. ');
|
|
1553
|
+
* </pre>
|
|
1554
|
+
* This results in:
|
|
1555
|
+
* <pre>
|
|
1556
|
+
* <div id="comments">Some additional text. Here is some text.<br/></div>
|
|
1557
|
+
* </pre>
|
|
1558
|
+
*
|
|
1559
|
+
* @example Using the following HTML:
|
|
1560
|
+
* <pre>
|
|
1561
|
+
* <ul id="myList">
|
|
1562
|
+
* <li>First list entry</li>
|
|
1563
|
+
* <li>Second list entry</li>
|
|
1564
|
+
* </ul>
|
|
1565
|
+
* </pre>
|
|
1566
|
+
* The following Javascript adds an element to the list:
|
|
1567
|
+
* <pre>
|
|
1568
|
+
* $('#myList').addFront(EE('li', 'My extra point'));
|
|
1569
|
+
* </pre>
|
|
1570
|
+
* This results in
|
|
1571
|
+
* <pre>
|
|
1572
|
+
* <ul id="myList">
|
|
1573
|
+
* <li>My extra point</li>
|
|
1574
|
+
* <li>First list entry</li>
|
|
1575
|
+
* <li>Second list entry</li>
|
|
1576
|
+
* </ul>
|
|
1577
|
+
* </pre>
|
|
1578
|
+
*
|
|
1579
|
+
* @example Use a list to add several elements at once:
|
|
1580
|
+
* <pre>
|
|
1581
|
+
* $('#comments').addFront([
|
|
1582
|
+
* EE('br'),
|
|
1583
|
+
* 'Some text',
|
|
1584
|
+
* EE('span', {'className': 'highlight'}, 'Some highlighted text')
|
|
1585
|
+
* ]);
|
|
1586
|
+
* </pre>
|
|
1587
|
+
*
|
|
1588
|
+
* @param text a string to add as text node of the list elements
|
|
1589
|
+
* @param factoryFunction a <code>function(listItem, listIndex)</code> that will be invoked for each list element to create the nodes:
|
|
1590
|
+
* <dl><dt>listItem</dt><dd>The list element that will receive the new children.</dd>
|
|
1591
|
+
* <dt>listIndex</dt><dd>The index of the list element that will receive the new children.</dd>
|
|
1592
|
+
* <dt class="returnValue">(callback return value)<dt><dd>The node(s) to be added to the list element.
|
|
1593
|
+
* Can be either a string for a text node, an HTML element or a list containing strings, lists, functions and/or DOM nodes.
|
|
1594
|
+
* If a function is returned or in the list, it will be invoked recursively with the same arguments.</dd></dl>
|
|
1595
|
+
|
|
1596
|
+
* @param list a list containing text, functions, nodes or nested lists containing those items. Please note that if you have DOM nodes in this list
|
|
1597
|
+
* and attempt to add them to more than one element, the result is undefined.
|
|
1598
|
+
* @param node a DOM node to add <strong>only to the first element</strong> of the list.
|
|
1599
|
+
* @return the current list
|
|
1600
|
+
*/
|
|
1601
|
+
'addFront': function (children) {
|
|
1602
|
+
return this.add(children, function(newNode, refNode) { refNode.insertBefore(newNode, refNode.firstChild); });
|
|
1603
|
+
},
|
|
1604
|
+
|
|
1605
|
+
/*$
|
|
1606
|
+
* @id replace
|
|
1607
|
+
* @group ELEMENT
|
|
1608
|
+
* @requires dollar add
|
|
1609
|
+
* @configurable default
|
|
1610
|
+
* @name .replace()
|
|
1611
|
+
* @syntax replace(text)
|
|
1612
|
+
* @syntax replace(factoryFunction)
|
|
1613
|
+
* @syntax replace(list)
|
|
1614
|
+
* @syntax replace(node)
|
|
1615
|
+
* @module WEB
|
|
1616
|
+
* Replaces the list items with the the given node(s) in the DOM tree.
|
|
1617
|
+
* If a string has been given, it will be set as text node.
|
|
1618
|
+
* If you pass a function, it will be invoked for each list element to create node(s) with the arguments <code>function(parent, index)</code>.
|
|
1619
|
+
* It can return all values allowed by <var>replace()</var>, including another function to be called.
|
|
1620
|
+
* If you pass a list or a function returns a list, all its elements will be set using the rules above.
|
|
1621
|
+
*
|
|
1622
|
+
* It is also possible to pass a DOM node, but it will replace <strong>only the first element of the list</strong>, because DOM
|
|
1623
|
+
* does not allow adding it more than once.
|
|
1624
|
+
*
|
|
1625
|
+
* @example Using the following HTML:
|
|
1626
|
+
* <pre>
|
|
1627
|
+
* <div id="comments">
|
|
1628
|
+
* <div id="commentOne">My old comment.</div>
|
|
1629
|
+
* </div>
|
|
1630
|
+
* </pre>
|
|
1631
|
+
* This replaces the div 'commentOne':
|
|
1632
|
+
* <pre>
|
|
1633
|
+
* $('#commentOne').replace('Some new comment.');
|
|
1634
|
+
* </pre>
|
|
1635
|
+
* The resulting HTML is:
|
|
1636
|
+
* <pre>
|
|
1637
|
+
* <div id="comments">
|
|
1638
|
+
* Some new comment.
|
|
1639
|
+
* </div>
|
|
1640
|
+
* </pre>
|
|
1641
|
+
* Please note that not only the text has changed, but the whole <div> has been replaced. If you only want to replace the element's text content
|
|
1642
|
+
* you should use ##fill() instead of <var>replace()</var>.
|
|
1643
|
+
*
|
|
1644
|
+
* @example Using the following HTML:
|
|
1645
|
+
* <pre>
|
|
1646
|
+
* <ul id="myList">
|
|
1647
|
+
* <li>First list entry</li>
|
|
1648
|
+
* <li>Second list entry</li>
|
|
1649
|
+
* </ul>
|
|
1650
|
+
* </pre>
|
|
1651
|
+
* The following example will replace <strong>only the first <li> element</strong>:
|
|
1652
|
+
* <pre>
|
|
1653
|
+
* $('#myList li').sub(0, 1).replace(EE('li', 'My extra point'));
|
|
1654
|
+
* </pre>
|
|
1655
|
+
* This results in
|
|
1656
|
+
* <pre>
|
|
1657
|
+
* <ul id="myList">
|
|
1658
|
+
* <li>My extra point</li>
|
|
1659
|
+
* <li>Second list entry</li>
|
|
1660
|
+
* </ul>
|
|
1661
|
+
* </pre>
|
|
1662
|
+
*
|
|
1663
|
+
*
|
|
1664
|
+
* @param text a text for the text nodes that replace the list elements
|
|
1665
|
+
* @param factoryFunction a <code>function(listItem, listIndex)</code> that will be invoked for each list element to determine its content:
|
|
1666
|
+
* <dl><dt>listItem</dt><dd>The list element that will receive the new children.</dd>
|
|
1667
|
+
* <dt>listIndex</dt><dd>The index of the list element that will receive the new children.</dd>
|
|
1668
|
+
* <dt class="returnValue">(callback return value)<dt><dd>The node(s) to be added to the list element.
|
|
1669
|
+
* Can be either a string for a text node, an HTML element or a list containing strings, lists, functions and/or DOM nodes.
|
|
1670
|
+
* If a function is returned or in the list, it will be invoked recursively with the same arguments.</dd></dl>
|
|
1671
|
+
* @param node content to replace <strong>only to the first element</strong> of the list with. The content can be a string for a text node,
|
|
1672
|
+
* an HTML node or a list containing strings and/or HTML node.
|
|
1673
|
+
* @return the current list
|
|
1674
|
+
*/
|
|
1675
|
+
'replace': function (children) {
|
|
1676
|
+
return this.add(children, function(newNode, refNode, parent) { parent.replaceChild(newNode, refNode); });
|
|
1677
|
+
},
|
|
1678
|
+
|
|
1679
|
+
/*$
|
|
1680
|
+
* @id clone
|
|
1681
|
+
* @group ELEMENT
|
|
1682
|
+
* @requires dollar ee
|
|
1683
|
+
* @configurable default
|
|
1684
|
+
* @name .clone()
|
|
1685
|
+
* @syntax clone()
|
|
1686
|
+
* @syntax clone(onCreate)
|
|
1687
|
+
* @module WEB
|
|
1688
|
+
* Creates a ##list#Minified list## of strings and Element Factories that return clones of the list's HTML elements. An Element Factory is a function
|
|
1689
|
+
* that creates a Minified list of fresh DOM nodes. You can pass the list to ##add(), ##fill() or similar functions to re-create the cloned nodes.
|
|
1690
|
+
*
|
|
1691
|
+
* <var>clone()</var> is very limited in what it will clone. Only elements, their attributes, text nodes and CDATA will be cloned.
|
|
1692
|
+
* Modifications of the elements, such as event handlers, will not be cloned.
|
|
1693
|
+
*
|
|
1694
|
+
* Please note that id attributes will be automatically skipped by the Element Factory. This allows you to address the element to clone by id
|
|
1695
|
+
* without having to worry about duplicate ids in the result.
|
|
1696
|
+
*
|
|
1697
|
+
* @example Using the following HTML:
|
|
1698
|
+
* <pre>
|
|
1699
|
+
* <div id="comments">
|
|
1700
|
+
* <div id="comment1">My comment.</div>
|
|
1701
|
+
* </div>
|
|
1702
|
+
* </pre>
|
|
1703
|
+
* Creating a clone factory:
|
|
1704
|
+
* <pre>
|
|
1705
|
+
* var myCloneFactory = $('#comment1').clone();
|
|
1706
|
+
* </pre>
|
|
1707
|
+
* Creating a clone and adding it below the existing one:
|
|
1708
|
+
* <pre>
|
|
1709
|
+
* $('#comments').add(myCloneFactory);
|
|
1710
|
+
* </pre>
|
|
1711
|
+
*
|
|
1712
|
+
* @example Creating an event handler for a clone:
|
|
1713
|
+
* <pre>
|
|
1714
|
+
* var buttonCloner = $('#myButton').clone(function(newButton) {
|
|
1715
|
+
* newButton.on('click', function() { alert('Cloned button clicked'); });
|
|
1716
|
+
* });
|
|
1717
|
+
* $('#buttonContainer').add(buttonCloner);
|
|
1718
|
+
* </pre>
|
|
1719
|
+
*
|
|
1720
|
+
* @param onCreate optional A <code>function(elementList)</code> that will be called for each top-level element created by the Element
|
|
1721
|
+
* Factory:
|
|
1722
|
+
* <dl><dt>elementList</dt><dd>The newly created element wrapped in a Minified list. </dd></dl>
|
|
1723
|
+
* The function's return value will be ignored.
|
|
1724
|
+
* The callback allows you, for example, to add event handlers to the element using ##on().
|
|
1725
|
+
* Please note that the callback will be not be called for cloned text nodes. If you clone
|
|
1726
|
+
* more than one element, <var>onCreate</var> will be invoked for each element.
|
|
1727
|
+
* @return the list of Element Factory functions and strings to create clones
|
|
1728
|
+
*/
|
|
1729
|
+
'clone': function (onCreate) {
|
|
1730
|
+
return new M(collect(this, function(e) {
|
|
1731
|
+
var nodeType = isNode(e);
|
|
1732
|
+
if (nodeType == 1) {
|
|
1733
|
+
var attrs = {
|
|
1734
|
+
// @condblock ie8compatibility
|
|
1735
|
+
'$': e['className'] || null,
|
|
1736
|
+
'$$': IS_PRE_IE9 ? e['style']['cssText'] : e.getAttribute('style')
|
|
1737
|
+
// @condend
|
|
1738
|
+
};
|
|
1739
|
+
each(e['attributes'], function(a) {
|
|
1740
|
+
var attrName = a['name'];
|
|
1741
|
+
if (attrName != 'id'
|
|
1742
|
+
// @condblock ie8compatibility
|
|
1743
|
+
&& attrName != 'style'
|
|
1744
|
+
&& attrName != 'class'
|
|
1745
|
+
&& e.getAttribute(attrName) // getAttribute for IE8
|
|
1746
|
+
// @condend
|
|
1747
|
+
) {
|
|
1748
|
+
attrs['@'+attrName] = a['value'];
|
|
1749
|
+
}
|
|
1750
|
+
});
|
|
1751
|
+
return EE(e['tagName'], attrs, $(e['childNodes'])['clone'](), onCreate);
|
|
1752
|
+
}
|
|
1753
|
+
else if (nodeType < 5) // 2 is impossible (attribute), so only 3 (text) and 4 (cdata)..
|
|
1754
|
+
return e['data'];
|
|
1755
|
+
else
|
|
1756
|
+
return null;
|
|
1757
|
+
}));
|
|
1758
|
+
},
|
|
1759
|
+
|
|
1760
|
+
|
|
1761
|
+
|
|
1762
|
+
|
|
1763
|
+
/*$
|
|
1764
|
+
* @id animate
|
|
1765
|
+
* @group ANIMATION
|
|
1766
|
+
* @requires loop dollar set get
|
|
1767
|
+
* @configurable default
|
|
1768
|
+
* @name .animate()
|
|
1769
|
+
* @syntax animate(properties)
|
|
1770
|
+
* @syntax animate(properties, durationMs)
|
|
1771
|
+
* @syntax animate(properties, durationMs, linearity)
|
|
1772
|
+
* @syntax animate(properties, durationMs, interpolationFunc)
|
|
1773
|
+
* @syntax animate(properties, durationMs, linearity, state)
|
|
1774
|
+
* @syntax animate(properties, durationMs, interpolationFunc, state)
|
|
1775
|
+
* @module WEB
|
|
1776
|
+
* Animates the items of the list by modifying their properties, CSS styles and attributes. <var>animate()</var> can work with numbers, strings that contain exactly one
|
|
1777
|
+
* number, and with colors in the CSS notations 'rgb(r,g,b)', '#rrggbb' or '#rgb'.
|
|
1778
|
+
*
|
|
1779
|
+
* When you invoke the function, it will first read all old values from the object and extract their numbers and colors. These start values will be compared to
|
|
1780
|
+
* the destination values that have been specified in the given properties. Then <var>animate()</var> will create a background task using ##$.loop() that updates the
|
|
1781
|
+
* specified properties in frequent intervals so that they transition to their destination values.
|
|
1782
|
+
*
|
|
1783
|
+
* The start values will be obtained using ##get(). It is recommended to set the start values using ##set() before you start the animation, even if this is not
|
|
1784
|
+
* always required.
|
|
1785
|
+
*
|
|
1786
|
+
* You can define the kind of transition using the <var>linearity</var> parameter. If you omit it or pass 0, animate's default algorithm will cause a smooth transition
|
|
1787
|
+
* from the start value to the end value. If you pass 1, the transition will be linear, with a sudden start and end of the animation. Any value between 0 and 1
|
|
1788
|
+
* is also allowed and will give you a transition that is 'somewhat smooth'.
|
|
1789
|
+
*
|
|
1790
|
+
* Instead of the <var>linearity</var> function you can also provide your own interpolation <code>function(startValue, endValue, t)</code> which will be
|
|
1791
|
+
* called every time an interpolated value is required. <var>startValue</var> and <var>endValue</var> define the start and end values. <var>t</var>
|
|
1792
|
+
* is a value between 0 and 1 that specifies the state of the transition. The function should return <var>startValue</var> for 0 and
|
|
1793
|
+
* <var>endValue</var> for 1. For values between 0 and 1, the function should return a transitional value.
|
|
1794
|
+
*
|
|
1795
|
+
* If the start value of a property is a string containing a number, <var>animate()</var> will always ignore all the surrounding text and use the destination value as a template
|
|
1796
|
+
* for the value to write. This can cause problems if you mix units in CSS. For example, if the start value is '10%' and you specify an end value of '20px', animate
|
|
1797
|
+
* will do an animation from '10px' to '20px'. It is not able to convert units.
|
|
1798
|
+
*
|
|
1799
|
+
* <var>animate()</var> does not only support strings with units, but any string containing exactly one number. This allows you, among other things, with IE-specific CSS properties.
|
|
1800
|
+
* For example, you can transition from a start value 'alpha(opacity = 0)' to 'alpha(opacity = 100)'.
|
|
1801
|
+
*
|
|
1802
|
+
* When you animate colors, <var>animate()</var> is able to convert between the three notations rgb(r,g,b), #rrggbb or #rgb. You can use them interchangeably, but you can not
|
|
1803
|
+
* use color names such as 'red'.
|
|
1804
|
+
*
|
|
1805
|
+
* You can prefix any number, including numbers with units, with "-=" or "+=" in order to specify a value relative to the starting value. The new value will be added
|
|
1806
|
+
* to or substracted from the start value to determine the end value.
|
|
1807
|
+
*
|
|
1808
|
+
* To allow more complex animation, <var>animate()</var> returns a ##promise#Promise## that is fulfulled when the animation has finished.
|
|
1809
|
+
*
|
|
1810
|
+
* @example Move an element.
|
|
1811
|
+
* <pre>
|
|
1812
|
+
* $('#myMovingDiv').set({$left: '0px', $top: '0px'}) // start values
|
|
1813
|
+
* .animate({$left: '50px', $top: '100px'}, 1000); // animation
|
|
1814
|
+
* </pre>
|
|
1815
|
+
*
|
|
1816
|
+
* @example Using relative values for animation:
|
|
1817
|
+
* <pre>
|
|
1818
|
+
* $('#myMovingDiv').set({$left: '100px', $top: '100px'}) // start values
|
|
1819
|
+
* .animate({$left: '-=50px', $top: '+=100px'}, 1000); // animation
|
|
1820
|
+
* </pre>
|
|
1821
|
+
*
|
|
1822
|
+
* @example Change the color of an element:
|
|
1823
|
+
* <pre>
|
|
1824
|
+
* $('#myBlushingDiv').set({$backgroundColor: '#000000'})
|
|
1825
|
+
* .animate({$backgroundColor: '#ff0000'}, 1000);
|
|
1826
|
+
* </pre>
|
|
1827
|
+
*
|
|
1828
|
+
* @example Fade-out effect:
|
|
1829
|
+
* <pre>
|
|
1830
|
+
* $('#myFadingDiv').animate({$$fade: 0}, 1000);
|
|
1831
|
+
* </pre>
|
|
1832
|
+
*
|
|
1833
|
+
* @example Slide-in effect:
|
|
1834
|
+
* <pre>
|
|
1835
|
+
* $('#myInvisibleDiv').animate({$$slide: 1}, 1000);
|
|
1836
|
+
* </pre>
|
|
1837
|
+
*
|
|
1838
|
+
* @example Chained animation using ##promise#Promise## callbacks. The element is first moved to the position 200/0, then to 200/200
|
|
1839
|
+
* and finally moves to 100/100.
|
|
1840
|
+
* <pre>
|
|
1841
|
+
* var div = $('#myMovingDiv').set({$left: '0px', $top: '0px'});
|
|
1842
|
+
* div.animate({$left: '200px', $top: '0px'}, 600, 0)
|
|
1843
|
+
* .then(function() {
|
|
1844
|
+
* return div.animate({$left: '200px', $top: '200px'}, 800, 0);
|
|
1845
|
+
* }).then(function() {
|
|
1846
|
+
* return div.animate({$left: '100px', $top: '100px'}, 400);
|
|
1847
|
+
* });
|
|
1848
|
+
* });
|
|
1849
|
+
* </pre>
|
|
1850
|
+
* </pre>
|
|
1851
|
+
*
|
|
1852
|
+
*
|
|
1853
|
+
* @param properties a property map describing the end values of the corresponding properties. The names can use the
|
|
1854
|
+
* set() syntax ('@' prefix for attributes, '$' for styles, '$$fade' for fading and '$$slide' for slide effects).
|
|
1855
|
+
* Values must be either numbers, numbers with units (e.g. "2 px") or colors ('rgb(r,g,b)', '#rrggbb' or '#rgb').
|
|
1856
|
+
* Number values, including those with units, can be prefixed with "+=" or "-=", meaning that the value is relative
|
|
1857
|
+
* to the original value and should be added or subtracted.
|
|
1858
|
+
* @param durationMs optional the duration of the animation in milliseconds. Default: 500ms.
|
|
1859
|
+
* @param linearity optional defines whether the animation should be linear (1), very smooth (0) or something in between. Default: 0.
|
|
1860
|
+
* @param interpolationFunc optional an interpolation <code>function(startValue, endValue, t)</code> which will be
|
|
1861
|
+
* called every time an interpolated value is required:
|
|
1862
|
+
* <dl>
|
|
1863
|
+
* <dt>startValue</dt><dd>The start value of the transition.</dd>
|
|
1864
|
+
* <dt>endValue</dt><dd>The end value of the transition.</dd>
|
|
1865
|
+
* <dt>t</dt><dd>A value between 0 and 1 that specifies the state of the transition.</dd>
|
|
1866
|
+
* <dt class="returnValue">(callback return value)</dt><dd>The value at the time <var>t</var>.</dd>
|
|
1867
|
+
* </dl>
|
|
1868
|
+
* @param state optional if set, the animation controller will write information about its state in this object. When <var>animate()</var> returns,
|
|
1869
|
+
* there will be a <var>stop()</var> function in the property <var>state.stop</var> that can be used to abort the animation.
|
|
1870
|
+
* The property <var>state.time</var> will be continously updated while the animation is running
|
|
1871
|
+
* and contains the number of milliseconds that have passed from the start, allowing you to track the progress of the animation.
|
|
1872
|
+
* If the animation finished, controller writes null into <var>state.time</var>. <var>state.stop</var> will not be
|
|
1873
|
+
* modified and can still be safely invoked even when the animation ended.
|
|
1874
|
+
* @return a ##promise#Promise## object to monitor the animation's progress.
|
|
1875
|
+
* It is fulfilled when the animation ended, and rejected if the animation had been stopped.
|
|
1876
|
+
* The fulfillment handler will be called as <code>function(list)</code>:
|
|
1877
|
+
* <dl><dt>list</dt><dd>A reference to the animated list.</dd></dl>
|
|
1878
|
+
* The rejection handler is called as <code>function()</code> without arguments.
|
|
1879
|
+
*/
|
|
1880
|
+
'animate': function (properties, durationMs, linearity, state) {
|
|
1881
|
+
// @cond debug if (!properties || typeof properties == 'string') error('First parameter must be a map of properties (e.g. "{top: 0, left: 0}") ');
|
|
1882
|
+
// @cond debug if (linearity && !isFunction(linearity) && (linearity < 0 || linearity > 1)) error('Third parameter must be at least 0 and not larger than 1.');
|
|
1883
|
+
// @cond debug var colorRegexp = /^(rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)|#\w{3}|#\w{6})\s*$/i;
|
|
1884
|
+
var self = this;
|
|
1885
|
+
var initState = []; // for each item contains a map {s:{}, e:{}, o} s/e are property name -> startValue of start/end. The item is in o.
|
|
1886
|
+
var numRegExp = /-?[\d.]+/;
|
|
1887
|
+
var loopStop;
|
|
1888
|
+
var prom = promise();
|
|
1889
|
+
var interpolate = isFunction(linearity) ? linearity : function(startValue, endValue, t) {
|
|
1890
|
+
return startValue + t * (endValue - startValue) * (linearity + (1-linearity) * t * (3 - 2*t));
|
|
1891
|
+
};
|
|
1892
|
+
state = state || {};
|
|
1893
|
+
state['time'] = 0;
|
|
1894
|
+
state['stop'] = function() { loopStop(); prom(false); };
|
|
1895
|
+
durationMs = durationMs || 500;
|
|
1896
|
+
linearity = linearity || 0;
|
|
1897
|
+
|
|
1898
|
+
|
|
1899
|
+
// find start values
|
|
1900
|
+
each(self, function(li) {
|
|
1901
|
+
var p = {o:$(li), e:{}};
|
|
1902
|
+
eachObj(p.s = p.o.get(properties), function(name, start) {
|
|
1903
|
+
var dest = properties[name];
|
|
1904
|
+
if (name == '$$slide')
|
|
1905
|
+
dest = dest*getNaturalHeight(p.o) + 'px';
|
|
1906
|
+
p.e[name] = /^[+-]=/.test(dest) ?
|
|
1907
|
+
replace(dest.substr(2), numRegExp, extractNumber(start) + extractNumber(replace(dest, /\+?=/)))
|
|
1908
|
+
: dest;
|
|
1909
|
+
});
|
|
1910
|
+
initState.push(p);
|
|
1911
|
+
});
|
|
1912
|
+
|
|
1913
|
+
// start animation
|
|
1914
|
+
loopStop = $.loop(function(timePassedMs) {
|
|
1915
|
+
function getColorComponent(colorCode, index) {
|
|
1916
|
+
return (/^#/.test(colorCode)) ?
|
|
1917
|
+
parseInt(colorCode.length > 6 ? colorCode.substr(1+index*2, 2) : ((colorCode=colorCode.charAt(1+index))+colorCode), 16)
|
|
1918
|
+
:
|
|
1919
|
+
parseInt(replace(colorCode, /[^\d,]+/g).split(',')[index]);
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
state['time'] = timePassedMs;
|
|
1923
|
+
if (timePassedMs >= durationMs || timePassedMs < 0) {
|
|
1924
|
+
each(initState, function(isi) { // set destination values
|
|
1925
|
+
isi.o.set(isi.e);
|
|
1926
|
+
});
|
|
1927
|
+
loopStop();
|
|
1928
|
+
state['time'] = null;
|
|
1929
|
+
prom(true, [self]);
|
|
1930
|
+
}
|
|
1931
|
+
else
|
|
1932
|
+
each(initState, function(isi) {
|
|
1933
|
+
eachObj(isi.s, function(name, start) {
|
|
1934
|
+
var newValue = 'rgb(', end=isi.e[name];
|
|
1935
|
+
var t = timePassedMs/durationMs;
|
|
1936
|
+
if (/^#|rgb\(/.test(end)) { // color in format '#rgb' or '#rrggbb' or 'rgb(r,g,b)'?
|
|
1937
|
+
for (var i = 0; i < 3; i++)
|
|
1938
|
+
newValue += Math.round(interpolate(getColorComponent(start, i), getColorComponent(end, i), t)) + (i < 2 ? ',' : ')');
|
|
1939
|
+
}
|
|
1940
|
+
else
|
|
1941
|
+
newValue = replace(end, numRegExp, toString(interpolate(extractNumber(start), extractNumber(end), t)));
|
|
1942
|
+
isi.o.set(name, newValue);
|
|
1943
|
+
});
|
|
1944
|
+
});
|
|
1945
|
+
});
|
|
1946
|
+
return prom;
|
|
1947
|
+
},
|
|
1948
|
+
|
|
1949
|
+
|
|
1950
|
+
/*$
|
|
1951
|
+
* @id toggle
|
|
1952
|
+
* @group ANIMATION
|
|
1953
|
+
* @requires animate set
|
|
1954
|
+
* @configurable default
|
|
1955
|
+
* @name .toggle()
|
|
1956
|
+
* @syntax toggle(cssClasses)
|
|
1957
|
+
* @syntax toggle(state1, state2)
|
|
1958
|
+
* @syntax toggle(state1, state2, durationMs)
|
|
1959
|
+
* @syntax toggle(state1, state2, durationMs, linearity)
|
|
1960
|
+
* @syntax toggle(state1, state2, durationMs, interpolationFunction)
|
|
1961
|
+
* @module WEB
|
|
1962
|
+
*
|
|
1963
|
+
* Creates a function that switches between the two given states for the list. The states use the ##set() property syntax. You can also
|
|
1964
|
+
* just pass a string of CSS classes, as you do with <var>set()</var>.
|
|
1965
|
+
*
|
|
1966
|
+
* If no duration is given, the returned function changes the state immediately using ##set(). If a duration has been passed, the returned function
|
|
1967
|
+
* uses ##animate() to smoothly transition the state. If the returned function is invoked while an animation is running, it interrupts the
|
|
1968
|
+
* animation and returns to the other state.
|
|
1969
|
+
*
|
|
1970
|
+
* @example Creates a toggle function that changes the background color of the page.
|
|
1971
|
+
* <pre>
|
|
1972
|
+
* var light = $('body').set({$backgroundColor: #000}, {$backgroundColor: #fff});
|
|
1973
|
+
* light(); // toggles state to second state
|
|
1974
|
+
* light(false); // sets first state (background color to #000).
|
|
1975
|
+
* light(true); // sets second state (background color to #fff).
|
|
1976
|
+
* light(); // toggles state to first state
|
|
1977
|
+
* </pre>
|
|
1978
|
+
*
|
|
1979
|
+
* @example Takes the previous function, but adds it as an onclick event handler that toggles the color.
|
|
1980
|
+
* <pre>
|
|
1981
|
+
* var light = $('body').toggle({$backgroundColor: #000}, {$backgroundColor: #fff});
|
|
1982
|
+
* $('#mySwitch').on('click', light);
|
|
1983
|
+
* </pre>
|
|
1984
|
+
*
|
|
1985
|
+
* @example Using an animated transition by passing a duration:
|
|
1986
|
+
* <pre>
|
|
1987
|
+
* var dimmer = $('body').toggle({$backgroundColor: #000}, {$backgroundColor: #fff}, 500);
|
|
1988
|
+
* $('#mySwitch').on('click', dimmer);
|
|
1989
|
+
* </pre>
|
|
1990
|
+
*
|
|
1991
|
+
* @example Toggling CSS classes using the full syntax:
|
|
1992
|
+
* <pre>
|
|
1993
|
+
* var t = $('#myElement').toggle({$: '-myClass1 -myClass2'}, {$: '+myClass1 +myClass2'});
|
|
1994
|
+
* $('#myController').on('click', t);
|
|
1995
|
+
* </pre>
|
|
1996
|
+
*
|
|
1997
|
+
* @example There is a shortcut for toggling CSS classes. Just list them space-separated in a string:
|
|
1998
|
+
* <pre>
|
|
1999
|
+
* var t = $('#myElement').toggle('myClass1 myClass2');
|
|
2000
|
+
* </pre>
|
|
2001
|
+
*
|
|
2002
|
+
* @param cssClasses a string containing space-separated CSS class names to toggle. Classes are disabled in the first state
|
|
2003
|
+
* and enabled in the second.
|
|
2004
|
+
* @param state1 a property map in ##set() syntax describing the initial state of the properties. The properties will automatically be set when the
|
|
2005
|
+
* <var>toggle()</var> function is created. The properties will be set for all elements of the list.
|
|
2006
|
+
* @param state2 a property map describing the second state of the properties. Uses ##set() syntax, like the other state.
|
|
2007
|
+
* @param durationMs optional if set, the duration of the animation in milliseconds. By default, there is no animation and the
|
|
2008
|
+
* properties will be changed immediately.
|
|
2009
|
+
* @param linearity optional defines whether the animation should be linear (1), very smooth (0) or something in between. Default: 0. Ignored if durationMs is 0.
|
|
2010
|
+
* @param interpolationFunc optional an interpolation <code>function(startValue, endValue, t)</code> for the animation which will be called every
|
|
2011
|
+
* time an interpolated value is required:
|
|
2012
|
+
* <dl>
|
|
2013
|
+
* <dt>startValue</dt><dd>The start value of the transition.</dd>
|
|
2014
|
+
* <dt>endValue</dt><dd>The end value of the transition.</dd>
|
|
2015
|
+
* <dt>t</dt><dd>A value between 0 and 1 that specifies the state of the transition.</dd>
|
|
2016
|
+
* <dt class="returnValue">(callback return value)</dt><dd>The value at the time <var>t</var>.</dd>
|
|
2017
|
+
* </dl>
|
|
2018
|
+
* @return a toggle function <code>function(newState)</code> that will toggle between the two states, or set a specific state.
|
|
2019
|
+
* <dl>
|
|
2020
|
+
* <dt>newState (optional)</dt><dd>If a boolean <var>true</var or <var>false</var> is given,
|
|
2021
|
+
* the toggle will set the first or second state, respectively. If called with any other value, or without a value,
|
|
2022
|
+
* the function toggles to the other state.</dd></dl>
|
|
2023
|
+
*/
|
|
2024
|
+
'toggle': function(state1, state2, durationMs, linearity) {
|
|
2025
|
+
var self = this;
|
|
2026
|
+
var animState = {};
|
|
2027
|
+
var state = false, regexg = /\b(?=\w)/g;
|
|
2028
|
+
|
|
2029
|
+
return !state2 ?
|
|
2030
|
+
self['toggle'](replace(state1, regexg, '-'), replace(state1, regexg, '+')) :
|
|
2031
|
+
self['set'](state1) &&
|
|
2032
|
+
function(newState) {
|
|
2033
|
+
if (newState === state)
|
|
2034
|
+
return;
|
|
2035
|
+
state = newState===true||newState===false ? newState : !state;
|
|
2036
|
+
|
|
2037
|
+
if (durationMs)
|
|
2038
|
+
self['animate'](state ? state2 : state1, animState['stop'] ? (animState['stop']() || animState['time']) : durationMs, linearity, animState);
|
|
2039
|
+
else
|
|
2040
|
+
self['set'](state ? state2 : state1);
|
|
2041
|
+
};
|
|
2042
|
+
},
|
|
2043
|
+
|
|
2044
|
+
|
|
2045
|
+
/*$
|
|
2046
|
+
* @id on
|
|
2047
|
+
* @group EVENTS
|
|
2048
|
+
* @requires dollar
|
|
2049
|
+
* @configurable default
|
|
2050
|
+
* @name .on()
|
|
2051
|
+
* @syntax on(names, eventHandler)
|
|
2052
|
+
* @syntax on(names, customFunc, args)
|
|
2053
|
+
* @syntax on(names, customFunc, fThis, args)
|
|
2054
|
+
* @module WEB
|
|
2055
|
+
* Registers the function as event handler for all items in the list.
|
|
2056
|
+
*
|
|
2057
|
+
* By default, Minified cancels event propagation and the element's default behaviour for all elements that have an event handler.
|
|
2058
|
+
* You can override this by prefixing the event name with a '|' or by returning a 'true' value in the handler, which will reinstate
|
|
2059
|
+
* the original JavaScript behaviour.
|
|
2060
|
+
*
|
|
2061
|
+
* Handlers are called with the original event object as first argument, the index of the source element in the
|
|
2062
|
+
* list as second argument and 'this' set to the source element of the event (e.g. the button that has been clicked).
|
|
2063
|
+
*
|
|
2064
|
+
* Instead of the event objects, you can also pass an array of arguments and a new value for 'this' to the callback.
|
|
2065
|
+
* When you pass arguments, the handler's return value is always ignored and the event with unnamed prefixes
|
|
2066
|
+
* will always be cancelled.
|
|
2067
|
+
*
|
|
2068
|
+
* Event handlers can be unregistered using #off#$.off().
|
|
2069
|
+
*
|
|
2070
|
+
* @example Adds a handler to all divs which paints the div background color to red when clicked.
|
|
2071
|
+
* <pre>
|
|
2072
|
+
* $('div').on('click', function() {
|
|
2073
|
+
* this.style.backgroundColor = 'red'; // 'this' contains the element that caused the event
|
|
2074
|
+
* });
|
|
2075
|
+
* </pre>
|
|
2076
|
+
*
|
|
2077
|
+
* @example Registers a handler to call a method setStatus('running') using an inline function:
|
|
2078
|
+
* <pre>
|
|
2079
|
+
* $('#myButton').on('click', function() {
|
|
2080
|
+
* myObject.setStatus('running');
|
|
2081
|
+
* });
|
|
2082
|
+
* </pre>
|
|
2083
|
+
* The previous example can bere written like this, using <var>on()</var>'s <var>args</var> and <var>fThis</var> parameters:
|
|
2084
|
+
* <pre>
|
|
2085
|
+
* $('#myButton').on('click', myObject.setStatus, myObject, ['running']);
|
|
2086
|
+
* </pre>
|
|
2087
|
+
*
|
|
2088
|
+
* @example Adds two handlers on an input field. The event names are prefixed with '|' and thus keep their original behaviour:
|
|
2089
|
+
* <pre>
|
|
2090
|
+
* $('#myInput').on('|keypress |keydown', function() {
|
|
2091
|
+
* // do something
|
|
2092
|
+
* });
|
|
2093
|
+
* </pre>
|
|
2094
|
+
*
|
|
2095
|
+
* @param names the space-separated names of the events to register for, e.g. 'click'. Case-sensitive. The 'on' prefix in front of
|
|
2096
|
+
* the name must not used. You can register the handler for more than one event by specifying several
|
|
2097
|
+
* space-separated event names. If the name is prefixed
|
|
2098
|
+
* with '|' (pipe), the handler's return value is ignored and the event will be passed through the event's default actions will
|
|
2099
|
+
* be executed by the browser.
|
|
2100
|
+
* @param eventHandler the callback <code>function(event, index)</code> to invoke when the event has been triggered:
|
|
2101
|
+
* <dl>
|
|
2102
|
+
* <dt>event</dt><dd>The original DOM event object.</dd>
|
|
2103
|
+
* <dt>index</dt><dd>The index of the target object in the ##list#Minified list## .</dd>
|
|
2104
|
+
* <dt class="returnValue">(callback return value)</dt><dd>Unless the handler returns <var>true</var>
|
|
2105
|
+
* or the event name is prefixed by '|', all further processing of the event will be
|
|
2106
|
+
* stopped and event bubbling will be disabled.</dd>
|
|
2107
|
+
* </dl>
|
|
2108
|
+
* 'this' is set to the element that caused the event.
|
|
2109
|
+
* @param customFunc a function to be called instead of a regular event handler with the arguments given in <var>args</var>
|
|
2110
|
+
* and optionally the 'this' context given using <var>fThis</var>.
|
|
2111
|
+
* @param fThis optional an value for 'this' in the custom callback, as alternative to the event target
|
|
2112
|
+
* @param args optional an array of arguments to pass to the custom callback function instead of the event objects.
|
|
2113
|
+
* If you pass custom arguments, the return value of the handler will always be ignored.
|
|
2114
|
+
* @return the list
|
|
2115
|
+
*/
|
|
2116
|
+
'on': function (eventName, handler, fThisOrArgs, args) {
|
|
2117
|
+
// @cond debug if (!(name && handler)) error("Both parameters to on() are required!");
|
|
2118
|
+
// @cond debug if (/^on/i.test(name)) error("The event name looks invalid. Don't use an 'on' prefix (e.g. use 'click', not 'onclick'");
|
|
2119
|
+
return each(this, function(el, index) {
|
|
2120
|
+
each(eventName.split(/\s/), function(namePrefixed) {
|
|
2121
|
+
var name = replace(namePrefixed, /\|/);
|
|
2122
|
+
var h = function(event) {
|
|
2123
|
+
var e = event || _window.event;
|
|
2124
|
+
// @cond debug try {
|
|
2125
|
+
if ((!handler.apply(args ? fThisOrArgs : e.target, args || fThisOrArgs || [e, index]) || args) && namePrefixed==name) {
|
|
2126
|
+
// @condblock ie8compatibility
|
|
2127
|
+
if (e.stopPropagation) {// W3C DOM3 event cancelling available?
|
|
2128
|
+
// @condend
|
|
2129
|
+
e.preventDefault();
|
|
2130
|
+
e.stopPropagation();
|
|
2131
|
+
// @condblock ie8compatibility
|
|
2132
|
+
}
|
|
2133
|
+
e.returnValue = false; // cancel for IE
|
|
2134
|
+
e.cancelBubble = true; // cancel bubble for IE
|
|
2135
|
+
// @condend
|
|
2136
|
+
}
|
|
2137
|
+
// @cond debug } catch (ex) { error("Error in event handler \""+name+"\": "+ex); }
|
|
2138
|
+
};
|
|
2139
|
+
(handler['M'] = handler['M'] || []).push({'e':el, 'h':h, 'n': name});
|
|
2140
|
+
// @condblock ie8compatibility
|
|
2141
|
+
if (el.addEventListener)
|
|
2142
|
+
// @condend
|
|
2143
|
+
el.addEventListener(name, h, true); // W3C DOM
|
|
2144
|
+
// @condblock ie8compatibility
|
|
2145
|
+
else
|
|
2146
|
+
el.attachEvent('on'+name, h); // IE < 9 version
|
|
2147
|
+
// @condend
|
|
2148
|
+
});
|
|
2149
|
+
});
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2152
|
+
/*$
|
|
2153
|
+
* @stop
|
|
2154
|
+
*/
|
|
2155
|
+
// @cond !on dummy:null
|
|
2156
|
+
}, function(n, v) {M.prototype[n]=v;});
|
|
2157
|
+
|
|
2158
|
+
|
|
2159
|
+
//// MINI FUNCTIONS ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
2160
|
+
|
|
2161
|
+
eachObj({
|
|
2162
|
+
/*$
|
|
2163
|
+
* @id request
|
|
2164
|
+
* @group REQUEST
|
|
2165
|
+
* @requires
|
|
2166
|
+
* @configurable default
|
|
2167
|
+
* @name $.request()
|
|
2168
|
+
* @syntax $.request(method, url)
|
|
2169
|
+
* @syntax $.request(method, url, data)
|
|
2170
|
+
* @syntax $.request(method, url, data, onSuccess)
|
|
2171
|
+
* @syntax $.request(method, url, data, onSuccess, onFailure)
|
|
2172
|
+
* @syntax $.request(method, url, data, onSuccess, onFailure, headers)
|
|
2173
|
+
* @syntax $.request(method, url, data, onSuccess, onFailure, headers, username, password)
|
|
2174
|
+
* @module WEB
|
|
2175
|
+
* Initiates a HTTP request to the given URL, using XMLHttpRequest. It returns a ##promise#Promise## object that allows you to obtain the result.
|
|
2176
|
+
*
|
|
2177
|
+
* @example Invokes a REST web service and parse the resulting document using JSON:
|
|
2178
|
+
* <pre>
|
|
2179
|
+
* $.request('get', 'http://service.example.com/weather', {zipcode: 90210})
|
|
2180
|
+
* .then(function(txt) {
|
|
2181
|
+
* var json = $.parseJSON(txt);
|
|
2182
|
+
* $('#weatherResult').fill('Today's forecast is is: ' + json.today.forecast);
|
|
2183
|
+
* })
|
|
2184
|
+
* .error(function(status, statusText, responseText) {
|
|
2185
|
+
* $('#weatherResult').fill('The weather service was not available.');
|
|
2186
|
+
* });
|
|
2187
|
+
* </pre>
|
|
2188
|
+
*
|
|
2189
|
+
* @example Sending a JSON object to a REST web service:
|
|
2190
|
+
* <pre>
|
|
2191
|
+
* var myRequest = { // create a request object that can be serialized via JSON
|
|
2192
|
+
* request: 'register',
|
|
2193
|
+
* entries: [
|
|
2194
|
+
* {name: 'Joe',
|
|
2195
|
+
* job: 'Plumber'
|
|
2196
|
+
* }]};
|
|
2197
|
+
*
|
|
2198
|
+
* function failureHandler() {
|
|
2199
|
+
* $('#registrationResult').fill('Registration failed');
|
|
2200
|
+
* }
|
|
2201
|
+
*
|
|
2202
|
+
* $.request('post', 'http://service.example.com/directory', $.toJSON(myRequest))
|
|
2203
|
+
* .then(function(txt) {
|
|
2204
|
+
* if (txt == 'OK')
|
|
2205
|
+
* $('#registrationResult').fill('Registration succeeded');
|
|
2206
|
+
* else
|
|
2207
|
+
* failureHandler();
|
|
2208
|
+
* })
|
|
2209
|
+
* .error(failureHandler);
|
|
2210
|
+
* </pre>
|
|
2211
|
+
*
|
|
2212
|
+
*
|
|
2213
|
+
* @param method the HTTP method, e.g. 'get', 'post' or 'head' (rule of thumb: use 'post' for requests that change data
|
|
2214
|
+
* on the server, and 'get' to request data). Not case sensitive.
|
|
2215
|
+
* @param url the server URL to request. May be a relative URL (relative to the document) or an absolute URL. Note that unless you do something
|
|
2216
|
+
* fancy on the server (keyword to google: Access-Control-Allow-Origin), you can only call URLs on the server your script originates from.
|
|
2217
|
+
* @param data optional data to send in the request, either as POST body or as URL parameters. It can be either an object as map of
|
|
2218
|
+
* parameters (for all HTTP methods), a string (for all HTTP methods) or a DOM document ('post' only). If the method is
|
|
2219
|
+
* 'post', it will be sent as body, otherwise parameters are appended to the URL. In order to send several parameters with the
|
|
2220
|
+
* same name, use an array of values in the map. Use null as value for a parameter without value.
|
|
2221
|
+
* @param headers optional a map of HTTP headers to add to the request. Note that you should use the proper capitalization for the
|
|
2222
|
+
* header 'Content-Type', if you set it, because otherwise it may be overwritten.
|
|
2223
|
+
* @param username optional username to be used for HTTP authentication, together with the password parameter
|
|
2224
|
+
* @param password optional password for HTTP authentication
|
|
2225
|
+
* @return a ##promise#Promise## containing the request's status. If the request has successfully completed with HTTP status 200,
|
|
2226
|
+
* the success handler will be called as <code>function(text, xml)</code>:
|
|
2227
|
+
* <dl><dt>text</dt><dd>The response sent by the server as text.</dd>
|
|
2228
|
+
* <dt>xml</dt><dd>If the response was a XML document, the DOM <var>Document</var>. Otherwise null.</a>.</dd></dl>
|
|
2229
|
+
* The failure handler will be called as <code>function(statusCode, statusText, text)</code>:
|
|
2230
|
+
* <dl><dt>statusCode</dt><dd>The HTTP status (never 200; 0 if no HTTP request took place).</dd>
|
|
2231
|
+
* <dt>statusText</dt><dd>The HTTP status text (or null, if the browser threw an exception).</dd>
|
|
2232
|
+
* <dt>text</dt><dd>the response's body text, if there was any, or the exception as string if the browser threw one.</a>.</dd></dl>
|
|
2233
|
+
*/
|
|
2234
|
+
'request': function (method, url, data, headers, username, password) {
|
|
2235
|
+
// @cond debug if (!method) error("request() requires a HTTP method as first argument.");
|
|
2236
|
+
// @cond debug if (!url) error("request() requires a url as second argument.");
|
|
2237
|
+
// @cond debug if (onSuccess && typeof onSuccess != 'function') error("request()'s fourth argument is optional, but if it is set, it must be a function.");
|
|
2238
|
+
// @cond debug if (onFailure && typeof onFailure != 'function') error("request()'s fifth argument is optional, but if it is set, it must be a function.");
|
|
2239
|
+
// @cond debug if (username && !password) error("If the user name is set (7th argument), you must also provide a password as 8th argument."); method = method.toUpperCase();
|
|
2240
|
+
/** @const */ var ContentType = 'Content-Type';
|
|
2241
|
+
var xhr, body = data, callbackCalled = 0, prom = promise();
|
|
2242
|
+
try {
|
|
2243
|
+
//@condblock ie6compatibility
|
|
2244
|
+
xhr = _window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Msxml2.XMLHTTP.3.0");
|
|
2245
|
+
//@condend
|
|
2246
|
+
// @cond !ie6compatibility xhr = new XMLHttpRequest();
|
|
2247
|
+
if (data != null) {
|
|
2248
|
+
headers = headers || {};
|
|
2249
|
+
if (!isString(data) && !isNode(data)) { // if data is parameter map...
|
|
2250
|
+
body = collectObj(data, function processParam(paramName, paramValue) {
|
|
2251
|
+
if (isList(paramValue))
|
|
2252
|
+
return collect(paramValue, function(v) {return processParam(paramName, v);});
|
|
2253
|
+
else
|
|
2254
|
+
return encodeURIComponent(paramName) + ((paramValue != null) ? '=' + encodeURIComponent(paramValue) : '');
|
|
2255
|
+
}).join('&');
|
|
2256
|
+
}
|
|
2257
|
+
|
|
2258
|
+
if (!/post/i.test(method)) {
|
|
2259
|
+
url += '?' + body;
|
|
2260
|
+
body = null;
|
|
2261
|
+
}
|
|
2262
|
+
else if (!isNode(data) && !isString(data) && !headers[ContentType])
|
|
2263
|
+
headers[ContentType] = 'application/x-www-form-urlencoded';
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
xhr.open(method, url, true, username, password);
|
|
2267
|
+
eachObj(headers, function(hdrName, hdrValue) {
|
|
2268
|
+
xhr.setRequestHeader(hdrName, hdrValue);
|
|
2269
|
+
});
|
|
2270
|
+
|
|
2271
|
+
xhr.onreadystatechange = function() {
|
|
2272
|
+
if (xhr.readyState == 4 && !callbackCalled++) {
|
|
2273
|
+
if (xhr.status == 200) {
|
|
2274
|
+
prom(true, [xhr.responseText, xhr.responseXML]);
|
|
2275
|
+
}
|
|
2276
|
+
else
|
|
2277
|
+
prom(false, [xhr.status, xhr.statusText, xhr.responseText]);
|
|
2278
|
+
}
|
|
2279
|
+
};
|
|
2280
|
+
|
|
2281
|
+
xhr.send(body);
|
|
2282
|
+
}
|
|
2283
|
+
catch (e) {
|
|
2284
|
+
if (!callbackCalled)
|
|
2285
|
+
prom(false, [0, null, toString(e)]);
|
|
2286
|
+
}
|
|
2287
|
+
return prom;
|
|
2288
|
+
},
|
|
2289
|
+
|
|
2290
|
+
|
|
2291
|
+
/*
|
|
2292
|
+
* JSON Module. Uses browser built-ins or json.org implementation if available. Otherwise its own implementation,
|
|
2293
|
+
* originally based on public domain implementation http://www.JSON.org/json2.js / http://www.JSON.org/js.html.
|
|
2294
|
+
* Extremely simplified code, made variables local, removed all side-effects (especially new properties for String, Date and Number).
|
|
2295
|
+
*/
|
|
2296
|
+
|
|
2297
|
+
|
|
2298
|
+
/*$
|
|
2299
|
+
* @id tojson
|
|
2300
|
+
* @group JSON
|
|
2301
|
+
* @requires ucode
|
|
2302
|
+
* @configurable default
|
|
2303
|
+
* @name $.toJSON()
|
|
2304
|
+
* @syntax $.toJSON(value)
|
|
2305
|
+
* @module WEB
|
|
2306
|
+
* Converts the given value into a JSON string. The value may be a map-like object, an array or list, a string, number, boolean or null.
|
|
2307
|
+
* If you build Minified without Internet Explorer compatibility, this is just an alias for <var>JSON.stringify</var>.
|
|
2308
|
+
*
|
|
2309
|
+
* The following types are supported by the built-in implementation:
|
|
2310
|
+
* <ul>
|
|
2311
|
+
* <li>Objects (direct properties will be serialized)</li>
|
|
2312
|
+
* <li>Arrays/Lists (with <var>length</var> property)</li>
|
|
2313
|
+
* <li>Strings</li>
|
|
2314
|
+
* <li>Numbers</li>
|
|
2315
|
+
* <li>Boolean</li>
|
|
2316
|
+
* <li>null</li>
|
|
2317
|
+
* </ul>
|
|
2318
|
+
* Any other types in your JSON tree, especially Dates, should be converted into Strings by you.
|
|
2319
|
+
*
|
|
2320
|
+
* @example Converts an object into a JSON object:
|
|
2321
|
+
* <pre>
|
|
2322
|
+
* var myObj = {name: 'Fruits', roles: ['apple', 'banana', 'orange']};
|
|
2323
|
+
* var jsonString = $.toJSON(myObj);
|
|
2324
|
+
* </pre>
|
|
2325
|
+
*
|
|
2326
|
+
* @param value the value (map-like object, array/list, string, number, boolean or null)
|
|
2327
|
+
* @return the JSON string
|
|
2328
|
+
*/
|
|
2329
|
+
// @condblock ie7compatibility
|
|
2330
|
+
'toJSON': function toJSON(value) {
|
|
2331
|
+
if (value == null)
|
|
2332
|
+
return ""+value; //result: "null"; toString(value) is not possible, because it returns an empty string for null
|
|
2333
|
+
if (isString(value = value.valueOf()))
|
|
2334
|
+
return '"' + replace(value, /[\\\"\x00-\x1f\x22\x5c]/g, ucode) + '"' ;
|
|
2335
|
+
if (isList(value))
|
|
2336
|
+
return '[' + collect(value, toJSON).join() + ']';
|
|
2337
|
+
if (isObject(value))
|
|
2338
|
+
return '{' + collectObj(value, function(k, n) { return toJSON(k) + ':' + toJSON(n); }).join() + '}';
|
|
2339
|
+
return toString(value);
|
|
2340
|
+
},
|
|
2341
|
+
// @condend
|
|
2342
|
+
// @cond !ie7compatibility 'toJSON': _window.JSON && JSON.stringify,
|
|
2343
|
+
|
|
2344
|
+
/*$
|
|
2345
|
+
* @id parsejson
|
|
2346
|
+
* @group JSON
|
|
2347
|
+
* @requires ucode
|
|
2348
|
+
* @configurable default
|
|
2349
|
+
* @name $.parseJSON()
|
|
2350
|
+
* @syntax $.parseJSON(text)
|
|
2351
|
+
* @module WEB
|
|
2352
|
+
* Parses a string containing JSON and returns the de-serialized object.
|
|
2353
|
+
* If the browser's built-in function <var>JSON.parse</var> is defined, which it is in pretty all browsers except
|
|
2354
|
+
* Internet Explorer 7 and earlier, it will be used. This is mainly to prevent possible security problems caused
|
|
2355
|
+
* by the use of <var>eval</var> in the implementation. Only in browsers without
|
|
2356
|
+
* <var>JSON.parse</var> Minified's own implementation will be used.
|
|
2357
|
+
*
|
|
2358
|
+
* If you use a Minified build without Internet Explorer 7 compatibility, <var>JSON.parse</var> will always be used.
|
|
2359
|
+
*
|
|
2360
|
+
* @example Parsing a JSON string:
|
|
2361
|
+
* <pre>
|
|
2362
|
+
* var jsonString = "{name: 'Fruits', roles: ['apple', 'banana', 'orange']}";
|
|
2363
|
+
* var myObj = $.parseJSON(jsonString);
|
|
2364
|
+
* </pre>
|
|
2365
|
+
*
|
|
2366
|
+
* @param text the JSON string
|
|
2367
|
+
* @return the resulting JavaScript object. <var>Undefined</var> if not valid.
|
|
2368
|
+
*/
|
|
2369
|
+
// @condblock ie7compatibility
|
|
2370
|
+
'parseJSON': _window.JSON ? _window.JSON.parse : function (text) {
|
|
2371
|
+
var t = replace(text, /[\x00\xad\u0600-\uffff]/g, ucode); // encode unsafe characters
|
|
2372
|
+
if (/^[[\],:{}\s]*$/ // test that, after getting rid of literals, only allowed characters can be found
|
|
2373
|
+
.test(replace(replace(t , /\\["\\\/bfnrtu]/g), // remove all escapes
|
|
2374
|
+
/"[^"\\\n\r]*"|true|false|null|[\d.eE+-]+/g)) // remove all literals
|
|
2375
|
+
)
|
|
2376
|
+
return eval('(' + t + ')');
|
|
2377
|
+
// fall through if not valid
|
|
2378
|
+
// @cond debug error('Can not parse JSON string. Aborting for security reasons.');
|
|
2379
|
+
},
|
|
2380
|
+
// @condend
|
|
2381
|
+
// @cond !ie7compatibility 'parseJSON': _window.JSON && JSON.parse,
|
|
2382
|
+
|
|
2383
|
+
/*$
|
|
2384
|
+
* @id ready
|
|
2385
|
+
* @group EVENTS
|
|
2386
|
+
* @requires ready_vars ready_init
|
|
2387
|
+
* @configurable default
|
|
2388
|
+
* @name $.ready()
|
|
2389
|
+
* @syntax $.ready(handler)
|
|
2390
|
+
* @module WEB
|
|
2391
|
+
* Registers a handler to be called as soon as the HTML has been fully loaded. Does not necessarily wait for images and other elements,
|
|
2392
|
+
* only the main HTML document needs to be complete. On older browsers, it is the same as <var>window.onload</var>.
|
|
2393
|
+
*
|
|
2394
|
+
* If you call <var>ready()</var> after the page is completed, the handler is scheduled for invocation in the event loop as soon as possible.
|
|
2395
|
+
*
|
|
2396
|
+
* @example Registers a handler that sets some text in an element:
|
|
2397
|
+
* <pre>
|
|
2398
|
+
* $.ready(function() {
|
|
2399
|
+
* $('#someElement').fill('ready() called');
|
|
2400
|
+
* });
|
|
2401
|
+
* </pre>
|
|
2402
|
+
*
|
|
2403
|
+
* @param handler the <code>function()</code> to be called when the HTML is ready.
|
|
2404
|
+
*/
|
|
2405
|
+
'ready': ready,
|
|
2406
|
+
|
|
2407
|
+
|
|
2408
|
+
/*$
|
|
2409
|
+
* @id setcookie
|
|
2410
|
+
* @group COOKIE
|
|
2411
|
+
* @configurable default
|
|
2412
|
+
* @name $.setCookie()
|
|
2413
|
+
* @syntax $.setCookie(name, value)
|
|
2414
|
+
* @syntax $.setCookie(name, value, dateOrDays)
|
|
2415
|
+
* @syntax $.setCookie(name, value, dateOrDays, path)
|
|
2416
|
+
* @syntax $.setCookie(name, value, dateOrDays, path, domain)
|
|
2417
|
+
* @module WEB
|
|
2418
|
+
* Creates, updates or deletes a cookie. If there is an an existing cookie
|
|
2419
|
+
* of the same name, will be overwritten with the new value and settings.
|
|
2420
|
+
*
|
|
2421
|
+
* To delete a cookie, overwrite it with an expiration date in the past. The easiest way to do this is to
|
|
2422
|
+
* use <code>-1</code> as third argument.
|
|
2423
|
+
*
|
|
2424
|
+
* @example Reads the existing cookie 'numberOfVisits', increases the number and stores it:
|
|
2425
|
+
* <pre>
|
|
2426
|
+
* var visits = $.getCookie('numberOfVisits');
|
|
2427
|
+
* $.setCookie('numberOfVisits',
|
|
2428
|
+
* visits ? (parseInt(visits) + 1) : 1, // if cookie not set, start with 1
|
|
2429
|
+
* 365); // store for 365 days
|
|
2430
|
+
* </pre>
|
|
2431
|
+
*
|
|
2432
|
+
* @example Deletes the cookie 'numberOfVisits':
|
|
2433
|
+
* <pre>
|
|
2434
|
+
* $.setCookie('numberOfVisits', '', -1);
|
|
2435
|
+
* </pre>
|
|
2436
|
+
*
|
|
2437
|
+
* @param name the name of the cookie. This should ideally be an alphanumeric name, as it will not be escaped by Minified and this
|
|
2438
|
+
* guarantees compatibility with all systems.
|
|
2439
|
+
* If it contains a '=', it is guaranteed not to work, because it breaks the cookie syntax.
|
|
2440
|
+
* @param value the value of the cookie. All characters can be used. Non-Alphanumeric other than "*@-_+./" will be escaped using the
|
|
2441
|
+
* JavaScript <var>escape()</var> function, unless you set the optional <var>dontEscape</var> parameter.
|
|
2442
|
+
* @param dateOrDays optional specifies when the cookie expires. Can be either a Date object or a number that specifies the
|
|
2443
|
+
* amount of days. If not set, the cookie has a session lifetime, which means it will be deleted as soon as the
|
|
2444
|
+
* browser has been closed. If the number negative or the date in the past, the cookie will be deleted.
|
|
2445
|
+
* @param path optional if set, the cookie will be restricted to documents in the given path. Otherwise it is valid
|
|
2446
|
+
* for the whole domain. This is rarely needed and defaults to '/'.
|
|
2447
|
+
* @param domain optional if set, you use it to specify the domain (e.g. example.com) which can read the cookie. If you don't set it,
|
|
2448
|
+
* the domain which hosts the current document is used. This parameter is rarely used, because there are only very
|
|
2449
|
+
* few use cases in which this makes sense.
|
|
2450
|
+
* @param dontEscape optional if set, the cookie value is not escaped. Note that without escaping you can not use every possible
|
|
2451
|
+
* character (e.g. ";" will break the cookie), but it may be needed for interoperability with systems that need
|
|
2452
|
+
* some non-alphanumeric characters unescaped or use a different escaping algorithm.
|
|
2453
|
+
*/
|
|
2454
|
+
'setCookie': function(name, value, dateOrDays, path, domain, dontEscape) {
|
|
2455
|
+
// @cond debug if (!name) error('Cookie name must be set!');
|
|
2456
|
+
// @cond debug if (/[^\w\d-_%]/.test(name)) error('Cookie name must not contain non-alphanumeric characters other than underscore and minus. Please escape them using encodeURIComponent().');
|
|
2457
|
+
_document.cookie = name + '=' + (dontEscape ? value : escape(value)) +
|
|
2458
|
+
(dateOrDays ? ('; expires='+(isObject(dateOrDays) ? dateOrDays : new Date(now() + dateOrDays * 8.64E7)).toUTCString()) : '') +
|
|
2459
|
+
'; path=' + (path ? escapeURI(path) : '/') + (domain ? ('; domain=' + escape(domain)) : '');
|
|
2460
|
+
},
|
|
2461
|
+
|
|
2462
|
+
/*$
|
|
2463
|
+
* @id getcookie
|
|
2464
|
+
* @group COOKIE
|
|
2465
|
+
* @requires
|
|
2466
|
+
* @configurable default
|
|
2467
|
+
* @name $.getCookie()
|
|
2468
|
+
* @syntax $.getCookie(name)
|
|
2469
|
+
* @syntax $.getCookie(name, dontUnescape)
|
|
2470
|
+
* @module WEB
|
|
2471
|
+
* Tries to find the cookie with the given name and returns it.
|
|
2472
|
+
*
|
|
2473
|
+
* @example Reads the existing cookie 'numberOfVisits' and displays the number in the element 'myCounter':
|
|
2474
|
+
* <pre>
|
|
2475
|
+
* var visits = $.getCookie('numberOfVisits');
|
|
2476
|
+
* if (!visits) // check whether cookie set. Null if not
|
|
2477
|
+
* $('#myCounter').set('innerHML', 'Your first visit.');
|
|
2478
|
+
* else
|
|
2479
|
+
* $('#myCounter').set('innerHTML', 'Visit No ' + visits);
|
|
2480
|
+
* </pre>
|
|
2481
|
+
*
|
|
2482
|
+
* @param name the name of the cookie. Should consist of alphanumeric characters, percentage, minus and underscore only, as it will not be escaped.
|
|
2483
|
+
* You may want to escape the name using <var>encodeURIComponent()</var> for all other characters.
|
|
2484
|
+
* @param dontUnescape optional if set and true, the value will be returned unescaped. Use this parameter only if the value has been encoded
|
|
2485
|
+
* in a special way, and not with the JavaScript <var>encode()</var> method.
|
|
2486
|
+
* @return the value of the cookie, or null if not found. Unless <var>dontUnescape</var> has been set, the value has been unescaped
|
|
2487
|
+
* using JavaScript's <code>unescape()</code> function.
|
|
2488
|
+
*/
|
|
2489
|
+
'getCookie': function(name, dontUnescape) {
|
|
2490
|
+
// @cond debug if (!name) error('Cookie name must be set!');
|
|
2491
|
+
// @cond debug if (/[^\w\d-_%]/.test(name)) error('Cookie name must not contain non-alphanumeric characters other than underscore and minus. Please escape them using encodeURIComponent().');
|
|
2492
|
+
var regexp, match = (regexp = new RegExp('(^|;)\\s*'+name+'=([^;]*)').exec(_document.cookie)) && regexp[2];
|
|
2493
|
+
return dontUnescape ? match : match && unescape(match);
|
|
2494
|
+
},
|
|
2495
|
+
|
|
2496
|
+
/*$
|
|
2497
|
+
* @id loop
|
|
2498
|
+
* @group ANIMATION
|
|
2499
|
+
* @requires animation_vars
|
|
2500
|
+
* @configurable default
|
|
2501
|
+
* @name $.loop()
|
|
2502
|
+
* @syntax $.loop(paintCallback)
|
|
2503
|
+
* @module WEB
|
|
2504
|
+
* Runs an animation loop. The given callback method will be invoked repeatedly to create a new animation frame.
|
|
2505
|
+
* In modern browsers, <var>requestAnimationFrame</var> will be used to invoke the callback every time the browser is ready for a new
|
|
2506
|
+
* animation frame.
|
|
2507
|
+
* The exact frequency is determined by the browser and may vary depending on factors such as the time needed to
|
|
2508
|
+
* render the current page, the screen's framerate and whether the page is currently visible to the user.
|
|
2509
|
+
* In older browsers, the callback function will be invoked approximately every 33 milliseconds.
|
|
2510
|
+
*
|
|
2511
|
+
* An animation loop runs indefinitely. To stop it, you have two options:
|
|
2512
|
+
* <ul><li><var>$.loop()</var> returns a <var>stop()</var> function. If you invoke it, the animation loops ends</li>
|
|
2513
|
+
* <li>The animation callback receives the same <var>stop()</var> function as second argument, so the callback can end the animation itself</li>
|
|
2514
|
+
* </ul>
|
|
2515
|
+
*
|
|
2516
|
+
* @example Animates a div by moving along in a circle.
|
|
2517
|
+
* <pre>
|
|
2518
|
+
* var myDiv = $$('#myAnimatedDiv');
|
|
2519
|
+
* var rotationsPerMs = 1000; // one rotation per second
|
|
2520
|
+
* var radius = 100;
|
|
2521
|
+
* var d = 3000; // duration in ms
|
|
2522
|
+
* $.loop(function(t, stopFunc) {
|
|
2523
|
+
* if (t > d) { // time is up: call stopFunc()!
|
|
2524
|
+
* stopFunc();
|
|
2525
|
+
* return;
|
|
2526
|
+
* }
|
|
2527
|
+
*
|
|
2528
|
+
* var a = 2 * Math.PI * t / rotationsPerMs // angular position
|
|
2529
|
+
* myDiv.style.left = (radius * Math.cos(a) + ' px';
|
|
2530
|
+
* myDiv.style.top = (radius * Math.sin(a) + ' px';
|
|
2531
|
+
* });
|
|
2532
|
+
* </pre>
|
|
2533
|
+
*
|
|
2534
|
+
* @param paintCallback a callback <code>function(timestamp, stopFunc)</code> to invoke for painting. Parameters given to callback:
|
|
2535
|
+
* <dl>
|
|
2536
|
+
* <dt>timestamp</dt><dd>The number of miliseconds since animation start.</dd>
|
|
2537
|
+
* <dt>stop</dt><dd>Call this <code>function()</code> to stop the currently running animation.</dd>
|
|
2538
|
+
* </dl>
|
|
2539
|
+
* The callback's return value will be ignored.
|
|
2540
|
+
* @return a <code>function()</code> that stops the currently running animation. This is the same function that is also given to the callback.
|
|
2541
|
+
*/
|
|
2542
|
+
'loop': function(paintCallback) {
|
|
2543
|
+
var entry = {c: paintCallback, t: now()};
|
|
2544
|
+
entry.s = function() {
|
|
2545
|
+
for (var i = 0; i < ANIMATION_HANDLERS.length; i++) // can't use each() or filter() here, list may be modified during run!!
|
|
2546
|
+
if (ANIMATION_HANDLERS[i] === entry)
|
|
2547
|
+
ANIMATION_HANDLERS.splice(i--, 1);
|
|
2548
|
+
};
|
|
2549
|
+
|
|
2550
|
+
if (ANIMATION_HANDLERS.push(entry) < 2) { // if first handler..
|
|
2551
|
+
(function raFunc() {
|
|
2552
|
+
if (each(ANIMATION_HANDLERS, function(a) {a.c(Math.max(0, now() - a.t), a.s);}).length) // check len after run, in case the callback invoked stop func
|
|
2553
|
+
REQUEST_ANIMATION_FRAME(raFunc);
|
|
2554
|
+
})();
|
|
2555
|
+
}
|
|
2556
|
+
return entry.s;
|
|
2557
|
+
},
|
|
2558
|
+
|
|
2559
|
+
/*$
|
|
2560
|
+
* @id wait
|
|
2561
|
+
* @configurable default
|
|
2562
|
+
* @requires
|
|
2563
|
+
* @name $.wait()
|
|
2564
|
+
* @syntax $.wait()
|
|
2565
|
+
* @syntax $.wait(durationMs)
|
|
2566
|
+
* @module WEB
|
|
2567
|
+
*
|
|
2568
|
+
* Creates a new promise that will be fulfilled as soon as the specified number of milliseconds have passed. This is mainly useful for animation,
|
|
2569
|
+
* because it allows you to chain delays into your animation chain.
|
|
2570
|
+
*
|
|
2571
|
+
* @example Chained animation using ##promise#Promise## callbacks. The element is first moved to the position 200/0, then to 200/200, waits for 50ms
|
|
2572
|
+
* and finally moves to 100/100.
|
|
2573
|
+
* <pre>
|
|
2574
|
+
* var div = $('#myMovingDiv').set({$left: '0px', $top: '0px'});
|
|
2575
|
+
* div.animate({$left: '200px', $top: '0px'}, 600, 0)
|
|
2576
|
+
* .then(function() {
|
|
2577
|
+
* div.animate({$left: '200px', $top: '200px'}, 800, 0);
|
|
2578
|
+
* }).then(function() {
|
|
2579
|
+
* return $.wait(50);
|
|
2580
|
+
* }).then(function() {
|
|
2581
|
+
* div.animate({$left: '100px', $top: '100px'}, 400);
|
|
2582
|
+
* });
|
|
2583
|
+
* });
|
|
2584
|
+
* </pre>
|
|
2585
|
+
*
|
|
2586
|
+
*
|
|
2587
|
+
* @param durationMs optional the number of milliseconds to wait. If omitted, the promise will be fulfilled as soon as the browser can run it
|
|
2588
|
+
* from the event loop.
|
|
2589
|
+
* @param args optional an array of arguments to pass to the promise handler
|
|
2590
|
+
* @return a ##promise#Promise## object that will be fulfilled when the time is over. It will never fail. The promise argument is the
|
|
2591
|
+
* <var>args</var> parameter as given to <var>wait()</var>.
|
|
2592
|
+
*/
|
|
2593
|
+
'wait': function(durationMs, args) {
|
|
2594
|
+
var p = promise();
|
|
2595
|
+
delay(function() {p(true, args);}, durationMs);
|
|
2596
|
+
return p;
|
|
2597
|
+
},
|
|
2598
|
+
|
|
2599
|
+
/*$
|
|
2600
|
+
* @id off
|
|
2601
|
+
* @group EVENTS
|
|
2602
|
+
* @requires on
|
|
2603
|
+
* @configurable default
|
|
2604
|
+
* @name $.off()
|
|
2605
|
+
* @syntax $.off(handler)
|
|
2606
|
+
* @module WEB
|
|
2607
|
+
* Removes the given event handler. The call will be ignored if the given handler has not been registered using ##on().
|
|
2608
|
+
* If the handler has been registered for more than one element or event, it will be removed from all instances.
|
|
2609
|
+
*
|
|
2610
|
+
* @example Adds a handler to an element:
|
|
2611
|
+
* <pre>
|
|
2612
|
+
* function myEventHandler() {
|
|
2613
|
+
* this.style.backgroundColor = 'red'; // 'this' contains the element that caused the event
|
|
2614
|
+
* }
|
|
2615
|
+
* $('#myElement').on('click', myEventHandler); // add event handler
|
|
2616
|
+
*
|
|
2617
|
+
* window.setInterval(function() { // after 5s, remove event handler
|
|
2618
|
+
* $.off(myEventHandler);
|
|
2619
|
+
* }, 5000);
|
|
2620
|
+
* </pre>
|
|
2621
|
+
*
|
|
2622
|
+
* @param handler the handler to unregister, as given to ##on(). It must be a handler that has previously been registered using ##on().
|
|
2623
|
+
* If the handler is not registered as event handler, the function does nothing.
|
|
2624
|
+
*/
|
|
2625
|
+
'off': function (handler) {
|
|
2626
|
+
// @cond debug if (!handler || !handler['M']) error("No handler given or handler invalid.");
|
|
2627
|
+
each(handler['M'], function(h) {
|
|
2628
|
+
// @condblock ie8compatibility
|
|
2629
|
+
if (h['e'].removeEventListener)
|
|
2630
|
+
// @condend
|
|
2631
|
+
h['e'].removeEventListener(h['n'], h['h'], true); // W3C DOM
|
|
2632
|
+
// @condblock ie8compatibility
|
|
2633
|
+
else
|
|
2634
|
+
h['e'].detachEvent('on'+h['n'], h['h']); // IE < 9 version
|
|
2635
|
+
// @condend
|
|
2636
|
+
});
|
|
2637
|
+
handler['M'] = null;
|
|
2638
|
+
}
|
|
2639
|
+
|
|
2640
|
+
|
|
2641
|
+
/*$
|
|
2642
|
+
* @stop
|
|
2643
|
+
*/
|
|
2644
|
+
// @cond !off dummy:null
|
|
2645
|
+
|
|
2646
|
+
}, function(n, v) {$[n]=v;});
|
|
2647
|
+
|
|
2648
|
+
//// GLOBAL INITIALIZATION ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
2649
|
+
|
|
2650
|
+
/*$
|
|
2651
|
+
* @id ready_init
|
|
2652
|
+
* @dependency
|
|
2653
|
+
*/
|
|
2654
|
+
// @condblock ie8compatibility
|
|
2655
|
+
_window.onload = triggerDomReady;
|
|
2656
|
+
|
|
2657
|
+
if (_document.addEventListener)
|
|
2658
|
+
// @condend
|
|
2659
|
+
_document.addEventListener("DOMContentLoaded", triggerDomReady, false);
|
|
2660
|
+
/*$
|
|
2661
|
+
@stop
|
|
2662
|
+
*/
|
|
2663
|
+
|
|
2664
|
+
// @condblock amdsupport
|
|
2665
|
+
return {
|
|
2666
|
+
// @condend amdsupport
|
|
2667
|
+
|
|
2668
|
+
// @cond !amdsupport var MINI = {
|
|
2669
|
+
|
|
2670
|
+
/*$
|
|
2671
|
+
* @id dollar
|
|
2672
|
+
* @group SELECTORS
|
|
2673
|
+
* @requires dollarraw
|
|
2674
|
+
* @dependency yes
|
|
2675
|
+
* @name $()
|
|
2676
|
+
* @syntax $(selector)
|
|
2677
|
+
* @syntax $(selector, context)
|
|
2678
|
+
* @syntax $(selector, context, childOnly)
|
|
2679
|
+
* @syntax $(list)
|
|
2680
|
+
* @syntax $(list, context)
|
|
2681
|
+
* @syntax $(list, context, childOnly)
|
|
2682
|
+
* @syntax $(object)
|
|
2683
|
+
* @syntax $(object, context)
|
|
2684
|
+
* @syntax $(object, context, childOnly)
|
|
2685
|
+
* @syntax $(domreadyFunction)
|
|
2686
|
+
* @module WEB
|
|
2687
|
+
* Creates a new ##list#Minified list##, or register a DOMReady-handler.
|
|
2688
|
+
* The most common usage is with a CSS-like selector. <var$()</var> will then create a list containing all elements of the current HTML
|
|
2689
|
+
* document that fulfill the filter conditions. Alternatively you can also specify a list of objects or a single object.
|
|
2690
|
+
* Nested lists will automatically be flattened, and nulls will automatically be removed from the resulting list.
|
|
2691
|
+
*
|
|
2692
|
+
* Additionally, you can specify a second argument to provide a context. Contexts only make sense if you selected only
|
|
2693
|
+
* HTML nodes with the first parameter. Then the context limits the resulting list to include only those nodes
|
|
2694
|
+
* that are descendants of the context nodes. The context can be either a selector, a list or a single HTML node, and will be
|
|
2695
|
+
* processed like the first argument. A third arguments allows you to limit the list to
|
|
2696
|
+
* only those elements that are direct children of the context nodes (so a child of a child would be filtered out).
|
|
2697
|
+
*
|
|
2698
|
+
*
|
|
2699
|
+
* As a special shortcut, if you pass a function to <var>$()</var>, it will be registered using #ready#$.ready() to be executed
|
|
2700
|
+
* when the DOM model is complete.
|
|
2701
|
+
*
|
|
2702
|
+
* @example A simple selector to find an element by id.
|
|
2703
|
+
* <pre>
|
|
2704
|
+
* var l0 = $('#myElementId');
|
|
2705
|
+
* </pre>
|
|
2706
|
+
*
|
|
2707
|
+
* @example You can pass a reference to a DOM node to the function to receive a list containing only this node:
|
|
2708
|
+
* <pre>
|
|
2709
|
+
* var l1 = $(document.getElementById('myElementId'));
|
|
2710
|
+
* </pre>
|
|
2711
|
+
*
|
|
2712
|
+
* @example Lists and arrays will be copied:
|
|
2713
|
+
* <pre>
|
|
2714
|
+
* var l2 = $([elementA, elementB, elementC]);
|
|
2715
|
+
* </pre>
|
|
2716
|
+
*
|
|
2717
|
+
* @example Lists will be automatically flattened and nulls removed. So this list <var>l3</var> has the same content as <var>l2</var>:
|
|
2718
|
+
* <pre>
|
|
2719
|
+
* var l3 = $([elementA, [elementB, null, elementC], null]);
|
|
2720
|
+
* </pre>
|
|
2721
|
+
*
|
|
2722
|
+
* @example This is a simple selector to find all elements with the given class.
|
|
2723
|
+
* <pre>
|
|
2724
|
+
* var l4 = $('.myClass');
|
|
2725
|
+
* </pre>
|
|
2726
|
+
*
|
|
2727
|
+
* @example A selector to find all elements with the given name.
|
|
2728
|
+
* <pre>
|
|
2729
|
+
* var l5 = $('input'); // finds all input elements
|
|
2730
|
+
* </pre>
|
|
2731
|
+
*
|
|
2732
|
+
* @example A selector to find all elements with the given name and class.
|
|
2733
|
+
* <pre>
|
|
2734
|
+
* var l6 = $('input.myRadio'); // finds all input elements with class 'myRadio'
|
|
2735
|
+
* </pre>
|
|
2736
|
+
*
|
|
2737
|
+
* @example A selector to find all elements that are descendants of the given element.
|
|
2738
|
+
* <pre>
|
|
2739
|
+
* var l7 = $('#myForm input'); // finds all input elements that are in the element with the id myForm
|
|
2740
|
+
* </pre>
|
|
2741
|
+
*
|
|
2742
|
+
* @example A selector to find all elements that have either CSS class 'a' or class 'b':
|
|
2743
|
+
* <pre>
|
|
2744
|
+
* var l8 = $('.a, .b'); // finds all elements that have either the class a or class b
|
|
2745
|
+
* </pre>
|
|
2746
|
+
*
|
|
2747
|
+
* @example A selector that finds all elements that are descendants of the element myDivision, are inside a .myForm class and are input elements:
|
|
2748
|
+
* <pre>
|
|
2749
|
+
* var l9 = $('#myDivision .myForm input');
|
|
2750
|
+
* </pre>
|
|
2751
|
+
*
|
|
2752
|
+
* @example Using contexts to make it easier to specify ancestors:
|
|
2753
|
+
* <pre>
|
|
2754
|
+
* var l10 = $('.myRadio', '#formA, #formB, #formC');
|
|
2755
|
+
* </pre>
|
|
2756
|
+
* The result is identical to:
|
|
2757
|
+
* <pre>
|
|
2758
|
+
* var l10 = $('#formA .myRadio, #formB .myRadio, #formC .myRadio');
|
|
2759
|
+
* </pre>
|
|
2760
|
+
*
|
|
2761
|
+
* @example Using one of the list functions, ##set(), on the list, and setting the element's text color. '$' at the beginning of the property name sets a CSS value.
|
|
2762
|
+
* <pre>
|
|
2763
|
+
* $('#myElementId').set('$color', 'red');
|
|
2764
|
+
* </pre>
|
|
2765
|
+
*
|
|
2766
|
+
* @example Most list methods return the list you invoked them on, allowing you to chain them:
|
|
2767
|
+
* <pre>
|
|
2768
|
+
* $('#myForm .myRadio').addClass('uncheckedRadio')
|
|
2769
|
+
* .set('checked', true)
|
|
2770
|
+
* .on('click', function() {
|
|
2771
|
+
* $(this).set({@: 'uncheckedRadio');
|
|
2772
|
+
* });
|
|
2773
|
+
* </pre>
|
|
2774
|
+
*
|
|
2775
|
+
* @example Using $() as a #ready#$.ready() shortcut:
|
|
2776
|
+
* <pre>
|
|
2777
|
+
* $(function() {
|
|
2778
|
+
* // in here you can safely work with the HTML document
|
|
2779
|
+
* });
|
|
2780
|
+
* </pre>
|
|
2781
|
+
*
|
|
2782
|
+
* @param selector a simple, CSS-like selector for HTML elements. It supports '#id' (lookup by id), '.class' (lookup by class),
|
|
2783
|
+
* 'element' (lookup by elements) and 'element.class' (combined class and element). Use commas to combine several selectors.
|
|
2784
|
+
* You can also join two or more selectors by space to find elements which are descendants of the previous selectors.
|
|
2785
|
+
* For example, use 'div' to find all div elements, '.header' to find all elements containing a class name called 'header', and
|
|
2786
|
+
* 'a.popup' for all a elements with the class 'popup'. To find all elements with 'header' or 'footer' class names,
|
|
2787
|
+
* write '.header, .footer'. To find all divs elements below the element with the id 'main', use '#main div'.
|
|
2788
|
+
* The selector "*" will return all elements.
|
|
2789
|
+
* @param list a list to copy. It can be an array, another Minified list, a DOM nodelist or anything else that has a <var>length</var> property and
|
|
2790
|
+
* allows read access by index. A shallow copy of the list will be returned. Nulls will be automatically removed from the copy. Nested lists
|
|
2791
|
+
* will be flattened, so the result only contains nodes.
|
|
2792
|
+
* @param object a object to create a single-element list containing only the object. If the object argument is null, an empty list will be returned.
|
|
2793
|
+
* @param domreadyFunction a function to be registered using #ready#$.ready().
|
|
2794
|
+
* @param context optional an optional selector, node or list of nodes which specifies one or more common ancestor nodes for the selection, using the same syntax variants as the
|
|
2795
|
+
* first argument. If given, the returned list contains only descendants of the context nodes, all others will be filtered out.
|
|
2796
|
+
* @param childOnly optional if set, only direct children of the context nodes are included in the list. Children of children will be filtered out. If omitted or not
|
|
2797
|
+
* true, all descendants of the context will be included.
|
|
2798
|
+
* @return the array-like ##list#Minified list## object containing the content specified by the selector.
|
|
2799
|
+
* Please note that duplicates (e.g. created using the comma-syntax or several context nodes) will not be removed. If the first argument was a list,
|
|
2800
|
+
* the existing order will be kept. If the first argument was a simple selector, the nodes are in document order. If you combined several selectors
|
|
2801
|
+
* using commas, only the individual results of the selectors will keep the document order, but will then be joined to form a single list. This list will,
|
|
2802
|
+
* not be in document order anymore, unless you use a build without legacy IE support.
|
|
2803
|
+
*/
|
|
2804
|
+
'$': $,
|
|
2805
|
+
|
|
2806
|
+
/*$
|
|
2807
|
+
* @id dollardollar
|
|
2808
|
+
* @group SELECTORS
|
|
2809
|
+
* @requires dollarraw
|
|
2810
|
+
* @configurable default
|
|
2811
|
+
* @name $$()
|
|
2812
|
+
* @syntax $$(selector)
|
|
2813
|
+
* @shortcut $$() - It is recommended that you assign MINI.$$ to a variable $$.
|
|
2814
|
+
* @module WEB
|
|
2815
|
+
* Returns a DOM object containing the first match of the given selector, or <var>undefined</var> if no match was found.
|
|
2816
|
+
* <var>$$</var> allows you to easily access an element directly. It is the equivalent to writing "$(selector)[0]".
|
|
2817
|
+
*
|
|
2818
|
+
* Please note that the function <var>$$</var> will not be automatically exported by Minified. You should always import it
|
|
2819
|
+
* using the recommended import statement:
|
|
2820
|
+
* <pre>
|
|
2821
|
+
* var MINI = require('minified'), $ = MINI.$, $$ = MINI.$$, EE = MINI.EE;
|
|
2822
|
+
* </pre>
|
|
2823
|
+
*
|
|
2824
|
+
* @example Select the checkbox 'myCheckbox':
|
|
2825
|
+
* <pre>
|
|
2826
|
+
* $$('#myCheckbox').checked = true;
|
|
2827
|
+
* </pre>
|
|
2828
|
+
*
|
|
2829
|
+
* @param selector a simple, CSS-like selector for the element. Uses the full syntax described in #dollar#$(). The most common
|
|
2830
|
+
* parameter for this function is the id selector with the syntax "#id".
|
|
2831
|
+
* @return a DOM object of the first match, or <var>undefined</var> if the selector did not return at least one match
|
|
2832
|
+
*/
|
|
2833
|
+
'$$': $$,
|
|
2834
|
+
|
|
2835
|
+
|
|
2836
|
+
/*$
|
|
2837
|
+
* @id ee
|
|
2838
|
+
* @group ELEMENT
|
|
2839
|
+
* @requires dollar set add
|
|
2840
|
+
* @configurable default
|
|
2841
|
+
* @name EE()
|
|
2842
|
+
* @syntax EE(elementName)
|
|
2843
|
+
* @syntax EE(elementName, properties)
|
|
2844
|
+
* @syntax EE(elementName, children)
|
|
2845
|
+
* @syntax EE(elementName, properties, children)
|
|
2846
|
+
* @syntax EE(elementName, properties, children, onCreate)
|
|
2847
|
+
* @shortcut EE() - It is recommended that you assign MINI.EE to a variable EE.
|
|
2848
|
+
* @module WEB
|
|
2849
|
+
* Creates a new Element Factory. An Element Factory is a function without arguments that returns a ##list#Minified list##
|
|
2850
|
+
* containing a newly created DOM element, optionally with attributes and children.
|
|
2851
|
+
* Typically it will be used to insert elements into the DOM tree using ##add() or a similar function.
|
|
2852
|
+
*
|
|
2853
|
+
* Please note that the function <var>EE</var> will not be automatically exported by Minified. You should always import it
|
|
2854
|
+
* using the recommended import statement:
|
|
2855
|
+
* <pre>
|
|
2856
|
+
* var MINI = require('minified'), $ = MINI.$, $$ = MINI.$$, EE = MINI.EE;
|
|
2857
|
+
* </pre>
|
|
2858
|
+
*
|
|
2859
|
+
* @example Creating a simple factory for a <span> element with some text:
|
|
2860
|
+
* <pre>
|
|
2861
|
+
* var mySpan = EE('span', 'Hello World');
|
|
2862
|
+
* </pre>
|
|
2863
|
+
* creates a factory to produce this:
|
|
2864
|
+
* <pre>
|
|
2865
|
+
* <span>Hello World</span>
|
|
2866
|
+
* </pre>
|
|
2867
|
+
*
|
|
2868
|
+
* @example Adding the 'Hello World; <span> element to all elements with the class '.greeting':
|
|
2869
|
+
* <pre>
|
|
2870
|
+
* $('.greeting').add(EE('span', 'Hello World'));
|
|
2871
|
+
*
|
|
2872
|
+
* @example Creating a factory for a <span> element with style and some text:
|
|
2873
|
+
* <pre>
|
|
2874
|
+
* var span2 = EE('span', {'@title': 'Greetings'}, 'Hello World');
|
|
2875
|
+
* </pre>
|
|
2876
|
+
* The factory creates this:
|
|
2877
|
+
* <pre>
|
|
2878
|
+
* <span title="Greetings">Hello World</span>
|
|
2879
|
+
* </pre>
|
|
2880
|
+
*
|
|
2881
|
+
* @example Creating a <form> element with two text fields, labels and a submit button:
|
|
2882
|
+
* <pre>var myForm = EE('form', {'@method': 'post'}, [
|
|
2883
|
+
* EE('label', {'@for': 'nameInput'}, 'Name:'),
|
|
2884
|
+
* EE('input', {'@id': 'nameInput', '@type': 'input'}),
|
|
2885
|
+
* EE('br'),
|
|
2886
|
+
* EE('label', {'@for': 'ageInput'}, 'Age:'),
|
|
2887
|
+
* EE('input', {'@id': 'ageInput', '@type': 'input'}),
|
|
2888
|
+
* EE('br'),
|
|
2889
|
+
* EE('input', {'@type': 'submit, '@value': 'Join'})
|
|
2890
|
+
* ]);
|
|
2891
|
+
* </pre>
|
|
2892
|
+
* results in (newlines and indentation added for readability):
|
|
2893
|
+
* <pre>
|
|
2894
|
+
* <form method="post>
|
|
2895
|
+
* <label for="nameInput">Name:</label>
|
|
2896
|
+
* <input id="nameInput" type="input"/>
|
|
2897
|
+
* <br/>
|
|
2898
|
+
* <label for="ageInput"/>Age:</label>
|
|
2899
|
+
* <input id="ageInput" type="input"/>
|
|
2900
|
+
* <br/>
|
|
2901
|
+
* <input value="Join" type="submit"/>
|
|
2902
|
+
* </form>
|
|
2903
|
+
* </pre>
|
|
2904
|
+
*
|
|
2905
|
+
* @example If you only want to add an attribute under a certain condition,
|
|
2906
|
+
* a simple trick is to pass null as value if you do not need it:
|
|
2907
|
+
* <pre>
|
|
2908
|
+
* var myInput = EE('input', {
|
|
2909
|
+
* '@id': 'myCheckbox',
|
|
2910
|
+
* '@type': 'checkbox',
|
|
2911
|
+
* '@checked': shouldBeChecked() ? 'checked' : null
|
|
2912
|
+
* });
|
|
2913
|
+
* </pre>
|
|
2914
|
+
*
|
|
2915
|
+
* @example You can set styles directly using a $ prefix for the name:
|
|
2916
|
+
* <pre>
|
|
2917
|
+
* var myStylesSpan = EE('span', {$color: "red", $fontWeight: "bold"}, "I'm styled");
|
|
2918
|
+
* </pre>
|
|
2919
|
+
*
|
|
2920
|
+
* @example To add event handlers, use the fourth argument:
|
|
2921
|
+
* <pre>
|
|
2922
|
+
* var myStylesSpan = EE('input', {'@name': "myInput"}, null, function(e) {
|
|
2923
|
+
* e.on('change', inputChanged);
|
|
2924
|
+
* });
|
|
2925
|
+
* </pre>
|
|
2926
|
+
*
|
|
2927
|
+
* @param elementName the element name to create (e.g. 'div')
|
|
2928
|
+
* @param properties optional an object which contains a map of attributes and other values. Uses the ##set() syntax:
|
|
2929
|
+
* Attribute values are prefixed with '@', CSS styles with '$' and regular properties can be set without prefix.
|
|
2930
|
+
* If the attribute value is null, the attribute will omitted (styles and properties can be set to null).
|
|
2931
|
+
* In order to stay compatible with Internet Explorer 7 and earlier, you should not set the
|
|
2932
|
+
* attributes '@class' and '@style'. Instead set the property 'className' instead of '@class' and set
|
|
2933
|
+
* styles using the '$' syntax.
|
|
2934
|
+
* @param children optional a node or a list of nodes to be added as children. Strings will be converted to text nodes.
|
|
2935
|
+
* Functions will be invoked and their return value will be used. Lists can be
|
|
2936
|
+
* nested and will then automatically be flattened. Null elements in lists will be ignored.
|
|
2937
|
+
* The syntax is exactly like ##add().
|
|
2938
|
+
* @param onCreate optional a <code>function(elementList)</code> that will be called each time an element had been created.
|
|
2939
|
+
* <dl><dt>elementList</dt><dd>The newly created element wrapped in a Minified list. </dd></dl>
|
|
2940
|
+
* The function's return value will be ignored.
|
|
2941
|
+
* The callback allows you, for example, to add event handlers to the element using ##on().
|
|
2942
|
+
* @return a Element Factory function, which returns a Minified list containing the DOM HTMLElement that has been created or modified as only element
|
|
2943
|
+
*/
|
|
2944
|
+
'EE': EE
|
|
2945
|
+
|
|
2946
|
+
/*$
|
|
2947
|
+
* @stop
|
|
2948
|
+
*/
|
|
2949
|
+
// @cond !ee dummy:null
|
|
2950
|
+
};
|
|
2951
|
+
// @cond !amdsupport _window['require'] = function(n) { if (n == 'minified') return MINI; };
|
|
2952
|
+
|
|
2953
|
+
|
|
2954
|
+
// @condblock amdsupport
|
|
2955
|
+
});
|
|
2956
|
+
// @condend amdsupport
|
|
2957
|
+
|
|
2958
|
+
// @cond !amdsupport })();
|
|
2959
|
+
|
|
2960
|
+
|
|
2961
|
+
/*$
|
|
2962
|
+
* @id list
|
|
2963
|
+
* @name Minified Lists
|
|
2964
|
+
* @module WEB, UTIL
|
|
2965
|
+
*
|
|
2966
|
+
* <i>Minified lists</i> are Array-like objects provided by Minified. Like a regular JavaScript array,
|
|
2967
|
+
* they provide a <var>length</var> property and you can access their content using the index operator (<code>a[5]</code>).
|
|
2968
|
+
* However, they do not provide the same methods as JavaScript's native array.
|
|
2969
|
+
*
|
|
2970
|
+
* Minified lists are usually created using the #dollar#$()</a></code> function. You can
|
|
2971
|
+
* also use <code>$()</code> to convert a JavaScript array into a Minified list, just be aware that <code>$()</code> will
|
|
2972
|
+
* remove nulls from the lists and will flatten nested lists.
|
|
2973
|
+
*
|
|
2974
|
+
* There is currently no function to convert a Minified list into a JavaScript array. The upcoming Utility module
|
|
2975
|
+
* will provide one though.
|
|
2976
|
+
*
|
|
2977
|
+
* The Minified Web module provides HTML-node oriented functions like ##set() to modify a list of nodes. It also has a
|
|
2978
|
+
* number of helper methods for working with Minified lists:
|
|
2979
|
+
* <ul>
|
|
2980
|
+
* <li>##collect() creates a new list using the collect function which can
|
|
2981
|
+
* transform list elements or collect data from them ("map() on steriods")</li>
|
|
2982
|
+
* <li>##each() iterates through all list elements</li>
|
|
2983
|
+
* <li>##filter() creates a new list that contains only elements that pass the
|
|
2984
|
+
* filter function's test</li>
|
|
2985
|
+
* <li>##find() finds a list element or its position</li>
|
|
2986
|
+
* <li>##sub() creates a list that copies the elements from the specified index range </li>
|
|
2987
|
+
* </ul>
|
|
2988
|
+
*/
|
|
2989
|
+
|
|
2990
|
+
/*$
|
|
2991
|
+
* @id promise
|
|
2992
|
+
* @name Promise
|
|
2993
|
+
* @module WEB, UTIL
|
|
2994
|
+
*
|
|
2995
|
+
* <i>Promises</i> are objects that represent the result of an asynchronous operation. When you start such an operation, using #request#$.request(),
|
|
2996
|
+
* ##animate(), or ##wait(), you will get a Promise object that allows you to get the result as soon as the operation is finished.
|
|
2997
|
+
*
|
|
2998
|
+
* Minified ships with a <a href="http://promises-aplus.github.io/promises-spec/">Promises/A+</a>-compliant implementation of Promises that should
|
|
2999
|
+
* be able to interoperate with most other Promises implementations.
|
|
3000
|
+
*
|
|
3001
|
+
* What may be somewhat surprising about this Promises specification is that there is no direct way to find out the state of the operation.
|
|
3002
|
+
* There is neither a property nor a function to find out what the result is or whether it is available. Instead, you always have to
|
|
3003
|
+
* register callbacks to find out the result. They will be invoked as soon as the operation is finished.
|
|
3004
|
+
* If the operation already ended when you register the callbacks, the callback will then just be called from the event loop as soon
|
|
3005
|
+
* as possible (but never while the ##then() you register them with is still running).<br/>
|
|
3006
|
+
* This design forces you to handle the operation result asynchronously and disencourages 'bad' techniques such as polling.
|
|
3007
|
+
*
|
|
3008
|
+
* The central method of a Promises, and indeed the only required function in Promises/A+, is ##then(). It allows you to register
|
|
3009
|
+
* two callback methods, one for success (called 'fulfillment' in Promises/A+ terminology) and one for failures (called 'rejection' in Promises/A+).
|
|
3010
|
+
*
|
|
3011
|
+
* This example shows you how to use <var>then()</var>:
|
|
3012
|
+
* <pre>
|
|
3013
|
+
* $.request('get', 'http://example.com/weather?zip=90210')
|
|
3014
|
+
* .then(function success(result) {
|
|
3015
|
+
* alert('The weather is ' + result);
|
|
3016
|
+
* }, function error(exception) {
|
|
3017
|
+
* alert('Something went wrong');
|
|
3018
|
+
* });
|
|
3019
|
+
* </pre>
|
|
3020
|
+
*
|
|
3021
|
+
* What makes Promises so special is that ##then() itself returns a new Promise, which is based on the Promise <var>then()</var> was called on, but can be
|
|
3022
|
+
* modified by the outcome of callbacks. Both arguments to <var>then()</var> are optional, and you can also write the code like this:
|
|
3023
|
+
* <pre>
|
|
3024
|
+
* $.request('get', 'http://example.com/weather?zip=90210')
|
|
3025
|
+
* .then(function success(result) {
|
|
3026
|
+
* alert('The weather is ' + result);
|
|
3027
|
+
* })
|
|
3028
|
+
* .then(null, function error(exception) {
|
|
3029
|
+
* alert('Something went wrong');
|
|
3030
|
+
* });
|
|
3031
|
+
* </pre>
|
|
3032
|
+
*
|
|
3033
|
+
* Because the first ##then() returns a new Promise based on the original Promise, the second <var>then()</var> will handle errors of the request just like
|
|
3034
|
+
* the first one did. There is only one subtle difference in the second example: the error handler will not only be called if the request failed,
|
|
3035
|
+
* but also when the request succeded but the success handler threw an exception. That's one of the two differences between the original Promise and
|
|
3036
|
+
* the Promise returned by <var>then()</var>. Any exception thrown in a callback causes the new Promise to be in error state.
|
|
3037
|
+
*
|
|
3038
|
+
* Before I show you the second difference between the original Promise and the new Promise, let me make the example a bit more readable
|
|
3039
|
+
* by using ##error(), which is not part of Promises/A+, but a simple extension by Minified. It just registers the failure callback without
|
|
3040
|
+
* forcing you to specify <var>null</var> as first argument:
|
|
3041
|
+
* <pre>
|
|
3042
|
+
* $.request('get', 'http://example.com/weather?zip=90210')
|
|
3043
|
+
* .then(function success(result) {
|
|
3044
|
+
* alert('The weather is ' + result);
|
|
3045
|
+
* })
|
|
3046
|
+
* .error(function error(exception) { // error(callback) is equivalent to then(null, callback)
|
|
3047
|
+
* alert('Something went wrong');
|
|
3048
|
+
* });
|
|
3049
|
+
* </pre>
|
|
3050
|
+
*
|
|
3051
|
+
* A very powerful capability of Promises is that you can easily chain them. If a ##then() callback returns a value, the new Promise returned
|
|
3052
|
+
* by <var>then()</var> will be marked as success (fulfilled) and this value is the result of the operation. If a callback returns a Promise,
|
|
3053
|
+
* the new Promise will assume the state of the returned Promise. You can use the latter to create chains of asynchronous operations,
|
|
3054
|
+
* but you still need only a single error handler for all of them and you do not need to nest functions to achieve this:
|
|
3055
|
+
* <pre>
|
|
3056
|
+
* $.request('get', 'http://example.com/zipcode?location=Beverly+Hills,+CA')
|
|
3057
|
+
* .then(function(resultZip) {
|
|
3058
|
+
* return $.request('get', 'http://example.com/weather', {zip: resultZip});
|
|
3059
|
+
* })
|
|
3060
|
+
* .then(function(resultWeather) {
|
|
3061
|
+
* alert('The weather in Beverly Hills is ' + resultWeather);
|
|
3062
|
+
* })
|
|
3063
|
+
* .error(function(exception) {
|
|
3064
|
+
* alert('Something went wrong');
|
|
3065
|
+
* });
|
|
3066
|
+
* </pre>
|
|
3067
|
+
*
|
|
3068
|
+
* Sometimes you want to just be notified of the end of an operation but are not interested in the outcome. For these cases, if you just had
|
|
3069
|
+
* the Promises/A+-compliant ##then() method, you would have to register the same callback handler twice. This is not very convenient,
|
|
3070
|
+
* especially when you define the handler function inline. Therefore Minified comes with a second small extension, ##always():
|
|
3071
|
+
*
|
|
3072
|
+
* <pre>
|
|
3073
|
+
* $.request('post', 'http://example.com/pageHit', {pageId: 12345})
|
|
3074
|
+
* .always(function() { // always(callback) is equivalent to then(callback, callback)
|
|
3075
|
+
* pageCountDone();
|
|
3076
|
+
* });
|
|
3077
|
+
* </pre>
|
|
3078
|
+
*
|
|
3079
|
+
* Please note that the Minified Web module only returns Promises, but it <strong>does not allow you to create Promises</strong> directly. The upcoming
|
|
3080
|
+
* Minified App module will allow this though.
|
|
3081
|
+
*/
|
|
3082
|
+
|
|
3083
|
+
|
|
3084
|
+
|
|
3085
|
+
|
|
3086
|
+
|