unpoly-rails 0.24.1 → 0.25.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/README_RAILS.md +8 -1
- data/dist/unpoly.css +22 -10
- data/dist/unpoly.js +406 -196
- data/dist/unpoly.min.css +1 -1
- data/dist/unpoly.min.js +3 -3
- data/lib/assets/javascripts/unpoly/flow.js.coffee +36 -19
- data/lib/assets/javascripts/unpoly/form.js.coffee +1 -2
- data/lib/assets/javascripts/unpoly/link.js.coffee +2 -2
- data/lib/assets/javascripts/unpoly/modal.js.coffee +174 -81
- data/lib/assets/javascripts/unpoly/navigation.js.coffee +3 -1
- data/lib/assets/javascripts/unpoly/popup.js.coffee +62 -37
- data/lib/assets/javascripts/unpoly/proxy.js.coffee +1 -0
- data/lib/assets/javascripts/unpoly/syntax.js.coffee +12 -4
- data/lib/assets/javascripts/unpoly/util.js.coffee +55 -13
- data/lib/assets/stylesheets/unpoly/modal.css.sass +28 -12
- data/lib/unpoly/rails/inspector.rb +26 -0
- data/lib/unpoly/rails/version.rb +1 -1
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/app/controllers/binding_test_controller.rb +6 -0
- data/spec_app/spec/controllers/binding_test_controller_spec.rb +82 -11
- data/spec_app/spec/javascripts/up/flow_spec.js.coffee +21 -7
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +15 -0
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +11 -10
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +232 -30
- data/spec_app/spec/javascripts/up/motion_spec.js.coffee +33 -27
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +72 -0
- data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +51 -13
- metadata +2 -2
@@ -840,6 +840,24 @@ up.util = (($) ->
|
|
840
840
|
$outer.remove()
|
841
841
|
width
|
842
842
|
|
843
|
+
###*
|
844
|
+
Returns whether the given element is currently showing a vertical scrollbar.
|
845
|
+
|
846
|
+
@function up.util.documentHasVerticalScrollbar
|
847
|
+
@internal
|
848
|
+
###
|
849
|
+
documentHasVerticalScrollbar = ->
|
850
|
+
body = document.body
|
851
|
+
$body = $(body)
|
852
|
+
html = document.documentElement
|
853
|
+
|
854
|
+
bodyOverflow = $body.css('overflow-y')
|
855
|
+
|
856
|
+
forcedScroll = (bodyOverflow == 'scroll')
|
857
|
+
forcedHidden = (bodyOverflow == 'hidden')
|
858
|
+
|
859
|
+
forcedScroll || (!forcedHidden && html.scrollHeight > html.clientHeight)
|
860
|
+
|
843
861
|
###*
|
844
862
|
Modifies the given function so it only runs once.
|
845
863
|
Subsequent calls will return the previous return value.
|
@@ -935,6 +953,9 @@ up.util = (($) ->
|
|
935
953
|
###
|
936
954
|
cssAnimate = (elementOrSelector, lastFrame, opts) ->
|
937
955
|
$element = $(elementOrSelector)
|
956
|
+
|
957
|
+
# Don't name the local variable `options` since that would override
|
958
|
+
# the `options` function in our scope. We really need `let` :(
|
938
959
|
opts = options(opts,
|
939
960
|
duration: 300,
|
940
961
|
delay: 0,
|
@@ -944,14 +965,32 @@ up.util = (($) ->
|
|
944
965
|
# We don't finish an existing animation here, since the public API
|
945
966
|
# we expose as `up.motion.animate` already does this.
|
946
967
|
deferred = $.Deferred()
|
968
|
+
|
969
|
+
transitionProperties = Object.keys(lastFrame)
|
947
970
|
transition =
|
948
|
-
'transition-property':
|
971
|
+
'transition-property': transitionProperties.join(', ')
|
949
972
|
'transition-duration': "#{opts.duration}ms"
|
950
973
|
'transition-delay': "#{opts.delay}ms"
|
951
974
|
'transition-timing-function': opts.easing
|
952
975
|
oldTransition = $element.css(Object.keys(transition))
|
953
976
|
|
954
977
|
$element.addClass('up-animating')
|
978
|
+
|
979
|
+
transitionFinished = ->
|
980
|
+
$element.removeClass('up-animating')
|
981
|
+
$element.off('transitionend', onTransitionEnd)
|
982
|
+
|
983
|
+
onTransitionEnd = (event) ->
|
984
|
+
completedProperty = event.originalEvent.propertyName
|
985
|
+
if contains(transitionProperties, completedProperty)
|
986
|
+
deferred.resolve() # unless isDetached($element)
|
987
|
+
transitionFinished()
|
988
|
+
|
989
|
+
$element.on('transitionend', onTransitionEnd)
|
990
|
+
|
991
|
+
# Clean up in case we're canceled through some other code that resolves our deferred.
|
992
|
+
deferred.then(transitionFinished)
|
993
|
+
|
955
994
|
withoutCompositing = forceCompositing($element)
|
956
995
|
$element.css(transition)
|
957
996
|
$element.css(lastFrame)
|
@@ -963,26 +1002,20 @@ up.util = (($) ->
|
|
963
1002
|
|
964
1003
|
# To interrupt the running transition we *must* set it to 'none' exactly.
|
965
1004
|
# We cannot simply restore the old transition properties because browsers
|
966
|
-
# would simply keep transitioning
|
1005
|
+
# would simply keep transitioning.
|
967
1006
|
$element.css('transition': 'none')
|
968
1007
|
|
969
|
-
# Restoring a previous transition involves
|
1008
|
+
# Restoring a previous transition involves forcing a repaint, so we only do it if
|
970
1009
|
# we know the element was transitioning before.
|
1010
|
+
# Note that the default transition for elements is actually "all 0s ease 0s"
|
1011
|
+
# instead of "none", although that has the same effect as "none".
|
971
1012
|
hadTransitionBefore = !(oldTransition['transition-property'] == 'none' || (oldTransition['transition-property'] == 'all' && oldTransition['transition-duration'][0] == '0'))
|
972
1013
|
if hadTransitionBefore
|
1014
|
+
# If there is no repaint between the "none" transition and restoring
|
1015
|
+
# the previous transition, the browser will simply keep transitioning.
|
973
1016
|
forceRepaint($element) # :(
|
974
1017
|
$element.css(oldTransition)
|
975
1018
|
|
976
|
-
# Since listening to transitionEnd events is painful, we wait for a timeout
|
977
|
-
# and then resolve our deferred. Maybe revisit that decision some day.
|
978
|
-
animationEnd = opts.duration + opts.delay
|
979
|
-
endTimeout = setTimer animationEnd, ->
|
980
|
-
$element.removeClass('up-animating')
|
981
|
-
deferred.resolve() unless isDetached($element)
|
982
|
-
# Clean up in case we're canceled through some other code that
|
983
|
-
# resolves our deferred.
|
984
|
-
deferred.then(-> clearTimeout(endTimeout))
|
985
|
-
|
986
1019
|
# Return the whole deferred and not just return a thenable.
|
987
1020
|
# Other code will need the possibility to cancel the animation
|
988
1021
|
# by resolving the deferred.
|
@@ -1652,6 +1685,13 @@ up.util = (($) ->
|
|
1652
1685
|
else
|
1653
1686
|
{}
|
1654
1687
|
|
1688
|
+
opacity = (element) ->
|
1689
|
+
rawOpacity = $(element).css('opacity')
|
1690
|
+
if isGiven(rawOpacity)
|
1691
|
+
parseFloat(rawOpacity)
|
1692
|
+
else
|
1693
|
+
undefined
|
1694
|
+
|
1655
1695
|
###*
|
1656
1696
|
Returns whether the given element has been detached from the DOM
|
1657
1697
|
(or whether it was never attached).
|
@@ -1752,6 +1792,7 @@ up.util = (($) ->
|
|
1752
1792
|
remove: remove
|
1753
1793
|
memoize: memoize
|
1754
1794
|
scrollbarWidth: scrollbarWidth
|
1795
|
+
documentHasVerticalScrollbar: documentHasVerticalScrollbar
|
1755
1796
|
config: config
|
1756
1797
|
cache: cache
|
1757
1798
|
unwrapElement: unwrapElement
|
@@ -1762,6 +1803,7 @@ up.util = (($) ->
|
|
1762
1803
|
extractOptions: extractOptions
|
1763
1804
|
isDetached: isDetached
|
1764
1805
|
noop: noop
|
1806
|
+
opacity: opacity
|
1765
1807
|
|
1766
1808
|
)($)
|
1767
1809
|
|
@@ -1,48 +1,64 @@
|
|
1
|
-
$stratum
|
2
|
-
$stratum-elements: 11000
|
1
|
+
$stratum: 10000
|
3
2
|
|
4
|
-
// These could actually be 1000, 2000, 3000 and 4000 since the `fixed` position of
|
3
|
+
// These could actually be 1000, 2000, 3000 and 4000 since the `fixed` position of an element defines
|
5
4
|
// a stacking context for all contained z-indexes.
|
6
5
|
//
|
7
6
|
// However, let's keep the option open that these elements will one day not have its stacking context.
|
8
7
|
//
|
9
8
|
// Also let's not do 1, 2, 3 and 4 so other elements have a chance to move themselves between the layers.
|
10
|
-
$substratum-
|
11
|
-
$substratum-
|
12
|
-
$substratum-
|
9
|
+
$substratum-backdrop: 11000
|
10
|
+
$substratum-elements: 12000
|
11
|
+
$substratum-dialog: 13000
|
12
|
+
$substratum-content: 14000
|
13
|
+
$substratum-close: 15000
|
13
14
|
|
14
15
|
$close-height: 36px
|
15
16
|
$close-width: 36px
|
16
17
|
$close-font-size: 34px
|
17
18
|
|
18
19
|
.up-modal
|
20
|
+
position: fixed
|
21
|
+
top: 0
|
22
|
+
left: 0
|
23
|
+
bottom: 0
|
24
|
+
right: 0
|
25
|
+
z-index: $stratum
|
26
|
+
overflow-x: hidden
|
19
27
|
|
20
28
|
.up-modal-backdrop
|
21
|
-
z-index: $
|
29
|
+
z-index: $substratum-backdrop
|
22
30
|
background-color: rgba(90, 90, 90, 0.4)
|
23
|
-
position:
|
31
|
+
position: absolute
|
24
32
|
top: 0
|
25
33
|
right: 0
|
26
34
|
bottom: 0
|
27
35
|
left: 0
|
28
36
|
|
29
37
|
.up-modal-viewport
|
30
|
-
|
31
|
-
position: fixed
|
38
|
+
position: absolute
|
32
39
|
top: 0
|
33
40
|
left: 0
|
34
41
|
bottom: 0
|
35
42
|
right: 0
|
43
|
+
z-index: $substratum-elements
|
36
44
|
overflow-x: hidden
|
37
|
-
|
45
|
+
// The viewport always has a scrollbar, except when we're animating (see below)
|
46
|
+
overflow-y: scroll
|
38
47
|
// We prefer centering the dialog as an `inline-block`
|
39
48
|
// to giving it a horizontal margin of `auto`. This way
|
40
49
|
// the width of `.up-modal-dialog` is controlled by the
|
41
50
|
// contents of `.up-modal-content`.
|
42
51
|
text-align: center
|
43
52
|
|
44
|
-
|
53
|
+
.up-modal.up-modal-animating
|
54
|
+
// During opening/closing animations we let the .up-modal container take over
|
55
|
+
// the scrollbars that would usually be owned by .up-modal-viewport.
|
56
|
+
// If .up-modal-viewport had a scrollbar while animating with
|
57
|
+
// "zoom-in" it would look strange that the scrollbar is scaled.
|
58
|
+
&
|
45
59
|
overflow-y: scroll
|
60
|
+
.up-modal-viewport
|
61
|
+
overflow-y: hidden
|
46
62
|
|
47
63
|
.up-modal-dialog
|
48
64
|
z-index: $substratum-dialog
|
@@ -35,6 +35,32 @@ module Unpoly
|
|
35
35
|
request.headers['X-Up-Target']
|
36
36
|
end
|
37
37
|
|
38
|
+
##
|
39
|
+
# Tests whether the given CSS selector is targeted by the current fragment update.
|
40
|
+
#
|
41
|
+
# Note that the matching logic is very simplistic and does not actually know
|
42
|
+
# how your page layout is structured. It will return `true` if
|
43
|
+
# the tested selector and the requested CSS selector matches exactly, or if the
|
44
|
+
# requested selector is `body` or `html`.
|
45
|
+
#
|
46
|
+
# Always returns `true` if the current request is not an Unpoly fragment update.
|
47
|
+
def target?(tested_target)
|
48
|
+
if up?
|
49
|
+
actual_target = target
|
50
|
+
if actual_target == tested_target
|
51
|
+
true
|
52
|
+
elsif actual_target == 'html'
|
53
|
+
true
|
54
|
+
elsif actual_target == 'body'
|
55
|
+
not ['head', 'title', 'meta'].include?(tested_target)
|
56
|
+
else
|
57
|
+
false
|
58
|
+
end
|
59
|
+
else
|
60
|
+
true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
38
64
|
##
|
39
65
|
# Returns whether the current form submission should be
|
40
66
|
# [validated](http://unpoly.com/up-validate) (and not be saved to the database).
|
data/lib/unpoly/rails/version.rb
CHANGED
data/spec_app/Gemfile.lock
CHANGED
@@ -8,6 +8,12 @@ class BindingTestController < ActionController::Base
|
|
8
8
|
render :text => up.target
|
9
9
|
end
|
10
10
|
|
11
|
+
def up_is_target
|
12
|
+
tested_target = params[:tested_target].presence
|
13
|
+
tested_target or raise "No target given"
|
14
|
+
render :text => up.target?(tested_target).to_s
|
15
|
+
end
|
16
|
+
|
11
17
|
def is_up_validate
|
12
18
|
render :text => up.validate?.to_s
|
13
19
|
end
|
@@ -17,7 +17,7 @@ describe BindingTestController do
|
|
17
17
|
|
18
18
|
describe '#up' do
|
19
19
|
|
20
|
-
describe '#
|
20
|
+
describe '#target' do
|
21
21
|
|
22
22
|
it 'returns the CSS selector that is requested via Unpoly' do
|
23
23
|
request.headers['X-Up-Target'] = '.foo'
|
@@ -27,6 +27,87 @@ describe BindingTestController do
|
|
27
27
|
|
28
28
|
end
|
29
29
|
|
30
|
+
describe '#target?' do
|
31
|
+
|
32
|
+
it 'returns true if the tested CSS selector is requested via Unpoly' do
|
33
|
+
request.headers['X-Up-Target'] = '.foo'
|
34
|
+
get :up_is_target, tested_target: '.foo'
|
35
|
+
expect(response.body).to eq('true')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns false if Unpoly is requesting another CSS selector' do
|
39
|
+
request.headers['X-Up-Target'] = '.bar'
|
40
|
+
get :up_is_target, tested_target: '.foo'
|
41
|
+
expect(response.body).to eq('false')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns true if the request is not an Unpoly request' do
|
45
|
+
get :up_is_target, tested_target: '.foo'
|
46
|
+
expect(response.body).to eq('true')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns true if testing a custom selector, and Unpoly requests "body"' do
|
50
|
+
request.headers['X-Up-Target'] = 'body'
|
51
|
+
get :up_is_target, tested_target: '.foo'
|
52
|
+
expect(response.body).to eq('true')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'returns true if testing a custom selector, and Unpoly requests "html"' do
|
56
|
+
request.headers['X-Up-Target'] = 'html'
|
57
|
+
get :up_is_target, tested_target: '.foo'
|
58
|
+
expect(response.body).to eq('true')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns true if testing "body", and Unpoly requests "html"' do
|
62
|
+
request.headers['X-Up-Target'] = 'html'
|
63
|
+
get :up_is_target, tested_target: 'body'
|
64
|
+
expect(response.body).to eq('true')
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'returns true if testing "head", and Unpoly requests "html"' do
|
68
|
+
request.headers['X-Up-Target'] = 'html'
|
69
|
+
get :up_is_target, tested_target: 'head'
|
70
|
+
expect(response.body).to eq('true')
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns false if the tested CSS selector is "head" but Unpoly requests "body"' do
|
74
|
+
request.headers['X-Up-Target'] = 'body'
|
75
|
+
get :up_is_target, tested_target: 'head'
|
76
|
+
expect(response.body).to eq('false')
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'returns false if the tested CSS selector is "title" but Unpoly requests "body"' do
|
80
|
+
request.headers['X-Up-Target'] = 'body'
|
81
|
+
get :up_is_target, tested_target: 'title'
|
82
|
+
expect(response.body).to eq('false')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'returns false if the tested CSS selector is "meta" but Unpoly requests "body"' do
|
86
|
+
request.headers['X-Up-Target'] = 'body'
|
87
|
+
get :up_is_target, tested_target: 'meta'
|
88
|
+
expect(response.body).to eq('false')
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'returns true if the tested CSS selector is "head", and Unpoly requests "html"' do
|
92
|
+
request.headers['X-Up-Target'] = 'html'
|
93
|
+
get :up_is_target, tested_target: 'head'
|
94
|
+
expect(response.body).to eq('true')
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'returns true if the tested CSS selector is "title", Unpoly requests "html"' do
|
98
|
+
request.headers['X-Up-Target'] = 'html'
|
99
|
+
get :up_is_target, tested_target: 'title'
|
100
|
+
expect(response.body).to eq('true')
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'returns true if the tested CSS selector is "meta", and Unpoly requests "html"' do
|
104
|
+
request.headers['X-Up-Target'] = 'html'
|
105
|
+
get :up_is_target, tested_target: 'meta'
|
106
|
+
expect(response.body).to eq('true')
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
30
111
|
describe '#validate?' do
|
31
112
|
|
32
113
|
it 'returns true the request is an Unpoly validation call' do
|
@@ -63,14 +144,4 @@ describe BindingTestController do
|
|
63
144
|
|
64
145
|
end
|
65
146
|
|
66
|
-
|
67
|
-
# describe '#test' do
|
68
|
-
#
|
69
|
-
# it 'does stuff' do
|
70
|
-
# get :test
|
71
|
-
# expect(response.body).to eq('foo')
|
72
|
-
# end
|
73
|
-
#
|
74
|
-
# end
|
75
|
-
|
76
147
|
end
|
@@ -47,6 +47,20 @@ describe 'up.flow', ->
|
|
47
47
|
expect(resolution).toHaveBeenCalled()
|
48
48
|
expect($('.middle')).toHaveText('new-middle')
|
49
49
|
|
50
|
+
it 'returns a promise that will be resolved once the server response was received and the swap animations have completed', (done) ->
|
51
|
+
resolution = jasmine.createSpy()
|
52
|
+
promise = up.replace('.middle', '/path', transition: 'cross-fade', duration: 50)
|
53
|
+
promise.then(resolution)
|
54
|
+
expect(resolution).not.toHaveBeenCalled()
|
55
|
+
expect($('.middle')).toHaveText('old-middle')
|
56
|
+
@respond()
|
57
|
+
expect(resolution).not.toHaveBeenCalled()
|
58
|
+
u.setTimer 20, ->
|
59
|
+
expect(resolution).not.toHaveBeenCalled()
|
60
|
+
u.setTimer 80, ->
|
61
|
+
expect(resolution).toHaveBeenCalled()
|
62
|
+
done()
|
63
|
+
|
50
64
|
describe 'with { data } option', ->
|
51
65
|
|
52
66
|
it "uses the given params as a non-GET request's payload", ->
|
@@ -470,19 +484,19 @@ describe 'up.flow', ->
|
|
470
484
|
|
471
485
|
it 'morphs between the old and new element', (done) ->
|
472
486
|
affix('.element').text('version 1')
|
473
|
-
up.extract('.element', '<div class="element">version 2</div>', transition: 'cross-fade', duration:
|
487
|
+
up.extract('.element', '<div class="element">version 2</div>', transition: 'cross-fade', duration: 200)
|
474
488
|
|
475
489
|
$ghost1 = $('.element.up-ghost:contains("version 1")')
|
476
490
|
expect($ghost1).toHaveLength(1)
|
477
|
-
expect($ghost1
|
491
|
+
expect(u.opacity($ghost1)).toBeAround(1.0, 0.1)
|
478
492
|
|
479
493
|
$ghost2 = $('.element.up-ghost:contains("version 2")')
|
480
494
|
expect($ghost2).toHaveLength(1)
|
481
|
-
expect($ghost2
|
495
|
+
expect(u.opacity($ghost2)).toBeAround(0.0, 0.1)
|
482
496
|
|
483
|
-
u.setTimer
|
484
|
-
expect($ghost1
|
485
|
-
expect($ghost2
|
497
|
+
u.setTimer 190, ->
|
498
|
+
expect(u.opacity($ghost1)).toBeAround(0.0, 0.3)
|
499
|
+
expect(u.opacity($ghost2)).toBeAround(1.0, 0.3)
|
486
500
|
done()
|
487
501
|
|
488
502
|
it 'marks the old fragment and its ghost as .up-destroying during the transition', ->
|
@@ -534,7 +548,7 @@ describe 'up.flow', ->
|
|
534
548
|
promise = up.extract('.element', '<div class="element">version 2</div>', transition: 'cross-fade', duration: 30)
|
535
549
|
promise.then(resolution)
|
536
550
|
expect(resolution).not.toHaveBeenCalled()
|
537
|
-
u.setTimer
|
551
|
+
u.setTimer 70, ->
|
538
552
|
expect(resolution).toHaveBeenCalled()
|
539
553
|
done()
|
540
554
|
|
@@ -215,6 +215,21 @@ describe 'up.form', ->
|
|
215
215
|
expect(submitSpy).toHaveBeenCalled()
|
216
216
|
done()
|
217
217
|
|
218
|
+
it 'marks the field with an .up-active class while the form is submitting', (done) ->
|
219
|
+
$form = affix('form')
|
220
|
+
$field = $form.affix('input[up-autosubmit][val="old-value"]')
|
221
|
+
up.hello($field)
|
222
|
+
submission = $.Deferred()
|
223
|
+
submitSpy = up.form.knife.mock('submit').and.returnValue(submission)
|
224
|
+
$field.val('new-value')
|
225
|
+
$field.trigger('change')
|
226
|
+
u.nextFrame ->
|
227
|
+
expect(submitSpy).toHaveBeenCalled()
|
228
|
+
expect($field).toHaveClass('up-active')
|
229
|
+
submission.resolve()
|
230
|
+
expect($field).not.toHaveClass('up-active')
|
231
|
+
done()
|
232
|
+
|
218
233
|
describe 'form[up-autosubmit]', ->
|
219
234
|
|
220
235
|
it 'submits the form when a change is observed in any of its fields', (done) ->
|
@@ -44,6 +44,8 @@ describe 'up.link', ->
|
|
44
44
|
|
45
45
|
it 'adds history entries and allows the user to use the back- and forward-buttons', (done) ->
|
46
46
|
|
47
|
+
waitForBrowser = 70
|
48
|
+
|
47
49
|
# By default, up.history will replace the <body> tag when
|
48
50
|
# the user presses the back-button. We reconfigure this
|
49
51
|
# so we don't lose the Jasmine runner interface.
|
@@ -83,21 +85,21 @@ describe 'up.link', ->
|
|
83
85
|
expect(document.title).toEqual('title from three')
|
84
86
|
|
85
87
|
history.back()
|
86
|
-
u.setTimer
|
88
|
+
u.setTimer waitForBrowser, ->
|
87
89
|
respondWith('restored text from two', 'restored title from two')
|
88
90
|
expect($('.target')).toHaveText('restored text from two')
|
89
91
|
expect(location.pathname).toEqual('/two')
|
90
92
|
expect(document.title).toEqual('restored title from two')
|
91
93
|
|
92
94
|
history.back()
|
93
|
-
u.setTimer
|
95
|
+
u.setTimer waitForBrowser, ->
|
94
96
|
respondWith('restored text from one', 'restored title from one')
|
95
97
|
expect($('.target')).toHaveText('restored text from one')
|
96
98
|
expect(location.pathname).toEqual('/one')
|
97
99
|
expect(document.title).toEqual('restored title from one')
|
98
100
|
|
99
101
|
history.forward()
|
100
|
-
u.setTimer
|
102
|
+
u.setTimer waitForBrowser, ->
|
101
103
|
# Since the response is cached, we don't have to respond
|
102
104
|
expect($('.target')).toHaveText('restored text from two', 'restored title from two')
|
103
105
|
expect(location.pathname).toEqual('/two')
|
@@ -367,7 +369,7 @@ describe 'up.link', ->
|
|
367
369
|
|
368
370
|
it 'morphs between the old and new target element', (done) ->
|
369
371
|
affix('.target.old')
|
370
|
-
$link = affix('a[href="/path"][up-target=".target"][up-transition="cross-fade"][up-duration="
|
372
|
+
$link = affix('a[href="/path"][up-target=".target"][up-transition="cross-fade"][up-duration="300"][up-easing="linear"]')
|
371
373
|
$link.click()
|
372
374
|
@respondWith '<div class="target new">new text</div>'
|
373
375
|
|
@@ -375,12 +377,11 @@ describe 'up.link', ->
|
|
375
377
|
$newGhost = $('.target.new.up-ghost')
|
376
378
|
expect($oldGhost).toExist()
|
377
379
|
expect($newGhost).toExist()
|
378
|
-
opacity
|
379
|
-
expect(opacity($
|
380
|
-
|
381
|
-
|
382
|
-
expect(opacity($
|
383
|
-
expect(opacity($newGhost)).toBeAround(0.5, 0.15)
|
380
|
+
expect(u.opacity($oldGhost)).toBeAround(1, 0.15)
|
381
|
+
expect(u.opacity($newGhost)).toBeAround(0, 0.15)
|
382
|
+
u.setTimer 150, ->
|
383
|
+
expect(u.opacity($oldGhost)).toBeAround(0.5, 0.15)
|
384
|
+
expect(u.opacity($newGhost)).toBeAround(0.5, 0.15)
|
384
385
|
done()
|
385
386
|
|
386
387
|
it 'does not add a history entry when an up-history attribute is set to "false"', ->
|