upjs-rails 0.9.1 → 0.10.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +142 -0
- data/README.md +4 -1
- data/design/ghost-debugging.txt +118 -0
- data/design/homepage.txt +236 -0
- data/dist/up-bootstrap.js +7 -3
- data/dist/up-bootstrap.min.js +1 -1
- data/dist/up.js +1611 -1222
- data/dist/up.min.js +2 -2
- data/lib/assets/javascripts/up/bus.js.coffee +1 -1
- data/lib/assets/javascripts/up/flow.js.coffee +21 -20
- data/lib/assets/javascripts/up/form.js.coffee +11 -12
- data/lib/assets/javascripts/up/history.js.coffee +137 -20
- data/lib/assets/javascripts/up/layout.js.coffee +134 -21
- data/lib/assets/javascripts/up/link.js.coffee +40 -17
- data/lib/assets/javascripts/up/modal.js.coffee +2 -2
- data/lib/assets/javascripts/up/motion.js.coffee +3 -1
- data/lib/assets/javascripts/up/navigation.js.coffee +5 -5
- data/lib/assets/javascripts/up/popup.js.coffee +2 -2
- data/lib/assets/javascripts/up/proxy.js.coffee +43 -82
- data/lib/assets/javascripts/up/tooltip.js.coffee +1 -1
- data/lib/assets/javascripts/up/util.js.coffee +145 -14
- data/lib/assets/javascripts/up-bootstrap/layout-ext.js.coffee +2 -2
- data/lib/assets/javascripts/up-bootstrap/navigation-ext.js.coffee +3 -1
- data/lib/assets/javascripts/up.js.coffee +2 -2
- data/lib/upjs/rails/version.rb +1 -1
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/config/routes.rb +1 -2
- data/spec_app/spec/javascripts/helpers/knife.js.coffee +1 -1
- data/spec_app/spec/javascripts/helpers/last_request.js.coffee +4 -0
- data/spec_app/spec/javascripts/helpers/set_timer.js.coffee +3 -3
- data/spec_app/spec/javascripts/helpers/to_end_with.js.coffee +5 -0
- data/spec_app/spec/javascripts/up/flow_spec.js.coffee +8 -6
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/history_spec.js.coffee +80 -1
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +64 -4
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +2 -2
- data/spec_app/spec/javascripts/up/motion_spec.js.coffee +7 -7
- data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +6 -6
- data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +2 -2
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +22 -4
- metadata +7 -2
@@ -11,26 +11,44 @@ up.layout = (->
|
|
11
11
|
u = up.util
|
12
12
|
|
13
13
|
###*
|
14
|
-
|
14
|
+
Configures the application layout.
|
15
15
|
|
16
16
|
@method up.layout.defaults
|
17
|
-
@param {String} [options.
|
18
|
-
|
19
|
-
|
17
|
+
@param {Array<String>} [options.viewports]
|
18
|
+
An array of CSS selectors that find viewports
|
19
|
+
(containers that scroll their contents).
|
20
|
+
@param {Array<String>} [options.fixedTop]
|
21
|
+
An array of CSS selectors that find elements fixed to the
|
22
|
+
top edge of the screen (using `position: fixed`).
|
23
|
+
@param {Array<String>} [options.fixedBottom]
|
24
|
+
An array of CSS selectors that find elements fixed to the
|
25
|
+
bottom edge of the screen (using `position: fixed`).
|
20
26
|
@param {Number} [options.duration]
|
27
|
+
The duration of the scrolling animation in milliseconds.
|
28
|
+
Setting this to `0` will disable scrolling animations.
|
21
29
|
@param {String} [options.easing]
|
30
|
+
The timing function that controls the animation's acceleration.
|
31
|
+
See [W3C documentation](http://www.w3.org/TR/css3-transitions/#transition-timing-function)
|
32
|
+
for a list of pre-defined timing functions.
|
22
33
|
@param {Number} [options.snap]
|
34
|
+
When [revealing](#up.reveal) elements, Up.js will scroll an viewport
|
35
|
+
to the top when the revealed element is closer to the top than `options.snap`.
|
23
36
|
###
|
24
37
|
config = u.config
|
25
38
|
duration: 0
|
26
|
-
|
27
|
-
fixedTop: '[up-fixed~=top]'
|
28
|
-
fixedBottom: '[up-fixed~=bottom]'
|
39
|
+
viewports: ['body', '.up-modal', '[up-viewport]']
|
40
|
+
fixedTop: ['[up-fixed~=top]']
|
41
|
+
fixedBottom: ['[up-fixed~=bottom]']
|
29
42
|
snap: 50
|
30
43
|
easing: 'swing'
|
31
44
|
|
45
|
+
lastScrollTops = u.cache
|
46
|
+
size: 30,
|
47
|
+
key: up.history.normalizeUrl
|
48
|
+
|
32
49
|
reset = ->
|
33
50
|
config.reset()
|
51
|
+
lastScrollTops.clear()
|
34
52
|
|
35
53
|
SCROLL_PROMISE_KEY = 'up-scroll-promise'
|
36
54
|
|
@@ -73,35 +91,35 @@ up.layout = (->
|
|
73
91
|
A promise that will be resolved when the scrolling ends.
|
74
92
|
###
|
75
93
|
scroll = (viewport, scrollTop, options) ->
|
76
|
-
$
|
94
|
+
$viewport = $(viewport)
|
77
95
|
options = u.options(options)
|
78
96
|
duration = u.option(options.duration, config.duration)
|
79
97
|
easing = u.option(options.easing, config.easing)
|
80
98
|
|
81
|
-
finishScrolling($
|
99
|
+
finishScrolling($viewport)
|
82
100
|
|
83
101
|
if duration > 0
|
84
102
|
deferred = $.Deferred()
|
85
103
|
|
86
|
-
$
|
104
|
+
$viewport.data(SCROLL_PROMISE_KEY, deferred)
|
87
105
|
deferred.then ->
|
88
|
-
$
|
106
|
+
$viewport.removeData(SCROLL_PROMISE_KEY)
|
89
107
|
# Since we're scrolling using #animate, #finish can be
|
90
108
|
# used to jump to the last frame:
|
91
109
|
# https://api.jquery.com/finish/
|
92
|
-
$
|
110
|
+
$viewport.finish()
|
93
111
|
|
94
112
|
targetProps =
|
95
113
|
scrollTop: scrollTop
|
96
114
|
|
97
|
-
$
|
115
|
+
$viewport.animate targetProps,
|
98
116
|
duration: duration,
|
99
117
|
easing: easing,
|
100
118
|
complete: -> deferred.resolve()
|
101
119
|
|
102
120
|
deferred
|
103
121
|
else
|
104
|
-
$
|
122
|
+
$viewport.scrollTop(scrollTop)
|
105
123
|
u.resolvedDeferred()
|
106
124
|
|
107
125
|
###*
|
@@ -122,10 +140,10 @@ up.layout = (->
|
|
122
140
|
u.error("Fixed element %o must have a CSS attribute %o", $obstructor, cssAttr)
|
123
141
|
parseInt(anchorPosition) + $obstructor.height()
|
124
142
|
|
125
|
-
fixedTopBottoms = for obstructor in $(config.fixedTop)
|
143
|
+
fixedTopBottoms = for obstructor in $(config.fixedTop.join(', '))
|
126
144
|
measurePosition(obstructor, 'top')
|
127
145
|
|
128
|
-
fixedBottomTops = for obstructor in $(config.fixedBottom)
|
146
|
+
fixedBottomTops = for obstructor in $(config.fixedBottom.join(', '))
|
129
147
|
measurePosition(obstructor, 'bottom')
|
130
148
|
|
131
149
|
top: Math.max(0, fixedTopBottoms...)
|
@@ -171,7 +189,7 @@ up.layout = (->
|
|
171
189
|
reveal = (elementOrSelector, options) ->
|
172
190
|
options = u.options(options)
|
173
191
|
$element = $(elementOrSelector)
|
174
|
-
$viewport =
|
192
|
+
$viewport = viewportOf($element, options.viewport)
|
175
193
|
|
176
194
|
snap = u.option(options.snap, config.snap)
|
177
195
|
|
@@ -220,23 +238,112 @@ up.layout = (->
|
|
220
238
|
else
|
221
239
|
u.resolvedDeferred()
|
222
240
|
|
241
|
+
viewportSelector = ->
|
242
|
+
config.viewports.join(', ')
|
243
|
+
|
223
244
|
###*
|
224
|
-
|
225
|
-
|
245
|
+
Returns the viewport for the given element.
|
246
|
+
|
247
|
+
Throws an error if no viewport could be found.
|
248
|
+
|
249
|
+
@protected
|
250
|
+
@method up.layout.viewportOf
|
251
|
+
@param {String|Element|jQuery} selectorOrElement
|
226
252
|
###
|
227
|
-
|
253
|
+
viewportOf = (selectorOrElement, viewportSelectorOrElement) ->
|
254
|
+
$element = $(selectorOrElement)
|
228
255
|
$viewport = undefined
|
229
256
|
# If someone has handed as a jQuery element, that's the
|
230
257
|
# view period.
|
231
258
|
if u.isJQuery(viewportSelectorOrElement)
|
232
259
|
$viewport = viewportSelectorOrElement
|
233
260
|
else
|
234
|
-
vieportSelector = u.presence(viewportSelectorOrElement) ||
|
261
|
+
vieportSelector = u.presence(viewportSelectorOrElement) || viewportSelector()
|
235
262
|
$viewport = $element.closest(vieportSelector)
|
236
263
|
|
237
264
|
$viewport.length or u.error("Could not find viewport for %o", $element)
|
238
265
|
$viewport
|
239
266
|
|
267
|
+
###*
|
268
|
+
Returns a jQuery collection of all the viewports contained within the
|
269
|
+
given selector or element.
|
270
|
+
|
271
|
+
@protected
|
272
|
+
@method up.layout.viewportsIn
|
273
|
+
@param {String|Element|jQuery} selectorOrElement
|
274
|
+
@return jQuery
|
275
|
+
###
|
276
|
+
viewportsIn = (selectorOrElement) ->
|
277
|
+
$element = $(selectorOrElement)
|
278
|
+
u.findWithSelf($element, viewportSelector())
|
279
|
+
|
280
|
+
###*
|
281
|
+
Returns a jQuery collection of all the viewports on the screen.
|
282
|
+
|
283
|
+
@protected
|
284
|
+
@method up.layout.viewports
|
285
|
+
###
|
286
|
+
viewports = ->
|
287
|
+
$(viewportSelector())
|
288
|
+
|
289
|
+
###*
|
290
|
+
Returns a hash with scroll positions.
|
291
|
+
|
292
|
+
Each key in the hash is a viewport selector. The corresponding
|
293
|
+
value is the viewport's top scroll position:
|
294
|
+
|
295
|
+
up.layout.scrollTops()
|
296
|
+
=> { '.main': 0, '.sidebar': 73 }
|
297
|
+
|
298
|
+
@protected
|
299
|
+
@method up.layout.scrollTops
|
300
|
+
@return Object<String, Number>
|
301
|
+
###
|
302
|
+
scrollTops = ->
|
303
|
+
topsBySelector = {}
|
304
|
+
for viewport in config.viewports
|
305
|
+
$viewport = $(viewport)
|
306
|
+
if $viewport.length
|
307
|
+
topsBySelector[viewport] = $viewport.scrollTop()
|
308
|
+
topsBySelector
|
309
|
+
|
310
|
+
###*
|
311
|
+
Saves the top scroll positions of all the
|
312
|
+
viewports configured in `up.layout.defaults('viewports').
|
313
|
+
The saved scroll positions can be restored by calling
|
314
|
+
[`up.layout.restoreScroll()`](#up.layout.restoreScroll).
|
315
|
+
|
316
|
+
@method up.layout.saveScroll
|
317
|
+
@param {String} [options.url]
|
318
|
+
@param {Object<String, Number>} [options.tops]
|
319
|
+
@protected
|
320
|
+
###
|
321
|
+
saveScroll = (options = {}) ->
|
322
|
+
url = u.option(options.url, up.history.url())
|
323
|
+
tops = u.option(options.tops, scrollTops())
|
324
|
+
lastScrollTops.set(url, tops)
|
325
|
+
|
326
|
+
###*
|
327
|
+
Restores the top scroll positions of all the
|
328
|
+
viewports configured in `up.layout.defaults('viewports')`.
|
329
|
+
|
330
|
+
@method up.layout.restoreScroll
|
331
|
+
@param {String} [options.within]
|
332
|
+
@protected
|
333
|
+
###
|
334
|
+
restoreScroll = (options = {}) ->
|
335
|
+
|
336
|
+
$viewports = if options.within
|
337
|
+
viewportsIn(options.within)
|
338
|
+
else
|
339
|
+
viewports()
|
340
|
+
|
341
|
+
tops = lastScrollTops.get(up.history.url())
|
342
|
+
|
343
|
+
for selector, scrollTop of tops
|
344
|
+
$matchingViewport = $viewports.filter(selector)
|
345
|
+
up.scroll($matchingViewport, scrollTop, duration: 0)
|
346
|
+
|
240
347
|
###*
|
241
348
|
Marks this element as a scrolling container. Apply this ttribute if your app uses
|
242
349
|
a custom panel layout with fixed positioning instead of scrolling `<body>`.
|
@@ -323,6 +430,12 @@ up.layout = (->
|
|
323
430
|
scroll: scroll
|
324
431
|
finishScrolling: finishScrolling
|
325
432
|
defaults: config.update
|
433
|
+
viewportOf: viewportOf
|
434
|
+
viewportsIn: viewportsIn
|
435
|
+
viewports: viewports
|
436
|
+
scrollTops: scrollTops
|
437
|
+
saveScroll: saveScroll
|
438
|
+
restoreScroll: restoreScroll
|
326
439
|
|
327
440
|
)()
|
328
441
|
|
@@ -132,9 +132,8 @@ up.link = (->
|
|
132
132
|
or to `body` if such an attribute does not exist.
|
133
133
|
@param {Function|String} [options.transition]
|
134
134
|
A transition function or name.
|
135
|
-
@param {Element|jQuery|String} [options.
|
136
|
-
|
137
|
-
case the replaced element is not visible in the viewport.
|
135
|
+
@param {Element|jQuery|String} [options.reveal]
|
136
|
+
Whether to reveal the followed element within its viewport.
|
138
137
|
@param {Number} [options.duration]
|
139
138
|
The duration of the transition. See [`up.morph`](/up.motion#up.morph).
|
140
139
|
@param {Number} [options.delay]
|
@@ -148,10 +147,11 @@ up.link = (->
|
|
148
147
|
options = u.options(options)
|
149
148
|
url = u.option($link.attr('up-href'), $link.attr('href'))
|
150
149
|
selector = u.option(options.target, $link.attr('up-target'), 'body')
|
151
|
-
options.transition = u.option(options.transition, $link
|
152
|
-
options.history = u.option(options.history, $link
|
153
|
-
options.
|
154
|
-
options.cache = u.option(options.cache, $link
|
150
|
+
options.transition = u.option(options.transition, u.castedAttr($link, 'up-transition'), u.castedAttr($link, 'up-animation'))
|
151
|
+
options.history = u.option(options.history, u.castedAttr($link, 'up-history'))
|
152
|
+
options.reveal = u.option(options.reveal, u.castedAttr($link, 'up-reveal'))
|
153
|
+
options.cache = u.option(options.cache, u.castedAttr($link, 'up-cache'))
|
154
|
+
options.restoreScroll = u.option(options.restoreScroll, u.castedAttr($link, 'up-restore-scroll'))
|
155
155
|
options.method = followMethod($link, options)
|
156
156
|
options = u.merge(options, up.motion.animateOptions(options, $link))
|
157
157
|
|
@@ -219,6 +219,9 @@ up.link = (->
|
|
219
219
|
@param [up-href]
|
220
220
|
The destination URL to follow.
|
221
221
|
If omitted, the the link's `href` attribute will be used.
|
222
|
+
@param [up-restore-scroll='false']
|
223
|
+
Whether to restore the scroll position of all viewports
|
224
|
+
within the target selector.
|
222
225
|
###
|
223
226
|
up.on 'click', 'a[up-target], [up-href][up-target]', (event, $link) ->
|
224
227
|
if shouldProcessLinkEvent(event, $link)
|
@@ -265,7 +268,21 @@ up.link = (->
|
|
265
268
|
|
266
269
|
shouldProcessLinkEvent = (event, $link) ->
|
267
270
|
u.isUnmodifiedMouseEvent(event) && !childClicked(event, $link)
|
268
|
-
|
271
|
+
|
272
|
+
###*
|
273
|
+
Makes sure that the given link is handled by Up.js.
|
274
|
+
|
275
|
+
This is done by giving the link an `up-follow` attribute
|
276
|
+
if it doesn't already have it an `up-target` or `up-follow` attribute.
|
277
|
+
|
278
|
+
@method up.link.makeFollowable
|
279
|
+
@protected
|
280
|
+
###
|
281
|
+
makeFollowable = (link) ->
|
282
|
+
$link = $(link)
|
283
|
+
if u.isMissing($link.attr('up-target')) && u.isMissing($link.attr('up-follow'))
|
284
|
+
$link.attr('up-follow', '')
|
285
|
+
|
269
286
|
###*
|
270
287
|
If applied on a link, Follows this link via AJAX and replaces the
|
271
288
|
current `<body>` element with the response's `<body>` element.
|
@@ -292,6 +309,9 @@ up.link = (->
|
|
292
309
|
@param [up-href]
|
293
310
|
The destination URL to follow.
|
294
311
|
If omitted, the the link's `href` attribute will be used.
|
312
|
+
@param [up-restore-scroll='false']
|
313
|
+
Whether to restore the scroll position of all viewports
|
314
|
+
within the response.
|
295
315
|
###
|
296
316
|
up.on 'click', 'a[up-follow], [up-href][up-follow]', (event, $link) ->
|
297
317
|
if shouldProcessLinkEvent(event, $link)
|
@@ -321,9 +341,9 @@ up.link = (->
|
|
321
341
|
@ujs
|
322
342
|
@method [up-expand]
|
323
343
|
###
|
324
|
-
up.compiler '[up-expand]', ($
|
325
|
-
link = $
|
326
|
-
link or u.error('No link to expand within %o', $
|
344
|
+
up.compiler '[up-expand]', ($area) ->
|
345
|
+
link = $area.find('a, [up-href]').get(0)
|
346
|
+
link or u.error('No link to expand within %o', $area)
|
327
347
|
upAttributePattern = /^up-/
|
328
348
|
newAttrs = {}
|
329
349
|
newAttrs['up-href'] = $(link).attr('href')
|
@@ -331,10 +351,10 @@ up.link = (->
|
|
331
351
|
name = attribute.name
|
332
352
|
if name.match(upAttributePattern)
|
333
353
|
newAttrs[name] = attribute.value
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
354
|
+
u.setMissingAttrs($area, newAttrs)
|
355
|
+
$area.removeAttr('up-expand')
|
356
|
+
makeFollowable($area)
|
357
|
+
|
338
358
|
|
339
359
|
###*
|
340
360
|
Marks up the current link to be followed *as fast as possible*.
|
@@ -356,12 +376,14 @@ up.link = (->
|
|
356
376
|
@ujs
|
357
377
|
###
|
358
378
|
up.compiler '[up-dash]', ($element) ->
|
359
|
-
target = $element
|
379
|
+
target = u.castedAttr($element, 'up-dash')
|
360
380
|
newAttrs = {
|
361
381
|
'up-preload': 'true',
|
362
382
|
'up-instant': 'true'
|
363
383
|
}
|
364
|
-
if
|
384
|
+
if target is true
|
385
|
+
# If it's literally `true` then we don't have a target selector.
|
386
|
+
# Just follow the link by replacing `<body>`.
|
365
387
|
newAttrs['up-follow'] = ''
|
366
388
|
else
|
367
389
|
newAttrs['up-target'] = target
|
@@ -371,6 +393,7 @@ up.link = (->
|
|
371
393
|
knife: eval(Knife?.point)
|
372
394
|
visit: visit
|
373
395
|
follow: follow
|
396
|
+
makeFollowable: makeFollowable
|
374
397
|
childClicked: childClicked
|
375
398
|
followMethod: followMethod
|
376
399
|
|
@@ -207,8 +207,8 @@ up.modal = (->
|
|
207
207
|
maxWidth = u.option(options.maxWidth, $link.attr('up-max-width'), config.maxWidth)
|
208
208
|
height = u.option(options.height, $link.attr('up-height'), config.height)
|
209
209
|
animation = u.option(options.animation, $link.attr('up-animation'), config.openAnimation)
|
210
|
-
sticky = u.option(options.sticky, $link
|
211
|
-
history = if up.browser.canPushState() then u.option(options.history, $link
|
210
|
+
sticky = u.option(options.sticky, u.castedAttr($link, 'up-sticky'))
|
211
|
+
history = if up.browser.canPushState() then u.option(options.history, u.castedAttr($link, 'up-history'), true) else false
|
212
212
|
animateOptions = up.motion.animateOptions(options, $link)
|
213
213
|
|
214
214
|
close()
|
@@ -123,6 +123,8 @@ up.motion = (->
|
|
123
123
|
$element = $(elementOrSelector)
|
124
124
|
finish($element)
|
125
125
|
options = animateOptions(options)
|
126
|
+
if animation == 'none' || animation == false
|
127
|
+
none()
|
126
128
|
if u.isFunction(animation)
|
127
129
|
assertIsDeferred(animation($element, options), animation)
|
128
130
|
else if u.isString(animation)
|
@@ -260,7 +262,7 @@ up.motion = (->
|
|
260
262
|
$new = $(target)
|
261
263
|
finish($old)
|
262
264
|
finish($new)
|
263
|
-
if transitionOrName == 'none'
|
265
|
+
if transitionOrName == 'none' or transitionOrName == false
|
264
266
|
# don't create ghosts if we aren't really transitioning
|
265
267
|
none()
|
266
268
|
else if transition = u.presence(transitionOrName, u.isFunction) || transitions[transitionOrName]
|
@@ -23,16 +23,16 @@ up.navigation = (->
|
|
23
23
|
The class to set on [links that point the current location](#up-current).
|
24
24
|
###
|
25
25
|
config = u.config
|
26
|
-
|
26
|
+
currentClasses: ['up-current']
|
27
27
|
|
28
28
|
reset = ->
|
29
29
|
config.reset()
|
30
30
|
|
31
31
|
currentClass = ->
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
classes = config.currentClasses
|
33
|
+
classes = classes.concat(['up-current'])
|
34
|
+
classes = u.uniq(classes)
|
35
|
+
classes.join(' ')
|
36
36
|
|
37
37
|
CLASS_ACTIVE = 'up-active'
|
38
38
|
SELECTORS_SECTION = ['a', '[up-href]', '[up-alias]']
|
@@ -141,8 +141,8 @@ up.popup = (->
|
|
141
141
|
selector = u.option(options.target, $link.attr('up-popup'), 'body')
|
142
142
|
position = u.option(options.position, $link.attr('up-position'), config.position)
|
143
143
|
animation = u.option(options.animation, $link.attr('up-animation'), config.openAnimation)
|
144
|
-
sticky = u.option(options.sticky, $link
|
145
|
-
history = if up.browser.canPushState() then u.option(options.history, $link
|
144
|
+
sticky = u.option(options.sticky, u.castedAttr($link, 'up-sticky'))
|
145
|
+
history = if up.browser.canPushState() then u.option(options.history, u.castedAttr($link, 'up-history'), false) else false
|
146
146
|
animateOptions = up.motion.animateOptions(options, $link)
|
147
147
|
|
148
148
|
close()
|
@@ -53,7 +53,6 @@ up.proxy = (->
|
|
53
53
|
|
54
54
|
u = up.util
|
55
55
|
|
56
|
-
cache = undefined
|
57
56
|
$waitingLink = undefined
|
58
57
|
preloadDelayTimer = undefined
|
59
58
|
busyDelayTimer = undefined
|
@@ -81,6 +80,44 @@ up.proxy = (->
|
|
81
80
|
cacheSize: 70
|
82
81
|
cacheExpiry: 1000 * 60 * 5
|
83
82
|
|
83
|
+
cacheKey = (request) ->
|
84
|
+
normalizeRequest(request)
|
85
|
+
[ request.url,
|
86
|
+
request.method,
|
87
|
+
request.data,
|
88
|
+
request.selector
|
89
|
+
].join('|')
|
90
|
+
|
91
|
+
cache = u.cache
|
92
|
+
size: -> config.cacheSize
|
93
|
+
expiry: -> config.cacheExpiry
|
94
|
+
key: cacheKey
|
95
|
+
log: 'up.proxy'
|
96
|
+
|
97
|
+
###*
|
98
|
+
@protected
|
99
|
+
@method up.proxy.get
|
100
|
+
###
|
101
|
+
get = cache.get
|
102
|
+
|
103
|
+
###*
|
104
|
+
@protected
|
105
|
+
@method up.proxy.set
|
106
|
+
###
|
107
|
+
set = cache.set
|
108
|
+
|
109
|
+
###*
|
110
|
+
@protected
|
111
|
+
@method up.proxy.remove
|
112
|
+
###
|
113
|
+
remove = cache.remove
|
114
|
+
|
115
|
+
###*
|
116
|
+
@protected
|
117
|
+
@method up.proxy.clear
|
118
|
+
###
|
119
|
+
clear = cache.clear
|
120
|
+
|
84
121
|
cancelPreloadDelay = ->
|
85
122
|
clearTimeout(preloadDelayTimer)
|
86
123
|
preloadDelayTimer = null
|
@@ -90,40 +127,18 @@ up.proxy = (->
|
|
90
127
|
busyDelayTimer = null
|
91
128
|
|
92
129
|
reset = ->
|
93
|
-
cache = {}
|
94
130
|
$waitingLink = null
|
95
131
|
cancelPreloadDelay()
|
96
132
|
cancelBusyDelay()
|
97
133
|
pendingCount = 0
|
98
134
|
config.reset()
|
99
135
|
busyEventEmitted = false
|
136
|
+
cache.clear()
|
100
137
|
|
101
138
|
reset()
|
102
139
|
|
103
|
-
|
104
|
-
|
105
|
-
[ request.url,
|
106
|
-
request.method,
|
107
|
-
request.data,
|
108
|
-
request.selector
|
109
|
-
].join('|')
|
110
|
-
|
111
|
-
trim = ->
|
112
|
-
keys = u.keys(cache)
|
113
|
-
if keys.length > config.cacheSize
|
114
|
-
oldestKey = null
|
115
|
-
oldestTimestamp = null
|
116
|
-
u.each keys, (key) ->
|
117
|
-
promise = cache[key] # we don't need to call cacheKey here
|
118
|
-
timestamp = promise.timestamp
|
119
|
-
if !oldestTimestamp || oldestTimestamp > timestamp
|
120
|
-
oldestKey = key
|
121
|
-
oldestTimestamp = timestamp
|
122
|
-
delete cache[oldestKey] if oldestKey
|
123
|
-
|
124
|
-
timestamp = ->
|
125
|
-
(new Date()).valueOf()
|
126
|
-
|
140
|
+
alias = cache.alias
|
141
|
+
|
127
142
|
normalizeRequest = (request) ->
|
128
143
|
unless request._normalized
|
129
144
|
request.method = u.normalizeMethod(request.method)
|
@@ -131,11 +146,6 @@ up.proxy = (->
|
|
131
146
|
request.selector ||= 'body'
|
132
147
|
request._normalized = true
|
133
148
|
request
|
134
|
-
|
135
|
-
alias = (oldRequest, newRequest) ->
|
136
|
-
u.debug("Aliasing %o to %o", oldRequest, newRequest)
|
137
|
-
if promise = get(oldRequest)
|
138
|
-
set(newRequest, promise)
|
139
149
|
|
140
150
|
###*
|
141
151
|
Makes a request to the given URL and caches the response.
|
@@ -160,8 +170,8 @@ up.proxy = (->
|
|
160
170
|
If set to `false` a network connection will always be attempted.
|
161
171
|
###
|
162
172
|
ajax = (options) ->
|
163
|
-
forceCache =
|
164
|
-
ignoreCache =
|
173
|
+
forceCache = (options.cache == true)
|
174
|
+
ignoreCache = (options.cache == false)
|
165
175
|
|
166
176
|
request = u.only(options, 'url', 'method', 'data', 'selector', '_normalized')
|
167
177
|
|
@@ -254,55 +264,6 @@ up.proxy = (->
|
|
254
264
|
normalizeRequest(request)
|
255
265
|
u.contains(SAFE_HTTP_METHODS, request.method)
|
256
266
|
|
257
|
-
isFresh = (promise) ->
|
258
|
-
timeSinceTouch = timestamp() - promise.timestamp
|
259
|
-
timeSinceTouch < config.cacheExpiry
|
260
|
-
|
261
|
-
###*
|
262
|
-
@protected
|
263
|
-
@method up.proxy.get
|
264
|
-
###
|
265
|
-
get = (request) ->
|
266
|
-
key = cacheKey(request)
|
267
|
-
if promise = cache[key]
|
268
|
-
if !isFresh(promise)
|
269
|
-
u.debug("Discarding stale cache entry for %o (%o)", request.url, request)
|
270
|
-
remove(request)
|
271
|
-
undefined
|
272
|
-
else
|
273
|
-
u.debug("Cache hit for %o (%o)", request.url, request)
|
274
|
-
# $('body').css('background-color': 'green')
|
275
|
-
promise
|
276
|
-
else
|
277
|
-
u.debug("Cache miss for %o (%o)", request.url, request)
|
278
|
-
undefined
|
279
|
-
|
280
|
-
###*
|
281
|
-
@protected
|
282
|
-
@method up.proxy.set
|
283
|
-
###
|
284
|
-
set = (request, promise) ->
|
285
|
-
trim()
|
286
|
-
key = cacheKey(request)
|
287
|
-
promise.timestamp = timestamp()
|
288
|
-
cache[key] = promise
|
289
|
-
promise
|
290
|
-
|
291
|
-
###*
|
292
|
-
@protected
|
293
|
-
@method up.proxy.remove
|
294
|
-
###
|
295
|
-
remove = (request) ->
|
296
|
-
key = cacheKey(request)
|
297
|
-
delete cache[key]
|
298
|
-
|
299
|
-
###*
|
300
|
-
@protected
|
301
|
-
@method up.proxy.clear
|
302
|
-
###
|
303
|
-
clear = ->
|
304
|
-
cache = {}
|
305
|
-
|
306
267
|
checkPreload = ($link) ->
|
307
268
|
delay = parseInt(u.presentAttr($link, 'up-delay')) || config.preloadDelay
|
308
269
|
unless $link.is($waitingLink)
|
@@ -60,7 +60,7 @@ up.tooltip = (->
|
|
60
60
|
$link = $(linkOrSelector)
|
61
61
|
html = u.option(options.html, $link.attr('up-tooltip'), $link.attr('title'))
|
62
62
|
position = u.option(options.position, $link.attr('up-position'), 'top')
|
63
|
-
animation = u.option(options.animation, $link
|
63
|
+
animation = u.option(options.animation, u.castedAttr($link, 'up-animation'), 'fade-in')
|
64
64
|
animateOptions = up.motion.animateOptions(options, $link)
|
65
65
|
close()
|
66
66
|
$tooltip = createElement(html)
|