dist/up.js in upjs-rails-0.2.2 vs dist/up.js in upjs-rails-0.3.0

- old
+ new

@@ -23,11 +23,11 @@ (function() { var __slice = [].slice; up.util = (function() { - var $createElementFromSelector, ajax, castsToFalse, castsToTrue, clientSize, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, detect, each, error, escapePressed, extend, findWithSelf, get, ifGiven, isArray, isBlank, isDefined, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, last, locationFromXhr, measure, merge, nextFrame, normalizeUrl, option, options, prependGhost, presence, presentAttr, select, temporaryCss, unwrap; + var $createElementFromSelector, ajax, castsToFalse, castsToTrue, clientSize, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, detect, each, error, escapePressed, extend, findWithSelf, forceCompositing, get, ifGiven, isArray, isBlank, isDefined, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, last, locationFromXhr, measure, merge, nextFrame, normalizeUrl, option, options, prependGhost, presence, presentAttr, select, temporaryCss, unwrap; get = function(url, options) { options = options || {}; options.url = url; return ajax(options); }; @@ -187,11 +187,11 @@ }; isGiven = function(object) { return !isMissing(object); }; isBlank = function(object) { - return isMissing(object) || (object.length === 0); + return isMissing(object) || (isObject(object) && Object.keys(object).length === 0) || (object.length === 0); }; presence = function(object, checker) { if (checker == null) { checker = isPresent; } @@ -355,10 +355,26 @@ return memo(); } else { return memo; } }; + forceCompositing = function($element) { + var memo, oldTransforms; + oldTransforms = $element.css(['transform', '-webkit-transform']); + if (isBlank(oldTransforms)) { + memo = function() { + return $element.css(oldTransforms); + }; + $element.css({ + 'transform': 'translateZ(0)', + '-webkit-transform': 'translateZ(0)' + }); + } else { + memo = function() {}; + } + return memo; + }; /** Animates the given element's CSS properties using CSS transitions. @method up.util.cssAnimate @@ -376,11 +392,11 @@ for a list of pre-defined timing functions. @return A promise for the animation's end. */ cssAnimate = function(elementOrSelector, lastFrame, opts) { - var $element, deferred, transition, withoutTransition; + var $element, deferred, transition, withoutCompositing, withoutTransition; opts = options(opts, { duration: 300, delay: 0, easing: 'ease' }); @@ -390,12 +406,14 @@ 'transition-property': Object.keys(lastFrame).join(', '), 'transition-duration': opts.duration + "ms", 'transition-delay': opts.delay + "ms", 'transition-timing-function': opts.easing }; + withoutCompositing = forceCompositing($element); withoutTransition = temporaryCss($element, transition); $element.css(lastFrame); + deferred.then(withoutCompositing); deferred.then(withoutTransition); setTimeout((function() { return deferred.resolve(); }), opts.duration + opts.delay); return deferred.promise(); @@ -403,14 +421,19 @@ measure = function($element, options) { var box, coordinates, viewport; coordinates = (options != null ? options.relative : void 0) ? $element.position() : $element.offset(); box = { left: coordinates.left, - top: coordinates.top, - width: $element.outerWidth(), - height: $element.outerHeight() + top: coordinates.top }; + if (options != null ? options.inner : void 0) { + box.width = $element.width(); + box.height = $element.height(); + } else { + box.width = $element.outerWidth(); + box.height = $element.outerHeight(); + } if (options != null ? options.full : void 0) { viewport = clientSize(); box.right = viewport.width - (box.left + box.width); box.bottom = viewport.height - (box.top + box.height); } @@ -430,22 +453,24 @@ } return _results; }; prependGhost = function($element) { var $ghost, dimensions; - dimensions = measure($element); + dimensions = measure($element, { + relative: true, + inner: true + }); $ghost = $element.clone(); $ghost.find('script').remove(); $ghost.css({ right: '', bottom: '', - margin: 0, position: 'absolute' }); $ghost.css(dimensions); $ghost.addClass('up-ghost'); - return $ghost.prependTo(document.body); + return $ghost.insertBefore($element); }; findWithSelf = function($element, selector) { return $element.find(selector).addBack(selector); }; escapePressed = function(event) { @@ -500,19 +525,21 @@ unwrap: unwrap, nextFrame: nextFrame, measure: measure, temporaryCss: temporaryCss, cssAnimate: cssAnimate, + forceCompositing: forceCompositing, prependGhost: prependGhost, escapePressed: escapePressed, copyAttributes: copyAttributes, findWithSelf: findWithSelf, contains: contains, isArray: isArray, castsToTrue: castsToTrue, castsToFalse: castsToFalse, - locationFromXhr: locationFromXhr + locationFromXhr: locationFromXhr, + clientSize: clientSize }; })(); }).call(this); @@ -739,10 +766,14 @@ implant = function(selector, html, options) { var $new, $old, fragment, htmlElement, step, _i, _len, _ref, _ref1, _results; options = u.options(options, { historyMethod: 'push' }); + if (options.history === 'false') { + options.history = null; + } + options.source = u.option(options.source, options.history); htmlElement = u.createElementFromHtml(html); options.title || (options.title = (_ref = htmlElement.querySelector("title")) != null ? _ref.textContent : void 0); _ref1 = implantSteps(selector, options); _results = []; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { @@ -756,26 +787,22 @@ } } return _results; }; elementsInserted = function($new, options) { - return $new.each(function() { - var $element; - $element = $(this); - if (typeof options.insert === "function") { - options.insert($element); + if (typeof options.insert === "function") { + options.insert($new); + } + if (options.history) { + if (options.title) { + document.title = options.title; } - if (options.history) { - if (options.title) { - document.title = options.title; - } - up.history[options.historyMethod](options.history); - } - setSource($element, u.presence(options.source) || options.history); - autofocus($element); - return up.ready($element); - }); + up.history[options.historyMethod](options.history); + } + setSource($new, options.source); + autofocus($new); + return up.ready($new); }; swapElements = function($old, $new, pseudoClass, transition, options) { var $addedChildren, insertionMethod; transition || (transition = 'none'); if (pseudoClass) { @@ -927,13 +954,15 @@ @class up.magic */ (function() { + var __slice = [].slice; + up.magic = (function() { - var DESTROYABLE_CLASS, DESTROYER_KEY, awaken, awakeners, compile, defaultAwakeners, defaultLiveDescriptions, destroy, live, liveDescriptions, onEscape, ready, reset, snapshot, util; - util = up.util; + var DESTROYABLE_CLASS, DESTROYER_KEY, applyAwakener, awaken, awakeners, compile, defaultAwakeners, defaultLiveDescriptions, destroy, live, liveDescriptions, onEscape, ready, reset, snapshot, u; + u = up.util; DESTROYABLE_CLASS = 'up-destroyable'; DESTROYER_KEY = 'up-destroyer'; /** Binds an event handler to the document, @@ -966,45 +995,68 @@ the given selector is inserted into the DOM through Up.js. @method up.awaken @param {String} selector The selector to match. + @param {Boolean} [options.batch=false] + If set to `true` and a fragment insertion contains multiple + elements matching the selector, `awakener` is only called once + with a jQuery collection containing all matching elements. @param {Function($element)} awakener The function to call when a matching element is inserted. The function takes the new element as the first argument (as a jQuery object). The function may return another function that destroys the awakened object when it is removed from the DOM, by clearing global state such as time-outs and event handlers bound to the document. */ awakeners = []; defaultAwakeners = null; - awaken = function(selector, awakener) { + awaken = function() { + var args, awakener, options, selector; + selector = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + awakener = args.pop(); + options = u.options(args[0], { + batch: false + }); return awakeners.push({ selector: selector, - callback: awakener + callback: awakener, + batch: options.batch }); }; + applyAwakener = function(awakener, $jqueryElement, nativeElement) { + var destroyer; + destroyer = awakener.callback.apply(nativeElement, [$jqueryElement]); + if (u.isFunction(destroyer)) { + $jqueryElement.addClass(DESTROYABLE_CLASS); + return $jqueryElement.data(DESTROYER_KEY, destroyer); + } + }; compile = function($fragment) { - var awakener, _i, _len, _results; + var $matches, awakener, _i, _len, _results; + console.log("Compiling fragment", $fragment); _results = []; for (_i = 0, _len = awakeners.length; _i < _len; _i++) { awakener = awakeners[_i]; - _results.push(util.findWithSelf($fragment, awakener.selector).each(function() { - var $element, destroyer; - $element = $(this); - destroyer = awakener.callback.apply(this, [$element]); - if (util.isFunction(destroyer)) { - $element.addClass(DESTROYABLE_CLASS); - return $element.data(DESTROYER_KEY, destroyer); + $matches = u.findWithSelf($fragment, awakener.selector); + if ($matches.length) { + if (awakener.batch) { + _results.push(applyAwakener(awakener, $matches, $matches.get())); + } else { + _results.push($matches.each(function() { + return applyAwakener(awakener, $(this), this); + })); } - })); + } else { + _results.push(void 0); + } } return _results; }; destroy = function($fragment) { - return util.findWithSelf($fragment, "." + DESTROYABLE_CLASS).each(function() { + return u.findWithSelf($fragment, "." + DESTROYABLE_CLASS).each(function() { var $element, destroyer; $element = $(this); destroyer = $element.data(DESTROYER_KEY); return destroyer(); }); @@ -1016,12 +1068,12 @@ @private @method up.magic.snapshot */ snapshot = function() { - defaultLiveDescriptions = util.copy(liveDescriptions); - return defaultAwakeners = util.copy(awakeners); + defaultLiveDescriptions = u.copy(liveDescriptions); + return defaultAwakeners = u.copy(awakeners); }; /** Resets the list of registered event listeners to the moment when the framework was booted. @@ -1031,16 +1083,16 @@ */ reset = function() { var description, _i, _len, _ref; for (_i = 0, _len = liveDescriptions.length; _i < _len; _i++) { description = liveDescriptions[_i]; - if (!util.contains(defaultLiveDescriptions, description)) { + if (!u.contains(defaultLiveDescriptions, description)) { (_ref = $(document)).off.apply(_ref, description); } } - liveDescriptions = util.copy(defaultLiveDescriptions); - return awakeners = util.copy(defaultAwakeners); + liveDescriptions = u.copy(defaultLiveDescriptions); + return awakeners = u.copy(defaultAwakeners); }; /** Sends a notification that the given element has been inserted into the DOM. This causes Up.js to compile the fragment (apply @@ -1059,11 +1111,11 @@ up.bus.emit('fragment:ready', $fragment); return $fragment; }; onEscape = function(handler) { return live('keydown', 'body', function(event) { - if (util.escapePressed(event)) { + if (u.escapePressed(event)) { return handler(event); } }); }; up.bus.on('app:ready', (function() { @@ -1120,12 +1172,15 @@ /** @method up.history.replace @param {String} url @protected */ - replace = function(url) { - if (!isCurrentUrl(url)) { + replace = function(url, options) { + options = u.options(options, { + force: false + }); + if (options.force || !isCurrentUrl(url)) { return manipulate("replace", url); } }; /** @@ -1152,16 +1207,18 @@ if (state != null ? state.fromUp : void 0) { return up.visit(up.browser.url(), { historyMethod: 'replace' }); } else { - return console.log("null state"); + return console.log("strange state", state); } }; setTimeout((function() { $(window).on("popstate", pop); - return replace(up.browser.url()); + return replace(up.browser.url(), { + force: true + }); }), 200); return { push: push, replace: replace }; @@ -1191,23 +1248,33 @@ @class up.motion */ (function() { up.motion = (function() { - var animate, animation, animations, assertIsPromise, defaultAnimations, defaultOptions, defaultTransitions, findAnimation, morph, none, reset, snapshot, transition, transitions, u, withGhosts; + var animate, animation, animations, assertIsPromise, config, defaultAnimations, defaultTransitions, defaults, findAnimation, morph, none, reset, snapshot, transition, transitions, u, withGhosts; u = up.util; - defaultOptions = { + config = { duration: 300, delay: 0, easing: 'ease' }; animations = {}; defaultAnimations = {}; transitions = {}; defaultTransitions = {}; /** + @method up.modal.defaults + @param {Number} options.duration + @param {Number} options.delay + @param {String} options.easing + */ + defaults = function(options) { + return u.extend(config, options); + }; + + /** Animates an element. The following animations are pre-registered: - `fade-in` @@ -1232,11 +1299,11 @@ A promise for the animation's end. */ animate = function(elementOrSelector, animation, options) { var $element; $element = $(elementOrSelector); - options = u.options(options, defaultOptions); + options = u.options(options, config); if (u.isFunction(animation)) { return assertIsPromise(animation($element, options), ["Animation did not return a Promise", animation]); } else if (u.isString(animation)) { return animate($element, findAnimation(animation), options); } else if (u.isHash(animation)) { @@ -1287,12 +1354,12 @@ Performs a transition between two elements. The following transitions are pre-registered: - `cross-fade` - - `move-top` - - `move-bottom` + - `move-up` + - `move-down` - `move-left` - `move-right` - `none` You can also compose a transition from two animation names @@ -1311,11 +1378,11 @@ @return {Promise} A promise for the transition's end. */ morph = function(source, target, transitionOrName, options) { var $new, $old, animation, parts, transition; - options = u.options(defaultOptions); + options = u.options(config); $old = $(source); $new = $(target); transition = u.presence(transitionOrName, u.isFunction) || transitions[transitionOrName]; if (transition) { return withGhosts($old, $new, function($oldGhost, $newGhost) { @@ -1395,71 +1462,95 @@ return animate($ghost, { opacity: 0 }, options); }); animation('move-to-top', function($ghost, options) { + var box, travelDistance; + box = u.measure($ghost); + travelDistance = box.top + box.height; $ghost.css({ - 'margin-top': '0%' + 'margin-top': '0px' }); return animate($ghost, { - 'margin-top': '-100%' + 'margin-top': "-" + travelDistance + "px" }, options); }); animation('move-from-top', function($ghost, options) { + var box, travelDistance; + box = u.measure($ghost); + travelDistance = box.top + box.height; $ghost.css({ - 'margin-top': '-100%' + 'margin-top': "-" + travelDistance + "px" }); return animate($ghost, { - 'margin-top': '0%' + 'margin-top': '0px' }, options); }); animation('move-to-bottom', function($ghost, options) { + var box, travelDistance; + box = u.measure($ghost); + travelDistance = u.clientSize().height - box.top; $ghost.css({ - 'margin-top': '0%' + 'margin-top': '0px' }); return animate($ghost, { - 'margin-top': '100%' + 'margin-top': travelDistance + "px" }, options); }); animation('move-from-bottom', function($ghost, options) { + var box, travelDistance; + box = u.measure($ghost); + travelDistance = u.clientSize().height - box.top; $ghost.css({ - 'margin-top': '100%' + 'margin-top': travelDistance + "px" }); return animate($ghost, { - 'margin-top': '0%' + 'margin-top': '0px' }, options); }); animation('move-to-left', function($ghost, options) { + var box, travelDistance; + box = u.measure($ghost); + travelDistance = box.left + box.width; $ghost.css({ - 'margin-left': '0%' + 'margin-left': '0px' }); return animate($ghost, { - 'margin-left': '-100%' + 'margin-left': "-" + travelDistance + "px" }, options); }); animation('move-from-left', function($ghost, options) { + var box, travelDistance; + box = u.measure($ghost); + travelDistance = box.left + box.width; $ghost.css({ - 'margin-left': '-100%' + 'margin-left': "-" + travelDistance + "px" }); return animate($ghost, { - 'margin-left': '0%' + 'margin-left': '0px' }, options); }); animation('move-to-right', function($ghost, options) { + var box, travelDistance; + box = u.measure($ghost); + travelDistance = u.clientSize().width - box.left; $ghost.css({ - 'margin-left': '0%' + 'margin-left': '0px' }); return animate($ghost, { - 'margin-left': '100%' + 'margin-left': travelDistance + "px" }, options); }); animation('move-from-right', function($ghost, options) { + var box, travelDistance; + box = u.measure($ghost); + travelDistance = u.clientSize().width - box.left; $ghost.css({ - 'margin-left': '100%' + 'margin-left': travelDistance + "px" }); return animate($ghost, { - 'margin-left': '0%' + 'margin-left': '0px' }, options); }); animation('roll-down', function($ghost, options) { var fullHeight, styleMemo; fullHeight = $ghost.height(); @@ -1492,10 +1583,11 @@ return { morph: morph, animate: animate, transition: transition, animation: animation, + defaults: defaults, none: none }; })(); up.transition = up.motion.transition; @@ -2389,15 +2481,16 @@ } }); up.on('click', 'body', function(event, $body) { var $target; $target = $(event.target); - if (!($target.closest('.up-dialog').length || $target.closest('[up-modal]').length)) { + if (!($target.closest('.up-modal-dialog').length || $target.closest('[up-modal]').length)) { return close(); } }); up.bus.on('fragment:ready', function($fragment) { if (!$fragment.closest('.up-modal').length) { + console.log('fragment inserted', $fragment, $fragment.closest('.up-modal')); return autoclose(); } }); up.magic.onEscape(function() { return close();