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.
@@ -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
  )($)