upjs-rails 0.3.0 → 0.3.2
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/dist/up.css +5 -1
- data/dist/up.js +239 -95
- data/dist/up.min.css +1 -1
- data/dist/up.min.js +1 -1
- data/lib/assets/javascripts/up.js.coffee +6 -2
- data/lib/assets/javascripts/up/browser.js.coffee +52 -0
- data/lib/assets/javascripts/up/flow.js.coffee +9 -2
- data/lib/assets/javascripts/up/form.js.coffee +4 -0
- data/lib/assets/javascripts/up/history.js.coffee +10 -6
- data/lib/assets/javascripts/up/magic.js.coffee +4 -0
- data/lib/assets/javascripts/up/marker.js.coffee +4 -2
- data/lib/assets/javascripts/up/modal.js.coffee +1 -1
- data/lib/assets/javascripts/up/motion.js.coffee +28 -26
- data/lib/assets/javascripts/up/popup.js.coffee +1 -1
- data/lib/assets/javascripts/up/util.js.coffee +99 -38
- data/lib/assets/stylesheets/up/modal.css.sass +7 -2
- data/lib/upjs/rails/version.rb +1 -1
- data/spec_app/spec/javascripts/helpers/reset_path.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/flow_spec.js.coffee +90 -68
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +90 -77
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +35 -24
- data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +52 -50
- metadata +2 -2
|
@@ -4,6 +4,11 @@ $stratum: 10000
|
|
|
4
4
|
$close-height: 24px
|
|
5
5
|
$close-width: 36px
|
|
6
6
|
|
|
7
|
+
=transform($transform)
|
|
8
|
+
transform: $transform
|
|
9
|
+
-ms-transform: $transform // IE9
|
|
10
|
+
-webkit-transform: $transform // Safari, Some Android
|
|
11
|
+
|
|
7
12
|
.up-modal
|
|
8
13
|
position: fixed
|
|
9
14
|
top: 0
|
|
@@ -17,7 +22,7 @@ $close-width: 36px
|
|
|
17
22
|
position: absolute
|
|
18
23
|
top: 50%
|
|
19
24
|
left: 50%
|
|
20
|
-
transform
|
|
25
|
+
+transform(translate(-50%, -50%))
|
|
21
26
|
max-width: 100%
|
|
22
27
|
max-height: 100%
|
|
23
28
|
background-color: #fff
|
|
@@ -40,7 +45,7 @@ $close-width: 36px
|
|
|
40
45
|
font-weight: bold
|
|
41
46
|
text-transform: uppercase
|
|
42
47
|
cursor: pointer
|
|
43
|
-
transform
|
|
48
|
+
+transform(translateY(-100%))
|
|
44
49
|
|
|
45
50
|
.up-modal-content
|
|
46
51
|
overflow-x: hidden
|
data/lib/upjs/rails/version.rb
CHANGED
|
@@ -1,58 +1,69 @@
|
|
|
1
1
|
describe 'up.flow', ->
|
|
2
2
|
|
|
3
|
-
describe 'Javascript functions', ->
|
|
4
|
-
|
|
3
|
+
describe 'Javascript functions', ->
|
|
4
|
+
|
|
5
|
+
beforeEach ->
|
|
6
|
+
jasmine.Ajax.install()
|
|
7
|
+
|
|
5
8
|
describe 'up.replace', ->
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
it 'replaces the given selector with the same selector from a freshly fetched page', (done) ->
|
|
26
|
-
@request = up.replace('.middle', '/path')
|
|
27
|
-
@respond()
|
|
28
|
-
@request.then ->
|
|
29
|
-
expect($('.before')).toHaveText('old-before')
|
|
30
|
-
expect($('.middle')).toHaveText('new-middle')
|
|
31
|
-
expect($('.after')).toHaveText('old-after')
|
|
32
|
-
done()
|
|
9
|
+
|
|
10
|
+
if up.browser.canPushState()
|
|
11
|
+
|
|
12
|
+
beforeEach ->
|
|
13
|
+
|
|
14
|
+
affix('.before').text('old-before')
|
|
15
|
+
affix('.middle').text('old-middle')
|
|
16
|
+
affix('.after').text('old-after')
|
|
17
|
+
|
|
18
|
+
@respond = ->
|
|
19
|
+
jasmine.Ajax.requests.mostRecent().respondWith
|
|
20
|
+
status: 200
|
|
21
|
+
contentType: 'text/html'
|
|
22
|
+
responseText:
|
|
23
|
+
"""
|
|
24
|
+
<div class="before">new-before</div>
|
|
25
|
+
<div class="middle">new-middle</div>
|
|
26
|
+
<div class="after">new-after</div>
|
|
27
|
+
"""
|
|
33
28
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
@request = up.replace('.middle', '/path')
|
|
43
|
-
@respond()
|
|
44
|
-
@request.then ->
|
|
45
|
-
expect($('.middle').attr('up-source')).toMatch(/\/path$/)
|
|
46
|
-
done()
|
|
29
|
+
it 'replaces the given selector with the same selector from a freshly fetched page', (done) ->
|
|
30
|
+
@request = up.replace('.middle', '/path')
|
|
31
|
+
@respond()
|
|
32
|
+
@request.then ->
|
|
33
|
+
expect($('.before')).toHaveText('old-before')
|
|
34
|
+
expect($('.middle')).toHaveText('new-middle')
|
|
35
|
+
expect($('.after')).toHaveText('old-after')
|
|
36
|
+
done()
|
|
47
37
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
38
|
+
it 'should set the browser location to the given URL', (done) ->
|
|
39
|
+
@request = up.replace('.middle', '/path')
|
|
40
|
+
@respond()
|
|
41
|
+
@request.then ->
|
|
42
|
+
expect(window.location.pathname).toBe('/path')
|
|
43
|
+
done()
|
|
44
|
+
|
|
45
|
+
it 'marks the element with the URL from which it was retrieved', (done) ->
|
|
46
|
+
@request = up.replace('.middle', '/path')
|
|
47
|
+
@respond()
|
|
48
|
+
@request.then ->
|
|
49
|
+
expect($('.middle').attr('up-source')).toMatch(/\/path$/)
|
|
50
|
+
done()
|
|
51
|
+
|
|
52
|
+
it 'replaces multiple selectors separated with a comma', (done) ->
|
|
53
|
+
@request = up.replace('.middle, .after', '/path')
|
|
54
|
+
@respond()
|
|
55
|
+
@request.then ->
|
|
56
|
+
expect($('.before')).toHaveText('old-before')
|
|
57
|
+
expect($('.middle')).toHaveText('new-middle')
|
|
58
|
+
expect($('.after')).toHaveText('new-after')
|
|
59
|
+
done()
|
|
60
|
+
|
|
61
|
+
else
|
|
62
|
+
|
|
63
|
+
it 'makes a full page load', ->
|
|
64
|
+
spyOn(up.browser, 'loadPage')
|
|
65
|
+
up.replace('.selector', '/path')
|
|
66
|
+
expect(up.browser.loadPage).toHaveBeenCalledWith('/path', jasmine.anything())
|
|
56
67
|
|
|
57
68
|
describe 'up.implant', ->
|
|
58
69
|
|
|
@@ -74,25 +85,36 @@ describe 'up.flow', ->
|
|
|
74
85
|
|
|
75
86
|
describe 'up.reload', ->
|
|
76
87
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
88
|
+
if up.browser.canPushState()
|
|
89
|
+
|
|
90
|
+
it 'reloads the given selector from the closest known source URL', (done) ->
|
|
91
|
+
affix('.container[up-source="/source"] .element').find('.element').text('old text')
|
|
92
|
+
|
|
93
|
+
up.reload('.element').then ->
|
|
94
|
+
expect($('.element')).toHaveText('new text')
|
|
95
|
+
done()
|
|
96
|
+
|
|
97
|
+
request = jasmine.Ajax.requests.mostRecent()
|
|
98
|
+
expect(request.url).toMatch(/\/source$/)
|
|
99
|
+
|
|
100
|
+
request.respondWith
|
|
101
|
+
status: 200
|
|
102
|
+
contentType: '/text/html'
|
|
103
|
+
responseText:
|
|
104
|
+
"""
|
|
105
|
+
<div class="container">
|
|
106
|
+
<div class="element">new text</div>
|
|
107
|
+
</div>
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
else
|
|
111
|
+
|
|
112
|
+
it 'makes a page load from the closest known source URL', ->
|
|
113
|
+
affix('.container[up-source="/source"] .element').find('.element').text('old text')
|
|
114
|
+
spyOn(up.browser, 'loadPage')
|
|
115
|
+
up.reload('.element')
|
|
116
|
+
expect(up.browser.loadPage).toHaveBeenCalledWith('/source', jasmine.anything())
|
|
83
117
|
|
|
84
|
-
request = jasmine.Ajax.requests.mostRecent()
|
|
85
|
-
expect(request.url).toMatch(/\/source$/)
|
|
86
|
-
|
|
87
|
-
request.respondWith
|
|
88
|
-
status: 200
|
|
89
|
-
contentType: '/text/html'
|
|
90
|
-
responseText:
|
|
91
|
-
"""
|
|
92
|
-
<div class="container">
|
|
93
|
-
<div class="element">new text</div>
|
|
94
|
-
</div>
|
|
95
|
-
"""
|
|
96
118
|
|
|
97
119
|
describe 'up.reset', ->
|
|
98
120
|
|
|
@@ -8,84 +8,97 @@ describe 'up.form', ->
|
|
|
8
8
|
|
|
9
9
|
describe 'up.submit', ->
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
jasmine.Ajax.install()
|
|
13
|
-
|
|
14
|
-
$form = affix('form[action="/path/to"][method="put"][up-target=".response"]')
|
|
15
|
-
$form.append('<input name="field1" value="value1">')
|
|
16
|
-
$form.append('<input name="field2" value="value2">')
|
|
17
|
-
|
|
18
|
-
affix('.response').text('old-text')
|
|
19
|
-
|
|
20
|
-
@promise = up.submit($form)
|
|
21
|
-
|
|
22
|
-
@request = jasmine.Ajax.requests.mostRecent()
|
|
23
|
-
expect(@request.url).toMatch /\/path\/to$/
|
|
24
|
-
expect(@request.method).toBe 'PUT'
|
|
25
|
-
expect(@request.data()).toEqual
|
|
26
|
-
field1: ['value1']
|
|
27
|
-
field2: ['value2']
|
|
28
|
-
|
|
29
|
-
it 'submits the given form and replaces the target with the response', (done) ->
|
|
30
|
-
|
|
31
|
-
@request.respondWith
|
|
32
|
-
status: 200
|
|
33
|
-
contentType: 'text/html'
|
|
34
|
-
responseText:
|
|
35
|
-
"""
|
|
36
|
-
text-before
|
|
37
|
-
|
|
38
|
-
<div class="response">
|
|
39
|
-
new-text
|
|
40
|
-
</div>
|
|
41
|
-
|
|
42
|
-
text-after
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
@promise.then ->
|
|
46
|
-
expect($('.response')).toHaveText('new-text')
|
|
47
|
-
expect($('body')).not.toHaveText('text-before')
|
|
48
|
-
expect($('body')).not.toHaveText('text-after')
|
|
49
|
-
done()
|
|
11
|
+
if up.browser.canPushState()
|
|
50
12
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
13
|
+
beforeEach ->
|
|
14
|
+
jasmine.Ajax.install()
|
|
15
|
+
|
|
16
|
+
$form = affix('form[action="/path/to"][method="put"][up-target=".response"]')
|
|
17
|
+
$form.append('<input name="field1" value="value1">')
|
|
18
|
+
$form.append('<input name="field2" value="value2">')
|
|
19
|
+
|
|
20
|
+
affix('.response').text('old-text')
|
|
21
|
+
|
|
22
|
+
@promise = up.submit($form)
|
|
23
|
+
|
|
24
|
+
@request = jasmine.Ajax.requests.mostRecent()
|
|
25
|
+
expect(@request.url).toMatch /\/path\/to$/
|
|
26
|
+
expect(@request.method).toBe 'PUT'
|
|
27
|
+
expect(@request.data()).toEqual
|
|
28
|
+
field1: ['value1']
|
|
29
|
+
field2: ['value2']
|
|
30
|
+
|
|
31
|
+
it 'submits the given form and replaces the target with the response', (done) ->
|
|
32
|
+
|
|
33
|
+
@request.respondWith
|
|
34
|
+
status: 200
|
|
35
|
+
contentType: 'text/html'
|
|
36
|
+
responseText:
|
|
37
|
+
"""
|
|
38
|
+
text-before
|
|
39
|
+
|
|
40
|
+
<div class="response">
|
|
41
|
+
new-text
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
text-after
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
@promise.then ->
|
|
48
|
+
expect($('.response')).toHaveText('new-text')
|
|
49
|
+
expect($('body')).not.toHaveText('text-before')
|
|
50
|
+
expect($('body')).not.toHaveText('text-after')
|
|
51
|
+
done()
|
|
52
|
+
|
|
53
|
+
it 'places the response into the form if the submission returns a 5xx status code', (done) ->
|
|
54
|
+
@request.respondWith
|
|
55
|
+
status: 500
|
|
56
|
+
contentType: 'text/html'
|
|
57
|
+
responseText:
|
|
58
|
+
"""
|
|
59
|
+
text-before
|
|
60
|
+
|
|
61
|
+
<form>
|
|
62
|
+
error-messages
|
|
63
|
+
</form>
|
|
64
|
+
|
|
65
|
+
text-after
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
@promise.always ->
|
|
69
|
+
expect($('.response')).toHaveText('old-text')
|
|
70
|
+
expect($('form')).toHaveText('error-messages')
|
|
71
|
+
expect($('body')).not.toHaveText('text-before')
|
|
72
|
+
expect($('body')).not.toHaveText('text-after')
|
|
73
|
+
done()
|
|
74
|
+
|
|
75
|
+
it 'respects a X-Up-Current-Location header that the server sends in case of a redirect', (done) ->
|
|
76
|
+
|
|
77
|
+
@request.respondWith
|
|
78
|
+
status: 200
|
|
79
|
+
contentType: 'text/html'
|
|
80
|
+
responseHeaders: { 'X-Up-Current-Location': '/other/path' }
|
|
81
|
+
responseText:
|
|
82
|
+
"""
|
|
83
|
+
<div class="response">
|
|
84
|
+
new-text
|
|
85
|
+
</div>
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
@promise.then ->
|
|
89
|
+
expect(up.browser.url()).toMatch(/\/other\/path$/)
|
|
90
|
+
done()
|
|
91
|
+
|
|
92
|
+
else
|
|
93
|
+
|
|
94
|
+
it 'submits the given form', ->
|
|
95
|
+
$form = affix('form[action="/path/to"][method="put"][up-target=".response"]')
|
|
96
|
+
form = $form.get(0)
|
|
97
|
+
spyOn(form, 'submit')
|
|
98
|
+
|
|
99
|
+
up.submit($form)
|
|
100
|
+
expect(form.submit).toHaveBeenCalled()
|
|
101
|
+
|
|
89
102
|
|
|
90
103
|
describe 'unobtrusive behavior', ->
|
|
91
104
|
|
|
@@ -4,31 +4,42 @@ describe 'up.link', ->
|
|
|
4
4
|
|
|
5
5
|
describe 'up.follow', ->
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
7
|
+
if up.browser.canPushState()
|
|
8
|
+
|
|
9
|
+
it 'loads the given link via AJAX and replaces the response in the given target', (done) ->
|
|
10
|
+
jasmine.Ajax.install()
|
|
11
|
+
|
|
12
|
+
affix('.before').text('old-before')
|
|
13
|
+
affix('.middle').text('old-middle')
|
|
14
|
+
affix('.after').text('old-after')
|
|
15
|
+
$link = affix('a[href="/path"][up-target=".middle"]')
|
|
16
|
+
|
|
17
|
+
promise = up.follow($link)
|
|
18
|
+
|
|
19
|
+
jasmine.Ajax.requests.mostRecent().respondWith
|
|
20
|
+
status: 200
|
|
21
|
+
contentType: 'text/html'
|
|
22
|
+
responseText:
|
|
23
|
+
"""
|
|
24
|
+
<div class="before">new-before</div>
|
|
25
|
+
<div class="middle">new-middle</div>
|
|
26
|
+
<div class="after">new-after</div>
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
promise.then ->
|
|
30
|
+
expect($('.before')).toHaveText('old-before')
|
|
31
|
+
expect($('.middle')).toHaveText('new-middle')
|
|
32
|
+
expect($('.after')).toHaveText('old-after')
|
|
33
|
+
done()
|
|
34
|
+
|
|
35
|
+
else
|
|
26
36
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
it 'follows the given link', ->
|
|
38
|
+
$link = affix('a[href="/path"][up-target=".middle"]')
|
|
39
|
+
spyOn(up.browser, 'loadPage')
|
|
40
|
+
up.follow($link)
|
|
41
|
+
expect(up.browser.loadPage).toHaveBeenCalledWith('/path', jasmine.anything())
|
|
42
|
+
|
|
32
43
|
|
|
33
44
|
describe 'up.visit', ->
|
|
34
45
|
|