upjs-rails 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,16 +2,17 @@
2
2
  Utility functions
3
3
  =================
4
4
 
5
- All methods in this module are for internal use by the Up.js framework
6
- and will frequently change between releases.
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
- @private
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 URLs, relative paths and absolute paths to a full URL
42
- that can be checked for equality with other normalized URL.
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
- @protected
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
- @private
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 = unJquery(urlOrAnchor)
101
+ anchor = unJQuery(urlOrAnchor)
85
102
  anchor
86
103
 
87
104
  ###*
88
105
  @function up.util.normalizeMethod
89
- @protected
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
- @protected
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
- @protected
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
- createSelectorFromElement = (element) ->
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
- identity = (x) -> x
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
- presence = (object, checker = isPresent) ->
297
- if checker(object) then object else null
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
- ifGiven = (object) ->
330
- object if isGiven(object)
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
- unJquery = (object) ->
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
- # Non-destructive extend
352
- merge = (object, otherObject) ->
353
- extend(copy(object), otherObject)
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 = detect(array, tester)
398
- isDefined(match)
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
- # This is how Bootstrap does it also:
434
- # https://github.com/twbs/bootstrap/blob/c591227602996c542b9fd0cb65cff3cc9519bdd5/dist/js/bootstrap.js#L1187
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
- @private
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
- # Temporarily sets the CSS for the given element.
466
- #
467
- # @function up.util.temporaryCss
468
- # @param {jQuery} $element
469
- # @param {Object} css
470
- # @param {Function} [block]
471
- # If given, the CSS is set, the block is called and
472
- # the old CSS is restored.
473
- # @private
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
- startsWith = (string, element) ->
627
- string.indexOf(element) == 0
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 = (stringOrArray, element) ->
633
- stringOrArray.indexOf(element) >= 0
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
- # willChangeHistory = (historyOption) ->
659
- # isPresent(historyOption) && !castsToFalse(historyOption)
660
-
661
- only = (object, keys...) ->
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 key in keys
664
- if object.hasOwnProperty(key)
665
- filtered[key] = object[key]
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
- nullJquery = ->
687
- is: -> false
688
- attr: ->
689
- find: -> []
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
- emptyJQuery = ->
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 = emptyJQuery()
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 || emptyJQuery()
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 = unJquery(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
- createSelectorFromElement: createSelectorFromElement
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
- nullJquery: nullJquery
978
- unJquery: unJquery
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
  )($)