upjs-rails 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/design/up-validate.js.coffee +4 -4
- data/dist/up.js +885 -158
- data/dist/up.min.js +2 -2
- data/lib/assets/javascripts/up/browser.js.coffee +7 -2
- data/lib/assets/javascripts/up/bus.js.coffee +10 -9
- data/lib/assets/javascripts/up/flow.js.coffee +13 -7
- data/lib/assets/javascripts/up/form.js.coffee +8 -2
- data/lib/assets/javascripts/up/history.js.coffee +28 -5
- data/lib/assets/javascripts/up/layout.js.coffee +19 -12
- data/lib/assets/javascripts/up/link.js.coffee +16 -7
- data/lib/assets/javascripts/up/modal.js.coffee +24 -6
- data/lib/assets/javascripts/up/motion.js.coffee +10 -3
- data/lib/assets/javascripts/up/navigation.js.coffee +2 -0
- data/lib/assets/javascripts/up/popup.js.coffee +9 -2
- data/lib/assets/javascripts/up/proxy.js.coffee +47 -9
- data/lib/assets/javascripts/up/syntax.js.coffee +7 -6
- data/lib/assets/javascripts/up/tooltip.js.coffee +6 -0
- data/lib/assets/javascripts/up/util.js.coffee +613 -95
- data/lib/upjs/rails/version.rb +1 -1
- data/spec_app/Gemfile +6 -0
- data/spec_app/Gemfile.lock +18 -13
- data/spec_app/spec/javascripts/helpers/to_end_with.js.coffee +4 -1
- data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +0 -2
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +6 -6
- metadata +2 -2
@@ -2,16 +2,17 @@
|
|
2
2
|
Utility functions
|
3
3
|
=================
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
If you use them in your own code, you will get hurt.
|
9
|
-
|
10
|
-
@protected
|
5
|
+
Up.js comes with a number of utility functions
|
6
|
+
that might save you from loading something like [Underscore.js](http://underscorejs.org/).
|
7
|
+
|
11
8
|
@class up.util
|
12
9
|
###
|
13
10
|
up.util = (($) ->
|
14
11
|
|
12
|
+
###*
|
13
|
+
@function up.util.memoize
|
14
|
+
@internal
|
15
|
+
###
|
15
16
|
memoize = (func) ->
|
16
17
|
cache = undefined
|
17
18
|
cached = false
|
@@ -22,6 +23,10 @@ up.util = (($) ->
|
|
22
23
|
cached = true
|
23
24
|
cache = func(args...)
|
24
25
|
|
26
|
+
###*
|
27
|
+
@function up.util.ajax
|
28
|
+
@internal
|
29
|
+
###
|
25
30
|
ajax = (request) ->
|
26
31
|
request = copy(request)
|
27
32
|
if request.selector
|
@@ -31,15 +36,18 @@ up.util = (($) ->
|
|
31
36
|
$.ajax(request)
|
32
37
|
|
33
38
|
###*
|
39
|
+
Returns if the given port is the default port for the given protocol.
|
40
|
+
|
34
41
|
@function up.util.isStandardPort
|
35
|
-
@
|
42
|
+
@internal
|
36
43
|
###
|
37
44
|
isStandardPort = (protocol, port) ->
|
45
|
+
port = port.toString()
|
38
46
|
((port == "" || port == "80") && protocol == 'http:') || (port == "443" && protocol == 'https:')
|
39
47
|
|
40
48
|
###*
|
41
|
-
Normalizes
|
42
|
-
that can be checked for equality with other normalized
|
49
|
+
Normalizes relative paths and absolute paths to a full URL
|
50
|
+
that can be checked for equality with other normalized URLs.
|
43
51
|
|
44
52
|
By default hashes are ignored, search queries are included.
|
45
53
|
|
@@ -50,7 +58,7 @@ up.util = (($) ->
|
|
50
58
|
Whether to include a `?query` string in the normalized URL
|
51
59
|
@param {Boolean} [options.stripTrailingSlash=false]
|
52
60
|
Whether to strip a trailing slash from the pathname
|
53
|
-
@
|
61
|
+
@internal
|
54
62
|
###
|
55
63
|
normalizeUrl = (urlOrAnchor, options) ->
|
56
64
|
anchor = parseUrl(urlOrAnchor)
|
@@ -68,8 +76,17 @@ up.util = (($) ->
|
|
68
76
|
normalized
|
69
77
|
|
70
78
|
###*
|
79
|
+
Parses the given URL into components such as hostname and path.
|
80
|
+
|
81
|
+
If the given URL is not fully qualified, it is assumed to be relative
|
82
|
+
to the current page.
|
83
|
+
|
71
84
|
@function up.util.parseUrl
|
72
|
-
@
|
85
|
+
@return {Object}
|
86
|
+
The parsed URL as an object with
|
87
|
+
`protocol`, `hostname`, `port`, `pathname`, `search` and `hash`
|
88
|
+
properties.
|
89
|
+
@experimental
|
73
90
|
###
|
74
91
|
parseUrl = (urlOrAnchor) ->
|
75
92
|
anchor = null
|
@@ -81,12 +98,12 @@ up.util = (($) ->
|
|
81
98
|
# https://gist.github.com/jlong/2428561#comment-1461205
|
82
99
|
anchor.href = anchor.href if isBlank(anchor.hostname)
|
83
100
|
else
|
84
|
-
anchor =
|
101
|
+
anchor = unJQuery(urlOrAnchor)
|
85
102
|
anchor
|
86
103
|
|
87
104
|
###*
|
88
105
|
@function up.util.normalizeMethod
|
89
|
-
@
|
106
|
+
@internal
|
90
107
|
###
|
91
108
|
normalizeMethod = (method) ->
|
92
109
|
if method
|
@@ -94,6 +111,10 @@ up.util = (($) ->
|
|
94
111
|
else
|
95
112
|
'GET'
|
96
113
|
|
114
|
+
###*
|
115
|
+
@function $createElementFromSelector
|
116
|
+
@internal
|
117
|
+
###
|
97
118
|
$createElementFromSelector = (selector) ->
|
98
119
|
path = selector.split(/[ >]/)
|
99
120
|
$root = null
|
@@ -126,8 +147,12 @@ up.util = (($) ->
|
|
126
147
|
element
|
127
148
|
|
128
149
|
###*
|
150
|
+
Prints a debugging message to the browser console.
|
151
|
+
|
129
152
|
@function up.debug
|
130
|
-
@
|
153
|
+
@param {String} message
|
154
|
+
@param {Array} args...
|
155
|
+
@internal
|
131
156
|
###
|
132
157
|
debug = (message, args...) ->
|
133
158
|
message = "[UP] #{message}"
|
@@ -135,7 +160,7 @@ up.util = (($) ->
|
|
135
160
|
|
136
161
|
###*
|
137
162
|
@function up.warn
|
138
|
-
@
|
163
|
+
@internal
|
139
164
|
###
|
140
165
|
warn = (message, args...) ->
|
141
166
|
message = "[UP] #{message}"
|
@@ -154,6 +179,7 @@ up.util = (($) ->
|
|
154
179
|
up.error('Unexpected result %o', result)
|
155
180
|
|
156
181
|
@function up.error
|
182
|
+
@internal
|
157
183
|
###
|
158
184
|
error = (args...) ->
|
159
185
|
args[0] = "[UP] #{args[0]}"
|
@@ -193,7 +219,23 @@ up.util = (($) ->
|
|
193
219
|
arg += " }"
|
194
220
|
arg
|
195
221
|
|
196
|
-
|
222
|
+
###*
|
223
|
+
Returns a CSS selector that matches the given element as good as possible.
|
224
|
+
|
225
|
+
This uses, in decreasing order of priority:
|
226
|
+
|
227
|
+
- The element's `up-id` attribute
|
228
|
+
- The element's ID
|
229
|
+
- The element's name
|
230
|
+
- The element's classes
|
231
|
+
- The element's tag names
|
232
|
+
|
233
|
+
@function up.util.selectorForElement
|
234
|
+
@param {String|Element|jQuery}
|
235
|
+
The element for which to create a selector.
|
236
|
+
@experimental
|
237
|
+
###
|
238
|
+
selectorForElement = (element) ->
|
197
239
|
$element = $(element)
|
198
240
|
selector = undefined
|
199
241
|
|
@@ -259,99 +301,359 @@ up.util = (($) ->
|
|
259
301
|
# we possibly received a layout-less fragment
|
260
302
|
createElement('div', html)
|
261
303
|
|
304
|
+
###*
|
305
|
+
Merge the contents of two or more objects together into the first object.
|
306
|
+
|
307
|
+
@function up.util.extend
|
308
|
+
@param {Object} target
|
309
|
+
@param {Array<Object>} sources...
|
310
|
+
@stable
|
311
|
+
###
|
262
312
|
extend = $.extend
|
263
|
-
|
313
|
+
|
314
|
+
###*
|
315
|
+
Returns a new string with whitespace removed from the beginning
|
316
|
+
and end of the given string.
|
317
|
+
|
318
|
+
@param {String}
|
319
|
+
A string that might have whitespace at the beginning and end.
|
320
|
+
@return {String}
|
321
|
+
The trimmed string.
|
322
|
+
@stable
|
323
|
+
###
|
264
324
|
trim = $.trim
|
265
|
-
|
266
|
-
each = (collection, block) ->
|
267
|
-
block(item, index) for item, index in collection
|
268
325
|
|
326
|
+
###*
|
327
|
+
Calls the given function for each element (and, optional, index)
|
328
|
+
of the given array.
|
329
|
+
|
330
|
+
@function up.util.each
|
331
|
+
@param {Array} array
|
332
|
+
@param {Function<Object, Number>} block
|
333
|
+
A function that will be called with each element and (optional) iteration index.
|
334
|
+
@stable
|
335
|
+
###
|
336
|
+
each = (array, block) ->
|
337
|
+
block(item, index) for item, index in array
|
338
|
+
|
339
|
+
###*
|
340
|
+
Translate all items in an array to new array of items.
|
341
|
+
|
342
|
+
@function up.util.map
|
343
|
+
@param {Array} array
|
344
|
+
@param {Function<Object, Number>} block
|
345
|
+
A function that will be called with each element and (optional) iteration index.
|
346
|
+
@return {Array}
|
347
|
+
A new array containing the result of each function call.
|
348
|
+
@stable
|
349
|
+
###
|
269
350
|
map = each
|
270
351
|
|
271
|
-
|
352
|
+
###*
|
353
|
+
Calls the given function for the given number of times.
|
272
354
|
|
355
|
+
@function up.util.times
|
356
|
+
@param {Number} count
|
357
|
+
@param {Function} block
|
358
|
+
@stable
|
359
|
+
###
|
273
360
|
times = (count, block) ->
|
274
361
|
block(iteration) for iteration in [0..(count - 1)]
|
275
362
|
|
363
|
+
###*
|
364
|
+
Returns whether the given argument is `null`.
|
365
|
+
|
366
|
+
@function up.util.isNull
|
367
|
+
@param object
|
368
|
+
@return {Boolean}
|
369
|
+
@stable
|
370
|
+
###
|
276
371
|
isNull = (object) ->
|
277
372
|
object == null
|
278
373
|
|
374
|
+
###*
|
375
|
+
Returns whether the given argument is `undefined`.
|
376
|
+
|
377
|
+
@function up.util.isUndefined
|
378
|
+
@param object
|
379
|
+
@return {Boolean}
|
380
|
+
@stable
|
381
|
+
###
|
279
382
|
isUndefined = (object) ->
|
280
383
|
object == `void(0)`
|
281
|
-
|
384
|
+
|
385
|
+
###*
|
386
|
+
Returns whether the given argument is not `undefined`.
|
387
|
+
|
388
|
+
@function up.util.isDefined
|
389
|
+
@param object
|
390
|
+
@return {Boolean}
|
391
|
+
@stable
|
392
|
+
###
|
282
393
|
isDefined = (object) ->
|
283
394
|
!isUndefined(object)
|
284
|
-
|
395
|
+
|
396
|
+
###*
|
397
|
+
Returns whether the given argument is either `undefined` or `null`.
|
398
|
+
|
399
|
+
Note that empty strings or zero are *not* considered to be "missing".
|
400
|
+
|
401
|
+
For the opposite of `up.util.isMissing` see [`up.util.isGiven`](/up.util.isGiven).
|
402
|
+
|
403
|
+
@function up.util.isMissing
|
404
|
+
@param object
|
405
|
+
@return {Boolean}
|
406
|
+
@stable
|
407
|
+
###
|
285
408
|
isMissing = (object) ->
|
286
409
|
isUndefined(object) || isNull(object)
|
287
410
|
|
411
|
+
###*
|
412
|
+
Returns whether the given argument is neither `undefined` nor `null`.
|
413
|
+
|
414
|
+
Note that empty strings or zero *are* considered to be "given".
|
415
|
+
|
416
|
+
For the opposite of `up.util.isGiven` see [`up.util.isMissing`](/up.util.isMissing).
|
417
|
+
|
418
|
+
@function up.util.isGiven
|
419
|
+
@param object
|
420
|
+
@return {Boolean}
|
421
|
+
@stable
|
422
|
+
###
|
288
423
|
isGiven = (object) ->
|
289
424
|
!isMissing(object)
|
290
|
-
|
425
|
+
|
426
|
+
###*
|
427
|
+
Return whether the given argument is considered to be blank.
|
428
|
+
|
429
|
+
This returns `true` for:
|
430
|
+
|
431
|
+
- `undefined`
|
432
|
+
- `null`
|
433
|
+
- Empty strings
|
434
|
+
- Empty arrays
|
435
|
+
- An object without own enumerable properties
|
436
|
+
|
437
|
+
All other arguments return `false`.
|
438
|
+
|
439
|
+
@function up.util.isBlank
|
440
|
+
@param object
|
441
|
+
@return {Boolean}
|
442
|
+
@stable
|
443
|
+
###
|
291
444
|
isBlank = (object) ->
|
292
445
|
isMissing(object) || # null or undefined
|
293
446
|
(isObject(object) && Object.keys(object).length == 0) ||
|
294
447
|
(object.length == 0) # String, Array, jQuery
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
448
|
+
|
449
|
+
###*
|
450
|
+
Returns the given argument if the argument is [present](/up.util.isPresent),
|
451
|
+
otherwise returns `undefined`.
|
452
|
+
|
453
|
+
@function up.util.presence
|
454
|
+
@param object
|
455
|
+
@param {Function<T>} [tester=up.util.isPresent]
|
456
|
+
The function that will be used to test whether the argument is present.
|
457
|
+
@return {T|Undefined}
|
458
|
+
@stable
|
459
|
+
###
|
460
|
+
presence = (object, tester = isPresent) ->
|
461
|
+
if tester(object) then object else undefined
|
462
|
+
|
463
|
+
###*
|
464
|
+
Returns whether the given argument is not [blank](/up.util.isBlank).
|
465
|
+
|
466
|
+
@function up.util.isPresent
|
467
|
+
@param object
|
468
|
+
@return {Boolean}
|
469
|
+
@stable
|
470
|
+
###
|
299
471
|
isPresent = (object) ->
|
300
472
|
!isBlank(object)
|
301
473
|
|
474
|
+
###*
|
475
|
+
Returns whether the given argument is a function.
|
476
|
+
|
477
|
+
@function up.util.isFunction
|
478
|
+
@param object
|
479
|
+
@return {Boolean}
|
480
|
+
@stable
|
481
|
+
###
|
302
482
|
isFunction = (object) ->
|
303
483
|
typeof(object) == 'function'
|
304
484
|
|
485
|
+
###*
|
486
|
+
Returns whether the given argument is a string.
|
487
|
+
|
488
|
+
@function up.util.isString
|
489
|
+
@param object
|
490
|
+
@return {Boolean}
|
491
|
+
@stable
|
492
|
+
###
|
305
493
|
isString = (object) ->
|
306
494
|
typeof(object) == 'string'
|
307
495
|
|
496
|
+
###*
|
497
|
+
Returns whether the given argument is a number.
|
498
|
+
|
499
|
+
Note that this will check the argument's *type*.
|
500
|
+
It will return `false` for a string like `"123"`.
|
501
|
+
|
502
|
+
@function up.util.isNumber
|
503
|
+
@param object
|
504
|
+
@return {Boolean}
|
505
|
+
@stable
|
506
|
+
###
|
308
507
|
isNumber = (object) ->
|
309
508
|
typeof(object) == 'number'
|
310
509
|
|
510
|
+
###*
|
511
|
+
Returns whether the given argument is an object, but not a function.
|
512
|
+
|
513
|
+
@function up.util.isHash
|
514
|
+
@param object
|
515
|
+
@return {Boolean}
|
516
|
+
@stable
|
517
|
+
###
|
311
518
|
isHash = (object) ->
|
312
519
|
typeof(object) == 'object' && !!object
|
313
520
|
|
521
|
+
###*
|
522
|
+
Returns whether the given argument is an object.
|
523
|
+
|
524
|
+
This also returns `true` for functions, which may behave like objects in Javascript.
|
525
|
+
For an alternative that returns `false` for functions, see [`up.util.isHash`](/up.util.isHash).
|
526
|
+
|
527
|
+
@function up.util.isObject
|
528
|
+
@param object
|
529
|
+
@return {Boolean}
|
530
|
+
@stable
|
531
|
+
###
|
314
532
|
isObject = (object) ->
|
315
533
|
isHash(object) || (typeof object == 'function')
|
316
534
|
|
535
|
+
###*
|
536
|
+
Returns whether the given argument is a DOM element.
|
537
|
+
|
538
|
+
@function up.util.isElement
|
539
|
+
@param object
|
540
|
+
@return {Boolean}
|
541
|
+
@stable
|
542
|
+
###
|
317
543
|
isElement = (object) ->
|
318
544
|
!!(object && object.nodeType == 1)
|
319
545
|
|
546
|
+
###*
|
547
|
+
Returns whether the given argument is a jQuery collection.
|
548
|
+
|
549
|
+
@function up.util.isJQuery
|
550
|
+
@param object
|
551
|
+
@return {Boolean}
|
552
|
+
@stable
|
553
|
+
###
|
320
554
|
isJQuery = (object) ->
|
321
555
|
object instanceof jQuery
|
322
556
|
|
557
|
+
###*
|
558
|
+
Returns whether the given argument is an object with a `then` method.
|
559
|
+
|
560
|
+
@function up.util.isPromise
|
561
|
+
@param object
|
562
|
+
@return {Boolean}
|
563
|
+
@stable
|
564
|
+
###
|
323
565
|
isPromise = (object) ->
|
324
566
|
isObject(object) && isFunction(object.then)
|
325
567
|
|
568
|
+
###*
|
569
|
+
Returns whether the given argument is an object with `then` and `resolve` methods.
|
570
|
+
|
571
|
+
@function up.util.isDeferred
|
572
|
+
@param object
|
573
|
+
@return {Boolean}
|
574
|
+
@stable
|
575
|
+
###
|
326
576
|
isDeferred = (object) ->
|
327
577
|
isPromise(object) && isFunction(object.resolve)
|
328
578
|
|
329
|
-
|
330
|
-
|
579
|
+
###*
|
580
|
+
Returns whether the given argument is an array.
|
331
581
|
|
582
|
+
@function up.util.isArray
|
583
|
+
@param object
|
584
|
+
@return {Boolean}
|
585
|
+
@stable
|
586
|
+
###
|
332
587
|
# https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
|
333
588
|
isArray = Array.isArray ||
|
334
589
|
(object) -> Object.prototype.toString.call(object) == '[object Array]'
|
335
|
-
|
590
|
+
|
591
|
+
###*
|
592
|
+
Converts the given array-like argument into an array.
|
593
|
+
|
594
|
+
Returns the array.
|
595
|
+
|
596
|
+
@function up.util.isDeferred
|
597
|
+
@param object
|
598
|
+
@return {Array}
|
599
|
+
@stable
|
600
|
+
###
|
336
601
|
toArray = (object) ->
|
337
602
|
Array.prototype.slice.call(object)
|
338
603
|
|
604
|
+
###*
|
605
|
+
Shallow-copies the given array or object into a new array or object.
|
606
|
+
|
607
|
+
Returns the new array or object.
|
608
|
+
|
609
|
+
@function up.util.copy
|
610
|
+
@param {Object|Array} object
|
611
|
+
@return {Object|Array}
|
612
|
+
@stable
|
613
|
+
###
|
339
614
|
copy = (object) ->
|
340
615
|
if isArray(object)
|
341
616
|
object.slice()
|
342
617
|
else
|
343
618
|
extend({}, object)
|
344
619
|
|
345
|
-
|
620
|
+
###*
|
621
|
+
If given a jQuery collection, returns the underlying array of DOM element.
|
622
|
+
If given any other argument, returns the argument unchanged.
|
623
|
+
|
624
|
+
@function up.util.unJQuery
|
625
|
+
@param object
|
626
|
+
@internal
|
627
|
+
###
|
628
|
+
unJQuery = (object) ->
|
346
629
|
if isJQuery(object)
|
347
630
|
object.get(0)
|
348
631
|
else
|
349
632
|
object
|
350
633
|
|
351
|
-
|
352
|
-
|
353
|
-
|
634
|
+
###*
|
635
|
+
Creates a new object by merging together the properties from the given objects.
|
636
|
+
|
637
|
+
@function up.util.merge
|
638
|
+
@param {Array<Object>} sources...
|
639
|
+
@return Object
|
640
|
+
@stable
|
641
|
+
###
|
642
|
+
merge = (sources...) ->
|
643
|
+
extend({}, sources...)
|
644
|
+
|
645
|
+
###*
|
646
|
+
Creates an options hash from the given argument and some defaults.
|
647
|
+
|
648
|
+
The semantics of this function are confusing.
|
649
|
+
We want to get rid of this in the future.
|
354
650
|
|
651
|
+
@function up.util.options
|
652
|
+
@param {Object} object
|
653
|
+
@param {Object} [defaults]
|
654
|
+
@return {Object}
|
655
|
+
@internal
|
656
|
+
###
|
355
657
|
options = (object, defaults) ->
|
356
658
|
merged = if object then copy(object) else {}
|
357
659
|
if defaults
|
@@ -373,6 +675,7 @@ up.util = (($) ->
|
|
373
675
|
|
374
676
|
@function up.util.option
|
375
677
|
@param {Array} args...
|
678
|
+
@internal
|
376
679
|
###
|
377
680
|
option = (args...) ->
|
378
681
|
# This behavior is subtly different from detect!
|
@@ -385,6 +688,18 @@ up.util = (($) ->
|
|
385
688
|
break
|
386
689
|
match
|
387
690
|
|
691
|
+
###*
|
692
|
+
Passes each element in the given array to the given function.
|
693
|
+
Returns the first element for which the function returns a truthy value.
|
694
|
+
|
695
|
+
If no object matches, returns `undefined`.
|
696
|
+
|
697
|
+
@function up.util.detect
|
698
|
+
@param {Array<T>} array
|
699
|
+
@param {Function<T>} tester
|
700
|
+
@return {T|Undefined}
|
701
|
+
@stable
|
702
|
+
###
|
388
703
|
detect = (array, tester) ->
|
389
704
|
match = undefined
|
390
705
|
for element in array
|
@@ -393,13 +708,44 @@ up.util = (($) ->
|
|
393
708
|
break
|
394
709
|
match
|
395
710
|
|
711
|
+
###*
|
712
|
+
Returns whether the given function returns a truthy value
|
713
|
+
for any element in the given array.
|
714
|
+
|
715
|
+
@function up.util.any
|
716
|
+
@param {Array<T>} array
|
717
|
+
@param {Function<T>} tester
|
718
|
+
@return {Boolean}
|
719
|
+
@experimental
|
720
|
+
###
|
396
721
|
any = (array, tester) ->
|
397
|
-
match =
|
398
|
-
|
722
|
+
match = false
|
723
|
+
for element in array
|
724
|
+
if tester(element)
|
725
|
+
match = true
|
726
|
+
break
|
727
|
+
match
|
728
|
+
|
729
|
+
###*
|
730
|
+
Returns all elements from the given array that are
|
731
|
+
neither `null` or `undefined`.
|
399
732
|
|
733
|
+
@function up.util.compact
|
734
|
+
@param {Array<T>} array
|
735
|
+
@return {Array<T>}
|
736
|
+
@stable
|
737
|
+
###
|
400
738
|
compact = (array) ->
|
401
739
|
select array, isGiven
|
402
740
|
|
741
|
+
###*
|
742
|
+
Returns the given array without duplicates.
|
743
|
+
|
744
|
+
@function up.util.uniq
|
745
|
+
@param {Array<T>} array
|
746
|
+
@return {Array<T>}
|
747
|
+
@stable
|
748
|
+
###
|
403
749
|
uniq = (array) ->
|
404
750
|
seen = {}
|
405
751
|
select array, (element) ->
|
@@ -408,6 +754,15 @@ up.util = (($) ->
|
|
408
754
|
else
|
409
755
|
seen[element] = true
|
410
756
|
|
757
|
+
###*
|
758
|
+
Returns all elements from the given array that return
|
759
|
+
a truthy value when passed to the given function.
|
760
|
+
|
761
|
+
@function up.util.select
|
762
|
+
@param {Array<T>} array
|
763
|
+
@return {Array<T>}
|
764
|
+
@stable
|
765
|
+
###
|
411
766
|
select = (array, tester) ->
|
412
767
|
matches = []
|
413
768
|
each array, (element) ->
|
@@ -415,24 +770,60 @@ up.util = (($) ->
|
|
415
770
|
matches.push(element)
|
416
771
|
matches
|
417
772
|
|
773
|
+
###*
|
774
|
+
Returns the first [present](/up.util.isPresent) element attribute
|
775
|
+
among the given list of attribute names.
|
776
|
+
|
777
|
+
@function up.util.presentAttr
|
778
|
+
@internal
|
779
|
+
###
|
418
780
|
presentAttr = ($element, attrNames...) ->
|
419
781
|
values = ($element.attr(attrName) for attrName in attrNames)
|
420
782
|
detect(values, isPresent)
|
421
|
-
|
783
|
+
|
784
|
+
###*
|
785
|
+
Schedules the given function to be called in the
|
786
|
+
next Javascript execution frame.
|
787
|
+
|
788
|
+
@function up.util.nextFrame
|
789
|
+
@param {Function} block
|
790
|
+
@stable
|
791
|
+
###
|
422
792
|
nextFrame = (block) ->
|
423
793
|
setTimeout(block, 0)
|
424
|
-
|
794
|
+
|
795
|
+
###*
|
796
|
+
Returns the last element of the given array.
|
797
|
+
|
798
|
+
@function up.util.last
|
799
|
+
@param {Array<T>} array
|
800
|
+
@return {T}
|
801
|
+
###
|
425
802
|
last = (array) ->
|
426
803
|
array[array.length - 1]
|
427
|
-
|
804
|
+
|
805
|
+
###*
|
806
|
+
Measures the drawable area of the document.
|
807
|
+
|
808
|
+
@function up.util.clientSize
|
809
|
+
@internal
|
810
|
+
###
|
428
811
|
clientSize = ->
|
429
812
|
element = document.documentElement
|
430
813
|
width: element.clientWidth
|
431
814
|
height: element.clientHeight
|
432
815
|
|
433
|
-
|
434
|
-
|
816
|
+
###*
|
817
|
+
Returns the width of a scrollbar.
|
818
|
+
|
819
|
+
This only runs once per page load.
|
820
|
+
|
821
|
+
@function up.util.scrollbarWidth
|
822
|
+
@internal
|
823
|
+
###
|
435
824
|
scrollbarWidth = memoize ->
|
825
|
+
# This is how Bootstrap does it also:
|
826
|
+
# https://github.com/twbs/bootstrap/blob/c591227602996c542b9fd0cb65cff3cc9519bdd5/dist/js/bootstrap.js#L1187
|
436
827
|
$outer = $('<div>').css
|
437
828
|
position: 'absolute'
|
438
829
|
top: '0'
|
@@ -446,31 +837,33 @@ up.util = (($) ->
|
|
446
837
|
$outer.remove()
|
447
838
|
width
|
448
839
|
|
449
|
-
|
450
840
|
###*
|
451
841
|
Modifies the given function so it only runs once.
|
452
842
|
Subsequent calls will return the previous return value.
|
453
843
|
|
454
844
|
@function up.util.once
|
455
|
-
@
|
845
|
+
@param {Function} fun
|
846
|
+
@experimental
|
456
847
|
###
|
457
848
|
once = (fun) ->
|
458
849
|
result = undefined
|
459
|
-
->
|
460
|
-
result = fun() if fun?
|
850
|
+
(args...) ->
|
851
|
+
result = fun(args...) if fun?
|
461
852
|
fun = undefined
|
462
853
|
result
|
463
854
|
|
464
855
|
###*
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
856
|
+
Temporarily sets the CSS for the given element.
|
857
|
+
|
858
|
+
@function up.util.temporaryCss
|
859
|
+
@param {jQuery} $element
|
860
|
+
@param {Object} css
|
861
|
+
@param {Function} [block]
|
862
|
+
If given, the CSS is set, the block is called and
|
863
|
+
the old CSS is restored.
|
864
|
+
@return {Function}
|
865
|
+
A function that restores the original CSS when called.
|
866
|
+
@internal
|
474
867
|
###
|
475
868
|
temporaryCss = ($element, css, block) ->
|
476
869
|
oldCss = $element.css(Object.keys(css))
|
@@ -481,7 +874,13 @@ up.util = (($) ->
|
|
481
874
|
memo()
|
482
875
|
else
|
483
876
|
once(memo)
|
484
|
-
|
877
|
+
|
878
|
+
###*
|
879
|
+
Forces the given jQuery element into an accelerated compositing layer.
|
880
|
+
|
881
|
+
@function up.util.forceCompositing
|
882
|
+
@internal
|
883
|
+
###
|
485
884
|
forceCompositing = ($element) ->
|
486
885
|
oldTransforms = $element.css(['transform', '-webkit-transform'])
|
487
886
|
if isBlank(oldTransforms) || oldTransforms['transform'] == 'none'
|
@@ -494,8 +893,7 @@ up.util = (($) ->
|
|
494
893
|
# drawn using compositing. Do nothing.
|
495
894
|
memo = ->
|
496
895
|
memo
|
497
|
-
|
498
|
-
|
896
|
+
|
499
897
|
###*
|
500
898
|
Animates the given element's CSS properties using CSS transitions.
|
501
899
|
|
@@ -520,7 +918,7 @@ up.util = (($) ->
|
|
520
918
|
for a list of pre-defined timing functions.
|
521
919
|
@return
|
522
920
|
A promise for the animation's end.
|
523
|
-
|
921
|
+
@internal
|
524
922
|
###
|
525
923
|
cssAnimate = (elementOrSelector, lastFrame, opts) ->
|
526
924
|
$element = $(elementOrSelector)
|
@@ -567,14 +965,20 @@ up.util = (($) ->
|
|
567
965
|
Also see [`up.motion.finish`](/up.motion.finish).
|
568
966
|
|
569
967
|
@function up.util.finishCssAnimate
|
570
|
-
@protected
|
571
968
|
@param {Element|jQuery|String} elementOrSelector
|
969
|
+
@internal
|
572
970
|
###
|
573
971
|
finishCssAnimate = (elementOrSelector) ->
|
574
972
|
$(elementOrSelector).each ->
|
575
973
|
if existingAnimation = $(this).data(ANIMATION_PROMISE_KEY)
|
576
974
|
existingAnimation.resolve()
|
577
975
|
|
976
|
+
###*
|
977
|
+
Measures the given element.
|
978
|
+
|
979
|
+
@function up.util.measure
|
980
|
+
@internal
|
981
|
+
###
|
578
982
|
measure = ($element, opts) ->
|
579
983
|
opts = options(opts, relative: false, inner: false, full: false)
|
580
984
|
|
@@ -611,27 +1015,51 @@ up.util = (($) ->
|
|
611
1015
|
box.right = viewport.width - (box.left + box.width)
|
612
1016
|
box.bottom = viewport.height - (box.top + box.height)
|
613
1017
|
box
|
614
|
-
|
1018
|
+
|
1019
|
+
###*
|
1020
|
+
Copies all attributes from the source element to the target element.
|
1021
|
+
|
1022
|
+
@function up.util.copyAttributes
|
1023
|
+
@internal
|
1024
|
+
###
|
615
1025
|
copyAttributes = ($source, $target) ->
|
616
1026
|
for attr in $source.get(0).attributes
|
617
1027
|
if attr.specified
|
618
1028
|
$target.attr(attr.name, attr.value)
|
619
1029
|
|
1030
|
+
###*
|
1031
|
+
Looks for the given selector in the element and its descendants.
|
1032
|
+
|
1033
|
+
@function up.util.findWithSelf
|
1034
|
+
@internal
|
1035
|
+
###
|
620
1036
|
findWithSelf = ($element, selector) ->
|
621
1037
|
$element.find(selector).addBack(selector)
|
622
1038
|
|
1039
|
+
###*
|
1040
|
+
Returns whether the given keyboard event involved the ESC key.
|
1041
|
+
|
1042
|
+
@function up.util.escapePressed
|
1043
|
+
@internal
|
1044
|
+
###
|
623
1045
|
escapePressed = (event) ->
|
624
1046
|
event.keyCode == 27
|
625
1047
|
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
endsWith = (string, element) ->
|
630
|
-
string.indexOf(element) == string.length - element.length
|
1048
|
+
###*
|
1049
|
+
Returns whether the given array or string contains the given element or substring.
|
631
1050
|
|
632
|
-
contains
|
633
|
-
|
1051
|
+
@function up.util.contains
|
1052
|
+
@param {Array|String} arrayOrString
|
1053
|
+
@param elementOrSubstring
|
1054
|
+
@stable
|
1055
|
+
###
|
1056
|
+
contains = (arrayOrString, elementOrSubstring) ->
|
1057
|
+
arrayOrString.indexOf(elementOrSubstring) >= 0
|
634
1058
|
|
1059
|
+
###*
|
1060
|
+
@function up.util.castedAttr
|
1061
|
+
@internal
|
1062
|
+
###
|
635
1063
|
castedAttr = ($element, attrName) ->
|
636
1064
|
value = $element.attr(attrName)
|
637
1065
|
switch value
|
@@ -645,69 +1073,147 @@ up.util = (($) ->
|
|
645
1073
|
#
|
646
1074
|
# castsToFalse = (object) ->
|
647
1075
|
# String(object) == "false"
|
648
|
-
|
1076
|
+
|
1077
|
+
###*
|
1078
|
+
@function up.util.locationFromXhr
|
1079
|
+
@internal
|
1080
|
+
###
|
649
1081
|
locationFromXhr = (xhr) ->
|
650
1082
|
xhr.getResponseHeader('X-Up-Location')
|
651
1083
|
|
1084
|
+
###*
|
1085
|
+
@function up.util.titleFromXhr
|
1086
|
+
@internal
|
1087
|
+
###
|
652
1088
|
titleFromXhr = (xhr) ->
|
653
1089
|
xhr.getResponseHeader('X-Up-Title')
|
654
1090
|
|
1091
|
+
###*
|
1092
|
+
@function up.util.methodFromXhr
|
1093
|
+
@internal
|
1094
|
+
###
|
655
1095
|
methodFromXhr = (xhr) ->
|
656
1096
|
xhr.getResponseHeader('X-Up-Method')
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
1097
|
+
|
1098
|
+
###*
|
1099
|
+
Returns a copy of the given object that only contains
|
1100
|
+
the given properties.
|
1101
|
+
|
1102
|
+
@function up.util.only
|
1103
|
+
@param {Object} object
|
1104
|
+
@param {Array} keys...
|
1105
|
+
@stable
|
1106
|
+
###
|
1107
|
+
only = (object, properties...) ->
|
662
1108
|
filtered = {}
|
663
|
-
for
|
664
|
-
if object.hasOwnProperty(
|
665
|
-
filtered[
|
1109
|
+
for property in properties
|
1110
|
+
if object.hasOwnProperty(property)
|
1111
|
+
filtered[property] = object[property]
|
666
1112
|
filtered
|
667
1113
|
|
1114
|
+
###*
|
1115
|
+
@function up.util.isUnmodifiedKeyEvent
|
1116
|
+
@internal
|
1117
|
+
###
|
668
1118
|
isUnmodifiedKeyEvent = (event) ->
|
669
1119
|
not (event.metaKey or event.shiftKey or event.ctrlKey)
|
670
1120
|
|
1121
|
+
###*
|
1122
|
+
@function up.util.isUnmodifiedMouseEvent
|
1123
|
+
@internal
|
1124
|
+
###
|
671
1125
|
isUnmodifiedMouseEvent = (event) ->
|
672
1126
|
isLeftButton = isUndefined(event.button) || event.button == 0
|
673
1127
|
isLeftButton && isUnmodifiedKeyEvent(event)
|
674
1128
|
|
1129
|
+
###*
|
1130
|
+
Returns a [Deferred object](https://api.jquery.com/category/deferred-object/) that is
|
1131
|
+
already resolved.
|
1132
|
+
|
1133
|
+
@function up.util.resolvedDeferred
|
1134
|
+
@return {Deferred}
|
1135
|
+
@stable
|
1136
|
+
###
|
675
1137
|
resolvedDeferred = ->
|
676
1138
|
deferred = $.Deferred()
|
677
1139
|
deferred.resolve()
|
678
1140
|
deferred
|
679
1141
|
|
1142
|
+
###*
|
1143
|
+
Returns a promise that is already resolved.
|
1144
|
+
|
1145
|
+
@function up.util.resolvedPromise
|
1146
|
+
@return {Promise}
|
1147
|
+
@stable
|
1148
|
+
###
|
680
1149
|
resolvedPromise = ->
|
681
1150
|
resolvedDeferred().promise()
|
682
1151
|
|
1152
|
+
###*
|
1153
|
+
Returns a promise that will never be resolved.
|
1154
|
+
|
1155
|
+
@function up.util.unresolvablePromise
|
1156
|
+
@experimental
|
1157
|
+
###
|
683
1158
|
unresolvablePromise = ->
|
684
1159
|
$.Deferred().promise()
|
685
1160
|
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
1161
|
+
###*
|
1162
|
+
Returns an empty jQuery collection.
|
1163
|
+
|
1164
|
+
@function up.util.nullJQuery
|
1165
|
+
@internal
|
1166
|
+
###
|
1167
|
+
nullJQuery = ->
|
1168
|
+
$()
|
1169
|
+
|
1170
|
+
###*
|
1171
|
+
Returns a new promise that resolves once all promises in arguments resolve.
|
1172
|
+
|
1173
|
+
Other then [`$.when` from jQuery](https://api.jquery.com/jquery.when/),
|
1174
|
+
the combined promise will have a `resolve` method. This `resolve` method
|
1175
|
+
will resolve all the wrapped promises.
|
690
1176
|
|
1177
|
+
@function up.util.resolvableWhen
|
1178
|
+
@internal
|
1179
|
+
###
|
691
1180
|
resolvableWhen = (deferreds...) ->
|
692
1181
|
joined = $.when(deferreds...)
|
693
1182
|
joined.resolve = ->
|
694
1183
|
each deferreds, (deferred) -> deferred.resolve?()
|
695
1184
|
joined
|
696
1185
|
|
1186
|
+
###*
|
1187
|
+
On the given element, set attributes that are still missing.
|
1188
|
+
|
1189
|
+
@function up.util.setMissingAttrs
|
1190
|
+
@internal
|
1191
|
+
###
|
697
1192
|
setMissingAttrs = ($element, attrs) ->
|
698
1193
|
for key, value of attrs
|
699
1194
|
if isMissing($element.attr(key))
|
700
1195
|
$element.attr(key, value)
|
701
1196
|
|
1197
|
+
###*
|
1198
|
+
Removes the given element from the given array.
|
1199
|
+
|
1200
|
+
This changes the given array.
|
1201
|
+
|
1202
|
+
@function up.util.remove
|
1203
|
+
@param {Array<T>} array
|
1204
|
+
@param {T} element
|
1205
|
+
@stable
|
1206
|
+
###
|
702
1207
|
remove = (array, element) ->
|
703
1208
|
index = array.indexOf(element)
|
704
1209
|
if index >= 0
|
705
1210
|
array.splice(index, 1)
|
706
1211
|
element
|
707
1212
|
|
708
|
-
|
709
|
-
|
710
|
-
|
1213
|
+
###*
|
1214
|
+
@function up.util.multiSelector
|
1215
|
+
@internal
|
1216
|
+
###
|
711
1217
|
multiSelector = (parts) ->
|
712
1218
|
|
713
1219
|
obj = {}
|
@@ -733,7 +1239,7 @@ up.util = (($) ->
|
|
733
1239
|
obj.find(undefined)
|
734
1240
|
|
735
1241
|
obj.find = ($root) ->
|
736
|
-
$result =
|
1242
|
+
$result = nullJQuery()
|
737
1243
|
for selector in obj.parsed
|
738
1244
|
$matches = if $root then $root.find(selector) else $(selector)
|
739
1245
|
$result = $result.add($matches)
|
@@ -757,7 +1263,7 @@ up.util = (($) ->
|
|
757
1263
|
$result = $element
|
758
1264
|
break
|
759
1265
|
$element = $element.parent()
|
760
|
-
$result ||
|
1266
|
+
$result || nullJQuery()
|
761
1267
|
|
762
1268
|
obj
|
763
1269
|
|
@@ -774,6 +1280,7 @@ up.util = (($) ->
|
|
774
1280
|
@param {Function<Object>} [config.key]
|
775
1281
|
A function that takes an argument and returns a `String` key
|
776
1282
|
for storage. If omitted, `toString()` is called on the argument.
|
1283
|
+
@internal
|
777
1284
|
###
|
778
1285
|
cache = (config = {}) ->
|
779
1286
|
|
@@ -879,6 +1386,10 @@ up.util = (($) ->
|
|
879
1386
|
clear: clear
|
880
1387
|
keys: keys
|
881
1388
|
|
1389
|
+
###*
|
1390
|
+
@function up.util.config
|
1391
|
+
@internal
|
1392
|
+
###
|
882
1393
|
config = (factoryOptions = {}) ->
|
883
1394
|
hash = {}
|
884
1395
|
hash.reset = -> extend(hash, factoryOptions)
|
@@ -886,14 +1397,22 @@ up.util = (($) ->
|
|
886
1397
|
Object.preventExtensions(hash)
|
887
1398
|
hash
|
888
1399
|
|
1400
|
+
###*
|
1401
|
+
@function up.util.unwrapElement
|
1402
|
+
@internal
|
1403
|
+
###
|
889
1404
|
unwrapElement = (wrapper) ->
|
890
|
-
wrapper =
|
1405
|
+
wrapper = unJQuery(wrapper)
|
891
1406
|
parent = wrapper.parentNode;
|
892
1407
|
wrappedNodes = toArray(wrapper.childNodes)
|
893
1408
|
each wrappedNodes, (wrappedNode) ->
|
894
1409
|
parent.insertBefore(wrappedNode, wrapper)
|
895
1410
|
parent.removeChild(wrapper)
|
896
1411
|
|
1412
|
+
###*
|
1413
|
+
@function up.util.offsetParent
|
1414
|
+
@internal
|
1415
|
+
###
|
897
1416
|
offsetParent = ($element) ->
|
898
1417
|
$match = undefined
|
899
1418
|
while ($element = $element.parent()) && $element.length
|
@@ -903,6 +1422,10 @@ up.util = (($) ->
|
|
903
1422
|
break
|
904
1423
|
$match
|
905
1424
|
|
1425
|
+
###*
|
1426
|
+
@function up.util.fixedToAbsolute
|
1427
|
+
@internal
|
1428
|
+
###
|
906
1429
|
fixedToAbsolute = (element, $viewport) ->
|
907
1430
|
$element = $(element)
|
908
1431
|
$futureOffsetParent = offsetParent($element)
|
@@ -935,7 +1458,7 @@ up.util = (($) ->
|
|
935
1458
|
normalizeMethod: normalizeMethod
|
936
1459
|
createElementFromHtml: createElementFromHtml
|
937
1460
|
$createElementFromSelector: $createElementFromSelector
|
938
|
-
|
1461
|
+
selectorForElement: selectorForElement
|
939
1462
|
ajax: ajax
|
940
1463
|
extend: extend
|
941
1464
|
copy: copy
|
@@ -947,7 +1470,6 @@ up.util = (($) ->
|
|
947
1470
|
warn: warn
|
948
1471
|
each: each
|
949
1472
|
map: map
|
950
|
-
identity: identity
|
951
1473
|
times: times
|
952
1474
|
any: any
|
953
1475
|
detect: detect
|
@@ -971,11 +1493,10 @@ up.util = (($) ->
|
|
971
1493
|
isPromise: isPromise
|
972
1494
|
isDeferred: isDeferred
|
973
1495
|
isHash: isHash
|
974
|
-
ifGiven: ifGiven
|
975
1496
|
isUnmodifiedKeyEvent: isUnmodifiedKeyEvent
|
976
1497
|
isUnmodifiedMouseEvent: isUnmodifiedMouseEvent
|
977
|
-
|
978
|
-
|
1498
|
+
nullJQuery: nullJQuery
|
1499
|
+
unJQuery: unJQuery
|
979
1500
|
nextFrame: nextFrame
|
980
1501
|
measure: measure
|
981
1502
|
temporaryCss: temporaryCss
|
@@ -986,8 +1507,6 @@ up.util = (($) ->
|
|
986
1507
|
copyAttributes: copyAttributes
|
987
1508
|
findWithSelf: findWithSelf
|
988
1509
|
contains: contains
|
989
|
-
startsWith: startsWith
|
990
|
-
endsWith: endsWith
|
991
1510
|
isArray: isArray
|
992
1511
|
toArray: toArray
|
993
1512
|
# castsToTrue: castsToTrue
|
@@ -1011,7 +1530,6 @@ up.util = (($) ->
|
|
1011
1530
|
cache: cache
|
1012
1531
|
unwrapElement: unwrapElement
|
1013
1532
|
multiSelector: multiSelector
|
1014
|
-
emptyJQuery: emptyJQuery
|
1015
1533
|
evalConsoleTemplate: evalConsoleTemplate
|
1016
1534
|
|
1017
1535
|
)($)
|