lib/assets/javascripts/up/modal.js.coffee in upjs-rails-0.11.1 vs lib/assets/javascripts/up/modal.js.coffee in upjs-rails-0.12.0

- old
+ new

@@ -7,47 +7,47 @@ For small popup overlays ("dropdowns") see [up.popup](/up.popup) instead. @class up.modal ### -up.modal = (-> +up.modal = (($) -> u = up.util ###* Sets default options for future modals. - @method up.modal.defaults - @param {Number} [options.width] + @method up.modal.config + @param {Number} [config.width] The width of the dialog as a CSS value like `'400px'` or `50%`. Defaults to `undefined`, meaning that the dialog will grow to fit its contents - until it reaches `options.maxWidth`. Leaving this as `undefined` will + until it reaches `config.maxWidth`. Leaving this as `undefined` will also allow you to control the width using CSS on `.up-modal-dialogĀ“. - @param {Number} [options.maxWidth] + @param {Number} [config.maxWidth] The width of the dialog as a CSS value like `'400px'` or `50%`. You can set this to `undefined` to make the dialog fit its contents. Be aware however, that e.g. Bootstrap stretches input elements to `width: 100%`, meaning the dialog will also stretch to the full width of the screen. - @param {Number} [options.height='auto'] + @param {Number} [config.height='auto'] The height of the dialog in pixels. Defaults to `undefined`, meaning that the dialog will grow to fit its contents. - @param {String|Function(config)} [options.template] + @param {String|Function(config)} [config.template] A string containing the HTML structure of the modal. You can supply an alternative template string, but make sure that it defines tag with the classes `up-modal`, `up-modal-dialog` and `up-modal-content`. You can also supply a function that returns a HTML string. The function will be called with the modal options (merged from these defaults and any per-open overrides) whenever a modal opens. - @param {String} [options.closeLabel='X'] + @param {String} [config.closeLabel='X'] The label of the button that closes the dialog. - @param {String} [options.openAnimation='fade-in'] + @param {String} [config.openAnimation='fade-in'] The animation used to open the modal. The animation will be applied to both the dialog box and the overlay dimming the page. - @param {String} [options.closeAnimation='fade-out'] + @param {String} [config.closeAnimation='fade-out'] The animation used to close the modal. The animation will be applied to both the dialog box and the overlay dimming the page. ### config = u.config maxWidth: undefined @@ -132,33 +132,31 @@ elementRightShift = scrollbarWidth + elementRight unshiftElement = u.temporaryCss($element, 'right': elementRightShift) unshiftElements.push(unshiftElement) updated = ($modal, animation, animateOptions) -> - up.bus.emit('modal:open') shiftElements() $modal.show() - promise = up.animate($modal, animation, animateOptions) - promise.then -> up.bus.emit('modal:opened') - promise + deferred = up.animate($modal, animation, animateOptions) + deferred.then -> up.bus.emit('up:modal:opened') ###* Opens the given link's destination in a modal overlay: var $link = $('...'); - up.modal.open($link); + up.modal.follow($link); Any option attributes for [`a[up-modal]`](#a.up-modal) will be honored. \#\#\#\# Events - - Emits an [event](/up.bus) `modal:open` when the modal + - Emits an [event](/up.bus) `up:modal:open` when the modal is starting to open. - - Emits an [event](/up.bus) `modal:opened` when the opening + - Emits an [event](/up.bus) `up:modal:opened` when the opening animation has finished and the modal contents are fully visible. - @method up.modal.open + @method up.modal.follow @param {Element|jQuery|String} elementOrSelector The link to follow. @param {String} [options.target] The selector to extract from the response and open in a modal dialog. @param {Number} [options.width] @@ -181,39 +179,47 @@ @param {String} [options.easing] The timing function that controls the animation's acceleration. [`up.animate`](/up.motion#up.animate). @return {Promise} A promise that will be resolved when the modal has finished loading. ### + follow = ($link, options) -> + options = u.options(options) + options.$link = $link + open(options) + ###* Opens a modal for the given URL. Example: - up.modal.open({ url: '/foo', target: '.list' }) + up.modal.visit('/foo', { target: '.list' }) This will request `/foo`, extract the `.list` selector from the response and open the selected container in a modal dialog. - @method up.modal.open - @param {String} options.url + @method up.modal.visit + @param {String} url The URL to load. @param {String} options.target The CSS selector to extract from the response. The extracted content will be placed into the dialog window. @param {Object} options See options for [previous `up.modal.open` variant](#up.modal.open). ### - open = (args...) -> - if u.isObject(args[0]) && !u.isElement(args[0]) && !u.isJQuery(args[0]) - $link = u.nullJquery() - options = args[0] - else - $link = $(args[0]) - options = args[1] + visit = (url, options) -> + options = u.options(options) + options.url = url + open(options) + + ###* + @private + ### + 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) @@ -224,21 +230,25 @@ # without an URL update. history = if up.browser.canPushState() then u.option(options.history, u.castedAttr($link, 'up-history'), true) else false animateOptions = up.motion.animateOptions(options, $link) close() - $modal = createHiddenModal - selector: selector - width: width - maxWidth: maxWidth - height: height - sticky: sticky - up.replace(selector, url, - history: history - insert: -> updated($modal, animation, animateOptions) - ) + if up.bus.nobodyPrevents('up:modal:open', url: url) + $modal = createHiddenModal + selector: selector + width: width + maxWidth: maxWidth + height: height + sticky: sticky + up.replace selector, url, + history: history + insert: -> updated($modal, animation, animateOptions) + else + # Although someone prevented the destruction, keep a uniform API for + # callers by returning a Deferred that will never be resolved. + $.Deferred() ###* Returns the source URL for the fragment displayed in the current modal overlay, or `undefined` if no modal is currently open. @@ -265,22 +275,26 @@ See options for [`up.animate`](/up.motion#up.animate) ### close = (options) -> $modal = $('.up-modal') if $modal.length - options = u.options(options, - animation: config.closeAnimation, - url: $modal.attr('up-previous-url') - title: $modal.attr('up-previous-title') - ) - currentSource = undefined - up.bus.emit('modal:close') - deferred = up.destroy($modal, options) - deferred.then -> - unshifter() while unshifter = unshiftElements.pop() - up.bus.emit('modal:closed') - deferred + if up.bus.nobodyPrevents('up:modal:close', $element: $modal) + options = u.options(options, + animation: config.closeAnimation, + url: $modal.attr('up-previous-url') + title: $modal.attr('up-previous-title') + ) + currentSource = undefined + deferred = up.destroy($modal, options) + deferred.then -> + unshifter() while unshifter = unshiftElements.pop() + up.bus.emit('up:modal:closed') + deferred + else + # Although someone prevented the destruction, keep a uniform API for + # callers by returning a Deferred that will never be resolved. + $.Deferred() else u.resolvedDeferred() autoclose = -> unless $('.up-modal').is('[up-sticky]') @@ -337,11 +351,11 @@ </div> </div> </div> If you want to change the design beyond CSS, you can - configure Up.js to [use a different HTML structure](#up.modal.defaults). + configure Up.js to [use a different HTML structure](#up.modal.config). \#\#\#\# Closing behavior By default the dialog automatically closes @@ -377,11 +391,11 @@ $target = $(event.target) unless $target.closest('.up-modal-dialog').length || $target.closest('[up-modal]').length close() ) - up.bus.on('fragment:ready', ($fragment) -> + up.on('up:fragment:inserted', (event, $fragment) -> if contains($fragment) if newSource = $fragment.attr('up-source') currentSource = newSource else if !up.popup.contains($fragment) autoclose() @@ -405,14 +419,17 @@ # but link to a destination if not. event.preventDefault() ) # The framework is reset between tests - up.bus.on 'framework:reset', reset + up.on 'up:framework:reset', reset - open: open + visit: visit + follow: follow + open: -> up.error('up.modal.open no longer exists. Please use either up.modal.follow or up.modal.visit.') close: close source: source - defaults: config.update + config: config + defaults: -> u.error('up.modal.defaults(...) no longer exists. Set values on he up.modal.config property instead.') contains: contains -)() +)(jQuery)