From f0df89e05b32ac97970b43e2b035380ddf894b6b Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Mon, 4 Mar 2013 01:54:55 +0100 Subject: [PATCH] use ember from drogus/ember.js:refresh-href --- assets/scripts/vendor/ember.js | 867 +++++++++++++++++++++++---------- 1 file changed, 599 insertions(+), 268 deletions(-) diff --git a/assets/scripts/vendor/ember.js b/assets/scripts/vendor/ember.js index 35a9c6a5..39ec6e62 100644 --- a/assets/scripts/vendor/ember.js +++ b/assets/scripts/vendor/ember.js @@ -1,5 +1,5 @@ -// Version: v1.0.0-pre.4-209-g455440d -// Last commit: 455440d (2013-02-13 12:03:37 -0800) +// Version: v1.0.0-rc.1-85-gd25f1ad +// Last commit: d25f1ad (2013-02-27 18:40:56 +0100) (function() { @@ -150,8 +150,8 @@ Ember.deprecateFunc = function(message, func) { })(); -// Version: v1.0.0-pre.4-209-g455440d -// Last commit: 455440d (2013-02-13 12:03:37 -0800) +// Version: v1.0.0-rc.1-85-gd25f1ad +// Last commit: d25f1ad (2013-02-27 18:40:56 +0100) (function() { @@ -211,7 +211,7 @@ var define, requireModule; @class Ember @static - @version 1.0.0-pre.4 + @version 1.0.0-rc.1 */ if ('undefined' === typeof Ember) { @@ -238,10 +238,10 @@ Ember.toString = function() { return "Ember"; }; /** @property VERSION @type String - @default '1.0.0-pre.4' + @default '1.0.0-rc.1' @final */ -Ember.VERSION = '1.0.0-pre.4'; +Ember.VERSION = '1.0.0-rc.1'; /** Standard environmental variables. You can define these in a global `ENV` @@ -297,6 +297,15 @@ Ember.LOG_STACKTRACE_ON_DEPRECATION = (Ember.ENV.LOG_STACKTRACE_ON_DEPRECATION ! */ Ember.SHIM_ES5 = (Ember.ENV.SHIM_ES5 === false) ? false : Ember.EXTEND_PROTOTYPES; +/** + Determines whether Ember logs info about version of used libraries + + @property LOG_VERSION + @type Boolean + @default true +*/ +Ember.LOG_VERSION = (Ember.ENV.LOG_VERSION === false) ? false : true; + /** Empty function. Useful for some operations. @@ -651,7 +660,7 @@ Ember.generateGuid = function generateGuid(obj, prefix) { @method guidFor @for Ember - @param obj {Object} any object, string, number, Element, or primitive + @param {Object} obj any object, string, number, Element, or primitive @return {String} the unique guid for this instance. */ Ember.guidFor = function guidFor(obj) { @@ -1001,8 +1010,8 @@ var needsFinallyFix = (function() { @method tryFinally @for Ember - @param {Function} function The function to run the try callback - @param {Function} function The function to run the finally callback + @param {Function} tryable The function to run the try callback + @param {Function} finalizer The function to run the finally callback @param [binding] @return {anything} The return value is the that of the finalizer, unless that valueis undefined, in which case it is the return value @@ -1051,9 +1060,9 @@ if (needsFinallyFix) { @method tryCatchFinally @for Ember - @param {Function} function The function to run the try callback - @param {Function} function The function to run the catchable callback - @param {Function} function The function to run the finally callback + @param {Function} tryable The function to run the try callback + @param {Function} catchable The function to run the catchable callback + @param {Function} finalizer The function to run the finally callback @param [binding] @return {anything} The return value is the that of the finalizer, unless that value is undefined, in which case it is the return value @@ -1565,8 +1574,8 @@ OrderedSet.prototype = { /** @method forEach - @param {Function} function - @param target + @param {Function} fn + @param self */ forEach: function(fn, self) { // allow mutation during iteration @@ -2087,7 +2096,7 @@ Ember.setPath = Ember.deprecateFunc('setPath is deprecated since set now support @method trySet @for Ember @param {Object} obj The object to modify. - @param {String} keyName The property key to set + @param {String} path The property path to set @param {Object} value The value to set */ Ember.trySet = function(root, path, value) { @@ -2232,6 +2241,7 @@ Ember.defineProperty = function(obj, keyName, desc, data, meta) { } else { obj[keyName] = undefined; // make enumerable } + desc.setup(obj, keyName); } else { descs[keyName] = undefined; // shadow descriptor in proto if (desc == null) { @@ -2950,12 +2960,15 @@ Ember.watch = function(obj, keyName) { // can't watch length on Array - it is special... if (keyName === 'length' && Ember.typeOf(obj) === 'array') { return this; } - var m = metaFor(obj), watching = m.watching; + var m = metaFor(obj), watching = m.watching, desc; // activate watching first time if (!watching[keyName]) { watching[keyName] = 1; if (isKeyName(keyName)) { + desc = m.descs[keyName]; + if (desc && desc.willWatch) { desc.willWatch(obj, keyName); } + if ('function' === typeof obj.willWatchProperty) { obj.willWatchProperty(keyName); } @@ -2990,12 +3003,15 @@ Ember.unwatch = function(obj, keyName) { // can't watch length on Array - it is special... if (keyName === 'length' && Ember.typeOf(obj) === 'array') { return this; } - var m = metaFor(obj), watching = m.watching; + var m = metaFor(obj), watching = m.watching, desc; if (watching[keyName] === 1) { watching[keyName] = 0; if (isKeyName(keyName)) { + desc = m.descs[keyName]; + if (desc && desc.didUnwatch) { desc.didUnwatch(obj, keyName); } + if ('function' === typeof obj.didUnwatchProperty) { obj.didUnwatchProperty(keyName); } @@ -3404,6 +3420,25 @@ ComputedPropertyPrototype.meta = function(meta) { } }; +/* impl descriptor API */ +ComputedPropertyPrototype.willWatch = function(obj, keyName) { + // watch already creates meta for this instance + var meta = obj[META_KEY]; + Ember.assert('watch should have setup meta to be writable', meta.source === obj); + if (!(keyName in meta.cache)) { + addDependentKeys(this, obj, keyName, meta); + } +}; + +ComputedPropertyPrototype.didUnwatch = function(obj, keyName) { + var meta = obj[META_KEY]; + Ember.assert('unwatch should have setup meta to be writable', meta.source === obj); + if (!(keyName in meta.cache)) { + // unwatch already creates meta for this instance + removeDependentKeys(this, obj, keyName, meta); + } +}; + /* impl descriptor API */ ComputedPropertyPrototype.didChange = function(obj, keyName) { // _suspended is set via a CP.set to ensure we don't clear @@ -3412,7 +3447,9 @@ ComputedPropertyPrototype.didChange = function(obj, keyName) { var meta = metaFor(obj); if (keyName in meta.cache) { delete meta.cache[keyName]; - removeDependentKeys(this, obj, keyName, meta); + if (!meta.watching[keyName]) { + removeDependentKeys(this, obj, keyName, meta); + } } } }; @@ -3425,7 +3462,9 @@ ComputedPropertyPrototype.get = function(obj, keyName) { cache = meta.cache; if (keyName in cache) { return cache[keyName]; } ret = cache[keyName] = this.func.call(obj, keyName); - addDependentKeys(this, obj, keyName, meta); + if (!meta.watching[keyName]) { + addDependentKeys(this, obj, keyName, meta); + } } else { ret = this.func.call(obj, keyName); } @@ -3478,7 +3517,7 @@ ComputedPropertyPrototype.set = function(obj, keyName, value) { } if (cacheable) { - if (!hadCachedValue) { + if (!watched && !hadCachedValue) { addDependentKeys(this, obj, keyName, meta); } cache[keyName] = ret; @@ -3491,11 +3530,19 @@ ComputedPropertyPrototype.set = function(obj, keyName, value) { return ret; }; +/* called when property is defined */ +ComputedPropertyPrototype.setup = function(obj, keyName) { + var meta = obj[META_KEY]; + if (meta && meta.watching[keyName]) { + addDependentKeys(this, obj, keyName, metaFor(obj)); + } +}; + /* called before property is overridden */ ComputedPropertyPrototype.teardown = function(obj, keyName) { var meta = metaFor(obj); - if (keyName in meta.cache) { + if (meta.watching[keyName] || keyName in meta.cache) { removeDependentKeys(this, obj, keyName, meta); } @@ -3719,6 +3766,7 @@ function actionsDiff(obj, eventName, otherActions) { @param {String} eventName @param {Object|Function} targetOrMethod A target object or a function @param {Function|String} method A function or the name of a function to be called on `target` + @param {Boolean} once A flag whether a function should only be called once */ function addListener(obj, eventName, target, method, once) { Ember.assert("You must pass at least an object and event name to Ember.addListener", !!obj && !!eventName); @@ -3904,6 +3952,7 @@ function watchedEvents(obj) { @param obj @param {String} eventName @param {Array} params + @param {Array} actions @return true */ function sendEvent(obj, eventName, params, actions) { @@ -4691,7 +4740,7 @@ Binding.prototype = { `get()` - see that method for more information. @method from - @param {String} propertyPath the property path to connect to + @param {String} path the property path to connect to @return {Ember.Binding} `this` */ from: function(path) { @@ -4709,7 +4758,7 @@ Binding.prototype = { `get()` - see that method for more information. @method to - @param {String|Tuple} propertyPath A property path or tuple + @param {String|Tuple} path A property path or tuple @return {Ember.Binding} `this` */ to: function(path) { @@ -5450,6 +5499,38 @@ Mixin.finishPartial = finishPartial; Ember.anyUnprocessedMixins = false; /** + Creates an instance of a class. Accepts either no arguments, or an object + containing values to initialize the newly instantiated object with. + + ```javascript + App.Person = Ember.Object.extend({ + helloWorld: function() { + alert("Hi, my name is " + this.get('name')); + } + }); + + var tom = App.Person.create({ + name: 'Tom Dale' + }); + + tom.helloWorld(); // alerts "Hi, my name is Tom Dale". + ``` + + `create` will call the `init` function if defined during + `Ember.AnyObject.extend` + + If no arguments are passed to `create`, it will not set values to the new + instance during initialization: + + ```javascript + var noName = App.Person.create(); + noName.helloWorld(); // alerts undefined + ``` + + NOTE: For performance reasons, you cannot declare methods or computed + properties during `create`. You should instead declare methods and computed + properties when using `extend`. + @method create @static @param arguments* @@ -5845,7 +5926,8 @@ define("rsvp", callbacks, callbackTuple, callback, binding, event; if (callbacks = allCallbacks[eventName]) { - for (var i=0, l=callbacks.length; i0) { /** The NativeArray mixin contains the properties needed to to make the native Array support Ember.MutableArray and all of its dependent APIs. Unless you - have `Ember.EXTEND_PROTOTYPES or `Ember.EXTEND_PROTOTYPES.Array` set to + have `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Array` set to false, this will be applied automatically. Otherwise you can apply the mixin at anytime by calling `Ember.NativeArray.activate`. @@ -12351,7 +12521,8 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin, objectAtContent: function(idx) { var length = get(this, 'length'), - object = get(this,'arrangedContent').objectAt(idx); + arrangedContent = get(this,'arrangedContent'), + object = arrangedContent && arrangedContent.objectAt(idx); if (idx >= 0 && idx < length) { var controllerClass = this.lookupItemController(object); @@ -12371,20 +12542,20 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin, arrangedContentDidChange: function() { this._super(); - this._resetSubContainers(); + this._resetSubControllers(); }, arrayContentDidChange: function(idx, removedCnt, addedCnt) { - var subContainers = get(this, 'subContainers'), - subContainersToRemove = subContainers.slice(idx, idx+removedCnt); + var subControllers = get(this, '_subControllers'), + subControllersToRemove = subControllers.slice(idx, idx+removedCnt); - forEach(subContainersToRemove, function(subContainer) { - if (subContainer) { subContainer.destroy(); } + forEach(subControllersToRemove, function(subController) { + if (subController) { subController.destroy(); } }); - replace(subContainers, idx, removedCnt, new Array(addedCnt)); + replace(subControllers, idx, removedCnt, new Array(addedCnt)); - // The shadow array of subcontainers must be updated before we trigger + // The shadow array of subcontrollers must be updated before we trigger // observers, otherwise observers will get the wrong subcontainer when // calling `objectAt` this._super(idx, removedCnt, addedCnt); @@ -12392,42 +12563,40 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin, init: function() { this._super(); - this._resetSubContainers(); + if (!this.get('content')) { Ember.defineProperty(this, 'content', undefined, Ember.A()); } + this.set('_subControllers', Ember.A()); }, controllerAt: function(idx, object, controllerClass) { var container = get(this, 'container'), - subContainers = get(this, 'subContainers'), - subContainer = subContainers[idx], - controller; + subControllers = get(this, '_subControllers'), + subController = subControllers[idx]; - if (!subContainer) { - subContainer = subContainers[idx] = container.child(); + if (!subController) { + subController = container.lookup("controller:" + controllerClass, { singleton: false }); + subControllers[idx] = subController; } - controller = subContainer.lookup("controller:" + controllerClass); - if (!controller) { + if (!subController) { throw new Error('Could not resolve itemController: "' + controllerClass + '"'); } - controller.set('target', this); - controller.set('content', object); + subController.set('target', this); + subController.set('content', object); - return controller; + return subController; }, - subContainers: null, + _subControllers: null, - _resetSubContainers: function() { - var subContainers = get(this, 'subContainers'); + _resetSubControllers: function() { + var subControllers = get(this, '_subControllers'); - if (subContainers) { - forEach(subContainers, function(subContainer) { - if (subContainer) { subContainer.destroy(); } - }); - } + forEach(subControllers, function(subController) { + if (subController) { subController.destroy(); } + }); - this.set('subContainers', Ember.A()); + this.set('_subControllers', Ember.A()); } }); @@ -12504,15 +12673,16 @@ Ember.$ = jQuery; @module ember @submodule ember-views */ +if (Ember.$) { + // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents + var dragEvents = Ember.String.w('dragstart drag dragenter dragleave dragover drop dragend'); -// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents -var dragEvents = Ember.String.w('dragstart drag dragenter dragleave dragover drop dragend'); - -// Copies the `dataTransfer` property from a browser event object onto the -// jQuery event object for the specified events -Ember.EnumerableUtils.forEach(dragEvents, function(eventName) { - Ember.$.event.fixHooks[eventName] = { props: ['dataTransfer'] }; -}); + // Copies the `dataTransfer` property from a browser event object onto the + // jQuery event object for the specified events + Ember.EnumerableUtils.forEach(dragEvents, function(eventName) { + Ember.$.event.fixHooks[eventName] = { props: ['dataTransfer'] }; + }); +} })(); @@ -12529,7 +12699,8 @@ Ember.EnumerableUtils.forEach(dragEvents, function(eventName) { // Internet Explorer prior to 9 does not allow setting innerHTML if the first element // is a "zero-scope" element. This problem can be worked around by making // the first node an invisible text node. We, like Modernizr, use ­ -var needsShy = (function(){ + +var needsShy = this.document && (function(){ var testEl = document.createElement('div'); testEl.innerHTML = "
"; testEl.firstChild.innerHTML = ""; @@ -12539,7 +12710,7 @@ var needsShy = (function(){ // IE 8 (and likely earlier) likes to move whitespace preceeding // a script tag to appear after it. This means that we can // accidentally remove whitespace when updating a morph. -var movesWhitespace = (function() { +var movesWhitespace = this.document && (function() { var testEl = document.createElement('div'); testEl.innerHTML = "Test: Value"; return testEl.childNodes[0].nodeValue === 'Test:' && @@ -13012,7 +13183,7 @@ Ember._RenderBuffer.prototype = for (prop in props) { if (props.hasOwnProperty(prop)) { var value = props[prop]; - if (value) { + if (value || typeof(value) === 'number') { if (value === true) { buffer.push(' ' + prop + '="' + prop + '"'); } else { @@ -13371,8 +13542,9 @@ Ember.EventDispatcher = Ember.Object.extend( // Add a new named queue for rendering views that happens // after bindings have synced, and a queue for scheduling actions // that that should occur after view rendering. -var queues = Ember.run.queues; -queues.splice(Ember.$.inArray('actions', queues)+1, 0, 'render', 'afterRender'); +var queues = Ember.run.queues, + indexOf = Ember.ArrayPolyfills.indexOf; +queues.splice(indexOf.call(queues, 'actions')+1, 0, 'render', 'afterRender'); })(); @@ -13457,7 +13629,7 @@ var childViewsProperty = Ember.computed(function() { ret.replace = function (idx, removedCount, addedViews) { if (view instanceof Ember.ContainerView) { - Ember.deprecate("Manipulating a Ember.ContainerView through its childViews property is deprecated. Please use the ContainerView instance itself as an Ember.MutableArray."); + Ember.deprecate("Manipulating an Ember.ContainerView through its childViews property is deprecated. Please use the ContainerView instance itself as an Ember.MutableArray."); return view.replace(idx, removedCount, addedViews); } throw new Error("childViews is immutable"); @@ -15618,17 +15790,24 @@ Ember.View = Ember.CoreView.extend( // once the view has been inserted into the DOM, legal manipulations // are done on the DOM element. +function notifyMutationListeners() { + Ember.run.once(Ember.View, 'notifyMutationListeners'); +} + var DOMManager = { prepend: function(view, html) { view.$().prepend(html); + notifyMutationListeners(); }, after: function(view, html) { view.$().after(html); + notifyMutationListeners(); }, html: function(view, html) { view.$().html(html); + notifyMutationListeners(); }, replace: function(view) { @@ -15638,15 +15817,18 @@ var DOMManager = { view._insertElementLater(function() { Ember.$(element).replaceWith(get(view, 'element')); + notifyMutationListeners(); }); }, remove: function(view) { view.$().remove(); + notifyMutationListeners(); }, empty: function(view) { view.$().empty(); + notifyMutationListeners(); } }; @@ -15761,6 +15943,20 @@ Ember.View.reopenClass({ } }); +var mutation = Ember.Object.extend(Ember.Evented).create(); + +Ember.View.addMutationListener = function(callback) { + mutation.on('change', callback); +}; + +Ember.View.removeMutationListener = function(callback) { + mutation.off('change', callback); +}; + +Ember.View.notifyMutationListeners = function() { + mutation.trigger('change'); +}; + /** Global views hash @@ -16637,7 +16833,7 @@ var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt; } else { viewClass = App.SongView; } - this._super(viewClass, attrs); + return this._super(viewClass, attrs); } }); ``` @@ -16920,15 +17116,15 @@ define("metamorph", var K = function(){}, guid = 0, - document = window.document, + document = this.document, // Feature-detect the W3C range API, the extended check is for IE9 which only partially supports ranges - supportsRange = ('createRange' in document) && (typeof Range !== 'undefined') && Range.prototype.createContextualFragment, + supportsRange = document && ('createRange' in document) && (typeof Range !== 'undefined') && Range.prototype.createContextualFragment, // Internet Explorer prior to 9 does not allow setting innerHTML if the first element // is a "zero-scope" element. This problem can be worked around by making // the first node an invisible text node. We, like Modernizr, use ­ - needsShy = (function(){ + needsShy = document && (function(){ var testEl = document.createElement('div'); testEl.innerHTML = "
"; testEl.firstChild.innerHTML = ""; @@ -16939,7 +17135,7 @@ define("metamorph", // IE 8 (and likely earlier) likes to move whitespace preceeding // a script tag to appear after it. This means that we can // accidentally remove whitespace when updating a morph. - movesWhitespace = (function() { + movesWhitespace = document && (function() { var testEl = document.createElement('div'); testEl.innerHTML = "Test: Value"; return testEl.childNodes[0].nodeValue === 'Test:' && @@ -17383,8 +17579,12 @@ var objectCreate = Object.create || function(parent) { return new F(); }; -var Handlebars = this.Handlebars || Ember.imports.Handlebars; -Ember.assert("Ember Handlebars requires Handlebars 1.0.rc.2 or greater", Handlebars && Handlebars.VERSION.match(/^1\.0\.rc\.[23456789]+/)); +var Handlebars = this.Handlebars || (Ember.imports && Ember.imports.Handlebars); +if(!Handlebars && typeof require === 'function') { + Handlebars = require('handlebars'); +} + +Ember.assert("Ember Handlebars requires Handlebars 1.0.0-rc.3 or greater", Handlebars && Handlebars.VERSION.match(/^1\.0\.[0-9](\.rc\.[23456789]+)?/)); /** Prepares the Handlebars templating library for use inside Ember's view @@ -18043,22 +18243,30 @@ Ember.Handlebars.resolvePaths = function(options) { var set = Ember.set, get = Ember.get; var Metamorph = requireModule('metamorph'); +function notifyMutationListeners() { + Ember.run.once(Ember.View, 'notifyMutationListeners'); +} + // DOMManager should just abstract dom manipulation between jquery and metamorph var DOMManager = { remove: function(view) { view.morph.remove(); + notifyMutationListeners(); }, prepend: function(view, html) { view.morph.prepend(html); + notifyMutationListeners(); }, after: function(view, html) { view.morph.after(html); + notifyMutationListeners(); }, html: function(view, html) { view.morph.html(html); + notifyMutationListeners(); }, // This is messed up. @@ -18081,11 +18289,13 @@ var DOMManager = { morph.replaceWith(buffer.string()); view.transitionTo('inDOM'); view.triggerRecursively('didInsertElement'); + notifyMutationListeners(); }); }, empty: function(view) { view.morph.html(""); + notifyMutationListeners(); } }; @@ -18977,7 +19187,9 @@ EmberHandlebars.registerHelper('bindAttr', function(options) { // Add an observer to the view for when the property changes. // When the observer fires, find the element using the // unique data id and update the attribute to the new value. - if (path !== 'this') { + // Note: don't add observer when path is 'this' or path + // is whole keyword e.g. {{#each x in list}} ... {{bindAttr attr="x"}} + if (path !== 'this' && !(normalized.isKeyword && normalized.path === '' )) { view.registerObserver(normalized.root, normalized.path, invoker); } @@ -20000,7 +20212,7 @@ GroupedEach.prototype = { ```handlebars {{#view App.MyView }} - {{each view.items itemViewClass="App.AnItemView"}} + {{each view.items itemViewClass="App.AnItemView"}} {{/view}} ``` @@ -20031,7 +20243,7 @@ GroupedEach.prototype = {
Greetings Sara
``` - + ### Representing each item with a Controller. By default the controller lookup within an `{{#each}}` block will be the controller of the template where the `{{#each}}` was used. If each @@ -20039,10 +20251,10 @@ GroupedEach.prototype = { `itemController` option which references a controller by lookup name. Each item in the loop will be wrapped in an instance of this controller and the item itself will be set to the `content` property of that controller. - + This is useful in cases where properties of model objects need transformation or synthesis for display: - + ```javascript App.DeveloperController = Ember.ObjectController.extend({ isAvailableForHire: function(){ @@ -20050,17 +20262,17 @@ GroupedEach.prototype = { }.property('isEmployed', 'isSeekingWork') }) ``` - + ```handlebars - {{#each person in Developers itemController="developer"}} + {{#each person in developers itemController="developer"}} {{person.name}} {{#if person.isAvailableForHire}}Hire me!{{/if}} {{/each}} ``` - + @method each @for Ember.Handlebars.helpers @param [name] {String} name for item (used with `in`) - @param path {String} path + @param [path] {String} path @param [options] {Object} Handlebars key/value pairs of options @param [options.itemViewClass] {String} a path to a view class used for each item @param [options.itemController] {String} name of a controller to be created for each item @@ -20119,6 +20331,14 @@ Ember.Handlebars.registerHelper('each', function(path, options) { ``` + ```handlebars + {{#if isUser}} + {{template "user_info"}} + {{else}} + {{template "unlogged_user_info"}} + {{/if}} + ``` + This helper looks for templates in the global `Ember.TEMPLATES` hash. If you add `