minifiedjs-rails 0.0.1.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|