lib/assets/javascripts/up/modal.js.coffee in upjs-rails-0.17.0 vs lib/assets/javascripts/up/modal.js.coffee in upjs-rails-0.18.0
- old
+ new
@@ -134,53 +134,48 @@
@function up.modal.coveredUrl
@return {String}
@experimental
###
coveredUrl = ->
- $modal = $('.up-modal')
- $modal.attr('up-covered-url')
+ $('.up-modal').attr('up-covered-url')
reset = ->
- close()
+ close(animation: false)
currentUrl = undefined
config.reset()
templateHtml = ->
template = config.template
if u.isFunction(template)
template(config)
else
template
- rememberHistory = ->
- $modal = $('.up-modal')
- $modal.attr('up-covered-url', up.browser.url())
- $modal.attr('up-covered-title', document.title)
-
discardHistory = ->
$modal = $('.up-modal')
$modal.removeAttr('up-covered-url')
$modal.removeAttr('up-covered-title')
- createHiddenModal = (options) ->
+ createFrame = (target, options) ->
+ shiftElements()
$modal = $(templateHtml())
$modal.attr('up-sticky', '') if options.sticky
$modal.attr('up-covered-url', up.browser.url())
$modal.attr('up-covered-title', document.title)
$dialog = $modal.find('.up-modal-dialog')
$dialog.css('width', options.width) if u.isPresent(options.width)
$dialog.css('max-width', options.maxWidth) if u.isPresent(options.maxWidth)
$dialog.css('height', options.height) if u.isPresent(options.height)
$content = $modal.find('.up-modal-content')
- $placeholder = u.$createElementFromSelector(options.selector)
+ # Create an empty element that will match the
+ # selector that is being replaced.
+ $placeholder = u.$createElementFromSelector(target)
$placeholder.appendTo($content)
$modal.appendTo(document.body)
- rememberHistory()
- $modal.hide()
$modal
- unshiftElements = []
+ unshifters = []
# Gives `<body>` a right padding in the width of a scrollbar.
# Also gives elements anchored to the right side of the screen
# an increased `right`.
#
@@ -193,27 +188,32 @@
bodyRightShift = scrollbarWidth + bodyRightPadding
unshiftBody = u.temporaryCss($('body'),
'padding-right': "#{bodyRightShift}px",
'overflow-y': 'hidden'
)
- unshiftElements.push(unshiftBody)
+ unshifters.push(unshiftBody)
up.layout.anchoredRight().each ->
$element = $(this)
elementRight = parseInt($element.css('right'))
elementRightShift = scrollbarWidth + elementRight
- unshiftElement = u.temporaryCss($element, 'right': elementRightShift)
- unshiftElements.push(unshiftElement)
+ unshifter = u.temporaryCss($element, 'right': elementRightShift)
+ unshifters.push(unshifter)
- updated = (animation, animateOptions) ->
- $modal = $('.up-modal')
- if $modal.is(':hidden')
- shiftElements()
- $modal.show()
- deferred = up.animate($modal, animation, animateOptions)
- deferred.then -> up.emit('up:modal:opened')
+ # Reverts the effects of `shiftElements`.
+ unshiftElements = ->
+ unshifter() while unshifter = unshifters.pop()
###*
+ Returns whether a modal is currently open.
+
+ @function up.modal.isOpen
+ @stable
+ ###
+ isOpen = ->
+ $('.up-modal').length > 0
+
+ ###*
Opens the given link's destination in a modal overlay:
var $link = $('...');
up.modal.follow($link);
@@ -233,10 +233,13 @@
The width of the dialog in pixels.
By [default](/up.modal.config) the dialog will grow to fit its contents.
@param {Boolean} [options.sticky=false]
If set to `true`, the modal remains
open even if the page changes in the background.
+ @param {String} [options.confirm]
+ A message that will be displayed in a cancelable confirmation dialog
+ before the modal is being opened.
@param {Object} [options.history=true]
Whether to add a browser history entry for the modal's source URL.
@param {String} [options.animation]
The animation to use when opening the modal.
@param {Number} [options.duration]
@@ -244,11 +247,12 @@
@param {Number} [options.delay]
The delay before the animation starts. See [`up.animate`](/up.animate).
@param {String} [options.easing]
The timing function that controls the animation's acceleration. [`up.animate`](/up.animate).
@return {Promise}
- A promise that will be resolved when the popup has been loaded and rendered.
+ A promise that will be resolved when the modal has been loaded and
+ the opening animation has completed.
@stable
###
follow = (linkOrSelector, options) ->
options = u.options(options)
options.$link = $(linkOrSelector)
@@ -273,11 +277,12 @@
The CSS selector to extract from the response.
The extracted content will be placed into the dialog window.
@param {Object} options
See options for [`up.modal.follow`](/up.modal.follow).
@return {Promise}
- A promise that will be resolved when the popup has been loaded and rendered.
+ A promise that will be resolved when the modal has been loaded and the opening
+ animation has completed.
@stable
###
visit = (url, options) ->
options = u.options(options)
options.url = url
@@ -289,39 +294,40 @@
###
open = (options) ->
options = u.options(options)
$link = u.option(options.$link, u.nullJQuery())
url = u.option(options.url, $link.attr('up-href'), $link.attr('href'))
- selector = u.option(options.target, $link.attr('up-modal'), 'body')
- width = u.option(options.width, $link.attr('up-width'), config.width)
- maxWidth = u.option(options.maxWidth, $link.attr('up-max-width'), config.maxWidth)
- height = u.option(options.height, $link.attr('up-height'), config.height)
- animation = u.option(options.animation, $link.attr('up-animation'), config.openAnimation)
- sticky = u.option(options.sticky, u.castedAttr($link, 'up-sticky'))
+ target = u.option(options.target, $link.attr('up-modal'), 'body')
+ options.width = u.option(options.width, $link.attr('up-width'), config.width)
+ options.maxWidth = u.option(options.maxWidth, $link.attr('up-max-width'), config.maxWidth)
+ options.height = u.option(options.height, $link.attr('up-height'), config.height)
+ options.animation = u.option(options.animation, $link.attr('up-animation'), config.openAnimation)
+ options.sticky = u.option(options.sticky, u.castedAttr($link, 'up-sticky'))
# Although we usually fall back to full page loads if a browser doesn't support pushState,
# in the case of modals we assume that the developer would rather see a dialog
# without an URL update.
- history = if up.browser.canPushState() then u.option(options.history, u.castedAttr($link, 'up-history'), config.history) else false
+ options.history = if up.browser.canPushState() then u.option(options.history, u.castedAttr($link, 'up-history'), config.history) else false
+ options.confirm = u.option(options.confirm, $link.attr('up-confirm'))
animateOptions = up.motion.animateOptions(options, $link)
- close()
+ up.browser.confirm(options.confirm).then ->
+ if up.bus.nobodyPrevents('up:modal:open', url: url)
+ wasOpen = isOpen()
+ close(animation: false) if wasOpen
+ options.beforeSwap = -> createFrame(target, options)
+ promise = up.replace(target, url, u.merge(options, animation: false))
+ unless wasOpen
+ promise = promise.then ->
+ up.animate($('.up-modal'), options.animation, animateOptions)
+ promise = promise.then ->
+ up.emit('up:modal:opened')
+ promise
+ else
+ # Although someone prevented opening the modal, keep a uniform API for
+ # callers by returning a Deferred that will never be resolved.
+ u.unresolvablePromise()
- if up.bus.nobodyPrevents('up:modal:open', url: url)
- createHiddenModal
- selector: selector
- width: width
- maxWidth: maxWidth
- height: height
- sticky: sticky
- promise = up.replace(selector, url, history: history, requireMatch: false)
- promise.then -> updated(animation, animateOptions)
- promise
- else
- # Although someone prevented the destruction, keep a uniform API for
- # callers by returning a Deferred that will never be resolved.
- u.unresolvableDeferred()
-
###*
This event is [emitted](/up.emit) when a modal dialog is starting to open.
@event up:modal:open
@param event.preventDefault()
@@ -359,15 +365,15 @@
animation: config.closeAnimation,
url: $modal.attr('up-covered-url')
title: $modal.attr('up-covered-title')
)
currentUrl = undefined
- deferred = up.destroy($modal, options)
- deferred.then ->
- unshifter() while unshifter = unshiftElements.pop()
+ promise = up.destroy($modal, options)
+ promise = promise.then ->
+ unshiftElements()
up.emit('up:modal:closed')
- deferred
+ promise
else
# Although someone prevented the destruction,
# keep a uniform API for callers by returning
# a Deferred that will never be resolved.
u.unresolvableDeferred()
@@ -421,23 +427,30 @@
the HTML response. Up.js will dim the page with an overlay
and place the matching `.blog-list` tag will be placed in
a modal dialog.
@selector a[up-modal]
- @param [up-sticky]
- @param [up-animation]
- @param [up-height]
+ @param {String} [up-confirm]
+ A message that will be displayed in a cancelable confirmation dialog
+ before the modal is opened.
+ @param {String} [up-sticky]
+ If set to `"true"`, the modal remains
+ open even if the page changes in the background.
+ @param {String} [up-animation]
+ The animation to use when opening the modal.
+ @param {String} [up-height]
+ The width of the dialog in pixels.
+ By [default](/up.modal.config) the dialog will grow to fit its contents.
@param [up-width]
- @param [up-history]
+ The width of the dialog in pixels.
+ By [default](/up.modal.config) the dialog will grow to fit its contents.
+ @param [up-history="true"]
+ Whether to add a browser history entry for the modal's source URL.
@stable
###
- up.link.registerFollowVariant '[up-modal]', ($link) ->
- event.preventDefault()
- if $link.is('.up-current')
- close()
- else
- follow($link)
+ up.link.onAction '[up-modal]', ($link) ->
+ follow($link)
# Close the modal when someone clicks outside the dialog
# (but not on a modal opener).
up.on('click', 'body', (event, $body) ->
$target = $(event.target)
@@ -489,8 +502,9 @@
url: -> currentUrl
coveredUrl: coveredUrl
config: config
defaults: -> u.error('up.modal.defaults(...) no longer exists. Set values on he up.modal.config property instead.')
contains: contains
- source: -> up.error('up.popup.source no longer exists. Please use up.popup.url instead.')
+ source: -> up.error('up.modal.source no longer exists. Please use up.popup.url instead.')
+ isOpen: isOpen
)(jQuery)