unpoly-rails 0.23.0 → 0.24.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.

Potentially problematic release.


This version of unpoly-rails might be problematic. Click here for more details.

Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -0
  3. data/dist/unpoly-bootstrap3.js +1 -1
  4. data/dist/unpoly-bootstrap3.min.js +1 -1
  5. data/dist/unpoly.css +18 -8
  6. data/dist/unpoly.js +498 -265
  7. data/dist/unpoly.min.css +1 -1
  8. data/dist/unpoly.min.js +3 -3
  9. data/lib/assets/javascripts/unpoly-bootstrap3/modal-ext.js.coffee +5 -2
  10. data/lib/assets/javascripts/unpoly/flow.js.coffee +3 -1
  11. data/lib/assets/javascripts/unpoly/form.js.coffee +3 -6
  12. data/lib/assets/javascripts/unpoly/layout.js.coffee +1 -1
  13. data/lib/assets/javascripts/unpoly/link.js.coffee +4 -2
  14. data/lib/assets/javascripts/unpoly/log.js.coffee +2 -2
  15. data/lib/assets/javascripts/unpoly/modal.js.coffee +125 -36
  16. data/lib/assets/javascripts/unpoly/motion.js.coffee +75 -37
  17. data/lib/assets/javascripts/unpoly/navigation.js.coffee +38 -26
  18. data/lib/assets/javascripts/unpoly/proxy.js.coffee +77 -52
  19. data/lib/assets/javascripts/unpoly/syntax.js.coffee +1 -0
  20. data/lib/assets/javascripts/unpoly/tooltip.js.coffee +2 -0
  21. data/lib/assets/javascripts/unpoly/util.js.coffee +138 -46
  22. data/lib/assets/stylesheets/unpoly/link.css.sass +1 -1
  23. data/lib/assets/stylesheets/unpoly/modal.css.sass +28 -15
  24. data/lib/unpoly/rails/version.rb +1 -1
  25. data/spec_app/Gemfile.lock +7 -7
  26. data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +2 -0
  27. data/spec_app/spec/javascripts/helpers/to_contain.js.coffee +5 -0
  28. data/spec_app/spec/javascripts/up/flow_spec.js.coffee +2 -2
  29. data/spec_app/spec/javascripts/up/history_spec.js.coffee +6 -4
  30. data/spec_app/spec/javascripts/up/link_spec.js.coffee +114 -5
  31. data/spec_app/spec/javascripts/up/modal_spec.js.coffee +28 -18
  32. data/spec_app/spec/javascripts/up/motion_spec.js.coffee +112 -7
  33. data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +157 -121
  34. data/spec_app/spec/javascripts/up/popup_spec.js.coffee +1 -1
  35. data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +42 -3
  36. data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +1 -2
  37. data/spec_app/spec/javascripts/up/util_spec.js.coffee +26 -1
  38. data/spec_app/vendor/assets/bower_components/jquery/.bower.json +1 -1
  39. metadata +3 -3
  40. data/spec_app/spec/javascripts/helpers/set_timer.js.coffee +0 -3
@@ -36,11 +36,8 @@ up.navigation = (($) ->
36
36
  classes.join(' ')
37
37
 
38
38
  CLASS_ACTIVE = 'up-active'
39
- SELECTORS_SECTION = ['a', '[up-href]', '[up-alias]']
40
- SELECTOR_SECTION = SELECTORS_SECTION.join(', ')
41
- SELECTOR_SECTION_INSTANT = ("#{selector}[up-instant]" for selector in SELECTORS_SECTION).join(', ')
42
- SELECTOR_ACTIVE = ".#{CLASS_ACTIVE}"
43
-
39
+ SELECTOR_SECTION = 'a, [up-href]'
40
+
44
41
  normalizeUrl = (url) ->
45
42
  if u.isPresent(url)
46
43
  u.normalizeUrl(url,
@@ -102,6 +99,22 @@ up.navigation = (($) ->
102
99
  else if $section.hasClass(klass) && $section.closest('.up-destroying').length == 0
103
100
  $section.removeClass(klass)
104
101
 
102
+ ###*
103
+ @function findClickArea
104
+ @param {String|Element|jQuery} elementOrSelector
105
+ @param {Boolean} options.enlarge
106
+ If `true`, tries to find a containing link that has expanded the link's click area.
107
+ If we find one, we prefer to mark the larger area as active.
108
+ @internal
109
+ ###
110
+ findClickArea = (elementOrSelector, options) ->
111
+ $area = $(elementOrSelector)
112
+ options = u.options(options, enlarge: false)
113
+ if options.enlarge
114
+ u.presence($area.parent(SELECTOR_SECTION)) || $area
115
+ else
116
+ $area
117
+
105
118
  ###*
106
119
  Links that are currently loading are assigned the `up-active`
107
120
  class automatically. Style `.up-active` in your CSS to improve the
@@ -129,24 +142,23 @@ up.navigation = (($) ->
129
142
  @selector .up-active
130
143
  @stable
131
144
  ###
132
- sectionClicked = ($section) ->
133
- unmarkActive()
134
- $section = enlargeClickArea($section)
135
- $section.addClass(CLASS_ACTIVE)
136
-
137
- enlargeClickArea = ($section) ->
138
- u.presence($section.parents(SELECTOR_SECTION)) || $section
139
-
140
- unmarkActive = ->
141
- $(SELECTOR_ACTIVE).removeClass(CLASS_ACTIVE)
142
-
143
- up.on 'click', SELECTOR_SECTION, (event, $section) ->
144
- if u.isUnmodifiedMouseEvent(event) && !$section.is('[up-instant]')
145
- sectionClicked($section)
146
-
147
- up.on 'mousedown', SELECTOR_SECTION_INSTANT, (event, $section) ->
148
- if u.isUnmodifiedMouseEvent(event)
149
- sectionClicked($section)
145
+ markActive = (elementOrSelector, options) ->
146
+ $element = findClickArea(elementOrSelector, options)
147
+ $element.addClass(CLASS_ACTIVE)
148
+
149
+ unmarkActive = (elementOrSelector, options) ->
150
+ $element = findClickArea(elementOrSelector, options)
151
+ $element.removeClass(CLASS_ACTIVE)
152
+
153
+ withActiveMark = (elementOrSelector, options, block) ->
154
+ $element = $(elementOrSelector)
155
+ markActive($element, options)
156
+ promise = block()
157
+ if u.isPromise(promise)
158
+ promise.always -> unmarkActive($element, options)
159
+ else
160
+ up.warn('Expected block to return a promise, but got %o', promise)
161
+ promise
150
162
 
151
163
  ###*
152
164
  Links that point to the current location are assigned
@@ -193,9 +205,6 @@ up.navigation = (($) ->
193
205
  @stable
194
206
  ###
195
207
  up.on 'up:fragment:inserted', ->
196
- # If a new fragment is inserted, it's likely to be the result
197
- # of the active action. So we can remove the active marker.
198
- unmarkActive()
199
208
  # When a fragment is inserted it might either have brought a location change
200
209
  # with it, or it might have opened a modal / popup which we consider
201
210
  # to be secondary location sources (the primary being the browser's
@@ -215,5 +224,8 @@ up.navigation = (($) ->
215
224
 
216
225
  config: config
217
226
  defaults: -> u.error('up.navigation.defaults(...) no longer exists. Set values on he up.navigation.config property instead.')
227
+ markActive: markActive
228
+ unmarkActive: unmarkActive
229
+ withActiveMark: withActiveMark
218
230
 
219
231
  )(jQuery)
@@ -112,67 +112,26 @@ up.proxy = (($) ->
112
112
  if response = cache.get(candidate)
113
113
  return response
114
114
 
115
- ###*
116
- Manually stores a promise for the response to the given request.
117
-
118
- @function up.proxy.set
119
- @param {String} request.url
120
- @param {String} [request.method='GET']
121
- @param {String} [request.target='body']
122
- @param {Promise} response
123
- A promise for the response that is API-compatible with the
124
- promise returned by [`jQuery.ajax`](http://api.jquery.com/jquery.ajax/).
125
- @experimental
126
- ###
127
- set = cache.set
128
-
129
- ###*
130
- Manually removes the given request from the cache.
131
-
132
- You can also [configure](/up.proxy.config) when the proxy
133
- automatically removes cache entries.
134
-
135
- @function up.proxy.remove
136
- @param {String} request.url
137
- @param {String} [request.method='GET']
138
- @param {String} [request.target='body']
139
- @experimental
140
- ###
141
- remove = cache.remove
142
-
143
- ###*
144
- Removes all cache entries.
145
-
146
- Unpoly also automatically clears the cache whenever it processes
147
- a request with a non-GET HTTP method.
148
-
149
- @function up.proxy.clear
150
- @stable
151
- ###
152
- clear = cache.clear
153
-
154
115
  cancelPreloadDelay = ->
155
116
  clearTimeout(preloadDelayTimer)
156
117
  preloadDelayTimer = null
157
118
 
158
- cancelBusyDelay = ->
119
+ cancelSlowDelay = ->
159
120
  clearTimeout(slowDelayTimer)
160
121
  slowDelayTimer = null
161
122
 
162
123
  reset = ->
163
124
  $waitingLink = null
164
125
  cancelPreloadDelay()
165
- cancelBusyDelay()
126
+ cancelSlowDelay()
166
127
  pendingCount = 0
167
128
  config.reset()
168
- slowEventEmitted = false
169
129
  cache.clear()
130
+ slowEventEmitted = false
170
131
  queuedRequests = []
171
132
 
172
133
  reset()
173
134
 
174
- alias = cache.alias
175
-
176
135
  normalizeRequest = (request) ->
177
136
  unless request._normalized
178
137
  request.method = u.normalizeMethod(request.method)
@@ -190,13 +149,23 @@ up.proxy = (($) ->
190
149
  Only requests with a method of `GET`, `OPTIONS` and `HEAD`
191
150
  are considered to be read-only.
192
151
 
152
+ \#\#\#\# Example
153
+
154
+ up.ajax('/search', data: { query: 'sunshine' }).then(function(data, status, xhr) {
155
+ console.log('The response body is %o', data);
156
+ }).fail(function(xhr, status, error) {
157
+ console.error('The request failed');
158
+ });
159
+
160
+ \#\#\#\# Events
161
+
193
162
  If a network connection is attempted, the proxy will emit
194
- a `up:proxy:load` event with the `request` as its argument.
195
- Once the response is received, a `up:proxy:receive` event will
163
+ a [`up:proxy:load`](/up:proxy:load) event with the `request` as its argument.
164
+ Once the response is received, a [`up:proxy:receive`](/up:proxy:receive) event will
196
165
  be emitted.
197
166
 
198
167
  @function up.ajax
199
- @param {String} request.url
168
+ @param {String} url
200
169
  @param {String} [request.method='GET']
201
170
  @param {String} [request.target='body']
202
171
  @param {Boolean} [request.cache]
@@ -207,12 +176,18 @@ up.proxy = (($) ->
207
176
  with the request.
208
177
  @param {Object} [request.data={}]
209
178
  An object of request parameters.
179
+ @param {String} [request.url]
180
+ You can omit the first string argument and pass the URL as
181
+ a `request` property instead.
210
182
  @return
211
183
  A promise for the response that is API-compatible with the
212
184
  promise returned by [`jQuery.ajax`](http://api.jquery.com/jquery.ajax/).
213
185
  @stable
214
186
  ###
215
- ajax = (options) ->
187
+ ajax = (args...) ->
188
+
189
+ options = u.extractOptions(args)
190
+ options.url = args[0] if u.isGiven(args[0])
216
191
 
217
192
  forceCache = (options.cache == true)
218
193
  ignoreCache = (options.cache == false)
@@ -293,10 +268,7 @@ up.proxy = (($) ->
293
268
  if isBusy() # a fast response might have beaten the delay
294
269
  up.emit('up:proxy:slow', message: 'Proxy is busy')
295
270
  slowEventEmitted = true
296
- if config.slowDelay > 0
297
- slowDelayTimer = setTimeout(emission, config.slowDelay)
298
- else
299
- emission()
271
+ slowDelayTimer = u.setTimer(config.slowDelay, emission)
300
272
 
301
273
  ###*
302
274
  This event is [emitted]/(up.emit) when [AJAX requests](/up.ajax)
@@ -423,6 +395,59 @@ up.proxy = (($) ->
423
395
  promise.done (args...) -> entry.deferred.resolve(args...)
424
396
  promise.fail (args...) -> entry.deferred.reject(args...)
425
397
 
398
+ ###*
399
+ Makes the proxy assume that `newRequest` has the same response as the
400
+ already cached `oldRequest`.
401
+
402
+ Unpoly uses this internally when the user redirects from `/old` to `/new`.
403
+ In that case, both `/old` and `/new` will cache the same response from `/new`.
404
+
405
+ @function up.proxy.alias
406
+ @param {Object} oldRequest
407
+ @param {Object} newRequest
408
+ @experimental
409
+ ###
410
+ alias = cache.alias
411
+
412
+ ###*
413
+ Manually stores a promise for the response to the given request.
414
+
415
+ @function up.proxy.set
416
+ @param {String} request.url
417
+ @param {String} [request.method='GET']
418
+ @param {String} [request.target='body']
419
+ @param {Promise} response
420
+ A promise for the response that is API-compatible with the
421
+ promise returned by [`jQuery.ajax`](http://api.jquery.com/jquery.ajax/).
422
+ @experimental
423
+ ###
424
+ set = cache.set
425
+
426
+ ###*
427
+ Manually removes the given request from the cache.
428
+
429
+ You can also [configure](/up.proxy.config) when the proxy
430
+ automatically removes cache entries.
431
+
432
+ @function up.proxy.remove
433
+ @param {String} request.url
434
+ @param {String} [request.method='GET']
435
+ @param {String} [request.target='body']
436
+ @experimental
437
+ ###
438
+ remove = cache.remove
439
+
440
+ ###*
441
+ Removes all cache entries.
442
+
443
+ Unpoly also automatically clears the cache whenever it processes
444
+ a request with a non-GET HTTP method.
445
+
446
+ @function up.proxy.clear
447
+ @stable
448
+ ###
449
+ clear = cache.clear
450
+
426
451
  ###*
427
452
  This event is [emitted]/(up.emit) before an [AJAX request](/up.ajax)
428
453
  is starting to load.
@@ -239,6 +239,7 @@ up.syntax = (($) ->
239
239
 
240
240
  Examples for built-in macros are [`up-dash`](/up-dash) and [`up-expand`](/up-expand).
241
241
 
242
+ @function up.macro
242
243
  @param {String} selector
243
244
  The selector to match.
244
245
  @param {Object} options
@@ -52,6 +52,8 @@ up.tooltip = (($) ->
52
52
  closeAnimation: 'fade-out'
53
53
 
54
54
  reset = ->
55
+ # Destroy the tooltip container regardless whether it's currently in a closing animation
56
+ close(animation: false)
55
57
  config.reset()
56
58
 
57
59
  setPosition = ($link, $tooltip, position) ->
@@ -9,6 +9,14 @@ that might save you from loading something like [Underscore.js](http://underscor
9
9
  ###
10
10
  up.util = (($) ->
11
11
 
12
+ ###*
13
+ A function that does nothing.
14
+
15
+ @function up.util.noop
16
+ @experimental
17
+ ###
18
+ noop = $.noop
19
+
12
20
  ###*
13
21
  @function up.util.memoize
14
22
  @internal
@@ -755,6 +763,24 @@ up.util = (($) ->
755
763
  values = ($element.attr(attrName) for attrName in attrNames)
756
764
  detect(values, isPresent)
757
765
 
766
+ ###*
767
+ Waits for the given number of milliseconds, the nruns the given callback.
768
+
769
+ If the number of milliseconds is zero, the callback is run in the current execution frame.
770
+ See [`up.util.nextFrame`] for running a function in the next executation frame.
771
+
772
+ @function up.util.setTimer
773
+ @param {Number} millis
774
+ @param {Function} callback
775
+ @experimental
776
+ ###
777
+ setTimer = (millis, callback) ->
778
+ if millis > 0
779
+ setTimeout(callback, millis)
780
+ else
781
+ callback()
782
+
783
+
758
784
  ###*
759
785
  Schedules the given function to be called in the
760
786
  next Javascript execution frame.
@@ -868,6 +894,16 @@ up.util = (($) ->
868
894
  memo = ->
869
895
  memo
870
896
 
897
+ ###*
898
+ Forces a repaint of the given element.
899
+
900
+ @function up.util.forceRepaint
901
+ @internal
902
+ ###
903
+ forceRepaint = (element) ->
904
+ element = unJQuery(element)
905
+ element.offsetHeight
906
+
871
907
  ###*
872
908
  Animates the given element's CSS properties using CSS transitions.
873
909
 
@@ -901,23 +937,49 @@ up.util = (($) ->
901
937
  delay: 0,
902
938
  easing: 'ease'
903
939
  )
904
- # We don't finish an existing animation here, since
905
- # the public API `up.motion.animate` already does this.
940
+
941
+ # We don't finish an existing animation here, since the public API
942
+ # we expose as `up.motion.animate` already does this.
906
943
  deferred = $.Deferred()
907
944
  transition =
908
945
  'transition-property': Object.keys(lastFrame).join(', ')
909
946
  'transition-duration': "#{opts.duration}ms"
910
947
  'transition-delay': "#{opts.delay}ms"
911
948
  'transition-timing-function': opts.easing
949
+ oldTransition = $element.css(Object.keys(transition))
950
+
951
+ $element.addClass('up-animating')
912
952
  withoutCompositing = forceCompositing($element)
913
- withoutTransition = temporaryCss($element, transition)
953
+ $element.css(transition)
914
954
  $element.css(lastFrame)
915
- deferred.then(withoutCompositing)
916
- deferred.then(withoutTransition)
917
955
  $element.data(ANIMATION_DEFERRED_KEY, deferred)
918
- deferred.then(-> $element.removeData(ANIMATION_DEFERRED_KEY))
919
- endTimeout = setTimeout((-> deferred.resolve()), opts.duration + opts.delay)
920
- deferred.then(-> clearTimeout(endTimeout)) # clean up in case we're canceled
956
+
957
+ deferred.then ->
958
+ $element.removeData(ANIMATION_DEFERRED_KEY)
959
+ withoutCompositing()
960
+
961
+ # To interrupt the running transition we *must* set it to 'none' exactly.
962
+ # We cannot simply restore the old transition properties because browsers
963
+ # would simply keep transitioning the old properties.
964
+ $element.css('transition': 'none')
965
+
966
+ # Restoring a previous transition involves some work, so we only do it if
967
+ # we know the element was transitioning before.
968
+ hadTransitionBefore = !(oldTransition['transition-property'] == 'none' || (oldTransition['transition-property'] == 'all' && oldTransition['transition-duration'][0] == '0'))
969
+ if hadTransitionBefore
970
+ forceRepaint($element) # :(
971
+ $element.css(oldTransition)
972
+
973
+ # Since listening to transitionEnd events is painful, we wait for a timeout
974
+ # and then resolve our deferred. Maybe revisit that decision some day.
975
+ animationEnd = opts.duration + opts.delay
976
+ endTimeout = setTimer animationEnd, ->
977
+ $element.removeClass('up-animating')
978
+ deferred.resolve() unless isDetached($element)
979
+ # Clean up in case we're canceled through some other code that
980
+ # resolves our deferred.
981
+ deferred.then(-> clearTimeout(endTimeout))
982
+
921
983
  # Return the whole deferred and not just return a thenable.
922
984
  # Other code will need the possibility to cancel the animation
923
985
  # by resolving the deferred.
@@ -1299,49 +1361,46 @@ up.util = (($) ->
1299
1361
 
1300
1362
  store = undefined
1301
1363
 
1364
+ optionEvaluator = (name) ->
1365
+ ->
1366
+ value = config[name]
1367
+ if isNumber(value)
1368
+ value
1369
+ else if isFunction(value)
1370
+ value()
1371
+ else
1372
+ undefined
1373
+
1374
+ maxKeys = optionEvaluator('size')
1375
+
1376
+ expiryMillis = optionEvaluator('expiry')
1377
+
1378
+ normalizeStoreKey = (key) ->
1379
+ if config.key
1380
+ config.key(key)
1381
+ else
1382
+ key.toString()
1383
+
1384
+ isEnabled = ->
1385
+ maxKeys() isnt 0 && expiryMillis() isnt 0
1386
+
1302
1387
  clear = ->
1303
1388
  store = {}
1304
1389
 
1305
1390
  clear()
1306
1391
 
1307
1392
  log = (args...) ->
1308
- if config.log
1309
- args[0] = "[#{config.log}] #{args[0]}"
1393
+ if config.logPrefix
1394
+ args[0] = "[#{config.logPrefix}] #{args[0]}"
1310
1395
  up.puts(args...)
1311
1396
 
1312
1397
  keys = ->
1313
1398
  Object.keys(store)
1314
1399
 
1315
- maxSize = ->
1316
- if isMissing(config.size)
1317
- undefined
1318
- else if isFunction(config.size)
1319
- config.size()
1320
- else if isNumber(config.size)
1321
- config.size
1322
- else
1323
- error("Invalid size config: %o", config.size)
1324
-
1325
- expiryMilis = ->
1326
- if isMissing(config.expiry)
1327
- undefined
1328
- else if isFunction(config.expiry)
1329
- config.expiry()
1330
- else if isNumber(config.expiry)
1331
- config.expiry
1332
- else
1333
- error("Invalid expiry config: %o", config.expiry)
1334
-
1335
- normalizeStoreKey = (key) ->
1336
- if config.key
1337
- config.key(key)
1338
- else
1339
- key.toString()
1340
-
1341
- trim = ->
1400
+ makeRoomForAnotherKey = ->
1342
1401
  storeKeys = copy(keys())
1343
- size = maxSize()
1344
- if size && storeKeys.length > size
1402
+ max = maxKeys()
1403
+ if max && storeKeys.length >= max
1345
1404
  oldestKey = null
1346
1405
  oldestTimestamp = null
1347
1406
  each storeKeys, (key) ->
@@ -1361,20 +1420,22 @@ up.util = (($) ->
1361
1420
  (new Date()).valueOf()
1362
1421
 
1363
1422
  set = (key, value) ->
1364
- storeKey = normalizeStoreKey(key)
1365
- store[storeKey] =
1366
- timestamp: timestamp()
1367
- value: value
1423
+ if isEnabled()
1424
+ makeRoomForAnotherKey()
1425
+ storeKey = normalizeStoreKey(key)
1426
+ store[storeKey] =
1427
+ timestamp: timestamp()
1428
+ value: value
1368
1429
 
1369
1430
  remove = (key) ->
1370
1431
  storeKey = normalizeStoreKey(key)
1371
1432
  delete store[storeKey]
1372
1433
 
1373
1434
  isFresh = (entry) ->
1374
- expiry = expiryMilis()
1375
- if expiry
1435
+ millis = expiryMillis()
1436
+ if millis
1376
1437
  timeSinceTouch = timestamp() - entry.timestamp
1377
- timeSinceTouch < expiryMilis()
1438
+ timeSinceTouch < millis
1378
1439
  else
1379
1440
  true
1380
1441
 
@@ -1570,12 +1631,37 @@ up.util = (($) ->
1570
1631
  $error.text(asString)
1571
1632
  throw new Error(asString)
1572
1633
 
1634
+ pluckKey = (object, key) ->
1635
+ value = object[key]
1636
+ delete object[key]
1637
+ value
1638
+
1573
1639
  pluckData = (elementOrSelector, key) ->
1574
1640
  $element = $(elementOrSelector)
1575
1641
  value = $element.data(key)
1576
1642
  $element.removeData(key)
1577
1643
  value
1578
1644
 
1645
+ extractOptions = (args) ->
1646
+ lastArg = last(args)
1647
+ if isObject(lastArg)
1648
+ args.pop()
1649
+ else
1650
+ {}
1651
+
1652
+ ###*
1653
+ Returns whether the given element has been detached from the DOM
1654
+ (or whether it was never attached).
1655
+
1656
+ @function up.util.isDetached
1657
+ @internal
1658
+ ###
1659
+ isDetached = (element) ->
1660
+ element = unJQuery(element)
1661
+ # This is by far the fastest way to do this
1662
+ not jQuery.contains(document.documentElement, element)
1663
+
1664
+ isDetached: isDetached
1579
1665
  requestDataAsArray: requestDataAsArray
1580
1666
  requestDataAsQuery: requestDataAsQuery
1581
1667
  appendRequestData: appendRequestData
@@ -1631,12 +1717,14 @@ up.util = (($) ->
1631
1717
  isUnmodifiedMouseEvent: isUnmodifiedMouseEvent
1632
1718
  nullJQuery: nullJQuery
1633
1719
  unJQuery: unJQuery
1720
+ setTimer: setTimer
1634
1721
  nextFrame: nextFrame
1635
1722
  measure: measure
1636
1723
  temporaryCss: temporaryCss
1637
1724
  cssAnimate: cssAnimate
1638
1725
  finishCssAnimate: finishCssAnimate
1639
1726
  forceCompositing: forceCompositing
1727
+ forceRepaint: forceRepaint
1640
1728
  escapePressed: escapePressed
1641
1729
  copyAttributes: copyAttributes
1642
1730
  findWithSelf: findWithSelf
@@ -1667,6 +1755,10 @@ up.util = (($) ->
1667
1755
  multiSelector: multiSelector
1668
1756
  error: error
1669
1757
  pluckData: pluckData
1758
+ pluckKey: pluckKey
1759
+ extractOptions: extractOptions
1760
+ isDetached: isDetached
1761
+ noop: noop
1670
1762
 
1671
1763
  )($)
1672
1764