unpoly-rails 0.30.1 → 0.31.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of unpoly-rails might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e53ab2c1cbdfe09b80e31d76371d5382ad40f70
4
- data.tar.gz: 7ba79eb21d2494bf69b3bc222a4b7e89778671a1
3
+ metadata.gz: f141062c454db36ff9fa469178c4980587858770
4
+ data.tar.gz: cd9474a9ab62e41572b56f731822ef1483f8543a
5
5
  SHA512:
6
- metadata.gz: 5789b11f34c69787dbf6fdd9fe9ed03d6c25c5c76fbf32b7028fcba36a6ecad14072c10d1cf5b4945d7edd104d11e581a302f6ca45b1c15baf4b5aa868c90691
7
- data.tar.gz: 3d07d31ce7a01814badad2a7e16fbe4bbf283dc574a6b27818ea9a2ba5a6cff9b9fdcf6a9acfd19b6d505d12f8c84486ea12b7322fae39fa7000cb9af3492c1d
6
+ metadata.gz: 81d7cf8973a69e968ca7063cc058fbef25403027638d504c2b8fb3919b87e24ea11d1b0f7ca219c8a2a8ca340d13a8cd45474ecab50a6275d1fbae86c8d1def5
7
+ data.tar.gz: eadfbdd2d046e641e8a93462d2bfb8cdb274086afedff58aa21681d1641a4d501ebc26722195f4d068f7a717e8ec2777ebb316cfda911264775f6e0f57a2d8d1
data/CHANGELOG.md CHANGED
@@ -10,9 +10,17 @@ Unreleased
10
10
 
11
11
  ### Compatible changes
12
12
 
13
+ - Drawers are now a built-in modal flavor! Use the `[up-drawer]` attribute to open page fragements
14
+ in a modal drawer that slides in from the edge of the screen.
15
+
13
16
 
14
17
  ### Breaking changes
15
18
 
19
+ - The [`up.modal.flavor`](/up.modal.flavor) function was deprecated. Set values on the
20
+ [`up.modal.flavors`](/up.modal.flavors) property instead.
21
+
22
+
23
+
16
24
 
17
25
  0.30.1
18
26
  ------
@@ -249,8 +249,6 @@ up.form = (($) ->
249
249
  delay = u.option($fields.attr('up-delay'), options.delay, config.observeDelay)
250
250
  delay = parseInt(delay)
251
251
 
252
- console.debug("Observing with delay %o", delay)
253
-
254
252
  destructors = u.map $fields, (field) ->
255
253
  observeField($(field), delay, callback)
256
254
 
@@ -116,6 +116,8 @@ up.modal = (($) ->
116
116
  @param {Boolean} [options.sticky=false]
117
117
  If set to `true`, the modal remains
118
118
  open even it changes the page in the background.
119
+ @param {String} [options.flavor='default']
120
+ The default [flavor](/up.modal.flavors).
119
121
  @stable
120
122
  ###
121
123
  config = u.config
@@ -135,21 +137,62 @@ up.modal = (($) ->
135
137
  closeLabel: '×'
136
138
  closable: true
137
139
  sticky: false
138
- flavors: { default: {} }
139
-
140
- template: (config) ->
140
+ flavor: 'default'
141
+ position: null
142
+ template: (options) ->
141
143
  """
142
144
  <div class="up-modal">
143
145
  <div class="up-modal-backdrop"></div>
144
146
  <div class="up-modal-viewport">
145
147
  <div class="up-modal-dialog">
146
148
  <div class="up-modal-content"></div>
147
- <div class="up-modal-close" up-close>#{flavorDefault('closeLabel')}</div>
149
+ <div class="up-modal-close" up-close>#{options.closeLabel}</div>
148
150
  </div>
149
151
  </div>
150
152
  </div>
151
153
  """
152
154
 
155
+ ###*
156
+ Define modal variants with their own default configuration, CSS or HTML template.
157
+
158
+ \#\#\# Example
159
+
160
+ Unpoly's [`[up-drawer]`](/up-drawer) is implemented as a modal flavor:
161
+
162
+ up.modal.flavors.drawer = {
163
+ openAnimation: 'move-from-right',
164
+ closeAnimation: 'move-to-right'
165
+ }
166
+
167
+ Modals with that flavor will have a container with an `up-flavor` attribute:
168
+
169
+ <div class='up-modal' up-flavor='drawer'>
170
+ ...
171
+ </div>
172
+
173
+ We can target the `up-flavor` attribute to override the default dialog styles:
174
+
175
+ .up-modal[up-flavor='drawer'] {
176
+
177
+ .up-modal-dialog {
178
+ margin: 0; // Remove margin so drawer starts at the screen edge
179
+ max-width: 350px; // Set drawer size
180
+ }
181
+
182
+ .up-modal-content {
183
+ min-height: 100vh; // Stretch background to full window height
184
+ }
185
+ }
186
+
187
+ @property up.modal.flavors
188
+ @param {Object} flavors
189
+ An object where the keys are flavor names (e.g. `'drawer') and
190
+ the values are the respective default configurations.
191
+ @experimental
192
+ ###
193
+ flavors = u.openConfig
194
+ default: {}
195
+
153
196
  ###*
154
197
  Returns the source URL for the fragment displayed in the current modal overlay,
155
198
  or `undefined` if no modal is currently open.
@@ -178,6 +221,7 @@ up.modal = (($) ->
178
221
  url: null
179
222
  coveredUrl: null
180
223
  coveredTitle: null
224
+ position: null
181
225
  unshifters: []
182
226
 
183
227
  chain = new u.DivertibleChain()
@@ -188,13 +232,11 @@ up.modal = (($) ->
188
232
  state.reset()
189
233
  chain.reset()
190
234
  config.reset()
235
+ flavors.reset()
191
236
 
192
237
  templateHtml = ->
193
238
  template = flavorDefault('template')
194
- if u.isFunction(template)
195
- template(config)
196
- else
197
- template
239
+ u.evalOption(template, closeLabel: flavorDefault('closeLabel'))
198
240
 
199
241
  discardHistory = ->
200
242
  state.coveredTitle = null
@@ -203,6 +245,7 @@ up.modal = (($) ->
203
245
  createFrame = (target, options) ->
204
246
  $modal = $(templateHtml())
205
247
  $modal.attr('up-flavor', state.flavor)
248
+ $modal.attr('up-position', state.position) if u.isPresent(state.position)
206
249
  $dialog = $modal.find('.up-modal-dialog')
207
250
  $dialog.css('width', options.width) if u.isPresent(options.width)
208
251
  $dialog.css('max-width', options.maxWidth) if u.isPresent(options.maxWidth)
@@ -389,12 +432,16 @@ up.modal = (($) ->
389
432
  url = u.option(u.pluckKey(options, 'url'), $link.attr('up-href'), $link.attr('href'))
390
433
  html = u.option(u.pluckKey(options, 'html'))
391
434
  target = u.option(u.pluckKey(options, 'target'), $link.attr('up-modal'), 'body')
392
- options.flavor = u.option(options.flavor, $link.attr('up-flavor'))
435
+ options.flavor = u.option(options.flavor, $link.attr('up-flavor'), config.flavor)
436
+ options.position = u.option(options.position, $link.attr('up-position'), flavorDefault('position', options.flavor))
437
+ options.position = u.evalOption(options.position, $link: $link)
393
438
  options.width = u.option(options.width, $link.attr('up-width'), flavorDefault('width', options.flavor))
394
439
  options.maxWidth = u.option(options.maxWidth, $link.attr('up-max-width'), flavorDefault('maxWidth', options.flavor))
395
440
  options.height = u.option(options.height, $link.attr('up-height'), flavorDefault('height'))
396
441
  options.animation = u.option(options.animation, $link.attr('up-animation'), flavorDefault('openAnimation', options.flavor))
442
+ options.animation = u.evalOption(options.animation, position: options.position)
397
443
  options.backdropAnimation = u.option(options.backdropAnimation, $link.attr('up-backdrop-animation'), flavorDefault('backdropOpenAnimation', options.flavor))
444
+ options.backdropAnimation = u.evalOption(options.backdropAnimation, position: options.position)
398
445
  options.sticky = u.option(options.sticky, u.castedAttr($link, 'up-sticky'), flavorDefault('sticky', options.flavor))
399
446
  options.closable = u.option(options.closable, u.castedAttr($link, 'up-closable'), flavorDefault('closable', options.flavor))
400
447
  options.confirm = u.option(options.confirm, $link.attr('up-confirm'))
@@ -414,6 +461,7 @@ up.modal = (($) ->
414
461
  state.flavor = options.flavor
415
462
  state.sticky = options.sticky
416
463
  state.closable = options.closable
464
+ state.position = options.position
417
465
  if options.history
418
466
  state.coveredUrl = up.browser.url()
419
467
  state.coveredTitle = document.title
@@ -473,7 +521,9 @@ up.modal = (($) ->
473
521
 
474
522
  options = u.options(options)
475
523
  viewportCloseAnimation = u.option(options.animation, flavorDefault('closeAnimation'))
524
+ viewportCloseAnimation = u.evalOption(viewportCloseAnimation, position: state.position)
476
525
  backdropCloseAnimation = u.option(options.backdropAnimation, flavorDefault('backdropCloseAnimation'))
526
+ backdropCloseAnimation = u.evalOption(backdropCloseAnimation, position: state.position)
477
527
  animateOptions = up.motion.animateOptions(options, duration: flavorDefault('closeDuration'), easing: flavorDefault('closeEasing'))
478
528
 
479
529
  destroyOptions = u.options(
@@ -502,6 +552,7 @@ up.modal = (($) ->
502
552
  state.flavor = null
503
553
  state.sticky = null
504
554
  state.closable = null
555
+ state.position = null
505
556
  up.emit('up:modal:closed', message: 'Modal closed')
506
557
 
507
558
  promise
@@ -557,42 +608,8 @@ up.modal = (($) ->
557
608
  $element = $(elementOrSelector)
558
609
  $element.closest('.up-modal').length > 0
559
610
 
560
- ###*
561
- Register a new modal variant with its own default configuration, CSS or HTML template.
562
-
563
- \#\#\# Example
564
-
565
- Let's implement a drawer that slides in from the right:
566
-
567
- up.modal.flavor('drawer', {
568
- openAnimation: 'move-from-right',
569
- closeAnimation: 'move-to-right',
570
- maxWidth: 400
571
- }
572
-
573
- Modals with that flavor will have a container `<div class='up-modal' up-flavor='drawer'>...</div>`.
574
- We can target the `up-flavor` attribute override the default dialog styles:
575
-
576
- .up-modal[up-flavor='drawer'] {
577
-
578
- // Align drawer on the right
579
- .up-modal-viewport { text-align: right; }
580
-
581
- // Remove margin so the drawer starts at the screen edge
582
- .up-modal-dialog { margin: 0; }
583
-
584
- // Stretch drawer background to full window height
585
- .up-modal-content { min-height: 100vh; }
586
- }
587
-
588
- @function up.modal.flavor
589
- @param {String} name
590
- The name of the new flavor.
591
- @param {Object} [overrideConfig]
592
- An object whose properties override the defaults in [`/up.modal.config`](/up.modal.config).
593
- @experimental
594
- ###
595
611
  flavor = (name, overrideConfig = {}) ->
612
+ up.log.warn 'The up.modal.flavor function is deprecated. Use the up.modal.flavors property instead.'
596
613
  u.extend(flavorOverrides(name), overrideConfig)
597
614
 
598
615
  ###*
@@ -604,7 +621,7 @@ up.modal = (($) ->
604
621
  @internal
605
622
  ###
606
623
  flavorOverrides = (flavor) ->
607
- config.flavors[flavor] ||= {}
624
+ flavors[flavor] ||= {}
608
625
 
609
626
  ###*
610
627
  Returns the config option for the current flavor.
@@ -621,16 +638,18 @@ up.modal = (($) ->
621
638
  Clicking this link will load the destination via AJAX and open
622
639
  the given selector in a modal dialog.
623
640
 
624
- Example:
641
+ \#\#\#\# Example
625
642
 
626
643
  <a href="/blogs" up-modal=".blog-list">Switch blog</a>
627
644
 
628
645
  Clicking would request the path `/blog` and select `.blog-list` from
629
- the HTML response. Unpoly will dim the page with an overlay
646
+ the HTML response. Unpoly will dim the page
630
647
  and place the matching `.blog-list` tag will be placed in
631
648
  a modal dialog.
632
649
 
633
650
  @selector [up-modal]
651
+ @param {String} up-modal
652
+ The CSS selector that will be extracted from the response and displayed in a modal dialog.
634
653
  @param {String} [up-confirm]
635
654
  A message that will be displayed in a cancelable confirmation dialog
636
655
  before the modal is opened.
@@ -712,6 +731,65 @@ up.modal = (($) ->
712
731
  up.bus.consumeAction(event)
713
732
  )
714
733
 
734
+ ###*
735
+ Clicking this link will load the destination via AJAX and open
736
+ the given selector in a modal drawer that slides in from the edge of the screen.
737
+
738
+ You can configure drawers using the [`up.modal.flavors.drawer`](/up.modal.flavors.drawer) property.
739
+
740
+ \#\#\#\# Example
741
+
742
+ <a href="/blogs" up-drawer=".blog-list">Switch blog</a>
743
+
744
+ Clicking would request the path `/blog` and select `.blog-list` from
745
+ the HTML response. Unpoly will dim the page
746
+ and place the matching `.blog-list` tag will be placed in
747
+ a modal drawer.
748
+
749
+ @selector [up-drawer]
750
+ @param {String} up-drawer
751
+ The CSS selector to extract from the response and open in the drawer.
752
+ @param {String} [up-position='auto']
753
+ The side from which the drawer slides in.
754
+
755
+ Valid values are `'left'`, `'right'` and `'auto'`. If set to `'auto'`, the
756
+ drawer will slide in from left if the opening link is on the left half of the screen.
757
+ Otherwise it will slide in from the right.
758
+ @experimental
759
+ ###
760
+ up.macro '[up-drawer]', ($link) ->
761
+ target = $link.attr('up-drawer')
762
+ $link.attr
763
+ 'up-modal': target
764
+ 'up-flavor': 'drawer'
765
+
766
+ ###*
767
+ Sets default options for future drawers.
768
+
769
+ @property up.modal.flavors.drawer
770
+ @param {Object} config
771
+ Default options for future drawers.
772
+
773
+ See [`up.modal.config`] for available options.
774
+ @experimental
775
+ ###
776
+ flavors.drawer =
777
+ openAnimation: (options) ->
778
+ switch options.position
779
+ when 'left' then 'move-from-left'
780
+ when 'right' then 'move-from-right'
781
+ closeAnimation: (options) ->
782
+ switch options.position
783
+ when 'left' then 'move-to-left'
784
+ when 'right' then 'move-to-right'
785
+ position: (options) ->
786
+ if u.isPresent(options.$link)
787
+ u.horizontalScreenHalf(options.$link)
788
+ else
789
+ # In case the drawer was opened programmatically through `up.modal.open`,
790
+ # we might now know the link that was clicked on.
791
+ 'left'
792
+
715
793
  # The framework is reset between tests
716
794
  up.on 'up:framework:reset', reset
717
795
 
@@ -723,8 +801,9 @@ up.modal = (($) ->
723
801
  url: -> state.url
724
802
  coveredUrl: -> state.coveredUrl
725
803
  config: config
804
+ flavors: flavors
726
805
  contains: contains
727
806
  isOpen: isOpen
728
- flavor: flavor
807
+ flavor: flavor # deprecated
729
808
 
730
809
  )(jQuery)
@@ -165,7 +165,7 @@ up.motion = (($) ->
165
165
  $element = $(elementOrSelector)
166
166
  finish($element)
167
167
  options = animateOptions(options)
168
- if animation == 'none' || animation == false
168
+ if animation == 'none' || animation == false || u.isMissing(animation)
169
169
  none()
170
170
  else if u.isFunction(animation)
171
171
  assertIsDeferred(animation($element, options), animation)
@@ -373,6 +373,9 @@ up.popup = (($) ->
373
373
  <a href="/settings" up-popup=".options" up-sticky>Settings</a>
374
374
 
375
375
  @selector [up-popup]
376
+ @param {String} up-popup
377
+ The CSS selector that will be extracted from the response and
378
+ displayed in a popup overlay.
376
379
  @param [up-position]
377
380
  Defines where the popup is attached to the opening element.
378
381
 
@@ -1381,6 +1381,19 @@ up.util = (($) ->
1381
1381
 
1382
1382
  obj
1383
1383
 
1384
+ ###*
1385
+ If the given `value` is a function, calls the function with the given `args`.
1386
+ Otherwise it just returns `value`.
1387
+
1388
+ @function up.util.evalOption
1389
+ @internal
1390
+ ###
1391
+ evalOption = (value, args...) ->
1392
+ if isFunction(value)
1393
+ value(args...)
1394
+ else
1395
+ value
1396
+
1384
1397
  ###*
1385
1398
  @function up.util.cache
1386
1399
  @param {Number|Function} [config.size]
@@ -1400,19 +1413,8 @@ up.util = (($) ->
1400
1413
 
1401
1414
  store = undefined
1402
1415
 
1403
- optionEvaluator = (name) ->
1404
- ->
1405
- value = config[name]
1406
- if isNumber(value)
1407
- value
1408
- else if isFunction(value)
1409
- value()
1410
- else
1411
- undefined
1412
-
1413
- maxKeys = optionEvaluator('size')
1414
-
1415
- expiryMillis = optionEvaluator('expiry')
1416
+ maxKeys = -> evalOption(config.size)
1417
+ expiryMillis = -> evalOption(config.expiry)
1416
1418
 
1417
1419
  normalizeStoreKey = (key) ->
1418
1420
  if config.key
@@ -1501,16 +1503,29 @@ up.util = (($) ->
1501
1503
 
1502
1504
  ###*
1503
1505
  @function up.util.config
1506
+ @param {Object|Function} blueprint
1507
+ Default configuration options.
1508
+ Will be restored by calling `reset` on the returned object.
1509
+ @return {Object}
1510
+ An object with a `reset` function.
1511
+ @internal
1512
+ ###
1513
+ config = (blueprint) ->
1514
+ hash = openConfig(blueprint)
1515
+ Object.preventExtensions(hash)
1516
+ hash
1517
+
1518
+ ###*
1519
+ @function up.util.openConfig
1504
1520
  @internal
1505
1521
  ###
1506
- config = (blueprint = {}) ->
1522
+ openConfig = (blueprint = {}) ->
1507
1523
  hash = {}
1508
1524
  hash.reset = ->
1509
1525
  newOptions = blueprint
1510
1526
  newOptions = newOptions() if isFunction(newOptions)
1511
1527
  extend(hash, newOptions)
1512
1528
  hash.reset()
1513
- Object.preventExtensions(hash)
1514
1529
  hash
1515
1530
 
1516
1531
  ###*
@@ -1873,6 +1888,23 @@ up.util = (($) ->
1873
1888
  deferred.cancel = -> clearTimeout(timeout)
1874
1889
  deferred
1875
1890
 
1891
+ ###*
1892
+ Returns `'left'` if the center of the given element is in the left 50% of the screen.
1893
+ Otherwise returns `'right'`.
1894
+
1895
+ @function up.util.horizontalScreenHalf
1896
+ @internal
1897
+ ###
1898
+ horizontalScreenHalf = ($element) ->
1899
+ elementDims = measure($element)
1900
+ screenDims = clientSize()
1901
+ elementMid = elementDims.left + 0.5 * elementDims.width
1902
+ screenMid = 0.5 * screenDims.width
1903
+ if elementMid < screenMid
1904
+ 'left'
1905
+ else
1906
+ 'right'
1907
+
1876
1908
  isDetached: isDetached
1877
1909
  requestDataAsArray: requestDataAsArray
1878
1910
  requestDataAsQuery: requestDataAsQuery
@@ -1965,6 +1997,7 @@ up.util = (($) ->
1965
1997
  scrollbarWidth: scrollbarWidth
1966
1998
  documentHasVerticalScrollbar: documentHasVerticalScrollbar
1967
1999
  config: config
2000
+ openConfig: openConfig
1968
2001
  cache: cache
1969
2002
  unwrapElement: unwrapElement
1970
2003
  multiSelector: multiSelector
@@ -1983,6 +2016,8 @@ up.util = (($) ->
1983
2016
  sequence: sequence
1984
2017
  promiseTimer: promiseTimer
1985
2018
  previewable: previewable
2019
+ evalOption: evalOption
2020
+ horizontalScreenHalf: horizontalScreenHalf
1986
2021
 
1987
2022
  )($)
1988
2023
 
@@ -2,3 +2,21 @@
2
2
  // Unpoly: Gives some default padding
3
3
  // BS: Expects content to set the padding
4
4
  padding: 0
5
+
6
+ .up-modal[up-flavor='drawer']
7
+
8
+ .up-modal-content
9
+ // Bootstrap gives its modals round corners, which looks wrong with a
10
+ // drawer that sits at the end of the screen.
11
+ border-radius: 0
12
+
13
+ // Bootstrap gives its modals a border, which looks wrong
14
+ // when touching the edge of the screen.
15
+ border-top: none
16
+ border-bottom: none
17
+
18
+ &[up-position='left'] .up-modal-content
19
+ border-left: none
20
+
21
+ &[up-position='right'] .up-modal-content
22
+ border-right: none
@@ -96,3 +96,16 @@ $close-font-size: 34px
96
96
  color: #666
97
97
  cursor: pointer
98
98
 
99
+ .up-modal[up-flavor='drawer']
100
+ .up-modal-viewport
101
+ text-align: left
102
+ &[up-position='right'] .up-modal-viewport
103
+ text-align: right
104
+ .up-modal-dialog
105
+ margin: 0
106
+ max-width: 350px
107
+ .up-modal-content
108
+ min-height: 100vh
109
+ box-sizing: border-box // since we're setting min-height on an element with padding
110
+
111
+
@@ -4,6 +4,6 @@ module Unpoly
4
4
  # The current version of the unpoly-rails gem.
5
5
  # This version number is also used for releases of the Unpoly
6
6
  # frontend code.
7
- VERSION = '0.30.1'
7
+ VERSION = '0.31.0'
8
8
  end
9
9
  end
data/spec_app/Gemfile CHANGED
@@ -11,6 +11,7 @@ gem 'therubyracer', platforms: :ruby
11
11
  gem 'jquery-rails'
12
12
  gem 'unpoly-rails', path: '..'
13
13
  gem 'bower-rails'
14
+ gem 'bootstrap-sass', '~> 3.3'
14
15
 
15
16
  # Jasmine spec runner won't boot with a more modern version of sprockets.
16
17
  # It crashes with an "asset not precompiled" error.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- unpoly-rails (0.30.0)
4
+ unpoly-rails (0.30.1)
5
5
  rails (>= 3)
6
6
 
7
7
  GEM
@@ -43,8 +43,13 @@ GEM
43
43
  thread_safe (~> 0.3, >= 0.3.4)
44
44
  tzinfo (~> 1.1)
45
45
  arel (6.0.3)
46
+ autoprefixer-rails (6.5.1.1)
47
+ execjs
46
48
  binding_of_caller (0.7.2)
47
49
  debug_inspector (>= 0.0.1)
50
+ bootstrap-sass (3.3.7)
51
+ autoprefixer-rails (>= 5.2.1)
52
+ sass (>= 3.3.4)
48
53
  bower-rails (0.9.2)
49
54
  builder (3.2.2)
50
55
  byebug (3.5.1)
@@ -195,6 +200,7 @@ PLATFORMS
195
200
  ruby
196
201
 
197
202
  DEPENDENCIES
203
+ bootstrap-sass (~> 3.3)
198
204
  bower-rails
199
205
  byebug
200
206
  coffee-rails (~> 4.1.0)
@@ -0,0 +1,6 @@
1
+ #= require bootstrap-sprockets
2
+
3
+ # From the docs (https://github.com/twbs/bootstrap-sass):
4
+ # bootstrap-sprockets and bootstrap should not both be included in application.js.
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.
@@ -0,0 +1,5 @@
1
+ =clear_after
2
+ &:after
3
+ content: ""
4
+ display: table
5
+ clear: both
@@ -0,0 +1,2 @@
1
+ @import bootstrap-sprockets
2
+ @import bootstrap
@@ -1,5 +1,7 @@
1
1
  //= require unpoly
2
2
 
3
+ @import helpers
4
+
3
5
  $block-spacing: 25px
4
6
 
5
7
  =block-spacing
@@ -14,6 +16,11 @@ body
14
16
  h1, h2, h3, h4, p
15
17
  +block-spacing
16
18
 
19
+ a
20
+ color: #169
21
+ &:hover
22
+ color: #e81
23
+
17
24
  .page
18
25
  min-height: 3000px
19
26
 
@@ -32,6 +39,7 @@ h1, h2, h3, h4, p
32
39
 
33
40
  .example
34
41
  margin: 50px
42
+ +clear-after
35
43
 
36
44
  .area
37
45
  +block-spacing
@@ -44,13 +52,14 @@ h1, h2, h3, h4, p
44
52
  line-height: 50px
45
53
  padding-left: 25px
46
54
  padding-right: 25px
47
- background-color: #e21
55
+ background-color: #37b
48
56
  color: white
49
57
  text-decoration: none
50
58
  &.up-current
51
- background-color: #921
59
+ background-color: #e21
52
60
  &:hover
53
61
  background-color: #fa1
62
+ color: white
54
63
  &.up-active
55
64
  background-color: #ff0
56
65
 
@@ -1,3 +1,13 @@
1
1
  <div class="example">
2
2
  <a class="button" href="/css_test/modal_contents" up-modal=".contents">Modal</a>
3
3
  </div>
4
+
5
+ <div class="example">
6
+ <a class="button" href="/css_test/modal_contents" up-drawer=".contents" style="float: left">Drawer (auto)</a>
7
+ <a class="button" href="/css_test/modal_contents" up-drawer=".contents" style="float: right">Drawer (auto)</a>
8
+ </div>
9
+
10
+ <div class="example">
11
+ <a class="button" href="/css_test/modal_contents" up-drawer=".contents" up-position="left">Drawer (left)</a>
12
+ <a class="button" href="/css_test/modal_contents" up-drawer=".contents" up-position="right">Drawer (right)</a>
13
+ </div>
@@ -1,5 +1,5 @@
1
1
  <div class="contents">
2
- Line 1: Foo bar baz bam qux foo bar baz bam qux<br>
3
- Line 2: Foo bar baz bam qux foo bar baz bam qux<br>
4
- Line 3: Foo bar baz bam qux foo bar baz bam qux
2
+ <% (1..100).each do |i| %>
3
+ Line <%= i %>: Foo bar baz bam qux foo bar baz bam qux<br>
4
+ <% end %>
5
5
  </div>
@@ -4,6 +4,12 @@
4
4
  <title>Integration test - Unpoly</title>
5
5
  <%= stylesheet_link_tag 'integration_test', media: 'all' %>
6
6
  <%= javascript_include_tag 'integration_test' %>
7
+ <% if params[:bootstrap] == '1' %>
8
+ <%= stylesheet_link_tag 'bootstrap_manifest', media: 'all' %>
9
+ <%= javascript_include_tag 'bootstrap_manifest' %>
10
+ <%= stylesheet_link_tag 'unpoly-bootstrap3', media: 'all' %>
11
+ <%= javascript_include_tag 'unpoly-bootstrap3' %>
12
+ <% end %>
7
13
  <%= csrf_meta_tags %>
8
14
  </head>
9
15
  <body>
@@ -11,15 +11,24 @@
11
11
  <h2>Integration tests</h2>
12
12
 
13
13
  <ul>
14
- <li><%= link_to 'Tooltip', '/css_test/tooltip' %></li>
14
+ <li>
15
+ <%= link_to 'Tooltip', '/css_test/tooltip' %>
16
+ (<%= link_to 'with Bootstrap', '/css_test/tooltip?bootstrap=1' %>)
17
+ </li>
15
18
  </ul>
16
19
 
17
20
  <ul>
18
- <li><%= link_to 'Popup', '/css_test/popup' %></li>
21
+ <li>
22
+ <%= link_to 'Popup', '/css_test/popup' %>
23
+ (<%= link_to 'with Bootstrap', '/css_test/popup?bootstrap=1' %>)
24
+ </li>
19
25
  </ul>
20
26
 
21
27
  <ul>
22
- <li><%= link_to 'Modal', '/css_test/modal' %></li>
28
+ <li>
29
+ <%= link_to 'Modal', '/css_test/modal' %>
30
+ (<%= link_to 'with Bootstrap', '/css_test/modal?bootstrap=1' %>)
31
+ </li>
23
32
  </ul>
24
33
 
25
34
  <ul>
@@ -11,4 +11,8 @@ Rails.application.config.assets.version = '1.0'
11
11
 
12
12
 
13
13
  Rails.application.config.assets.precompile += %w( application.js application.css )
14
- Rails.application.config.assets.precompile += %w( jasmine_specs.js jasmine_specs.css integration_test.js integration_test.css )
14
+ Rails.application.config.assets.precompile += %w( jasmine_specs.js jasmine_specs.css )
15
+ Rails.application.config.assets.precompile += %w( integration_test.js integration_test.css )
16
+ Rails.application.config.assets.precompile += %w( bootstrap_manifest.js bootstrap_manifest.css )
17
+ Rails.application.config.assets.precompile += %w( unpoly-bootstrap3.js unpoly-bootstrap3.css )
18
+
@@ -100,7 +100,6 @@ describe 'up.form', ->
100
100
  it 'does not run multiple callbacks if a long-running callback has been blocking multiple subsequent callbacks'
101
101
 
102
102
  it "runs a callback in the same frame if the delay is 0", ->
103
- console.debug('*** next example')
104
103
  $input = affix('input[value="old-value"]')
105
104
  callback = jasmine.createSpy('change callback')
106
105
  up.observe($input, { delay: 0 }, callback)
@@ -394,6 +394,30 @@ describe 'up.link', ->
394
394
  expect($('.document .target')).toHaveText('new text from document link')
395
395
  done()
396
396
 
397
+ describe 'with [up-fail-target] modifier', ->
398
+
399
+ beforeEach ->
400
+ affix('.success-target').text('old success text')
401
+ affix('.failure-target').text('old failure text')
402
+ @$link = affix('a[href="/path"][up-target=".success-target"][up-fail-target=".failure-target"]')
403
+
404
+ it 'uses the [up-fail-target] selector for a failed response', (done) ->
405
+ Trigger.clickSequence(@$link)
406
+ u.nextFrame =>
407
+ @respondWith('<div class="failure-target">new failure text</div>', status: 500)
408
+ u.nextFrame =>
409
+ expect($('.success-target')).toHaveText('old success text')
410
+ expect($('.failure-target')).toHaveText('new failure text')
411
+ done()
412
+
413
+ it 'uses the [up-target] selector for a successful response', (done) ->
414
+ Trigger.clickSequence(@$link)
415
+ u.nextFrame =>
416
+ @respondWith('<div class="success-target">new success text</div>', status: 200)
417
+ u.nextFrame =>
418
+ expect($('.success-target')).toHaveText('new success text')
419
+ expect($('.failure-target')).toHaveText('old failure text')
420
+ done()
397
421
 
398
422
  describe 'with [up-transition] modifier', ->
399
423
 
@@ -225,7 +225,7 @@ describe 'up.modal', ->
225
225
  up.modal.config.openDuration = 20
226
226
  up.modal.config.closeAnimation = 'fade-out'
227
227
  up.modal.config.closeDuration = 20
228
- up.modal.flavor 'drawer',
228
+ up.modal.flavor 'custom-drawer',
229
229
  openAnimation: 'move-from-right'
230
230
  closeAnimation: 'move-to-right'
231
231
 
@@ -252,7 +252,7 @@ describe 'up.modal', ->
252
252
  ]
253
253
 
254
254
 
255
- up.modal.extract('.target', '<div class="target">response2</div>', flavor: 'drawer')
255
+ up.modal.extract('.target', '<div class="target">response2</div>', flavor: 'custom-drawer')
256
256
  expect(animations).toEqual [
257
257
  { animation: 'fade-in', text: 'response1' },
258
258
  { animation: 'fade-out', text: 'response1' },
@@ -266,7 +266,7 @@ describe 'up.modal', ->
266
266
  { animation: 'move-from-right', text: 'response2' }
267
267
  ]
268
268
 
269
- expect($('.up-modal').attr('up-flavor')).toEqual('drawer')
269
+ expect($('.up-modal').attr('up-flavor')).toEqual('custom-drawer')
270
270
 
271
271
  done()
272
272
 
@@ -293,10 +293,10 @@ describe 'up.modal', ->
293
293
  expect(up.modal.coveredUrl()).toBeMissing()
294
294
  done()
295
295
 
296
- describe 'up.modal.flavor', ->
296
+ describe 'up.modal.flavors', ->
297
297
 
298
- it 'registers a new modal variant with its own default configuration', ->
299
- up.modal.flavor('variant', { maxWidth: 200 })
298
+ it 'allows to register new modal variants with its own default configuration', ->
299
+ up.modal.flavors.variant = { maxWidth: 200 }
300
300
  $link = affix('a[href="/path"][up-modal=".target"][up-flavor="variant"]')
301
301
  Trigger.click($link)
302
302
  @respondWith('<div class="target">new text</div>')
@@ -307,7 +307,7 @@ describe 'up.modal', ->
307
307
  expect($dialog.attr('style')).toContain('max-width: 200px')
308
308
 
309
309
  it 'does not change the configuration of non-flavored modals', ->
310
- up.modal.flavor('variant', { maxWidth: 200 })
310
+ up.modal.flavors.variant = { maxWidth: 200 }
311
311
  $link = affix('a[href="/path"][up-modal=".target"]')
312
312
  Trigger.click($link)
313
313
  @respondWith('<div class="target">new text</div>')
@@ -417,6 +417,40 @@ describe 'up.modal', ->
417
417
  Trigger.click($link)
418
418
  expect(@lastRequest().method).toEqual 'POST'
419
419
 
420
+ describe '[up-drawer]', ->
421
+
422
+ beforeEach ->
423
+ up.motion.config.enabled = false
424
+
425
+ it 'slides in a drawer that covers the full height of the screen', (done) ->
426
+ $link = affix('a[href="/foo"][up-drawer=".target"]').text('label')
427
+ up.hello($link)
428
+ Trigger.clickSequence($link)
429
+ u.nextFrame =>
430
+ @respondWith '<div class="target">new text</div>'
431
+ expect(up.modal.isOpen()).toBe(true)
432
+ expect($('.up-modal').attr('up-flavor')).toEqual('drawer')
433
+ windowHeight = u.clientSize().height
434
+ modalHeight = $('.up-modal-content').outerHeight()
435
+ expect(modalHeight).toEqual(windowHeight)
436
+ expect($('.up-modal-content').offset()).toEqual(top: 0, left: 0)
437
+ done()
438
+
439
+ it 'puts the drawer on the right if the opening link sits in the right 50% of the screen', (done) ->
440
+ $link = affix('a[href="/foo"][up-drawer=".target"]').text('label')
441
+ $link.css
442
+ position: 'absolute'
443
+ right: '0'
444
+ up.hello($link)
445
+ Trigger.clickSequence($link)
446
+ u.nextFrame =>
447
+ @respondWith '<div class="target">new text</div>'
448
+ expect(up.modal.isOpen()).toBe(true)
449
+ windowWidth = u.clientSize().width
450
+ modalWidth = $('.up-modal-content').outerWidth()
451
+ scrollbarWidth = u.scrollbarWidth()
452
+ expect($('.up-modal-content').offset().left).toBeAround(windowWidth - modalWidth - scrollbarWidth, 1.0)
453
+ done()
420
454
 
421
455
  describe '[up-close]', ->
422
456
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unpoly-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.30.1
4
+ version: 0.31.0
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-10-05 00:00:00.000000000 Z
11
+ date: 2016-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -139,8 +139,11 @@ files:
139
139
  - spec_app/Rakefile
140
140
  - spec_app/app/assets/images/.keep
141
141
  - spec_app/app/assets/images/grid.png
142
+ - spec_app/app/assets/javascripts/bootstrap_manifest.coffee
142
143
  - spec_app/app/assets/javascripts/integration_test.coffee
143
144
  - spec_app/app/assets/javascripts/jasmine_specs.coffee
145
+ - spec_app/app/assets/stylesheets/_helpers.sass
146
+ - spec_app/app/assets/stylesheets/bootstrap_manifest.sass
144
147
  - spec_app/app/assets/stylesheets/integration_test.sass
145
148
  - spec_app/app/assets/stylesheets/jasmine_specs.sass
146
149
  - spec_app/app/controllers/application_controller.rb