unpoly-rails 0.31.2 → 0.32.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 +49 -5
- data/README.md +21 -15
- data/README_RAILS.md +2 -2
- data/Rakefile +1 -1
- data/bower.json +4 -3
- data/design/homepage.txt +2 -2
- data/dist/unpoly-bootstrap3.css +3 -0
- data/dist/unpoly-bootstrap3.min.css +1 -1
- data/dist/unpoly.css +4 -4
- data/dist/unpoly.js +114 -80
- data/dist/unpoly.min.css +1 -1
- data/dist/unpoly.min.js +3 -3
- data/lib/assets/javascripts/unpoly/browser.js.coffee +1 -1
- data/lib/assets/javascripts/unpoly/bus.js.coffee +3 -3
- data/lib/assets/javascripts/unpoly/flow.js.coffee +15 -11
- data/lib/assets/javascripts/unpoly/form.js.coffee +1 -1
- data/lib/assets/javascripts/unpoly/layout.js.coffee +12 -9
- data/lib/assets/javascripts/unpoly/link.js.coffee +22 -7
- data/lib/assets/javascripts/unpoly/log.js.coffee +3 -2
- data/lib/assets/javascripts/unpoly/modal.js.coffee +11 -13
- data/lib/assets/javascripts/unpoly/motion.js.coffee +1 -1
- data/lib/assets/javascripts/unpoly/navigation.js.coffee +5 -5
- data/lib/assets/javascripts/unpoly/popup.js.coffee +8 -9
- data/lib/assets/javascripts/unpoly/proxy.js.coffee +2 -2
- data/lib/assets/javascripts/unpoly/syntax.js.coffee +19 -15
- data/lib/assets/javascripts/unpoly/util.js.coffee +19 -3
- data/lib/assets/stylesheets/unpoly-bootstrap3/modal-ext.css.sass +6 -1
- data/lib/assets/stylesheets/unpoly/modal.css.sass +7 -2
- data/lib/unpoly/rails/version.rb +1 -1
- data/package.json +2 -2
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/app/assets/javascripts/bootstrap_manifest.coffee +2 -2
- data/spec_app/app/views/css_test/modal.erb +4 -0
- data/spec_app/app/views/css_test/modal_contents_wide.erb +5 -0
- data/spec_app/app/views/layouts/integration_test.erb +1 -0
- data/spec_app/spec/javascripts/helpers/knife.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/browser_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/bus_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/flow_spec.js.coffee +63 -5
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +2 -2
- data/spec_app/spec/javascripts/up/history_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/layout_spec.js.coffee +27 -1
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +3 -3
- data/spec_app/spec/javascripts/up/log_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +3 -3
- data/spec_app/spec/javascripts/up/motion_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +21 -3
- data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +2 -2
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/README.md +2 -2
- data/unpoly-rails.gemspec +1 -1
- metadata +5 -4
@@ -456,7 +456,7 @@ up.util = (($) ->
|
|
456
456
|
###*
|
457
457
|
Returns whether the given argument is an object.
|
458
458
|
|
459
|
-
This also returns `true` for functions, which may behave like objects in
|
459
|
+
This also returns `true` for functions, which may behave like objects in JavaScript.
|
460
460
|
For an alternative that returns `false` for functions, see [`up.util.isHash`](/up.util.isHash).
|
461
461
|
|
462
462
|
@function up.util.isObject
|
@@ -783,7 +783,7 @@ up.util = (($) ->
|
|
783
783
|
|
784
784
|
###*
|
785
785
|
Schedules the given function to be called in the
|
786
|
-
next
|
786
|
+
next JavaScript execution frame.
|
787
787
|
|
788
788
|
@function up.util.nextFrame
|
789
789
|
@param {Function} block
|
@@ -1684,7 +1684,7 @@ up.util = (($) ->
|
|
1684
1684
|
data
|
1685
1685
|
|
1686
1686
|
###*
|
1687
|
-
Throws a [
|
1687
|
+
Throws a [JavaScript error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)
|
1688
1688
|
with the given message.
|
1689
1689
|
|
1690
1690
|
The message will also be printed to the [error log](/up.log.error). Also a notification will be shown at the bottom of the screen.
|
@@ -1905,6 +1905,21 @@ up.util = (($) ->
|
|
1905
1905
|
else
|
1906
1906
|
'right'
|
1907
1907
|
|
1908
|
+
###*
|
1909
|
+
Like `$old.replaceWith($new)`, but keeps event handlers bound to `$old`.
|
1910
|
+
|
1911
|
+
Note that this is a memory leak unless you re-attach `$new` to the DOM aferwards.
|
1912
|
+
|
1913
|
+
@function up.util.detachWith
|
1914
|
+
@internal
|
1915
|
+
###
|
1916
|
+
detachWith = ($old, $new) ->
|
1917
|
+
$insertion = $('<div></div>')
|
1918
|
+
$insertion.insertAfter($old)
|
1919
|
+
$old.detach()
|
1920
|
+
$insertion.replaceWith($new)
|
1921
|
+
$old
|
1922
|
+
|
1908
1923
|
isDetached: isDetached
|
1909
1924
|
requestDataAsArray: requestDataAsArray
|
1910
1925
|
requestDataAsQuery: requestDataAsQuery
|
@@ -2018,6 +2033,7 @@ up.util = (($) ->
|
|
2018
2033
|
previewable: previewable
|
2019
2034
|
evalOption: evalOption
|
2020
2035
|
horizontalScreenHalf: horizontalScreenHalf
|
2036
|
+
detachWith: detachWith
|
2021
2037
|
|
2022
2038
|
)($)
|
2023
2039
|
|
@@ -1,8 +1,13 @@
|
|
1
1
|
.up-modal-content
|
2
2
|
// Unpoly: Gives some default padding
|
3
|
-
//
|
3
|
+
// Bootstrap: Expects content to set the padding
|
4
4
|
padding: 0
|
5
5
|
|
6
|
+
.up-modal-dialog
|
7
|
+
// Unpoly: Dialog margin is a padding of .up-modal-viewport so we can give .up-modal-dialog a max-width of 100%
|
8
|
+
// Bootstrap: Dialog margin is a margin of .modal-dialog
|
9
|
+
margin: 0
|
10
|
+
|
6
11
|
.up-modal[up-flavor='drawer']
|
7
12
|
|
8
13
|
.up-modal-content
|
@@ -50,6 +50,12 @@ $close-font-size: 34px
|
|
50
50
|
// contents of `.up-modal-content`.
|
51
51
|
text-align: center
|
52
52
|
|
53
|
+
// Implement the margin around the dialog box with a padding of the viewport.
|
54
|
+
// This way we can give .up-modal-dialog a max-width of 100%, (1) preventing people
|
55
|
+
// from setting withs larger than the viewport, and (2) sizing approproately
|
56
|
+
// if the modal contents are very wide and cannot wrap (e.g. code blocks).
|
57
|
+
padding: 30px 10px
|
58
|
+
|
53
59
|
.up-modal.up-modal-animating
|
54
60
|
// During opening/closing animations we let the .up-modal container take over
|
55
61
|
// the scrollbars that would usually be owned by .up-modal-viewport.
|
@@ -68,7 +74,6 @@ $close-font-size: 34px
|
|
68
74
|
// the width and height attributes set by up.modal
|
69
75
|
// should be honored exactly.
|
70
76
|
box-sizing: border-box
|
71
|
-
margin: 30px 10px
|
72
77
|
|
73
78
|
// In case someone sets a huge width on the dialog.
|
74
79
|
max-width: 100%
|
@@ -99,10 +104,10 @@ $close-font-size: 34px
|
|
99
104
|
.up-modal[up-flavor='drawer']
|
100
105
|
.up-modal-viewport
|
101
106
|
text-align: left
|
107
|
+
padding: 0
|
102
108
|
&[up-position='right'] .up-modal-viewport
|
103
109
|
text-align: right
|
104
110
|
.up-modal-dialog
|
105
|
-
margin: 0
|
106
111
|
max-width: 350px
|
107
112
|
.up-modal-content
|
108
113
|
min-height: 100vh
|
data/lib/unpoly/rails/version.rb
CHANGED
data/package.json
CHANGED
data/spec_app/Gemfile.lock
CHANGED
@@ -2,5 +2,5 @@
|
|
2
2
|
|
3
3
|
# From the docs (https://github.com/twbs/bootstrap-sass):
|
4
4
|
# bootstrap-sprockets and bootstrap should not both be included in application.js.
|
5
|
-
# bootstrap-sprockets provides individual Bootstrap
|
6
|
-
# while bootstrap provides a concatenated file containing all Bootstrap
|
5
|
+
# bootstrap-sprockets provides individual Bootstrap JavaScript files (alert.js or dropdown.js, for example),
|
6
|
+
# while bootstrap provides a concatenated file containing all Bootstrap JavaScripts.
|
@@ -2,6 +2,10 @@
|
|
2
2
|
<a class="button" href="/css_test/modal_contents" up-modal=".contents">Modal</a>
|
3
3
|
</div>
|
4
4
|
|
5
|
+
<div class="example">
|
6
|
+
<a class="button" href="/css_test/modal_contents_wide" up-modal=".contents">Modal (wide contents)</a>
|
7
|
+
</div>
|
8
|
+
|
5
9
|
<div class="example">
|
6
10
|
<a class="button" href="/css_test/modal_contents" up-drawer=".contents" style="float: left">Drawer (auto)</a>
|
7
11
|
<a class="button" href="/css_test/modal_contents" up-drawer=".contents" style="float: right">Drawer (auto)</a>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
##
|
2
|
-
# Knife: Get, set or mock inaccessible variables in a
|
2
|
+
# Knife: Get, set or mock inaccessible variables in a JavaScript closure
|
3
3
|
# ======================================================================
|
4
4
|
#
|
5
5
|
# Requires [Jasmine](http://jasmine.github.io/) 2+.
|
@@ -2,7 +2,7 @@ describe 'up.flow', ->
|
|
2
2
|
|
3
3
|
u = up.util
|
4
4
|
|
5
|
-
describe '
|
5
|
+
describe 'JavaScript functions', ->
|
6
6
|
|
7
7
|
describe 'up.replace', ->
|
8
8
|
|
@@ -493,10 +493,12 @@ describe 'up.flow', ->
|
|
493
493
|
beforeEach ->
|
494
494
|
@revealedHTML = []
|
495
495
|
@revealedText = []
|
496
|
+
@revealOptions = {}
|
496
497
|
|
497
|
-
@revealMock = up.layout.knife.mock('reveal').and.callFake ($
|
498
|
-
@revealedHTML.push $
|
499
|
-
@revealedText.push $
|
498
|
+
@revealMock = up.layout.knife.mock('reveal').and.callFake ($element, options) =>
|
499
|
+
@revealedHTML.push $element.get(0).outerHTML
|
500
|
+
@revealedText.push $element.text().trim()
|
501
|
+
@revealOptions = options
|
500
502
|
u.resolvedDeferred()
|
501
503
|
|
502
504
|
it 'reveals a new element before it is being replaced', (done) ->
|
@@ -519,7 +521,7 @@ describe 'up.flow', ->
|
|
519
521
|
|
520
522
|
describe 'when there is an anchor #hash in the URL', ->
|
521
523
|
|
522
|
-
it '
|
524
|
+
it 'scrolls to the top of a child with the ID of that #hash', (done) ->
|
523
525
|
promise = up.replace('.middle', '/path#three', reveal: true)
|
524
526
|
@responseText =
|
525
527
|
"""
|
@@ -532,6 +534,7 @@ describe 'up.flow', ->
|
|
532
534
|
@respond()
|
533
535
|
promise.then =>
|
534
536
|
expect(@revealedHTML).toEqual ['<div id="three">three</div>']
|
537
|
+
expect(@revealOptions).toEqual { top: true }
|
535
538
|
done()
|
536
539
|
|
537
540
|
it "reveals the entire element if it has no child with the ID of that #hash", (done) ->
|
@@ -794,34 +797,67 @@ describe 'up.flow', ->
|
|
794
797
|
expect(keptListener).toHaveBeenCalledWith(jasmine.anything(), $('.keeper'), jasmine.anything())
|
795
798
|
|
796
799
|
it "removes an [up-keep] element if no matching element is found in the response", ->
|
800
|
+
barCompiler = jasmine.createSpy()
|
801
|
+
barDestructor = jasmine.createSpy()
|
802
|
+
up.compiler '.bar', ($bar) ->
|
803
|
+
text = $bar.text()
|
804
|
+
barCompiler(text)
|
805
|
+
return -> barDestructor(text)
|
806
|
+
|
797
807
|
$container = affix('.container')
|
798
808
|
$container.html """
|
799
809
|
<div class='foo'>old-foo</div>
|
800
810
|
<div class='bar' up-keep>old-bar</div>
|
801
811
|
"""
|
812
|
+
up.hello($container)
|
813
|
+
|
814
|
+
expect(barCompiler.calls.allArgs()).toEqual [['old-bar']]
|
815
|
+
expect(barDestructor.calls.allArgs()).toEqual []
|
816
|
+
|
802
817
|
up.extract '.container', """
|
803
818
|
<div class='container'>
|
804
819
|
<div class='foo'>new-foo</div>
|
805
820
|
</div>
|
806
821
|
"""
|
822
|
+
|
807
823
|
expect($('.container .foo')).toExist()
|
808
824
|
expect($('.container .bar')).not.toExist()
|
809
825
|
|
826
|
+
expect(barCompiler.calls.allArgs()).toEqual [['old-bar']]
|
827
|
+
expect(barDestructor.calls.allArgs()).toEqual [['old-bar']]
|
828
|
+
|
810
829
|
it "updates an element if a matching element is found in the response, but that other element is no longer [up-keep]", ->
|
830
|
+
barCompiler = jasmine.createSpy()
|
831
|
+
barDestructor = jasmine.createSpy()
|
832
|
+
up.compiler '.bar', ($bar) ->
|
833
|
+
text = $bar.text()
|
834
|
+
console.info('Compiling %o', text)
|
835
|
+
barCompiler(text)
|
836
|
+
return -> barDestructor(text)
|
837
|
+
|
811
838
|
$container = affix('.container')
|
812
839
|
$container.html """
|
813
840
|
<div class='foo'>old-foo</div>
|
814
841
|
<div class='bar' up-keep>old-bar</div>
|
815
842
|
"""
|
843
|
+
up.hello($container)
|
844
|
+
|
845
|
+
expect(barCompiler.calls.allArgs()).toEqual [['old-bar']]
|
846
|
+
expect(barDestructor.calls.allArgs()).toEqual []
|
847
|
+
|
816
848
|
up.extract '.container', """
|
817
849
|
<div class='container'>
|
818
850
|
<div class='foo'>new-foo</div>
|
819
851
|
<div class='bar'>new-bar</div>
|
820
852
|
</div>
|
821
853
|
"""
|
854
|
+
|
822
855
|
expect($('.container .foo')).toHaveText('new-foo')
|
823
856
|
expect($('.container .bar')).toHaveText('new-bar')
|
824
857
|
|
858
|
+
expect(barCompiler.calls.allArgs()).toEqual [['old-bar'], ['new-bar']]
|
859
|
+
expect(barDestructor.calls.allArgs()).toEqual [['old-bar']]
|
860
|
+
|
825
861
|
it 'moves a kept element to the ancestry position of the matching element in the response', ->
|
826
862
|
$container = affix('.container')
|
827
863
|
$container.html """
|
@@ -874,6 +910,28 @@ describe 'up.flow', ->
|
|
874
910
|
expect(compiler.calls.count()).toEqual(1)
|
875
911
|
expect('.keeper').toExist()
|
876
912
|
|
913
|
+
it 'does not lose jQuery event handlers on a kept element (bugfix)', ->
|
914
|
+
handler = jasmine.createSpy('event handler')
|
915
|
+
up.compiler '.keeper', ($keeper) ->
|
916
|
+
$keeper.on 'click', handler
|
917
|
+
|
918
|
+
$container = affix('.container')
|
919
|
+
$container.html """
|
920
|
+
<div class="keeper" up-keep>old-text</div>
|
921
|
+
"""
|
922
|
+
up.hello($container)
|
923
|
+
|
924
|
+
up.extract '.container', """
|
925
|
+
<div class='container'>
|
926
|
+
<div class="keeper" up-keep>new-text</div>
|
927
|
+
</div>
|
928
|
+
"""
|
929
|
+
|
930
|
+
$keeper = $('.keeper')
|
931
|
+
expect($keeper).toHaveText('old-text')
|
932
|
+
Trigger.click($keeper)
|
933
|
+
expect(handler).toHaveBeenCalled()
|
934
|
+
|
877
935
|
it 'lets listeners cancel the keeping by preventing default on an up:fragment:keep event', ->
|
878
936
|
$keeper = affix('.keeper[up-keep]').text('old-inside')
|
879
937
|
$keeper.on 'up:fragment:keep', (event) -> event.preventDefault()
|
@@ -2,7 +2,7 @@ describe 'up.form', ->
|
|
2
2
|
|
3
3
|
u = up.util
|
4
4
|
|
5
|
-
describe '
|
5
|
+
describe 'JavaScript functions', ->
|
6
6
|
|
7
7
|
describe 'up.observe', ->
|
8
8
|
|
@@ -419,7 +419,7 @@ describe 'up.form', ->
|
|
419
419
|
afterEach ->
|
420
420
|
window.observeCallbackSpy = undefined
|
421
421
|
|
422
|
-
it 'runs the
|
422
|
+
it 'runs the JavaScript code in the attribute value when a change is observed in the field', (done) ->
|
423
423
|
$form = affix('form')
|
424
424
|
window.observeCallbackSpy = jasmine.createSpy('observe callback')
|
425
425
|
$field = $form.affix('input[val="old-value"][up-observe="window.observeCallbackSpy(value, $field.get(0))"]')
|
@@ -2,7 +2,7 @@ describe 'up.layout', ->
|
|
2
2
|
|
3
3
|
u = up.util
|
4
4
|
|
5
|
-
describe '
|
5
|
+
describe 'JavaScript functions', ->
|
6
6
|
|
7
7
|
describe 'up.reveal', ->
|
8
8
|
|
@@ -78,6 +78,18 @@ describe 'up.layout', ->
|
|
78
78
|
# [2] 70 ......... 5069
|
79
79
|
expect($(document).scrollTop()).toBe(0)
|
80
80
|
|
81
|
+
it 'does not snap to the top if it would un-reveal an element at the bottom edge of the screen (bugfix)', ->
|
82
|
+
up.layout.config.snap = 100
|
83
|
+
|
84
|
+
up.reveal(@$elements[1])
|
85
|
+
# ---------------------
|
86
|
+
# [0] 0 .......... ch-1
|
87
|
+
# [1] ch+0 ...... ch+49
|
88
|
+
# ---------------------
|
89
|
+
# [2] ch+50 ... ch+5049
|
90
|
+
expect($(document).scrollTop()).toBe(50)
|
91
|
+
|
92
|
+
|
81
93
|
it 'scrolls far enough so the element is not obstructed by an element fixed to the top', ->
|
82
94
|
$topNav = affix('[up-fixed=top]').css(
|
83
95
|
position: 'fixed',
|
@@ -161,6 +173,20 @@ describe 'up.layout', ->
|
|
161
173
|
# [F] 0 ............ 99
|
162
174
|
expect($(document).scrollTop()).toBe(@clientHeight + 50)
|
163
175
|
|
176
|
+
describe 'with { top: true } option', ->
|
177
|
+
|
178
|
+
it 'scrolls the viewport to the first row of the element, even if that element is already fully revealed', ->
|
179
|
+
|
180
|
+
@$elements[0].css(height: '20px')
|
181
|
+
|
182
|
+
up.reveal(@$elements[1], { top: true })
|
183
|
+
# [0] 0 ............ 19
|
184
|
+
# [1] 20 ........... 69
|
185
|
+
# ---------------------
|
186
|
+
# [2] 70 ......... 5069
|
187
|
+
# ---------------------
|
188
|
+
expect($(document).scrollTop()).toBe(20)
|
189
|
+
|
164
190
|
|
165
191
|
describe 'when the viewport is a container with overflow-y: scroll', ->
|
166
192
|
|
@@ -2,7 +2,7 @@ describe 'up.link', ->
|
|
2
2
|
|
3
3
|
u = up.util
|
4
4
|
|
5
|
-
describe '
|
5
|
+
describe 'JavaScript functions', ->
|
6
6
|
|
7
7
|
describe 'up.follow', ->
|
8
8
|
|
@@ -462,7 +462,7 @@ describe 'up.link', ->
|
|
462
462
|
Trigger.click(@$link)
|
463
463
|
expect(@followSpy).toHaveBeenCalledWith(@$link)
|
464
464
|
|
465
|
-
# IE does not call
|
465
|
+
# IE does not call JavaScript and always performs the default action on right clicks
|
466
466
|
unless navigator.userAgent.match(/Trident/)
|
467
467
|
it 'does nothing if the right mouse button is used', ->
|
468
468
|
Trigger.click(@$link, button: 2)
|
@@ -497,7 +497,7 @@ describe 'up.link', ->
|
|
497
497
|
Trigger.click(@$link)
|
498
498
|
expect(@followSpy).not.toHaveBeenCalled()
|
499
499
|
|
500
|
-
# IE does not call
|
500
|
+
# IE does not call JavaScript and always performs the default action on right clicks
|
501
501
|
unless navigator.userAgent.match(/Trident/)
|
502
502
|
it 'does nothing if the right mouse button is pressed down', ->
|
503
503
|
Trigger.mousedown(@$link, button: 2)
|