dist/up.js in upjs-rails-0.8.1 vs dist/up.js in upjs-rails-0.8.2

- old
+ new

@@ -784,21 +784,31 @@ factoryOptions = {}; } hash = { reset: function() { var j, key, len, ownKeys; - ownKeys = Object.getOwnPropertyNames(hash); + ownKeys = copy(Object.getOwnPropertyNames(hash)); for (j = 0, len = ownKeys.length; j < len; j++) { key = ownKeys[j]; if (!contains(apiKeys, key)) { delete hash[key]; } } return hash.update(copy(factoryOptions)); }, update: function(options) { - return extend(hash, options); + var key, results, value; + results = []; + for (key in options) { + value = options[key]; + if (factoryOptions.hasOwnProperty(key)) { + results.push(hash[key] = value); + } else { + results.push(error("Unknown setting %o", key)); + } + } + return results; } }; apiKeys = Object.getOwnPropertyNames(hash); hash.reset(); return hash; @@ -1154,28 +1164,34 @@ This modules contains functions to scroll the viewport and reveal contained elements. By default Up.js will always scroll to an element before updating it. +The container that will be scrolled is the closest parent of the element that is either: + +- The currently open [modal](/up.modal) +- An element with the attribute `[up-viewport]` +- The `<body>` element +- An element matching the selector you have configured using `up.viewport.defaults({ viewSelector: 'my-custom-selector' })`. + @class up.viewport */ (function() { up.viewport = (function() { - var SCROLL_PROMISE_KEY, config, finishScrolling, reset, reveal, scroll, u; + var SCROLL_PROMISE_KEY, config, findView, finishScrolling, reset, reveal, scroll, u; u = up.util; /** @method up.viewport.defaults @param {Number} [options.duration] @param {String} [options.easing] - @param {Number} [options.padding] - @param {String|Element|jQuery} [options.view] + @param {String} [options.viewSelector] */ config = u.config({ duration: 0, - view: 'body', + viewSelector: 'body, .up-modal, [up-viewport]', easing: 'swing' }); reset = function() { return config.reset(); }; @@ -1188,11 +1204,11 @@ @param {String}[options.duration] @param {String}[options.easing] @return {Deferred} @protected */ - scroll = function(viewOrSelector, scrollPos, options) { + scroll = function(viewOrSelector, scrollTop, options) { var $view, deferred, duration, easing, targetProps; $view = $(viewOrSelector); options = u.options(options); duration = u.option(options.duration, config.duration); easing = u.option(options.easing, config.easing); @@ -1203,22 +1219,22 @@ deferred.then(function() { $view.removeData(SCROLL_PROMISE_KEY); return $view.finish(); }); targetProps = { - scrollTop: scrollPos + scrollTop: scrollTop }; $view.animate(targetProps, { duration: duration, easing: easing, complete: function() { return deferred.resolve(); } }); return deferred; } else { - $view.scrollTop(scrollPos); + $view.scrollTop(scrollTop); return u.resolvedDeferred(); } }; /** @@ -1238,37 +1254,71 @@ @method up.reveal @param {String|Element|jQuery} element @param {String|Element|jQuery} [options.view] @param {Number} [options.duration] @param {String} [options.easing] - @param {Number} [options.padding] @return {Deferred} @protected */ reveal = function(elementOrSelector, options) { - var $element, $view, elementTooHigh, elementTooLow, elementTop, firstVisibleRow, lastVisibleRow, padding, scrollPos, view, viewHeight; + var $element, $view, elementDims, firstElementRow, firstVisibleRow, lastElementRow, lastVisibleRow, newScrollPos, offsetShift, originalScrollPos, viewHeight, viewIsBody; options = u.options(options); - view = u.option(options.view, config.view); - padding = u.option(options.padding, config.padding); $element = $(elementOrSelector); - $view = $(view); - viewHeight = $view.height(); - scrollPos = $view.scrollTop(); - firstVisibleRow = scrollPos; - lastVisibleRow = scrollPos + viewHeight; - elementTop = $element.position().top; - elementTooHigh = elementTop - padding < firstVisibleRow; - elementTooLow = elementTop > lastVisibleRow - padding; - if (elementTooHigh || elementTooLow) { - scrollPos = elementTop - padding; - scrollPos = Math.max(scrollPos, 0); - scrollPos = Math.min(scrollPos, viewHeight - 1); - return scroll($view, scrollPos, options); + $view = findView($element, options.view); + viewIsBody = $view.is('body'); + viewHeight = viewIsBody ? u.clientSize().height : $view.height(); + originalScrollPos = $view.scrollTop(); + newScrollPos = originalScrollPos; + offsetShift = viewIsBody ? 0 : originalScrollPos; + firstVisibleRow = function() { + return newScrollPos; + }; + lastVisibleRow = function() { + return newScrollPos + viewHeight - 1; + }; + elementDims = u.measure($element, { + relative: true + }); + firstElementRow = elementDims.top + offsetShift; + lastElementRow = firstElementRow + elementDims.height - 1; + if (lastElementRow > lastVisibleRow()) { + newScrollPos += lastElementRow - lastVisibleRow(); + } + if (firstElementRow < firstVisibleRow()) { + newScrollPos = firstElementRow; + } + if (newScrollPos !== originalScrollPos) { + return scroll($view, newScrollPos, options); } else { return u.resolvedDeferred(); } }; + + /** + @private + @method up.viewport.findView + */ + findView = function($element, viewSelectorOrElement) { + var $view, viewSelector; + $view = void 0; + if (u.isJQuery(viewSelectorOrElement)) { + $view = viewSelectorOrElement; + } else { + viewSelector = u.presence(viewSelectorOrElement) || config.viewSelector; + $view = $element.closest(viewSelector); + } + $view.length || u.error("Could not find view to scroll for %o (tried selectors %o)", $element, viewSelectors); + return $view; + }; + + /** + Marks this element as a scrolling container. + Use this e.g. if your app uses a custom panel layout with fixed positioning + instead of scrolling `<body>`. + + @method [up-viewport] + */ up.bus.on('framework:reset', reset); return { reveal: reveal, scroll: scroll, finishScrolling: finishScrolling, @@ -4176,11 +4226,11 @@ 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] A string containing the HTML structure of the modal. You can supply an alternative template string, but make sure that it - contains a containing tag with the class `up-modal`. + 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'] @@ -4712,13 +4762,13 @@ u = up.util; /** Sets default options for this module. + @method up.navigation.defaults @param {Number} [options.currentClass] The class to set on [links that point the current location](#up-current). - @method up.navigation.defaults */ config = u.config({ currentClass: 'up-current' }); reset = function() { @@ -4752,23 +4802,26 @@ stripTrailingSlash: true }); } }; sectionUrls = function($section) { - var aliases, attr, i, len, ref, urls, value, values; + var attr, i, j, len, len1, ref, url, urls, value, values; urls = []; - ref = ['href', 'up-href']; + ref = ['href', 'up-href', 'up-alias']; for (i = 0, len = ref.length; i < len; i++) { attr = ref[i]; if (value = u.presentAttr($section, attr)) { - urls.push(value); + values = attr === 'up-alias' ? value.split(' ') : [value]; + for (j = 0, len1 = values.length; j < len1; j++) { + url = values[j]; + if (url !== '#') { + url = normalizeUrl(url); + urls.push(url); + } + } } } - if (aliases = u.presentAttr($section, 'up-alias')) { - values = aliases.split(' '); - urls = urls.concat(values); - } - return urls.map(normalizeUrl); + return urls; }; urlSet = function(urls) { var doesMatchFully, doesMatchPrefix, matches, matchesAny; urls = u.compact(urls); matches = function(testUrl) {