upjs-rails 0.18.0 → 0.18.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0282df3df026ad3d48b9f10614eb73790b146243
4
- data.tar.gz: 1fd5ddad76f7ab45668da13b90e7727a24d7f4ac
3
+ metadata.gz: 6d1b52fa522fbde804ecf3db0de54efa03a5efa5
4
+ data.tar.gz: 2f8c0c4b0589ffb165a1237caa492a41922a3157
5
5
  SHA512:
6
- metadata.gz: 5b2c33b0c3835ebac5f42bd58f90536da481cce4ab252b3295f1b6d727ba875ec2a0543fc3e28baa16500ae8cd6767d3fe1af41625afd9740017c5f982dd24b9
7
- data.tar.gz: 10773603d25db7f0aaf99eea17926ab4b253378834900780f95627c4b71eeec7f87e9cbb515eee1151b7ff4b26b682ff9fa5a4a1f36c2ed3e8e88876c7b2c8d6
6
+ metadata.gz: 688084094aeea1ae88a73f96d5243e632e82b089376e95d3ee0cf37e77b57ef5b10259bdc0ae3f1ddf25b3d005b7bd07ee43d1530f012b9f8c6dd51bcd5660ec
7
+ data.tar.gz: af2131873f4c54165dc49780fb724b96bb4ab6b5ae0c830abb18d7469e3b01b9da6cf689066579089c0dd5325c33cd61a5b9f8f1d5b847b2629f6c0e61aef412
data/CHANGELOG.md CHANGED
@@ -10,9 +10,18 @@ Unreleased
10
10
 
11
11
  ### Compatible changes
12
12
 
13
+
13
14
  ### Breaking changes
14
15
 
15
16
 
17
+ 0.18.1
18
+ ------
19
+
20
+ ### Compatible changes
21
+
22
+ - The logging output to the developer console is now much quieter and more useful
23
+
24
+
16
25
  0.18.0
17
26
  ------
18
27
 
@@ -1,5 +1,6 @@
1
1
  #= require up/module
2
2
  #= require up/util
3
+ #= require up/log
3
4
  #= require up/browser
4
5
  #= require up/bus
5
6
  #= require up/syntax
@@ -17,4 +18,3 @@
17
18
  #= require up/rails
18
19
 
19
20
  up.boot()
20
-
@@ -56,9 +56,43 @@ up.browser = (($) ->
56
56
  console[stream](args...)
57
57
  else
58
58
  # IE <= 9 cannot pass varargs to console.log using Function#apply because IE
59
- message = u.evalConsoleTemplate(args...)
59
+ message = sprintf(args...)
60
60
  console[stream](message)
61
61
 
62
+ CONSOLE_PLACEHOLDERS = /\%[odisf]/g
63
+
64
+ ###*
65
+ See https://developer.mozilla.org/en-US/docs/Web/API/Console#Using_string_substitutions
66
+
67
+ @function up.browser.sprintf
68
+ @internal
69
+ ###
70
+ sprintf = (message, args...) ->
71
+ i = 0
72
+ maxLength = 80
73
+ message.replace CONSOLE_PLACEHOLDERS, ->
74
+ arg = args[i]
75
+ argType = (typeof arg)
76
+ if argType == 'string'
77
+ arg = arg.replace(/\s+/g, ' ')
78
+ arg = "#{arg.substr(0, maxLength)}…" if arg.length > maxLength
79
+ arg = "\"#{arg}\""
80
+ else if argType == 'undefined'
81
+ # JSON.stringify(undefined) is actually undefined
82
+ arg = 'undefined'
83
+ else if argType == 'number' || argType == 'function'
84
+ arg = arg.toString()
85
+ else
86
+ arg = JSON.stringify(arg)
87
+ if arg.length > maxLength
88
+ arg = "#{arg.substr(0, maxLength)} …"
89
+ # For truncated objects or functions, add a trailing brace so
90
+ # long log lines are easier to parse visually
91
+ if argType == 'object' || argType == 'function'
92
+ arg += " }"
93
+ i += 1
94
+ arg
95
+
62
96
  url = ->
63
97
  location.href
64
98
 
@@ -193,6 +227,14 @@ up.browser = (($) ->
193
227
  isSupported = ->
194
228
  (!isIE8OrWorse()) && isRecentJQuery()
195
229
 
230
+ ###*
231
+ @internal
232
+ ###
233
+ installPolyfills = ->
234
+ console.group ||= (args...) -> puts('group', args...)
235
+ console.groupCollapsed ||= (args...) -> puts('groupCollapsed', args...)
236
+ console.groupEnd ||= (args...) -> puts('groupEnd', args...)
237
+
196
238
  url: url
197
239
  loadPage: loadPage
198
240
  confirm: confirm
@@ -201,6 +243,8 @@ up.browser = (($) ->
201
243
  canInputEvent: canInputEvent
202
244
  canLogSubstitution: canLogSubstitution
203
245
  isSupported: isSupported
246
+ installPolyfills: installPolyfills
204
247
  puts: puts
248
+ sprintf: sprintf
205
249
 
206
250
  )(jQuery)
@@ -234,15 +234,41 @@ up.bus = (($) ->
234
234
  or `stopPropagation()`.
235
235
  @param {jQuery} [eventProps.$element=$(document)]
236
236
  The element on which the event is triggered.
237
+ @param {String|Array} [eventProps.message]
238
+ A message to print to the console when the event is emitted.
239
+ If omitted, a default message is printed.
240
+ Set this to `false` to prevent any console output.
237
241
  @experimental
238
242
  ###
239
243
  emit = (eventName, eventProps = {}) ->
240
244
  event = $.Event(eventName, eventProps)
241
- $target = eventProps.$element || $(document)
242
- u.debug("Emitting %o on %o with props %o", eventName, $target, eventProps)
245
+ if $target = eventProps.$element
246
+ delete eventProps.$element
247
+ else
248
+ $target = $(document)
249
+ logEmission(eventName, eventProps)
243
250
  $target.trigger(event)
244
251
  event
245
252
 
253
+ logEmission = (eventName, eventProps) ->
254
+ if eventProps.hasOwnProperty('message')
255
+ niceMessage = eventProps.message
256
+ delete eventProps.message
257
+ if u.isArray(niceMessage)
258
+ [niceMessage, niceMessageArgs...] = niceMessage
259
+ else
260
+ niceMessageArgs = []
261
+ if niceMessage
262
+ if u.isPresent(eventProps)
263
+ up.puts "#{niceMessage} (%s (%o))", niceMessageArgs..., eventName, eventProps
264
+ else
265
+ up.puts "#{niceMessage} (%s)", niceMessageArgs..., eventName
266
+ else
267
+ if u.isPresent(eventProps)
268
+ up.puts 'Emitted event %s (%o)', eventName, eventProps
269
+ else
270
+ up.puts 'Emitted event %s', eventName
271
+
246
272
  ###*
247
273
  [Emits an event](/up.emit) and returns whether any listener
248
274
  has prevented the default action.
@@ -250,11 +276,16 @@ up.bus = (($) ->
250
276
  @function up.bus.nobodyPrevents
251
277
  @param {String} eventName
252
278
  @param {Object} eventProps
279
+ @param {String|Array} [eventProps.message]
253
280
  @experimental
254
281
  ###
255
282
  nobodyPrevents = (args...) ->
256
283
  event = emit(args...)
257
- not event.isDefaultPrevented()
284
+ if event.isDefaultPrevented()
285
+ up.puts "An observer prevented the event %s", args[0]
286
+ false
287
+ else
288
+ true
258
289
 
259
290
  ###*
260
291
  Registers an event listener to be called when the user
@@ -281,7 +312,7 @@ up.bus = (($) ->
281
312
  ###
282
313
  snapshot = ->
283
314
  for description in liveUpDescriptions
284
- description._isDefault = true
315
+ description.isDefault = true
285
316
 
286
317
  ###*
287
318
  Resets the list of registered event listeners to the
@@ -290,7 +321,7 @@ up.bus = (($) ->
290
321
  @internal
291
322
  ###
292
323
  restoreSnapshot = ->
293
- doomedDescriptions = u.reject(liveUpDescriptions, (description) -> description._isDefault)
324
+ doomedDescriptions = u.reject(liveUpDescriptions, (description) -> description.isDefault)
294
325
  unbind(description...) for description in doomedDescriptions
295
326
 
296
327
  ###*
@@ -305,7 +336,7 @@ up.bus = (($) ->
305
336
  @experimental
306
337
  ###
307
338
  emitReset = ->
308
- up.emit('up:framework:reset')
339
+ up.emit('up:framework:reset', message: 'Resetting framework')
309
340
 
310
341
  ###*
311
342
  This event is [emitted](/up.emit) when Up.js is [reset](/up.reset) during unit tests.
@@ -329,7 +360,10 @@ up.bus = (($) ->
329
360
  ###
330
361
  boot = ->
331
362
  if up.browser.isSupported()
332
- up.emit('up:framework:boot')
363
+ # Can't decouple this via the event bus, since up.bus would require
364
+ # up.browser.isSupported() and up.browser would require up.on()
365
+ up.browser.installPolyfills()
366
+ up.emit('up:framework:boot', message: 'Booting framework')
333
367
 
334
368
  ###*
335
369
  This event is [emitted](/up.emit) when Up.js [boots](/up.boot).
@@ -49,7 +49,7 @@ up.flow = (($) ->
49
49
  originSelector = u.selectorForElement(origin)
50
50
  selector = selector.replace(/\&/, originSelector)
51
51
  else
52
- u.error("Found origin reference %o in selector %o, but options.origin is missing", '&', selector)
52
+ u.error("Found origin reference (%s) in selector %s, but options.origin is missing", '&', selector)
53
53
  else
54
54
  selector = u.selectorForElement(selectorOrElement)
55
55
  selector
@@ -177,8 +177,7 @@ up.flow = (($) ->
177
177
  @stable
178
178
  ###
179
179
  replace = (selectorOrElement, url, options) ->
180
- u.debug("Replace %o with %o (options %o)", selectorOrElement, url, options)
181
-
180
+ up.puts "Replacing %s from %s (%o)", selectorOrElement, url, options
182
181
  options = u.options(options)
183
182
  target = resolveSelector(selectorOrElement, options.origin)
184
183
  failTarget = u.option(options.failTarget, 'body')
@@ -206,14 +205,12 @@ up.flow = (($) ->
206
205
 
207
206
  promise.fail (xhr, textStatus, errorThrown) ->
208
207
  processResponse(false, failTarget, url, request, xhr, options)
209
-
210
208
  promise
211
209
 
212
210
  ###*
213
211
  @internal
214
212
  ###
215
213
  processResponse = (isSuccess, selector, url, request, xhr, options) ->
216
-
217
214
  options.method = u.normalizeMethod(u.option(u.methodFromXhr(xhr), options.method))
218
215
  options.title = u.option(u.titleFromXhr(xhr), options.title)
219
216
  isReloadable = (options.method == 'GET')
@@ -326,7 +323,7 @@ up.flow = (($) ->
326
323
 
327
324
  oldFragmentNotFound = (selector, options) ->
328
325
  if options.requireMatch
329
- message = 'Could not find selector %o in current body HTML'
326
+ message = 'Could not find selector %s in current body HTML'
330
327
  if message[0] == '#'
331
328
  message += ' (avoid using IDs)'
332
329
  u.error(message, selector)
@@ -344,7 +341,7 @@ up.flow = (($) ->
344
341
  if child = $.find(selector, htmlElement)[0]
345
342
  $(child)
346
343
  else if options.requireMatch
347
- u.error("Could not find selector %o in response %o", selector, html)
344
+ u.error("Could not find selector %s in response %o", selector, html)
348
345
 
349
346
  elementsInserted = ($new, options) ->
350
347
  if options.history
@@ -401,7 +398,7 @@ up.flow = (($) ->
401
398
  $new.insertBefore($old)
402
399
  elementsInserted($new, options)
403
400
  if $old.is('body') && transition != 'none'
404
- u.error('Cannot apply transitions to body-elements (%o)', transition)
401
+ u.error('Cannot apply transitions to body-elements')
405
402
  # Morphing will also process options.reveal
406
403
  up.morph($old, $new, transition, options)
407
404
 
@@ -417,7 +414,7 @@ up.flow = (($) ->
417
414
  for selectorAtom, i in disjunction
418
415
  # Splitting the atom
419
416
  selectorParts = selectorAtom.match(/^(.+?)(?:\:(before|after))?$/)
420
- selectorParts or u.error('Could not parse selector atom %o', selectorAtom)
417
+ selectorParts or u.error('Could not parse selector atom "%s"', selectorAtom)
421
418
  selector = selectorParts[1]
422
419
  if selector == 'html'
423
420
  # If someone really asked us to replace the <html> root, the best
@@ -501,7 +498,10 @@ up.flow = (($) ->
501
498
  ###
502
499
  destroy = (selectorOrElement, options) ->
503
500
  $element = $(selectorOrElement)
504
- if up.bus.nobodyPrevents('up:fragment:destroy', $element: $element)
501
+ unless $element.is('.up-placeholder, .up-tooltip, .up-modal, .up-popup')
502
+ destroyMessage = ['Destroying fragment %o', $element.get(0)]
503
+ destroyedMessage = ['Destroyed fragment %o', $element.get(0)]
504
+ if up.bus.nobodyPrevents('up:fragment:destroy', $element: $element, message: destroyMessage)
505
505
  options = u.options(options, animation: false)
506
506
  animateOptions = up.motion.animateOptions(options)
507
507
  $element.addClass('up-destroying')
@@ -515,7 +515,7 @@ up.flow = (($) ->
515
515
  animationDeferred.then ->
516
516
  # Emit this while $element is still part of the DOM, so event
517
517
  # listeners bound to the document will receive the event.
518
- up.emit('up:fragment:destroyed', $element: $element)
518
+ up.emit 'up:fragment:destroyed', $element: $element, message: destroyedMessage
519
519
  $element.remove()
520
520
  animationDeferred
521
521
  else
@@ -218,7 +218,7 @@ up.form = (($) ->
218
218
  callback = null
219
219
 
220
220
  if u.isGiven(options.change)
221
- up.error('up.observe now takes the change callback as the last argument')
221
+ u.error('up.observe now takes the change callback as the last argument')
222
222
 
223
223
  rawCallback = u.option(u.presentAttr($element, 'op-observe'), callbackArg)
224
224
  if u.isString(rawCallback)
@@ -334,7 +334,7 @@ up.form = (($) ->
334
334
  $field.closest(resolvedDefault).length
335
335
  )
336
336
  if u.isBlank(target)
337
- error('Could not find default validation target for %o (tried ancestors %o)', $field, config.validateTargets)
337
+ u.error('Could not find default validation target for %o (tried ancestors %o)', $field.get(0), config.validateTargets)
338
338
  unless u.isString(target)
339
339
  target = u.selectorForElement(target)
340
340
  target
@@ -387,16 +387,12 @@ up.form = (($) ->
387
387
  else
388
388
  values = [':unchecked', ':blank']
389
389
  else if $field.is('input[type=radio]')
390
- console.log('-- it is a radio button --')
391
390
  $checkedButton = $field.closest('form, body').find("input[type='radio'][name='#{$field.attr('name')}']:checked")
392
- console.log('checked button is %o', $checkedButton)
393
- console.log('checked button val is %o', $checkedButton.val())
394
391
  if $checkedButton.length
395
392
  values = [':checked', ':present', $checkedButton.val()]
396
393
  else
397
394
  values = [':unchecked', ':blank']
398
395
  else
399
- console.log('-- else -- for %o', $field)
400
396
  value = $field.val()
401
397
  if u.isPresent(value)
402
398
  values = [':present', value]
@@ -450,7 +446,7 @@ up.form = (($) ->
450
446
  $field = $(fieldOrSelector)
451
447
  options = u.options(options)
452
448
  targets = u.option(options.target, $field.attr('up-toggle'))
453
- u.isPresent(targets) or u.error("No toggle target given for %o", $field)
449
+ u.isPresent(targets) or u.error("No toggle target given for %o", $field.get(0))
454
450
  fieldValues = currentValuesForToggle($field)
455
451
  $(targets).each ->
456
452
  $target = $(this)
@@ -781,7 +777,7 @@ up.form = (($) ->
781
777
 
782
778
  @selector [up-hide-for]
783
779
  @param up-hide-for
784
- A space-separated list of values for which to show this element.
780
+ A space-separated list of values for which to hide this element.
785
781
  @stable
786
782
  ###
787
783
 
@@ -106,6 +106,7 @@ up.history = (($) ->
106
106
  @experimental
107
107
  ###
108
108
  push = (url, options) ->
109
+ up.puts("Current location is now %s", url)
109
110
  manipulate('push', url, options)
110
111
 
111
112
  manipulate = (method, url, options) ->
@@ -114,9 +115,6 @@ up.history = (($) ->
114
115
  if up.browser.canPushState()
115
116
  fullMethod = "#{method}State" # resulting in either pushState or replaceState
116
117
  state = buildState()
117
- # console.log("[#{method}] URL %o with state %o", url, state)
118
- u.debug("Changing history to URL %o (%o)", url, method)
119
- # previousUrl = url
120
118
  window.history[fullMethod](state, '', url)
121
119
  observeNewUrl(currentUrl())
122
120
  else
@@ -126,25 +124,25 @@ up.history = (($) ->
126
124
  fromUp: true
127
125
 
128
126
  restoreStateOnPop = (state) ->
129
- url = currentUrl()
130
- u.debug "Restoring state %o (now on #{url})", state
131
- popSelector = config.popTargets.join(', ')
132
- up.replace popSelector, url,
133
- history: false,
134
- reveal: false,
135
- transition: 'none',
136
- saveScroll: false # since the URL was already changed by the browser, don't save scroll state
137
- restoreScroll: config.restoreScroll
127
+ if state?.fromUp
128
+ url = currentUrl()
129
+ up.log.group "Restoring URL %s", url, ->
130
+ popSelector = config.popTargets.join(', ')
131
+ up.replace popSelector, url,
132
+ history: false,
133
+ reveal: false,
134
+ transition: 'none',
135
+ saveScroll: false # since the URL was already changed by the browser, don't save scroll state
136
+ restoreScroll: config.restoreScroll
137
+ else
138
+ up.puts 'Ignoring a state not pushed by Up.js (%o)', state
138
139
 
139
140
  pop = (event) ->
140
- u.debug("History state popped to URL %o", currentUrl())
141
- observeNewUrl(currentUrl())
142
- up.layout.saveScroll(url: previousUrl)
143
- state = event.originalEvent.state
144
- if state?.fromUp
141
+ up.log.group "History state popped to URL %s", currentUrl(), ->
142
+ observeNewUrl(currentUrl())
143
+ up.layout.saveScroll(url: previousUrl)
144
+ state = event.originalEvent.state
145
145
  restoreStateOnPop(state)
146
- else
147
- u.debug 'Discarding unknown state %o', state
148
146
 
149
147
  # up.on 'framework:ready', ->
150
148
  if up.browser.canPushState()
@@ -157,7 +157,7 @@ up.layout = (($) ->
157
157
  $obstructor = $(obstructor)
158
158
  anchorPosition = $obstructor.css(cssAttr)
159
159
  unless u.isPresent(anchorPosition)
160
- u.error("Fixed element %o must have a CSS attribute %o", $obstructor, cssAttr)
160
+ u.error("Fixed element %o must have a CSS attribute %s", $obstructor.get(0), cssAttr)
161
161
  parseInt(anchorPosition) + $obstructor.height()
162
162
 
163
163
  fixedTopBottoms = for obstructor in $(config.fixedTop.join(', '))
@@ -213,9 +213,9 @@ up.layout = (($) ->
213
213
  @stable
214
214
  ###
215
215
  reveal = (elementOrSelector, options) ->
216
- u.debug('Revealing %o', elementOrSelector)
217
- options = u.options(options)
218
216
  $element = $(elementOrSelector)
217
+ up.puts 'Revealing fragment %o', elementOrSelector.get(0)
218
+ options = u.options(options)
219
219
  $viewport = if options.viewport then $(options.viewport) else viewportOf($element)
220
220
 
221
221
  snap = u.option(options.snap, config.snap)
@@ -359,7 +359,7 @@ up.layout = (($) ->
359
359
  saveScroll = (options = {}) ->
360
360
  url = u.option(options.url, up.history.url())
361
361
  tops = u.option(options.tops, scrollTops())
362
- u.debug('Saving scroll positions for URL %o: %o', url, tops)
362
+ up.puts('Saving scroll positions for URL %s (%o)', url, tops)
363
363
  lastScrollTops.set(url, tops)
364
364
 
365
365
  ###*
@@ -390,16 +390,15 @@ up.layout = (($) ->
390
390
 
391
391
  tops = lastScrollTops.get(url)
392
392
 
393
- u.debug('Restoring scroll positions for URL %o (viewports are %o, saved tops are %o)', url, $viewports, tops)
393
+ up.log.group 'Restoring scroll positions for URL %s to %o', url, tops, ->
394
+ for key, scrollTop of tops
395
+ right = if key == 'document' then document else key
396
+ $matchingViewport = $viewports.filter(right)
397
+ scroll($matchingViewport, scrollTop, duration: 0)
394
398
 
395
- for key, scrollTop of tops
396
- right = if key == 'document' then document else key
397
- $matchingViewport = $viewports.filter(right)
398
- scroll($matchingViewport, scrollTop, duration: 0)
399
-
400
- # Since scrolling happens without animation, we don't need to
401
- # join promises from the up.scroll call above
402
- u.resolvedDeferred()
399
+ # Since scrolling happens without animation, we don't need to
400
+ # join promises from the up.scroll call above
401
+ u.resolvedDeferred()
403
402
 
404
403
  ###*
405
404
  @function up.layout.revealOrRestoreScroll
@@ -0,0 +1,72 @@
1
+ up.log = (($) ->
2
+
3
+ prefix = (message) ->
4
+ "ᴜᴘ #{message}"
5
+
6
+ ###*
7
+ Prints a debugging message to the browser console.
8
+
9
+ @function up.debug
10
+ @param {String} message
11
+ @param {Array} args...
12
+ @internal
13
+ ###
14
+ debug = (message, args...) ->
15
+ if message
16
+ up.browser.puts('debug', prefix(message), args...)
17
+
18
+ ###*
19
+ Prints a logging message to the browser console.
20
+
21
+ @function up.puts
22
+ @param {String} message
23
+ @param {Array} args...
24
+ @internal
25
+ ###
26
+ puts = (message, args...) ->
27
+ if message
28
+ up.browser.puts('log', prefix(message), args...)
29
+
30
+ ###*
31
+ @function up.log.warn
32
+ @internal
33
+ ###
34
+ warn = (message, args...) ->
35
+ if message
36
+ up.browser.puts('warn', prefix(message), args...)
37
+
38
+ ###*
39
+ - Makes sure the group always closes
40
+ - Does not make a group if the message is nil
41
+
42
+ @function up.log.group
43
+ @internal
44
+ ###
45
+ group = (message, args...) ->
46
+ block = args.pop() # Coffeescript copies the arguments array
47
+ if message
48
+ up.browser.puts('groupCollapsed', prefix(message), args...)
49
+ try
50
+ block()
51
+ finally
52
+ console.groupEnd() if message
53
+ else
54
+ block()
55
+
56
+ ###*
57
+ @function up.log.error
58
+ @internal
59
+ ###
60
+ error = (message, args...) ->
61
+ if message
62
+ up.browser.puts('error', prefix(message), args...)
63
+
64
+ puts: puts
65
+ debug: debug
66
+ error: error
67
+ warn: warn
68
+ group: group
69
+
70
+ )(jQuery)
71
+
72
+ up.puts = up.log.puts
@@ -168,8 +168,7 @@ up.modal = (($) ->
168
168
  $content = $modal.find('.up-modal-content')
169
169
  # Create an empty element that will match the
170
170
  # selector that is being replaced.
171
- $placeholder = u.$createElementFromSelector(target)
172
- $placeholder.appendTo($content)
171
+ u.$createPlaceholder(target, $content)
173
172
  $modal.appendTo(document.body)
174
173
  $modal
175
174
 
@@ -310,7 +309,7 @@ up.modal = (($) ->
310
309
  animateOptions = up.motion.animateOptions(options, $link)
311
310
 
312
311
  up.browser.confirm(options.confirm).then ->
313
- if up.bus.nobodyPrevents('up:modal:open', url: url)
312
+ if up.bus.nobodyPrevents('up:modal:open', url: url, message: 'Opening modal')
314
313
  wasOpen = isOpen()
315
314
  close(animation: false) if wasOpen
316
315
  options.beforeSwap = -> createFrame(target, options)
@@ -319,7 +318,7 @@ up.modal = (($) ->
319
318
  promise = promise.then ->
320
319
  up.animate($('.up-modal'), options.animation, animateOptions)
321
320
  promise = promise.then ->
322
- up.emit('up:modal:opened')
321
+ up.emit('up:modal:opened', message: 'Modal opened')
323
322
  promise
324
323
  else
325
324
  # Although someone prevented opening the modal, keep a uniform API for
@@ -360,7 +359,7 @@ up.modal = (($) ->
360
359
  close = (options) ->
361
360
  $modal = $('.up-modal')
362
361
  if $modal.length
363
- if up.bus.nobodyPrevents('up:modal:close', $element: $modal)
362
+ if up.bus.nobodyPrevents('up:modal:close', $element: $modal, message: 'Closing modal')
364
363
  options = u.options(options,
365
364
  animation: config.closeAnimation,
366
365
  url: $modal.attr('up-covered-url')
@@ -370,7 +369,7 @@ up.modal = (($) ->
370
369
  promise = up.destroy($modal, options)
371
370
  promise = promise.then ->
372
371
  unshiftElements()
373
- up.emit('up:modal:closed')
372
+ up.emit('up:modal:closed', message: 'Modal closed')
374
373
  promise
375
374
  else
376
375
  # Although someone prevented the destruction,
@@ -270,7 +270,7 @@ up.motion = (($) ->
270
270
 
271
271
  finishGhosting = ($element) ->
272
272
  if existingGhosting = $element.data(GHOSTING_PROMISE_KEY)
273
- u.debug('Canceling existing ghosting on %o', $element)
273
+ up.puts('Canceling existing ghosting on %o', $element)
274
274
  existingGhosting.resolve?()
275
275
 
276
276
  assertIsDeferred = (object, source) ->
@@ -343,40 +343,42 @@ up.motion = (($) ->
343
343
  @stable
344
344
  ###
345
345
  morph = (source, target, transitionOrName, options) ->
346
+ if transitionOrName == 'none'
347
+ transitionOrName = false
346
348
 
347
- u.debug('Morphing %o to %o (using %o)', source, target, transitionOrName)
349
+ up.log.group ('Morphing %o to %o (using %o)' if transitionOrName), source, target, transitionOrName, ->
348
350
 
349
- $old = $(source)
350
- $new = $(target)
351
+ $old = $(source)
352
+ $new = $(target)
351
353
 
352
- parsedOptions = u.only(options, 'reveal', 'restoreScroll', 'source')
353
- parsedOptions = u.extend(parsedOptions, animateOptions(options))
354
+ parsedOptions = u.only(options, 'reveal', 'restoreScroll', 'source')
355
+ parsedOptions = u.extend(parsedOptions, animateOptions(options))
354
356
 
355
- if isEnabled()
356
- finish($old)
357
- finish($new)
358
-
359
- if transitionOrName == 'none' || transitionOrName == false
360
- return skipMorph($old, $new, parsedOptions)
361
- else if animation = animations[transitionOrName]
362
- skipMorph($old, $new, parsedOptions)
363
- return animate($new, animation, parsedOptions)
364
- else if transition = u.presence(transitionOrName, u.isFunction) || transitions[transitionOrName]
365
- return withGhosts $old, $new, parsedOptions, ($oldGhost, $newGhost) ->
366
- transitionPromise = transition($oldGhost, $newGhost, parsedOptions)
367
- assertIsDeferred(transitionPromise, transitionOrName)
368
- else if u.isString(transitionOrName) && transitionOrName.indexOf('/') >= 0
369
- parts = transitionOrName.split('/')
370
- transition = ($old, $new, options) ->
371
- resolvableWhen(
372
- animate($old, parts[0], options),
373
- animate($new, parts[1], options)
374
- )
375
- return morph($old, $new, transition, parsedOptions)
357
+ if isEnabled()
358
+ finish($old)
359
+ finish($new)
360
+
361
+ if !transitionOrName
362
+ return skipMorph($old, $new, parsedOptions)
363
+ else if animation = animations[transitionOrName]
364
+ skipMorph($old, $new, parsedOptions)
365
+ return animate($new, animation, parsedOptions)
366
+ else if transition = u.presence(transitionOrName, u.isFunction) || transitions[transitionOrName]
367
+ return withGhosts $old, $new, parsedOptions, ($oldGhost, $newGhost) ->
368
+ transitionPromise = transition($oldGhost, $newGhost, parsedOptions)
369
+ assertIsDeferred(transitionPromise, transitionOrName)
370
+ else if u.isString(transitionOrName) && transitionOrName.indexOf('/') >= 0
371
+ parts = transitionOrName.split('/')
372
+ transition = ($old, $new, options) ->
373
+ resolvableWhen(
374
+ animate($old, parts[0], options),
375
+ animate($new, parts[1], options)
376
+ )
377
+ return morph($old, $new, transition, parsedOptions)
378
+ else
379
+ u.error("Unknown transition %o", transitionOrName)
376
380
  else
377
- u.error("Unknown transition %o", transitionOrName)
378
- else
379
- return skipMorph($old, $new, parsedOptions)
381
+ return skipMorph($old, $new, parsedOptions)
380
382
 
381
383
  ###*
382
384
  This causes the side effects of a successful transition, but instantly.
@@ -109,7 +109,7 @@ up.popup = (($) ->
109
109
  left: linkBox.left
110
110
  bottom: linkBox.top
111
111
  else
112
- u.error("Unknown position %o", position)
112
+ u.error("Unknown position option '%s'", position)
113
113
  $popup = $('.up-popup')
114
114
  $popup.attr('up-position', position)
115
115
  $popup.css(css)
@@ -153,8 +153,7 @@ up.popup = (($) ->
153
153
  $popup.attr('up-covered-title', document.title)
154
154
  # Create an empty element that will match the
155
155
  # selector that is being replaced.
156
- $placeholder = u.$createElementFromSelector(target)
157
- $placeholder.appendTo($popup)
156
+ u.$createPlaceholder(target, $popup)
158
157
  $popup.appendTo(document.body)
159
158
  $popup
160
159
 
@@ -214,7 +213,7 @@ up.popup = (($) ->
214
213
  animateOptions = up.motion.animateOptions(options, $link)
215
214
 
216
215
  up.browser.confirm(options.confirm).then ->
217
- if up.bus.nobodyPrevents('up:popup:open', url: url)
216
+ if up.bus.nobodyPrevents('up:popup:open', url: url, message: 'Opening popup')
218
217
  wasOpen = isOpen()
219
218
  close(animation: false) if wasOpen
220
219
  options.beforeSwap = -> createFrame(target, options)
@@ -225,7 +224,7 @@ up.popup = (($) ->
225
224
  promise = promise.then ->
226
225
  up.animate($('.up-popup'), options.animation, animateOptions)
227
226
  promise = promise.then ->
228
- up.emit('up:popup:opened')
227
+ up.emit('up:popup:opened', message: 'Popup opened')
229
228
  promise
230
229
  else
231
230
  # Although someone prevented the destruction, keep a uniform API for
@@ -274,7 +273,7 @@ up.popup = (($) ->
274
273
  )
275
274
  currentUrl = undefined
276
275
  deferred = up.destroy($popup, options)
277
- deferred.then -> up.emit('up:popup:closed')
276
+ deferred.then -> up.emit('up:popup:closed', message: 'Popup closed')
278
277
  deferred
279
278
  else
280
279
  # Although someone prevented the destruction,
@@ -122,7 +122,7 @@ up.proxy = (($) ->
122
122
  size: -> config.cacheSize
123
123
  expiry: -> config.cacheExpiry
124
124
  key: cacheKey
125
- log: 'up.proxy'
125
+ # log: 'up.proxy'
126
126
 
127
127
  ###*
128
128
  Returns a cached response for the given request.
@@ -254,6 +254,7 @@ up.proxy = (($) ->
254
254
  ignoreCache = (options.cache == false)
255
255
 
256
256
  request = u.only(options, 'url', 'method', 'data', 'target', 'headers', '_normalized')
257
+ request = normalizeRequest(request)
257
258
 
258
259
  pending = true
259
260
 
@@ -267,6 +268,7 @@ up.proxy = (($) ->
267
268
  # we use it unless `options.cache` is explicitly set to `false`.
268
269
  # The promise might still be pending.
269
270
  else if (promise = get(request)) && !ignoreCache
271
+ up.puts 'Re-using cached response for %s %s', request.method, request.url
270
272
  pending = (promise.state() == 'pending')
271
273
  # If no existing promise is available, we make a network request.
272
274
  else
@@ -289,6 +291,8 @@ up.proxy = (($) ->
289
291
  loadStarted()
290
292
  promise.always(loadEnded)
291
293
 
294
+ console.groupEnd()
295
+
292
296
  promise
293
297
 
294
298
  ###*
@@ -329,7 +333,7 @@ up.proxy = (($) ->
329
333
  # we wrap the mission in a function for scheduling below.
330
334
  emission = ->
331
335
  if busy() # a fast response might have beaten the delay
332
- up.emit('up:proxy:busy')
336
+ up.emit('up:proxy:busy', message: 'Proxy is busy')
333
337
  busyEventEmitted = true
334
338
  if config.busyDelay > 0
335
339
  busyDelayTimer = setTimeout(emission, config.busyDelay)
@@ -358,7 +362,7 @@ up.proxy = (($) ->
358
362
  loadEnded = ->
359
363
  pendingCount -= 1
360
364
  if idle() && busyEventEmitted
361
- up.emit('up:proxy:idle')
365
+ up.emit('up:proxy:idle', message: 'Proxy is idle')
362
366
  busyEventEmitted = false
363
367
 
364
368
  ###*
@@ -376,7 +380,7 @@ up.proxy = (($) ->
376
380
  queue(request)
377
381
 
378
382
  queue = (request) ->
379
- u.debug('Queuing URL %o', request.url)
383
+ up.puts('Queuing request for %s %s', request.method, request.url)
380
384
  deferred = $.Deferred()
381
385
  entry =
382
386
  deferred: deferred
@@ -385,8 +389,7 @@ up.proxy = (($) ->
385
389
  deferred.promise()
386
390
 
387
391
  load = (request) ->
388
- u.debug('Fetching %o via %o', request.url, request.method)
389
- up.emit('up:proxy:load', request)
392
+ up.emit('up:proxy:load', u.merge(request, message: ['Loading %s %s', request.method, request.url]))
390
393
 
391
394
  # We will modify the request below for features like method wrapping.
392
395
  # Let's not change the original request which would confuse API clients
@@ -404,11 +407,14 @@ up.proxy = (($) ->
404
407
  request.method = 'POST'
405
408
 
406
409
  promise = $.ajax(request)
407
- promise.always ->
408
- up.emit('up:proxy:received', request)
409
- pokeQueue()
410
+ promise.done (data, textStatus, xhr) -> responseReceived(request, xhr)
411
+ promise.fail (xhr, textStatus, errorThrown) -> responseReceived(request, xhr)
410
412
  promise
411
413
 
414
+ responseReceived = (request, xhr) ->
415
+ up.emit('up:proxy:received', u.merge(request, message: ['Server responded with %s %s (%d bytes)', xhr.status, xhr.statusText, xhr.responseText?.length]))
416
+ pokeQueue()
417
+
412
418
  pokeQueue = ->
413
419
  if entry = queuedRequests.shift()
414
420
  promise = load(entry.request)
@@ -468,11 +474,11 @@ up.proxy = (($) ->
468
474
 
469
475
  method = up.link.followMethod($link, options)
470
476
  if isIdempotent(method: method)
471
- u.debug("Preloading %o", $link)
472
- options.preload = true
473
- up.follow($link, options)
477
+ up.log.group "Preloading link %o", $link, ->
478
+ options.preload = true
479
+ up.follow($link, options)
474
480
  else
475
- u.debug("Won't preload %o due to unsafe method %o", $link, method)
481
+ up.puts("Won't preload %o due to unsafe method %s", $link, method)
476
482
  u.resolvedPromise()
477
483
 
478
484
  ###*
@@ -195,7 +195,6 @@ up.syntax = (($) ->
195
195
  @stable
196
196
  ###
197
197
  compilers = []
198
- defaultCompilers = null
199
198
 
200
199
  compiler = (selector, args...) ->
201
200
  # Silently discard any compilers that are registered on unsupported browsers
@@ -208,21 +207,22 @@ up.syntax = (($) ->
208
207
  batch: options.batch
209
208
 
210
209
  applyCompiler = (compiler, $jqueryElement, nativeElement) ->
211
- u.debug "Applying compiler %o on %o", compiler.selector, nativeElement
210
+ up.puts ("Compiling '%s' on %o" unless compiler.isDefault), compiler.selector, nativeElement
212
211
  destroyer = compiler.callback.apply(nativeElement, [$jqueryElement, data($jqueryElement)])
213
212
  if u.isFunction(destroyer)
214
213
  $jqueryElement.addClass(DESTROYABLE_CLASS)
215
214
  $jqueryElement.data(DESTROYER_KEY, destroyer)
216
215
 
217
216
  compile = ($fragment) ->
218
- u.debug "Compiling fragment %o", $fragment
219
- for compiler in compilers
220
- $matches = u.findWithSelf($fragment, compiler.selector)
221
- if $matches.length
222
- if compiler.batch
223
- applyCompiler(compiler, $matches, $matches.get())
224
- else
225
- $matches.each -> applyCompiler(compiler, $(this), this)
217
+ up.log.group "Compiling fragment %o", $fragment.get(0), ->
218
+ for compiler in compilers
219
+ $matches = u.findWithSelf($fragment, compiler.selector)
220
+ if $matches.length
221
+ up.log.group ("Compiling '%s' on %d element(s)" unless compiler.isDefault), compiler.selector, $matches.length, ->
222
+ if compiler.batch
223
+ applyCompiler(compiler, $matches, $matches.get())
224
+ else
225
+ $matches.each -> applyCompiler(compiler, $(this), this)
226
226
 
227
227
  runDestroyers = ($fragment) ->
228
228
  u.findWithSelf($fragment, ".#{DESTROYABLE_CLASS}").each ->
@@ -274,7 +274,8 @@ up.syntax = (($) ->
274
274
  @internal
275
275
  ###
276
276
  snapshot = ->
277
- defaultCompilers = u.copy(compilers)
277
+ for compiler in compilers
278
+ compiler.isDefault = true
278
279
 
279
280
  ###*
280
281
  Resets the list of registered compiler directives to the
@@ -283,7 +284,7 @@ up.syntax = (($) ->
283
284
  @internal
284
285
  ###
285
286
  reset = ->
286
- compilers = u.copy(defaultCompilers)
287
+ compilers = u.select compilers, (compiler) -> compiler.isDefault
287
288
 
288
289
  ###*
289
290
  Compiles a page fragment that has been inserted into the DOM
@@ -311,7 +312,9 @@ up.syntax = (($) ->
311
312
  ###
312
313
  hello = (selectorOrElement, options) ->
313
314
  $element = $(selectorOrElement)
314
- eventAttrs = u.options(options, $element: $element)
315
+ eventAttrs = u.options options,
316
+ $element: $element
317
+ message: ['Inserted fragment %o', $element.get(0)]
315
318
  up.emit('up:fragment:inserted', eventAttrs)
316
319
  $element
317
320
 
@@ -65,7 +65,7 @@ up.tooltip = (($) ->
65
65
  left: linkBox.left + 0.5 * (linkBox.width - tooltipBox.width)
66
66
  top: linkBox.top + linkBox.height
67
67
  else
68
- u.error("Unknown position %o", position)
68
+ u.error("Unknown position option '%s'", position)
69
69
  $tooltip.attr('up-position', position)
70
70
  $tooltip.css(css)
71
71
 
@@ -135,77 +135,13 @@ up.util = (($) ->
135
135
  element
136
136
 
137
137
  ###*
138
- Prints a debugging message to the browser console.
139
-
140
- @function up.debug
141
- @param {String} message
142
- @param {Array} args...
143
- @internal
144
- ###
145
- debug = (message, args...) ->
146
- message = "[UP] #{message}"
147
- up.browser.puts('debug', message, args...)
148
-
149
- ###*
150
- @function up.warn
151
- @internal
152
- ###
153
- warn = (message, args...) ->
154
- message = "[UP] #{message}"
155
- up.browser.puts('warn', message, args...)
156
-
157
- ###*
158
- Throws a fatal error with the given message.
159
-
160
- - The error will be printed to the [error console](https://developer.mozilla.org/en-US/docs/Web/API/Console/error)
161
- - An [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) (exception) will be thrown, unwinding the current call stack
162
- - The error message will be printed in a corner of the screen
163
-
164
- \#\#\#\# Examples
165
-
166
- up.error('Division by zero')
167
- up.error('Unexpected result %o', result)
168
-
169
- @function up.error
170
- @internal
138
+ @function $create
171
139
  ###
172
- error = (args...) ->
173
- args[0] = "[UP] #{args[0]}"
174
- up.browser.puts('error', args...)
175
- asString = evalConsoleTemplate(args...)
176
- $error = presence($('.up-error')) || $('<div class="up-error"></div>').prependTo('body')
177
- $error.addClass('up-error')
178
- $error.text(asString)
179
- throw new Error(asString)
180
-
181
- CONSOLE_PLACEHOLDERS = /\%[odisf]/g
182
-
183
- evalConsoleTemplate = (args...) ->
184
- message = args[0]
185
- i = 0
186
- maxLength = 80
187
- message.replace CONSOLE_PLACEHOLDERS, ->
188
- i += 1
189
- arg = args[i]
190
- argType = (typeof arg)
191
- if argType == 'string'
192
- arg = arg.replace(/\s+/g, ' ')
193
- arg = "#{arg.substr(0, maxLength)}…" if arg.length > maxLength
194
- arg = "\"#{arg}\""
195
- else if argType == 'undefined'
196
- # JSON.stringify(undefined) is actually undefined
197
- arg = 'undefined'
198
- else if argType == 'number' || argType == 'function'
199
- arg = arg.toString()
200
- else
201
- arg = JSON.stringify(arg)
202
- if arg.length > maxLength
203
- arg = "#{arg.substr(0, maxLength)} …"
204
- # For truncated objects or functions, add a trailing brace so
205
- # long log lines are easier to parse visually
206
- if argType == 'object' || argType == 'function'
207
- arg += " }"
208
- arg
140
+ $createPlaceholder = (selector, container = document.body) ->
141
+ $placeholder = $createElementFromSelector(selector)
142
+ $placeholder.addClass('up-placeholder')
143
+ $placeholder.appendTo(container)
144
+ $placeholder
209
145
 
210
146
  ###*
211
147
  Returns a CSS selector that matches the given element as good as possible.
@@ -227,7 +163,7 @@ up.util = (($) ->
227
163
  $element = $(element)
228
164
  selector = undefined
229
165
 
230
- debug("Creating selector from element %o", $element.get(0))
166
+ # up.puts("Creating selector from element %o", $element.get(0))
231
167
 
232
168
  if upId = presence($element.attr("up-id"))
233
169
  selector = "[up-id='#{upId}']"
@@ -1336,7 +1272,7 @@ up.util = (($) ->
1336
1272
  log = (args...) ->
1337
1273
  if config.log
1338
1274
  args[0] = "[#{config.log}] #{args[0]}"
1339
- debug(args...)
1275
+ up.puts(args...)
1340
1276
 
1341
1277
  keys = ->
1342
1278
  Object.keys(store)
@@ -1382,7 +1318,7 @@ up.util = (($) ->
1382
1318
  delete store[oldestKey] if oldestKey
1383
1319
 
1384
1320
  alias = (oldKey, newKey) ->
1385
- value = get(oldKey)
1321
+ value = get(oldKey, silent: true)
1386
1322
  if isDefined(value)
1387
1323
  set(newKey, value)
1388
1324
 
@@ -1407,19 +1343,19 @@ up.util = (($) ->
1407
1343
  else
1408
1344
  true
1409
1345
 
1410
- get = (key, fallback = undefined) ->
1346
+ get = (key, options = {}) ->
1411
1347
  storeKey = normalizeStoreKey(key)
1412
1348
  if entry = store[storeKey]
1413
1349
  if isFresh(entry)
1414
- log("Cache hit for %o", key)
1350
+ log("Cache hit for '%s'", key) unless options.silent
1415
1351
  entry.value
1416
1352
  else
1417
- log("Discarding stale cache entry for %o", key)
1353
+ log("Discarding stale cache entry for '%s'", key) unless options.silent
1418
1354
  remove(key)
1419
- fallback
1355
+ undefined
1420
1356
  else
1421
- log("Cache miss for %o", key)
1422
- fallback
1357
+ log("Cache miss for '%s'", key) unless options.silent
1358
+ undefined
1423
1359
 
1424
1360
  alias: alias
1425
1361
  get: get
@@ -1526,6 +1462,28 @@ up.util = (($) ->
1526
1462
  query += encodeURIComponent(field.name) + '=' + encodeURIComponent(field.value)
1527
1463
  query
1528
1464
 
1465
+ ###*
1466
+ Throws a fatal error with the given message.
1467
+
1468
+ - The error will be printed to the [error console](https://developer.mozilla.org/en-US/docs/Web/API/Console/error)
1469
+ - An [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) (exception) will be thrown, unwinding the current call stack
1470
+ - The error message will be printed in a corner of the screen
1471
+
1472
+ \#\#\#\# Examples
1473
+
1474
+ up.error('Division by zero')
1475
+ up.error('Unexpected result %o', result)
1476
+
1477
+ @experimental
1478
+ ###
1479
+ error = (args...) ->
1480
+ up.log.error(args...)
1481
+ asString = up.browser.sprintf(args...)
1482
+ $error = presence($('.up-error')) || $('<div class="up-error"></div>').prependTo('body')
1483
+ $error.addClass('up-error')
1484
+ $error.text(asString)
1485
+ throw new Error(asString)
1486
+
1529
1487
  requestDataAsArray: requestDataAsArray
1530
1488
  requestDataAsQueryString: requestDataAsQueryString
1531
1489
  offsetParent: offsetParent
@@ -1537,6 +1495,7 @@ up.util = (($) ->
1537
1495
  normalizeMethod: normalizeMethod
1538
1496
  createElementFromHtml: createElementFromHtml
1539
1497
  $createElementFromSelector: $createElementFromSelector
1498
+ $createPlaceholder: $createPlaceholder
1540
1499
  selectorForElement: selectorForElement
1541
1500
  extend: extend
1542
1501
  copy: copy
@@ -1544,8 +1503,6 @@ up.util = (($) ->
1544
1503
  options: options
1545
1504
  option: option
1546
1505
  error: error
1547
- debug: debug
1548
- warn: warn
1549
1506
  each: each
1550
1507
  map: map
1551
1508
  times: times
@@ -1612,10 +1569,8 @@ up.util = (($) ->
1612
1569
  cache: cache
1613
1570
  unwrapElement: unwrapElement
1614
1571
  multiSelector: multiSelector
1615
- evalConsoleTemplate: evalConsoleTemplate
1572
+ error: error
1616
1573
 
1617
1574
  )($)
1618
1575
 
1619
1576
  up.error = up.util.error
1620
- up.warn = up.util.warn
1621
- up.debug = up.util.debug
@@ -4,6 +4,6 @@ module Upjs
4
4
  # The current version of the upjs-rails gem.
5
5
  # This version number is also used for releases of the Up.js
6
6
  # frontend code.
7
- VERSION = '0.18.0'
7
+ VERSION = '0.18.1'
8
8
  end
9
9
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- upjs-rails (0.17.0)
4
+ upjs-rails (0.18.0)
5
5
  rails (>= 3)
6
6
 
7
7
  GEM
@@ -210,3 +210,6 @@ DEPENDENCIES
210
210
  uglifier (>= 1.3.0)
211
211
  upjs-rails!
212
212
  web-console (~> 2.0)
213
+
214
+ BUNDLED WITH
215
+ 1.11.2
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upjs-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.18.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henning Koch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-09 00:00:00.000000000 Z
11
+ date: 2016-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -102,6 +102,7 @@ files:
102
102
  - lib/assets/javascripts/up/history.js.coffee
103
103
  - lib/assets/javascripts/up/layout.js.coffee
104
104
  - lib/assets/javascripts/up/link.js.coffee
105
+ - lib/assets/javascripts/up/log.js.coffee
105
106
  - lib/assets/javascripts/up/modal.js.coffee
106
107
  - lib/assets/javascripts/up/module.js.coffee
107
108
  - lib/assets/javascripts/up/motion.js.coffee